Add support for Raven, the protocol used by Sentry (http://github.com/dcramer/sentry) #76

Merged
merged 17 commits into from Jan 7, 2013

Projects

None yet

8 participants

@msabramo

Raven is the protocol used by Sentry. Uses raven-php, which is maintained by the Sentry team.

@Seldaek Seldaek and 1 other commented on an outdated diff Apr 26, 2012
composer.json
@@ -16,9 +16,11 @@
"php": ">=5.3.0"
},
"require-dev": {
+ "raven/raven": ">=0.2.0",
@Seldaek
Seldaek Apr 26, 2012

Please use 0.2.* or >=0.2.0,<1.0.0 or something more restrictive because this is not good since they could break BC in a future release. We shouldn't assume they won't.

@Seldaek Seldaek and 2 others commented on an outdated diff Apr 26, 2012
src/Monolog/Formatter/RavenFormatter.php
@@ -0,0 +1,51 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+use Monolog\Logger;
+use \Raven_Client;
@Seldaek
Seldaek Apr 26, 2012

No need for the leading \

@damianb
damianb Apr 26, 2012

Some IDEs flip out and bork autocomplete if the leading \ is not present (I know Komodo IDE 6 does, at the very least).

@msabramo
msabramo Apr 26, 2012

See ac161a0 (though don't know if I should put it back in light of what @damianb said?)

@Seldaek Seldaek and 1 other commented on an outdated diff Apr 26, 2012
src/Monolog/Formatter/RavenFormatter.php
+
+/**
+ * Serializes a log message for Raven (https://github.com/getsentry/raven-php)
+ *
+ * @author Marc Abramowitz <marc@marc-abramowitz.com>
+ */
+class RavenFormatter extends NormalizerFormatter
+{
+ /**
+ * Translates Monolog log levels to Raven log levels.
+ */
+ private $logLevels = array(
+ Logger::DEBUG => Raven_Client::DEBUG,
+ Logger::INFO => Raven_Client::INFO,
+ Logger::WARNING => Raven_Client::WARNING,
+ Logger::ERROR => Raven_Client::ERROR,
@Seldaek
Seldaek Apr 26, 2012

You should map CRITICAL and ALERT to ERROR as well if raven doesn't have more than ERROR, because otherwise those messages will fail.

@Seldaek Seldaek and 2 others commented on an outdated diff Apr 26, 2012
src/Monolog/Formatter/RavenFormatter.php
+ Logger::ERROR => Raven_Client::ERROR,
+ );
+
+ /**
+ * {@inheritdoc}
+ */
+ public function format(array $record)
+ {
+ $record = parent::format($record);
+
+ $record['level'] = $this->logLevels[$record['level']];
+ $record['message'] = $record['channel'] . ': ' . $record['message'];
+
+ if (isset($record['context']['context']))
+ {
+ $record['context'] = $record['context']['context'];
@Seldaek
Seldaek Apr 26, 2012

the { should be on the same line as the if, but more importantly.. what is this context=>context? :)

@stof
stof Apr 26, 2012

and what if there is other stuff in the context ?

@msabramo
msabramo Apr 26, 2012

See f158009 for curly brace. The if statement turned out to be not needed after changes to that context/exception stuff in 3238a74.

@Seldaek Seldaek and 1 other commented on an outdated diff Apr 26, 2012
src/Monolog/Handler/RavenHandler.php
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function close()
+ {
+ $this->ravenClient = null;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function write(array $record)
+ {
+ if ($record['level'] == Logger::ERROR)
@Seldaek
Seldaek Apr 26, 2012

Same thing here all the braces should be on the same line for if/else (and try/catch below), also this should be >= and not ==.

@Seldaek Seldaek and 1 other commented on an outdated diff Apr 26, 2012
tests/Monolog/Handler/RavenHandlerTest.php
+ $this->assertEquals(Raven_Client::WARNING, $ravenClient->lastData['level']);
+ $this->assertContains($record['message'], $ravenClient->lastData['message']);
+ }
+
+ public function testException()
+ {
+ $ravenClient = $this->getRavenClient();
+ $handler = $this->getHandler($ravenClient);
+
+ try
+ {
+ $this->methodThatThrowsAnException();
+ }
+ catch (\Exception $e)
+ {
+ $record = $this->getRecord(Logger::ERROR, $e->getMessage(), array('context' => $e));
@Seldaek
Seldaek Apr 26, 2012

Ok I get the context thing now, but.. I think this should be called exception, and then we should probably document this and make it a convention that logging an exception in monolog should ideally contain the exception object in the context array's "exception" key. That way we can adapt frameworks and such using it so that they do this, and we could detect that it's an exception and do some more stuff in some handlers. It would also be useful for the IntrospectionProcessor that could use the exception backtrace if it's available instead of crazy hackery like now.

@msabramo
msabramo Apr 26, 2012

Yeah that was a mess with that ['context']['context'] crap. See 3238a74 which changes it to ['context']['exception'] and checks that it's present before calling Raven_Client::captureException (otherwise it will fall back to calling Raven_Client::captureMessage).

@Seldaek Seldaek and 2 others commented on an outdated diff Apr 26, 2012
src/Monolog/Handler/RavenHandler.php
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function write(array $record)
+ {
+ if ($record['level'] == Logger::ERROR)
+ {
+ $this->ravenClient->captureException($record['context']['context']);
+ }
+ else
+ {
+ $this->ravenClient->captureMessage(
+ $record['formatted']['message'], $params = $record,
+ $record['formatted']['level'], $stack = true
@Seldaek
Seldaek Apr 26, 2012

If you expand it to multiple lines, I think one arg per line is more readable.

@stof
stof Apr 26, 2012

why are you creating a $params and a $stack (unused) local variables ? This is some PHP code, not some Python code. We don't have named arguments

@msabramo
msabramo Apr 26, 2012

See f6e75e4 and 7a81acd. I changed my local variables to comments, because I hate seeing arguments like true and having no idea what they mean. If folks don't like them I can remove them, but IMHO the added clarity is worth the slight ugliness.

@stof stof and 1 other commented on an outdated diff Apr 26, 2012
src/Monolog/Handler/RavenHandler.php
+ /**
+ * {@inheritdoc}
+ */
+ public function close()
+ {
+ $this->ravenClient = null;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function write(array $record)
+ {
+ if ($record['level'] == Logger::ERROR)
+ {
+ $this->ravenClient->captureException($record['context']['context']);
@stof
stof Apr 26, 2012

what if there is no exception provided for the ERROR message ? You get a nice NOTICE error when reading a invalid key in the array

@msabramo
msabramo Apr 26, 2012

Good point. I think the RavenHandler::write change in 3238a74 addresses this concern.

@stof stof commented on the diff Apr 26, 2012
tests/Monolog/Handler/RavenHandlerTest.php
+ public function capture($data, $stack)
+ {
+ $this->lastData = $data;
+ $this->lastStack = $stack;
+ }
+
+ public $lastData;
+ public $lastStack;
+}
+
+class RavenHandlerTest extends TestCase
+{
+ public function setUp()
+ {
+ if (!class_exists("Raven_Client")) {
+ $this->markTestSkipped("raven/raven not installed");
@stof
stof Apr 26, 2012

There is an issue here: this will never be reached as a fatal error will already be thrown by the mock class definition. You would need to move MockRavenClient to a separate file

@msabramo
msabramo Apr 26, 2012

Yeah, this seems to be a problem. Note that I copied this idiom from https://github.com/Seldaek/monolog/blob/master/tests/Monolog/Handler/GelfHandlerTest.php so it probably has the same problem.

@msabramo
msabramo Apr 26, 2012

OK, I have a fix for this in 44d2441:

Here's how I tested with and without raven-php available...

(sentry)[last: 0] marca@SCML-MarcA:~/Sites/sentry-test/vendor/monolog/monolog$ ls -ld vendor/raven 
drwxr-xr-x 3 marca CHEGG\domain users 102 Apr 25 08:10 vendor/raven/
(sentry)[last: 0] marca@SCML-MarcA:~/Sites/sentry-test/vendor/monolog/monolog$ phpunit
PHPUnit 3.6.10 by Sebastian Bergmann.

Configuration read from /Users/marca/Sites/sentry-test/vendor/monolog/monolog/phpunit.xml.dist

...............................................................  63 / 137 ( 45%)
............................................................... 126 / 137 ( 91%)
...........

Time: 0 seconds, Memory: 13.50Mb

OK (137 tests, 328 assertions)
(sentry)[last: 0] marca@SCML-MarcA:~/Sites/sentry-test/vendor/monolog/monolog$ mv vendor/raven vendor/_raven
(sentry)[last: 0] marca@SCML-MarcA:~/Sites/sentry-test/vendor/monolog/monolog$ ls -ld vendor/raven
gls: cannot access vendor/raven: No such file or directory
(sentry)[last: 0] marca@SCML-MarcA:~/Sites/sentry-test/vendor/monolog/monolog$ phpunit
PHPUnit 3.6.10 by Sebastian Bergmann.

Configuration read from /Users/marca/Sites/sentry-test/vendor/monolog/monolog/phpunit.xml.dist

...............................................................  63 / 137 ( 45%)
.SSSS.......................................................... 126 / 137 ( 91%)
...........

Time: 1 second, Memory: 13.50Mb

OK, but incomplete or skipped tests!
@msabramo
msabramo Apr 26, 2012

It looks like GelfHandlerTest has the same issue, filed as GH-78:

~/Sites/sentry-test/vendor/monolog/monolog$ mv vendor/mlehner vendor/_mlehner 
~/Sites/sentry-test/vendor/monolog/monolog$ ls -ld vendor/mlehner
ls: cannot access vendor/mlehner: No such file or directory
~/Sites/sentry-test/vendor/monolog/monolog$ phpunit
PHP Fatal error:  Class 'Gelf\MessagePublisher' not found in /Users/marca/Sites/sentry-test/vendor/monolog/monolog/tests/Monolog/Handler/GelfHandlerTest.php on line 21
PHP Stack trace:
PHP   1. {main}() /Users/marca/pear/bin/phpunit:0
PHP   2. PHPUnit_TextUI_Command::main() /Users/marca/pear/bin/phpunit:46
PHP   3. PHPUnit_TextUI_Command->run() /Users/marca/pear/share/pear/PHPUnit/TextUI/Command.php:130
PHP   4. PHPUnit_TextUI_Command->handleArguments() /Users/marca/pear/share/pear/PHPUnit/TextUI/Command.php:139
PHP   5. PHPUnit_Util_Configuration->getTestSuiteConfiguration() /Users/marca/pear/share/pear/PHPUnit/TextUI/Command.php:671
PHP   6. PHPUnit_Util_Configuration->getTestSuite() /Users/marca/pear/share/pear/PHPUnit/Util/Configuration.php:768
PHP   7. PHPUnit_Framework_TestSuite->addTestFiles() /Users/marca/pear/share/pear/PHPUnit/Util/Configuration.php:848
PHP   8. PHPUnit_Framework_TestSuite->addTestFile() /Users/marca/pear/share/pear/PHPUnit/Framework/TestSuite.php:419
PHP   9. PHPUnit_Util_Fileloader::checkAndLoad() /Users/marca/pear/share/pear/PHPUnit/Framework/TestSuite.php:358
PHP  10. PHPUnit_Util_Fileloader::load() /Users/marca/pear/share/pear/PHPUnit/Util/Fileloader.php:79
PHP  11. include_once() /Users/marca/pear/share/pear/PHPUnit/Util/Fileloader.php:95

Fatal error: Class 'Gelf\MessagePublisher' not found in /Users/marca/Sites/sentry-test/vendor/monolog/monolog/tests/Monolog/Handler/GelfHandlerTest.php on line 21

Call Stack:
    0.0003     633432   1. {main}() /Users/marca/pear/bin/phpunit:0
    0.0041    1150600   2. PHPUnit_TextUI_Command::main() /Users/marca/pear/bin/phpunit:46
    0.0042    1151328   3. PHPUnit_TextUI_Command->run() /Users/marca/pear/share/pear/PHPUnit/TextUI/Command.php:130
    0.0042    1151328   4. PHPUnit_TextUI_Command->handleArguments() /Users/marca/pear/share/pear/PHPUnit/TextUI/Command.php:139
    0.0164    3191376   5. PHPUnit_Util_Configuration->getTestSuiteConfiguration() /Users/marca/pear/share/pear/PHPUnit/TextUI/Command.php:671
    0.0164    3192408   6. PHPUnit_Util_Configuration->getTestSuite() /Users/marca/pear/share/pear/PHPUnit/Util/Configuration.php:768
    0.0232    3560352   7. PHPUnit_Framework_TestSuite->addTestFiles() /Users/marca/pear/share/pear/PHPUnit/Util/Configuration.php:848
    0.0596    6247784   8. PHPUnit_Framework_TestSuite->addTestFile() /Users/marca/pear/share/pear/PHPUnit/Framework/TestSuite.php:419
    0.0597    6248384   9. PHPUnit_Util_Fileloader::checkAndLoad() /Users/marca/pear/share/pear/PHPUnit/Framework/TestSuite.php:358
    0.0597    6248544  10. PHPUnit_Util_Fileloader::load() /Users/marca/pear/share/pear/PHPUnit/Util/Fileloader.php:79
    0.0600    6392056  11. include_once('/Users/marca/Sites/sentry-test/vendor/monolog/monolog/tests/Monolog/Handler/GelfHandlerTest.php') /Users/marca/pear/share/pear/PHPUnit/Util/Fileloader.php:95
msabramo added some commits Apr 26, 2012
@msabramo msabramo composer.json: Tighten requirement "raven/raven": ">=0.2.0" to
"raven/raven": "0.2.*" as suggested by @Seldaek in
https://github.com/Seldaek/monolog/pull/76/files#r737288
8aeb75a
@msabramo msabramo Remove leading \ in use statement, as suggested by @Seldaek in ac161a0
@msabramo msabramo Map CRITICAL and ALERT to ERROR because raven doesn't have more than
ERROR, because otherwise those messages will fail. As suggested by
@Seldaek in https://github.com/Seldaek/monolog/pull/76/files#r737292
0e579f1
@msabramo msabramo Minor reformatting suggested by @Seldaek in f158009
@msabramo msabramo Put braces on same line for if statements, as requested by @Seldaek in 6d15811
@msabramo msabramo Put args one per line, as suggested by @Seldaek in f6e75e4
@msabramo msabramo Rework how exceptions are stored and accessed using suggestions from 3238a74
@msabramo msabramo Change check of record level to >= Logger::ERROR instead of >
Logger::ERROR, as suggested by @Seldaek in
Seldaek#76 (comment)
1c59696
@msabramo msabramo Eliminate local variables used as pseudo-named-arguments, as suggested 7a81acd
@msabramo msabramo Change key from 'context' to 'exception' in
RavenHandlerTest::testException
6b4b2a6
@msabramo msabramo Pull MockRavenClient (which depends on Raven_Client) out of
tests/Monolog/Handler/RavenHandlerTest.php into a separate file so that
the test can pass when raven-php is installed and can be skipped when
raven-php is not installed. Addresses @Stof's comment in
Seldaek#76 (comment)
44d2441
@stof stof and 1 other commented on an outdated diff Apr 27, 2012
tests/Monolog/Handler/RavenHandlerTest.php
+
+ $this->assertEquals($ravenClient::WARNING, $ravenClient->lastData['level']);
+ $this->assertContains($record['message'], $ravenClient->lastData['message']);
+ }
+
+ public function testException()
+ {
+ $ravenClient = $this->getRavenClient();
+ $handler = $this->getHandler($ravenClient);
+
+ try
+ {
+ $this->methodThatThrowsAnException();
+ }
+ catch (\Exception $e)
+ {
@stof
stof Apr 27, 2012

curly braces should be on the same line than the control structure (same than if, for, foreach and while)

@msabramo

Any more changes needed on this PR?

@Seldaek
Owner

Nope it looks good but I haven't had time to look more in depth.

@msabramo

@stof, Any more feedback?

@stof stof commented on an outdated diff May 6, 2012
src/Monolog/Formatter/RavenFormatter.php
+ Logger::DEBUG => Raven_Client::DEBUG,
+ Logger::INFO => Raven_Client::INFO,
+ Logger::WARNING => Raven_Client::WARNING,
+ Logger::ERROR => Raven_Client::ERROR,
+ Logger::CRITICAL => Raven_Client::ERROR,
+ Logger::ALERT => Raven_Client::ERROR,
+ );
+
+ /**
+ * {@inheritdoc}
+ */
+ public function format(array $record)
+ {
+ $record = parent::format($record);
+
+ $record['level'] = $this->logLevels[$record['level']];
@stof
stof May 6, 2012

instead of changing the level here, I would move the level map to the handler to be consistent with other handlers

@stof
stof Jun 19, 2012

and the formatter should return only the formatted message instead of returning a full record with a different message.

@stof stof commented on an outdated diff May 6, 2012
src/Monolog/Handler/RavenHandler.php
+ public function close()
+ {
+ $this->ravenClient = null;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function write(array $record)
+ {
+ if ($record['level'] >= Logger::ERROR && isset($record['context']['exception'])) {
+ $this->ravenClient->captureException($record['context']['exception']);
+ } else {
+ $this->ravenClient->captureMessage(
+ $record['formatted']['message'],
+ $record, // $params
@stof
stof May 6, 2012

this will duplicate many things (as $record['formatted'] contains the normalized record). It should probably be limited to $record['formatted'].

Thus, looking at the raven client, it seems wrong. the params array is meant to contain params to fill placeholders of the message through sprintf. This is not what the record is about. With your current implementation, the message sent to Raven will not contain any data of the context or extra array (and it will store its own timestamp instead of the timestamp provided by Monolog)

@stof stof and 1 other commented on an outdated diff May 6, 2012
src/Monolog/Handler/RavenHandler.php
+ $this->ravenClient = null;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function write(array $record)
+ {
+ if ($record['level'] >= Logger::ERROR && isset($record['context']['exception'])) {
+ $this->ravenClient->captureException($record['context']['exception']);
+ } else {
+ $this->ravenClient->captureMessage(
+ $record['formatted']['message'],
+ $record, // $params
+ $record['formatted']['level'], // $level
+ true // $stack
@stof
stof May 6, 2012

I don't think forcing to use the stacktrace is a good idea. It should be configurable in the constructor

@Seldaek
Seldaek Jun 19, 2012

I agree that for messages it's probably not needed in most cases, for exceptions though it's great. Maybe just capture if level is above ERROR?

@stof stof commented on an outdated diff May 6, 2012
src/Monolog/Handler/RavenHandler.php
+
+ /**
+ * {@inheritdoc}
+ */
+ public function close()
+ {
+ $this->ravenClient = null;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function write(array $record)
+ {
+ if ($record['level'] >= Logger::ERROR && isset($record['context']['exception'])) {
+ $this->ravenClient->captureException($record['context']['exception']);
@stof
stof May 6, 2012

While having a convention about the way to provide exception in the context to allow a special handling is fine, I'm concerned with this implementation: it will log only the exception and drop the log message (which could be better to understand the issue as the dev could have explained why he catched the exception in this case and logged it).

@yguedidi

Some news about this PR ?

@stof

Well, there is still some feedback which has not been taken into account

@msabramo

Sorry to take so long. I'm not really working with Sentry or monolog these days, so this is all very rusty in my head now I'm afraid.

I just pushed commit 5d17212 which addresses some but not all of @stof's comments. Maybe it's too late at night or perhaps it's simply because I've been away from monolog and raven for a long time, but I had trouble grokking some of it, particularly the comment about the $params passed to the Raven_Client, so I didn't handle all of the concerns.

If there are other folks who are interested in this PR, then it may be most expedient for them to tackle what's remaining. I don't have quite as much time or motivation as I did when I first submitted this many months ago.

I wonder also if the tests could use some improving. It sounds like some stuff with params doesn't work, so maybe I am missing some test cases here.

@msabramo

Looking at this a little bit more this morning, I guess I'm a little confused about what should be done in formatters vs. handlers.

Some of the existing stuff in Monolog follows what you said -- where the translation of log levels happens in the handler and often these have no formatter (which makes sense because the formatters as they're explained in the docs mostly do things that are completely independent of the handler -- e.g.: adding timestamps). An example of this type of handler is SyslogHandler.

Others are splitting processing between the handler and the formatter (and I probably copied the structure of one of these; in fact, I probably copied GelfHandler since Graylog seemed most similar to Sentry). Examples are:

  • FirePHPHandler and WildfireFormatter.
  • ChromePHPHandler and ChromePHPFormatter
  • GelfHandler and GelfMessageFormatter

I think I followed the model of the latter group (specifically GelfHandler), but I wonder if I should be following the model of the former. It seems to me that I probably could get by with just RavenHandler and completely get rid of RavenFormatter. This would let me take advantage of other formatters. Am I right about this?

@stof

In this case, indeed. Your formatted message is not a special format (like for ChromePHP or FirePHP) but a string. So you should simply use a LineFormatter here (btw, your RavenFormatter is simply a Lineformatter with a particular format which is not the default one)

@msabramo

Can I just remove getDefaultFormatter entirely and let it fall back to the default formatter defined by AbstractHandler?

@msabramo

I'm also leaning towards passing $params = array() to Raven_Client::captureMessage because I don't see anything useful at the moment that I can put there (I think what I had before was silly and not doing anything). This seems to be a special feature of Raven which monolog doesn't really need (since it has its own formatters)...?

@msabramo msabramo Remove RavenFormatter; this is not needed since Raven is a very simple
text-oriented interface and doesn't need special processing.
368b1f0
@msabramo

Hopefully, with 368b1f0, we are almost there.

@stof stof and 1 other commented on an outdated diff Oct 25, 2012
src/Monolog/Handler/RavenHandler.php
+ * @param integer $level The minimum logging level at which this handler will be triggered
+ * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
+ */
+ public function __construct(Raven_Client $ravenClient, $level = Logger::DEBUG, $bubble = true)
+ {
+ parent::__construct($level, $bubble);
+
+ $this->ravenClient = $ravenClient;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function close()
+ {
+ $this->ravenClient = null;
@stof
stof Oct 25, 2012

Removing the dependency seems weird to me

@msabramo
msabramo Oct 25, 2012

Which dependency? I meant to remove RavenFormatter. RavenHandler still depends on RavenClient (in line 16). Or maybe you wanted me to keep a defintion of getDefaultFormatter?

Let me know what you meant and I'll try to turn it around quick.

@stof
stof Oct 25, 2012

you are removing the dependency of the handler (the raven client) on close, which seems weird to me. This means that the handler is in a totally broken state once close (calling a method on it would trigger a fatal error). And removing the reference is not needed. PHP is able to garbage collect objects.

@msabramo

OK, I removed the close method. As an aside, GelfHandler does this as well and that is almost certainly where it came from for me.

Personally, I expect things to be unusable after I call close on them so that didn't bother me. But I don't think it matters much either way as garbage collection will take care of like you said, so I'm fine with removing the close method.

Maybe close in monolog is more of a flush in that for RotatingFileHandler it does log rotation. I don't think I realized that until now and thought of close more in the sense of what you do on a raw file or a database connection.

Although just now I noticed that StreamHandler also closes and sets the underlying stream to null. So I don't know what close is supposed to do; I guess it's implementation-dependent.

I don't really see any place where Logger calls close (either implicitly or exposing a method that lets the user close the logger), so this might be a moot point.

@msabramo

Let me know if you'd like me to make more changes.

@stof

This looks good to me. Could you update the readme to add the handler in the list ?

@msabramo

Okey doke. Done in 10fcd61.

@msabramo

Bump (only because my last day at my PHP-focused job is tomorrow and I'd like to get closure on this before I get busy with other stuff).

@Seldaek
Owner

@msabramo thanks, unfortunately I don't have time right now but I'll try to look at all the monolog PRs in the nearish future. I'm sure this is fine by now though, don't let this keep you up at night :)

@msabramo

@Seldaek Thanks! No problem. If minor tweaks are needed later on I might be able to make them, but I hesitate to commit. Like you said, it's been through quite a few rounds of discussion, so it's probably very close.

@vytautasgimbutas

I think you shouldn't use captureMessage as you can't pass additional data parameters.

@luxifer

+1 for this pull request

@skrivanos skrivanos commented on the diff Dec 7, 2012
src/Monolog/Handler/RavenHandler.php
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function write(array $record)
+ {
+ $this->ravenClient->captureMessage(
+ $record['formatted'],
+ array(), // $params - not used
+ $this->logLevels[$record['level']], // $level
+ false // $stack
+ );
+ if ($record['level'] >= Logger::ERROR && isset($record['context']['exception'])) {
+ $this->ravenClient->captureException($record['context']['exception']);
+ }
@skrivanos
skrivanos Dec 7, 2012

Won't this capture exceptions twice? Once as a regular message and once as an exception.

@Seldaek Seldaek merged commit 10fcd61 into Seldaek:master Jan 7, 2013
@Seldaek
Owner

Merged, thanks. I mapped the new monolog log levels to sentry equivalents and added FATAL levels since it seems raven 0.3 added that level. If anyone uses this and thinks it can be improved somehow feel free to open an issue. I know there was some unresolved feedback above but from what I can tell it should work as it is, I just don't know sentry/raven enough to assess this in greater detail. Feedback from the trenches would be welcome.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment