Skip to content

Commit 6c655fb

Browse files
committed
feature #492 Add support for configuring Gelf encoders in Monolog configuration (Tibor Rac, Tib-z, HypeMC)
This PR was merged into the 3.x branch. Discussion ---------- Add support for configuring Gelf encoders in Monolog configuration This commit introduces the ability to specify custom encoders (`json` and `compressed_json`) for Gelf publishers in Monolog's configuration. Overview This PR introduces an enhancement to the Symfony Monolog Bundle by adding a configuration option for setting the message encoder for the GELF handler's publisher. This change addresses a backward compatibility issue introduced in the 2.0 update of the graylog2/gelf-php package, which shifted the default message encoder from CompressedJsonEncoder to JsonEncoder. Thus an upgrade silently breakes the logging. bzikarsky/gelf-php@f2625cf#diff-9520be6ea98f5ded11cbe62c500f1a8fef819810d8836d2b15189cdbc073900cR32 bzikarsky/gelf-php@f2625cf#diff-72a9d13c23b7d615833219f0dfc92be317d9a4981de7b4747e287db62aaa1079L69 In a Symfony project, to override this default behavior, users had to manually construct and define the transport, publisher, and encoder as a service and then use it in the Monolog configuration. This approach, while functional, is cumbersome. It would be more user-friendly to enable setting the encoder via a simple configuration option. The proposed change would be: ``` gelf: type: gelf level: debug publisher: hostname: '%env(resolve:LOGSTASH_HOSTNAME)%' port: '%env(resolve:LOGSTASH_PORT)%' encoder: compressed_json # Optional: 'json' or 'compressed_json' ``` This new encoder configuration is optional and does not have an explicit default value, thereby preserving the existing behavior (albeit the recent default may not align with prior expectations). While it might be tempting to expose more variability (like using class names or service IDs directly), overly customizable options may not add practical value and could complicate the configuration unnecessarily, 'coz YAGNI :) Commits ------- e208cca Fix CS b2ee640 Use RuntimeException instead of InvalidConfigurationException in extension 1d2d39c Use RuntimeException instead of InvalidConfigurationException in extension 234ea20 Change encoder config node from scalar to enum b9eedd6 Fix indentation e86b0b4 Update GELF config documentation for clarity b234af6 Remove tests that fake Gelf classes 7bf64b8 Fix typo in configuration comment 5cb4306 Fix compatibility issue, update class_alias to use DummyClassForClassExistsCheck ec1de9e Add support for custom Gelf encoders in Monolog configuration
2 parents 2ebfbee + e208cca commit 6c655fb

File tree

4 files changed

+51
-1
lines changed

4 files changed

+51
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
* Drop support for Symfony < 6.4
1313
* Add TelegramBotHandler `topic` support
1414
* Deprecate `sentry` and `raven` handler, use a `service` handler with [`sentry/sentry-symfony`](https://docs.sentry.io/platforms/php/guides/symfony/logs/) instead
15+
* Add configuration for Gelf encoders
1516

1617
## 3.10.0 (2023-11-06)
1718

src/DependencyInjection/Configuration.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,15 @@
5252
* - [bubble]: bool, defaults to true
5353
*
5454
* - gelf:
55-
* - publisher: {id: ...} or {hostname: ..., port: ..., chunk_size: ...}
55+
* - publisher: (one of the following configurations)
56+
* # Option 1: Service-based configuration
57+
* - id: string, service id of a publisher implementation
58+
*
59+
* # Option 2: Direct connection configuration
60+
* - hostname: string, server hostname
61+
* - [port]: int, server port (default: 12201)
62+
* - [chunk_size]: int, UDP packet size (default: 1420)
63+
* - [encoder]: string, encoding format ('json' or 'compressed_json')
5664
* - [level]: level name or int value, defaults to DEBUG
5765
* - [bubble]: bool, defaults to true
5866
*
@@ -831,6 +839,7 @@ private function addGelfSection(ArrayNodeDefinition $handlerNode)
831839
->scalarNode('hostname')->end()
832840
->scalarNode('port')->defaultValue(12201)->end()
833841
->scalarNode('chunk_size')->defaultValue(1420)->end()
842+
->enumNode('encoder')->values(['json', 'compressed_json'])->end()
834843
->end()
835844
->validate()
836845
->ifTrue(function ($v) {

src/DependencyInjection/MonologExtension.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,10 +221,28 @@ private function buildHandler(ContainerBuilder $container, $name, array $handler
221221
]);
222222
$transport->setPublic(false);
223223

224+
if (isset($handler['publisher']['encoder'])) {
225+
if ('compressed_json' === $handler['publisher']['encoder']) {
226+
$encoderClass = 'Gelf\Encoder\CompressedJsonEncoder';
227+
} elseif ('json' === $handler['publisher']['encoder']) {
228+
$encoderClass = 'Gelf\Encoder\JsonEncoder';
229+
} else {
230+
throw new \RuntimeException('The gelf message encoder must be either "compressed_json" or "json".');
231+
}
232+
233+
$encoder = new Definition($encoderClass);
234+
$encoder->setPublic(false);
235+
236+
$transport->addMethodCall('setMessageEncoder', [$encoder]);
237+
}
238+
224239
$publisher = new Definition('Gelf\Publisher', []);
225240
$publisher->addMethodCall('addTransport', [$transport]);
226241
$publisher->setPublic(false);
227242
} elseif (class_exists('Gelf\MessagePublisher')) {
243+
if (isset($handler['publisher']['encoder']) && 'compressed_json' !== $handler['publisher']['encoder']) {
244+
throw new \RuntimeException('The Gelf\MessagePublisher publisher supports only the compressed json encoding. Omit the option to use the default encoding or use "compressed_json" as the encoder option.');
245+
}
228246
$publisher = new Definition('Gelf\MessagePublisher', [
229247
$handler['publisher']['hostname'],
230248
$handler['publisher']['port'],

tests/DependencyInjection/ConfigurationTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,28 @@ public function testGelfPublisherService($publisher)
111111
$this->assertEquals('gelf.publisher', $config['handlers']['gelf']['publisher']['id']);
112112
}
113113

114+
public function testGelfPublisherWithEncoder()
115+
{
116+
$configs = [
117+
[
118+
'handlers' => [
119+
'gelf' => [
120+
'type' => 'gelf',
121+
'publisher' => [
122+
'hostname' => 'localhost',
123+
'encoder' => 'compressed_json',
124+
],
125+
],
126+
],
127+
],
128+
];
129+
130+
$config = $this->process($configs);
131+
132+
$this->assertEquals('localhost', $config['handlers']['gelf']['publisher']['hostname']);
133+
$this->assertEquals('compressed_json', $config['handlers']['gelf']['publisher']['encoder']);
134+
}
135+
114136
public function testArrays()
115137
{
116138
$configs = [

0 commit comments

Comments
 (0)