From b293ac7cfca269fa75e5a534c54679b2093ff88f Mon Sep 17 00:00:00 2001 From: Sebastian Kurfuerst Date: Mon, 24 Apr 2017 16:56:52 +0200 Subject: [PATCH 1/5] FEATURE: Take exception rendering configuration into account when logging exceptions to Graylog As an example, the following configuration can be used to disable logging (to disk AND to graylog): ``` Neos: Flow: error: exceptionHandler: renderingGroups: hmacErrors: matchingExceptionClassNames: ['Neos\Flow\Security\Exception\InvalidHashException'] options: logException: FALSE ``` --- Classes/Error/GraylogExceptionHandler.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Classes/Error/GraylogExceptionHandler.php b/Classes/Error/GraylogExceptionHandler.php index 66a6034..ccb27d7 100644 --- a/Classes/Error/GraylogExceptionHandler.php +++ b/Classes/Error/GraylogExceptionHandler.php @@ -28,10 +28,15 @@ class GraylogExceptionHandler extends ProductionExceptionHandler */ protected function echoExceptionWeb($exception) { + if ($this->graylogService === null) { $this->graylogService = new GraylogService(); } - $this->graylogService->logException($exception); + + if (isset($this->renderingOptions['logException']) && $this->renderingOptions['logException']) { + $this->graylogService->logException($exception); + } + parent::echoExceptionWeb($exception); } @@ -44,7 +49,11 @@ protected function echoExceptionCli($exception) if ($this->graylogService === null) { $this->graylogService = new GraylogService(); } - $this->graylogService->logException($exception); + + if (isset($this->renderingOptions['logException']) && $this->renderingOptions['logException']) { + $this->graylogService->logException($exception); + } + parent::echoExceptionCli($exception); } } From 046fb718925eca81dfec5711fa2a217ee24a8f38 Mon Sep 17 00:00:00 2001 From: Bastian Date: Tue, 25 Apr 2017 15:37:42 +0200 Subject: [PATCH 2/5] TASK: Tweak retrieval of GraylogService in Exception handler --- Classes/Error/GraylogExceptionHandler.php | 31 +++++++++++++++-------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/Classes/Error/GraylogExceptionHandler.php b/Classes/Error/GraylogExceptionHandler.php index ccb27d7..5986624 100644 --- a/Classes/Error/GraylogExceptionHandler.php +++ b/Classes/Error/GraylogExceptionHandler.php @@ -8,6 +8,7 @@ use Neos\Flow\Annotations as Flow; use Neos\Flow\Error\ProductionExceptionHandler; +use Neos\Flow\ObjectManagement\DependencyInjection\DependencyProxy; use Yeebase\Graylog\GraylogService; /** @@ -28,13 +29,8 @@ class GraylogExceptionHandler extends ProductionExceptionHandler */ protected function echoExceptionWeb($exception) { - - if ($this->graylogService === null) { - $this->graylogService = new GraylogService(); - } - if (isset($this->renderingOptions['logException']) && $this->renderingOptions['logException']) { - $this->graylogService->logException($exception); + $this->getGraylogService()->logException($exception); } parent::echoExceptionWeb($exception); @@ -46,14 +42,27 @@ protected function echoExceptionWeb($exception) */ protected function echoExceptionCli($exception) { - if ($this->graylogService === null) { - $this->graylogService = new GraylogService(); - } - if (isset($this->renderingOptions['logException']) && $this->renderingOptions['logException']) { - $this->graylogService->logException($exception); + $this->getGraylogService()->logException($exception); } parent::echoExceptionCli($exception); } + + /** + * Returns an instance of the injected GraylogService (including a fallback to a manually instantiated instance + * if Dependency Injection is not (yet) available) + * + * @return GraylogService + */ + private function getGraylogService() + { + if ($this->graylogService instanceof GraylogService) { + return $this->graylogService; + } elseif ($this->graylogService instanceof DependencyProxy) { + return $this->graylogService->_activateDependency(); + } else { + return new GraylogService(); + } + } } From 3178c35056f1bc829bbc88ce3ce5795296409aa3 Mon Sep 17 00:00:00 2001 From: Bastian Date: Tue, 25 Apr 2017 15:46:53 +0200 Subject: [PATCH 3/5] FEATURE: Tweak README --- README.md | 52 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index f38c247..735c6b1 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,18 @@ -Yeebase.Graylog -================ +# Yeebase.Graylog The Yeebase.Graylog Flow package logs your exceptions as well as single messages to a central Graylog server. This package also provides a simple backend to log message of Flows Logger classes to a Graylog server. It depends on the official GELF php package https://github.com/bzikarsky/gelf-php -Installation & configuration ------------- +## Installation & configuration -Just add "yeebase/graylog" as dependency to your composer.json and run a "composer update" in your project's root folder. +Just add "yeebase/graylog" as dependency to your composer.json and run a "composer update" in your project's root folder +or simply execute: +``` +composer require yeebase/graylog +``` +from your project's root. Configure your Graylog Server: ```yaml @@ -18,9 +21,9 @@ Yeebase: host: '127.0.0.1' port: 12201 chunksize: 'wan' - skipStatusCodes: [403, 404] ``` +### Log exceptions Activate the exception handler and configure the connection to your graylog server in your Settings.yaml: @@ -32,17 +35,50 @@ Neos: className: 'Yeebase\Graylog\Error\GraylogExceptionHandler' ``` -If you wish to log normal log messages to your Graylog server just use the provided GraylogLoggerInterface: +*Note:* For `Development` context, the `Neos.Flow` package overrides this setting. Make sure to add this configuration +in the right context Settings.yaml. + +#### Filter exceptions + +To skip certain exceptions from being logged you can either use the `skipStatusCodes` setting: ```yaml +Yeebase: + Graylog: + # don't log any exceptions that would result in a HTTP status 403 (access denied) / 404 (not found) + skipStatusCodes: [403, 404] +``` + +Since version 2.1 you can alternatively use the `renderingGroups` Flow setting, i.e. to exclude certain Exception +*classes* from being logged: + +```yaml +Neos: + Flow: + error: + exceptionHandler: + className: 'Yeebase\Graylog\Error\GraylogExceptionHandler' + renderingGroups: + 'accessDeniedExceptions': + matchingExceptionClassNames: ['Neos\Flow\Security\Exception\AccessDeniedException'] + options: + logException: false +``` + +### Manual logging + + +If you wish to log normal log messages to your Graylog server just use the provided `GraylogLoggerInterface`: +```php use Neos\Flow\Annotations as Flow; +use Yeebase\Graylog\Log\GraylogLoggerInterface; class SomeClass { /** * @Flow\Inject - * @var Yeebase\Graylog\Log\GraylogLoggerInterface + * @var GraylogLoggerInterface */ protected $graylogLogger; From c29d18040295c17e2651fbc911d7477b8e102a58 Mon Sep 17 00:00:00 2001 From: Johannes Steu Date: Tue, 12 Sep 2017 12:40:33 +0200 Subject: [PATCH 4/5] TASK: Make sure that the GraylogService is present --- Classes/Log/Backend/GraylogBackend.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Classes/Log/Backend/GraylogBackend.php b/Classes/Log/Backend/GraylogBackend.php index 3179d20..8091c6e 100644 --- a/Classes/Log/Backend/GraylogBackend.php +++ b/Classes/Log/Backend/GraylogBackend.php @@ -56,7 +56,11 @@ public function append($message, $severity = LOG_INFO, $additionalData = null, $ !is_null($additionalData) ? $messageContext['additionalData'] = $additionalData : ''; !is_null($ipAddress) ? $messageContext['ipAddress'] = $ipAddress : ''; !is_null($severityLabel) ? $messageContext['severityLabel'] = $severityLabel : ''; - + + if (!$this->graylogService instanceof GraylogService) { + $this->graylogService = new GraylogService(); + } + $this->graylogService->logMessage($output, $messageContext, $severity); } From 6b9a0dd276764b7ecb47b7749b8f279eb06183e9 Mon Sep 17 00:00:00 2001 From: Bastian Date: Fri, 29 Sep 2017 12:46:19 +0200 Subject: [PATCH 5/5] BUGFIX: Some tweaks and minor fixes * Correctly set $messageContext in `GraylogBackendGraylogBackend` * Retrieve the injected GraylogService if available * Fix some @param and class annotations --- Classes/Log/Backend/GraylogBackend.php | 64 ++++++++++++++++++-------- Classes/Log/GraylogLoggerInterface.php | 6 --- 2 files changed, 45 insertions(+), 25 deletions(-) diff --git a/Classes/Log/Backend/GraylogBackend.php b/Classes/Log/Backend/GraylogBackend.php index 8091c6e..a252592 100644 --- a/Classes/Log/Backend/GraylogBackend.php +++ b/Classes/Log/Backend/GraylogBackend.php @@ -8,6 +8,7 @@ use Neos\Flow\Annotations as Flow; use Neos\Flow\Log\Backend\AbstractBackend; +use Neos\Flow\ObjectManagement\DependencyInjection\DependencyProxy; use Yeebase\Graylog\GraylogService; /** @@ -31,12 +32,13 @@ class GraylogBackend extends AbstractBackend /** * This method will send a message to our graylog service * - * @param string $message - * @param int $severity - * @param null $additionalData - * @param null $packageKey - * @param null $className - * @param null $methodName + * @param string $message The message to log + * @param integer $severity One of the LOG_* constants + * @param mixed $additionalData A variable containing more information about the event to be logged + * @param string $packageKey Key of the package triggering the log (determined automatically if not specified) + * @param string $className Name of the class triggering the log (determined automatically if not specified) + * @param string $methodName Name of the method triggering the log (determined automatically if not specified) + * @return void */ public function append($message, $severity = LOG_INFO, $additionalData = null, $packageKey = null, $className = null, $methodName = null) { @@ -49,21 +51,22 @@ public function append($message, $severity = LOG_INFO, $additionalData = null, $ $output = $severityLabel . ': ' . $message; - $messageContext = []; - !is_null($packageKey) ? $messageContext['packageKey'] = $packageKey : ''; - !is_null($className) ? $messageContext['className'] = $className : ''; - !is_null($methodName) ? $messageContext['methodName'] = $methodName : ''; - !is_null($additionalData) ? $messageContext['additionalData'] = $additionalData : ''; - !is_null($ipAddress) ? $messageContext['ipAddress'] = $ipAddress : ''; - !is_null($severityLabel) ? $messageContext['severityLabel'] = $severityLabel : ''; - - if (!$this->graylogService instanceof GraylogService) { - $this->graylogService = new GraylogService(); - } - - $this->graylogService->logMessage($output, $messageContext, $severity); + $messageContext = [ + 'packageKey' => !is_null($packageKey) ? $packageKey : '', + 'className' => !is_null($className) ? $className : '', + 'methodName' => !is_null($methodName) ? $methodName : '', + 'additionalData' => !is_null($additionalData) ? $additionalData : '', + 'ipAddress' => !is_null($ipAddress) ? $ipAddress : '', + 'severityLabel' => !is_null($severityLabel) ? $severityLabel : '', + ]; + $this->getGraylogService()->logMessage($output, $messageContext, $severity); } + /** + * Called when this backend is added to a logger + * + * @return void + */ public function open() { $this->severityLabels = [ @@ -78,7 +81,30 @@ public function open() ]; } + /** + * Called when this backend is removed from a logger + * + * @return void + */ public function close() { + // nothing to do here + } + + /** + * Returns an instance of the injected GraylogService (including a fallback to a manually instantiated instance + * if Dependency Injection is not (yet) available) + * + * @return GraylogService + */ + private function getGraylogService() + { + if ($this->graylogService instanceof GraylogService) { + return $this->graylogService; + } elseif ($this->graylogService instanceof DependencyProxy) { + return $this->graylogService->_activateDependency(); + } else { + return new GraylogService(); + } } } diff --git a/Classes/Log/GraylogLoggerInterface.php b/Classes/Log/GraylogLoggerInterface.php index e017ee8..43deda2 100644 --- a/Classes/Log/GraylogLoggerInterface.php +++ b/Classes/Log/GraylogLoggerInterface.php @@ -6,14 +6,8 @@ * * * */ -use Neos\Flow\Annotations as Flow; use Neos\Flow\Log\LoggerInterface; -/** - * Class ContentApiLogger - * - * @package Yeebase\t3n\ContentApi\Log - */ interface GraylogLoggerInterface extends LoggerInterface {