Explorar o código

[RavenHandler] Add environment and breadcrumbs support

Dimitri Gritsajuk %!s(int64=7) %!d(string=hai) anos
pai
achega
869ca5963f

+ 1 - 1
composer.json

@@ -19,7 +19,7 @@
     "require-dev": {
         "phpunit/phpunit": "^6.5",
         "graylog2/gelf-php": "^1.4.2",
-        "sentry/sentry": "^0.13",
+        "sentry/sentry": "^1.9",
         "ruflin/elastica": ">=0.90 <3.0",
         "doctrine/couchdb": "~1.0@dev",
         "aws/aws-sdk-php": "^2.4.9 || ^3.0",

+ 36 - 9
src/Monolog/Handler/RavenHandler.php

@@ -38,6 +38,11 @@ class RavenHandler extends AbstractProcessingHandler
         Logger::EMERGENCY => Raven_Client::FATAL,
     ];
 
+    /**
+     * @var string the current application environment (staging|preprod|prod)
+     */
+    private $environment;
+
     /**
      * @var string should represent the current version of the calling
      *             software. Can be any string (git commit, version number)
@@ -109,17 +114,15 @@ class RavenHandler extends AbstractProcessingHandler
      *
      * @param FormatterInterface $formatter
      */
-    public function setBatchFormatter(FormatterInterface $formatter)
+    public function setBatchFormatter(FormatterInterface $formatter): void
     {
         $this->batchFormatter = $formatter;
     }
 
     /**
      * Gets the formatter for the logs generated by handleBatch().
-     *
-     * @return FormatterInterface
      */
-    public function getBatchFormatter()
+    public function getBatchFormatter(): FormatterInterface
     {
         if (!$this->batchFormatter) {
             $this->batchFormatter = $this->getDefaultBatchFormatter();
@@ -177,6 +180,10 @@ class RavenHandler extends AbstractProcessingHandler
             $options['extra']['extra'] = $record['extra'];
         }
 
+        if (!empty($this->environment) && !isset($options['environment'])) {
+            $options['environment'] = $this->environment;
+        }
+
         if (!empty($this->release) && !isset($options['release'])) {
             $options['release'] = $this->release;
         }
@@ -190,7 +197,7 @@ class RavenHandler extends AbstractProcessingHandler
 
         // restore the user context if it was modified
         if (!is_bool($previousUserContext)) {
-            $this->ravenClient->user_context($previousUserContext);
+            $this->ravenClient->user_context($previousUserContext, false);
         }
     }
 
@@ -207,7 +214,7 @@ class RavenHandler extends AbstractProcessingHandler
      *
      * @return FormatterInterface
      */
-    protected function getDefaultBatchFormatter()
+    protected function getDefaultBatchFormatter(): FormatterInterface
     {
         return new LineFormatter();
     }
@@ -217,19 +224,39 @@ class RavenHandler extends AbstractProcessingHandler
      *
      * @return array
      */
-    protected function getExtraParameters()
+    protected function getExtraParameters(): array
     {
-        return ['checksum', 'release', 'event_id'];
+        return ['checksum', 'release', 'environment', 'event_id'];
     }
 
     /**
      * @param  string $value
      * @return self
      */
-    public function setRelease($value)
+    public function setRelease($value): self
     {
         $this->release = $value;
 
         return $this;
     }
+
+    public function setEnvironment($value): self
+    {
+        $this->environment = $value;
+
+        return $this;
+    }
+
+    /**
+     * @link https://docs.sentry.io/learn/breadcrumbs/
+     */
+    public function addBreadcrumb(array $crumb): void
+    {
+        $this->ravenClient->breadcrumbs->record($crumb);
+    }
+
+    public function resetBreadcrumbs(): void
+    {
+        $this->ravenClient->breadcrumbs->reset();
+    }
 }

+ 1 - 1
tests/Monolog/Handler/MockRavenClient.php

@@ -15,7 +15,7 @@ use Raven_Client;
 
 class MockRavenClient extends Raven_Client
 {
-    public function capture($data, $stack, $vars = null)
+    public function capture($data, $stack = null, $vars = null)
     {
         $data = array_merge($this->get_user_data(), $data);
         $this->lastData = $data;

+ 41 - 5
tests/Monolog/Handler/RavenHandlerTest.php

@@ -42,9 +42,7 @@ class RavenHandlerTest extends TestCase
 
     protected function getHandler($ravenClient)
     {
-        $handler = new RavenHandler($ravenClient);
-
-        return $handler;
+        return new RavenHandler($ravenClient);
     }
 
     protected function getRavenClient()
@@ -144,7 +142,7 @@ class RavenHandlerTest extends TestCase
         $this->assertSame('test_user_id', $ravenClient->context->user['id']);
 
         // handle with null context
-        $ravenClient->user_context(null);
+        $ravenClient->user_context(null, false);
         $handler->handle($recordWithContext);
         $this->assertEquals($user, $ravenClient->lastData['user']);
 
@@ -165,7 +163,7 @@ class RavenHandlerTest extends TestCase
             $handler->handle($record);
         }
 
-        $this->assertEquals($record['message'], $ravenClient->lastData['message']);
+        $this->assertEquals('[test] ' . $record['message'], $ravenClient->lastData['message']);
     }
 
     public function testHandleBatch()
@@ -256,6 +254,44 @@ class RavenHandlerTest extends TestCase
         $this->assertEquals($localRelease, $ravenClient->lastData['release']);
     }
 
+    public function testEnvironment()
+    {
+        $ravenClient = $this->getRavenClient();
+        $handler = $this->getHandler($ravenClient);
+        $handler->setEnvironment('preprod');
+
+        $handler->handle($this->getRecord(Logger::INFO, 'Hello 👋 from PREPROD env'));
+        $this->assertEquals('preprod', $ravenClient->lastData['environment']);
+
+        $handler->handle($this->getRecord(Logger::INFO, 'Hello 👋 from STAGING env', ['environment' => 'staging']));
+        $this->assertEquals('staging', $ravenClient->lastData['environment']);
+    }
+
+    public function testBreadcrumbs()
+    {
+        $ravenClient = $this->getRavenClient();
+        $handler = $this->getHandler($ravenClient);
+
+        $handler->addBreadcrumb($crumb1 = [
+            'level' => 'info',
+            'category' => 'test',
+            'message' => 'Step 1: user auth',
+        ]);
+
+        $handler->addBreadcrumb($crumb2 = [
+            'level' => 'info',
+            'category' => 'test',
+            'message' => 'Step 2: prepare user redirect',
+        ]);
+
+        $handler->handle($this->getRecord(Logger::ERROR, 'ERROR 💥'));
+        $this->assertArraySubset([$crumb1, $crumb2], $ravenClient->breadcrumbs->fetch());
+
+        $handler->resetBreadcrumbs();
+        $handler->handle($this->getRecord(Logger::INFO, 'Hello!'));
+        $this->assertEmpty($ravenClient->breadcrumbs->fetch());
+    }
+
     private function methodThatThrowsAnException()
     {
         throw new \Exception('This is an exception');