Skip to content

Commit 981c94e

Browse files
committed
fix nginx error logs having multiline messages
1 parent e9e4c41 commit 981c94e

File tree

3 files changed

+51
-1
lines changed

3 files changed

+51
-1
lines changed

src/Logs/HttpNginxErrorLog.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
class HttpNginxErrorLog extends Log
1111
{
1212
public static string $name = 'HTTP Errors (Nginx)';
13-
public static string $regex = '/^(?P<datetime>[\d+\/ :]+) \[(?P<level>.+)\] .*?: (?P<errormessage>.+?)(?:, client: (?P<client>.+?))?(?:, server: (?P<server>.+?))?(?:, request: "?(?P<request>.+?)"?)?(?:, host: "?(?P<host>.+?)"?)?$/';
13+
public static string $regex = '~^(?P<datetime>[\d+\/ :]+) \[(?P<level>.+?)\] .*?: (?P<errormessage>(?:(?!, client: |, server: |, request: |, upstream: |, host: |, referrer: ).)*(?:\n(?![\d/]|\Z).*)*?)(?:, client: (?P<client>.+?))?(?:, server: (?P<server>.+?))?(?:, request: "?(?P<request>.+?)"?)?(?:, upstream: "?(?P<upstream>.+?)"?)?(?:, host: "?(?P<host>.+?)"?)?(?:, referrer: "?(?P<referrer>.+?)"?)?$~ms';
1414
public static string $levelClass = NginxStatusLevel::class;
1515

1616
protected function fillMatches(array $matches = []): void
@@ -26,6 +26,8 @@ protected function fillMatches(array $matches = []): void
2626
'server' => $matches['server'] ?? null,
2727
'request' => $matches['request'] ?? null,
2828
'host' => $matches['host'] ?? null,
29+
'upstream' => $matches['upstream'] ?? null,
30+
'referrer' => $matches['referrer'] ?? null,
2931
];
3032
}
3133

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2024/08/21 09:08:18 [error] 2761052#2761052: *84719 upstream sent too big header while reading response header from upstream, client: 123.123.123.123, server: xxx, request: "GET /api/xx/yy/zz?lang=de HTTP/2.0", upstream: "fastcgi://unix:/var/run/php/php8.1-fpm.sock:", host: "xxx", referrer: "http://some-ip:3000/"
2+
2024/08/21 09:08:19 [error] 2761052#2761052: *84719 FastCGI sent in stderr: "PHP message: [2024-08-21 11:08:18] develop.DEBUG: ActivityService: some message
3+
PHP message: [2024-08-21 11:08:18] develop.DEBUG: ActivityService: another message
4+
PHP message: [2024-08-21 11:08:18] develop.DEBUG: ActivityService: blabla: [{"id":308363,"lat":"xx","lng":"yy"}]
5+
PHP message: [2024-08-21 11:08:18] develop.INFO: provider Payload: {"attr1":"t","attr2":14400,"sources":[{"id":"source","lat":xx,"lng":yy,"tm":{"t":{"maxT":2},"c":{"":""}}}],"t":[{"id":308363,"lat":"xx","lng":"yy"}],"g_s_client":false,"reversed":false,"polygon":{"id":4326},"pathSerializer":"g"}
6+
PHP message: [2024-08-21 11:08:18] develop.DEBUG: Sending request to final Url (V1) https://someurl/path/v1/endpoint?param=***

tests/Unit/AccessLogs/HttpNginxErrorLogTest.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,45 @@
4343
->and($log->context['request'])->toBe(null)
4444
->and($log->context['host'])->toBe(null);
4545
});
46+
47+
it('can parse multiline nginx log entries', function () {
48+
$file = new \Opcodes\LogViewer\LogFile(__DIR__.'/Fixtures/multiline_nginx_error_dummy.log');
49+
$file->logs()->scan();
50+
51+
$logs = $file->logs()->get();
52+
53+
expect($logs)->toHaveCount(2);
54+
55+
/** @var HttpNginxErrorLog $firstLog */
56+
$firstLog = $logs[0];
57+
58+
// 2024/08/21 09:08:18 [error] 2761052#2761052: *84719 upstream sent too big header while reading response header from upstream,
59+
// client: 123.123.123.123, server: xxx, request: "GET /api/xx/yy/zz?lang=de HTTP/2.0",
60+
// upstream: "fastcgi://unix:/var/run/php/php8.1-fpm.sock:", host: "xxx", referrer: "http://some-ip:3000/"
61+
expect($firstLog->index)->toBe(0)
62+
->and($firstLog)->toBeInstanceOf(HttpNginxErrorLog::class)
63+
->and($firstLog->datetime->toDateTimeString())->toBe('2024-08-21 09:08:18')
64+
->and($firstLog->level)->toBe('error')
65+
->and($firstLog->message)->toBe('*84719 upstream sent too big header while reading response header from upstream')
66+
->and($firstLog->context['client'])->toBe('123.123.123.123')
67+
->and($firstLog->context['server'])->toBe('xxx')
68+
->and($firstLog->context['request'])->toBe('GET /api/xx/yy/zz?lang=de HTTP/2.0')
69+
->and($firstLog->context['upstream'])->toBe('fastcgi://unix:/var/run/php/php8.1-fpm.sock:')
70+
->and($firstLog->context['host'])->toBe('xxx')
71+
->and($firstLog->context['referrer'])->toBe('http://some-ip:3000/');
72+
73+
$secondLog = $logs[1];
74+
75+
expect($secondLog->index)->toBe(1)
76+
->and($secondLog)->toBeInstanceOf(HttpNginxErrorLog::class)
77+
->and($secondLog->datetime->toDateTimeString())->toBe('2024-08-21 09:08:19')
78+
->and($secondLog->level)->toBe('error')
79+
->and($secondLog->message)->toBe(<<<'EOF'
80+
*84719 FastCGI sent in stderr: "PHP message: [2024-08-21 11:08:18] develop.DEBUG: ActivityService: some message
81+
PHP message: [2024-08-21 11:08:18] develop.DEBUG: ActivityService: another message
82+
PHP message: [2024-08-21 11:08:18] develop.DEBUG: ActivityService: blabla: [{"id":308363,"lat":"xx","lng":"yy"}]
83+
PHP message: [2024-08-21 11:08:18] develop.INFO: provider Payload: {"attr1":"t","attr2":14400,"sources":[{"id":"source","lat":xx,"lng":yy,"tm":{"t":{"maxT":2},"c":{"":""}}}],"t":[{"id":308363,"lat":"xx","lng":"yy"}],"g_s_client":false,"reversed":false,"polygon":{"id":4326},"pathSerializer":"g"}
84+
PHP message: [2024-08-21 11:08:18] develop.DEBUG: Sending request to final Url (V1) https://someurl/path/v1/endpoint?param=***
85+
EOF);
86+
87+
});

0 commit comments

Comments
 (0)