Skip to content

Commit 6bc1a44

Browse files
committed
Truncate messages if they reach the max length of GELF messages, fixes #751
1 parent 15e21f3 commit 6bc1a44

File tree

2 files changed

+46
-2
lines changed

2 files changed

+46
-2
lines changed

src/Monolog/Formatter/GelfMessageFormatter.php

+28-2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
*/
2323
class GelfMessageFormatter extends NormalizerFormatter
2424
{
25+
const MAX_LENGTH = 32766;
26+
2527
/**
2628
* @var string the name of the system for the Gelf log message
2729
*/
@@ -79,24 +81,48 @@ public function format(array $record)
7981
->setHost($this->systemName)
8082
->setLevel($this->logLevels[$record['level']]);
8183

84+
// start count with message length + system name length + 200 for padding / metadata
85+
$len = 200 + strlen((string) $record['message']) + strlen($this->systemName);
86+
87+
if ($len > self::MAX_LENGTH) {
88+
$message->setShortMessage(substr($record['message'], 0, self::MAX_LENGTH - 200));
89+
90+
return $message;
91+
}
92+
8293
if (isset($record['channel'])) {
8394
$message->setFacility($record['channel']);
95+
$len += strlen($record['channel']);
8496
}
8597
if (isset($record['extra']['line'])) {
8698
$message->setLine($record['extra']['line']);
99+
$len += 10;
87100
unset($record['extra']['line']);
88101
}
89102
if (isset($record['extra']['file'])) {
90103
$message->setFile($record['extra']['file']);
104+
$len += strlen($record['extra']['file']);
91105
unset($record['extra']['file']);
92106
}
93107

94108
foreach ($record['extra'] as $key => $val) {
95-
$message->setAdditional($this->extraPrefix . $key, is_scalar($val) ? $val : $this->toJson($val));
109+
$val = is_scalar($val) ? $val : $this->toJson($val);
110+
$len += strlen($this->extraPrefix . $key . $val);
111+
if ($len > self::MAX_LENGTH) {
112+
$message->setAdditional($this->extraPrefix . $key, substr($val, 0, self::MAX_LENGTH - $len));
113+
break;
114+
}
115+
$message->setAdditional($this->extraPrefix . $key, $val);
96116
}
97117

98118
foreach ($record['context'] as $key => $val) {
99-
$message->setAdditional($this->contextPrefix . $key, is_scalar($val) ? $val : $this->toJson($val));
119+
$val = is_scalar($val) ? $val : $this->toJson($val);
120+
$len += strlen($this->contextPrefix . $key . $val);
121+
if ($len > self::MAX_LENGTH) {
122+
$message->setAdditional($this->contextPrefix . $key, substr($val, 0, self::MAX_LENGTH - $len));
123+
break;
124+
}
125+
$message->setAdditional($this->contextPrefix . $key, $val);
100126
}
101127

102128
if (null === $message->getFile() && isset($record['context']['exception']['file'])) {

tests/Monolog/Formatter/GelfMessageFormatterTest.php

+18
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,24 @@ public function testFormatWithExtra()
197197
$this->assertEquals('pair', $message_array['_EXTkey']);
198198
}
199199

200+
public function testFormatWithLargeData()
201+
{
202+
$formatter = new GelfMessageFormatter();
203+
$record = array(
204+
'level' => Logger::ERROR,
205+
'level_name' => 'ERROR',
206+
'channel' => 'meh',
207+
'context' => array('exception' => str_repeat(' ', 32767)),
208+
'datetime' => new \DateTime("@0"),
209+
'extra' => array('key' => str_repeat(' ', 32767)),
210+
'message' => 'log'
211+
);
212+
$message = $formatter->format($record);
213+
$messageArray = $message->toArray();
214+
$this->assertLessThanOrEqual(32766, strlen($messageArray['_key']));
215+
$this->assertLessThanOrEqual(32766, strlen($messageArray['_ctxt_exception']));
216+
}
217+
200218
private function isLegacy()
201219
{
202220
return interface_exists('\Gelf\IMessagePublisher');

0 commit comments

Comments
 (0)