У нас есть Nginx как обратный прокси перед Tomcat. Они оба регистрируют доступ с метками времени ISO 8601, но кот добавляет в миллисекундах (который является частью стандарта). Таким образом, если Nginx получает запрос и передает его на Tomcat, журнал Nginx мог бы иметь метку времени "2015-10-29T00:37:02+00:00", и Tomcat будет иметь метку времени "2015-10-29T00:37:02,106+0000" для того же доступа. Я не обеспокоен незначительными различиями в форматировании, но не наличие миллисекунд (", 106" частей в журнале Tomcat) является проблемой, потому что это препятствует тому, чтобы мы коррелировали журналы правильно.
Там какой-либо путь состоит в том, чтобы заставить Nginx включать миллисекунды в, он - журналы?
К сожалению, исходя из прочтения исходного кода nginx, не кажется, что существует простой способ сделать это. Для этого нужно было бы обработать лог-файлы (можно было бы взять вывод $msec и превратить его в ISO8601 с помощью ms самостоятельно) или внести патч в nginx.
Интересно, что патч был предложен несколько лет назад, что дало бы достаточно гибкости, чтобы сделать это возможным, но я не думаю, что он куда-то ушел: http://nginx.2469901.n2.nabble.com/PATCH-time-custom-supports-a-custom-log-timestamp-td3505292.html#none
Вот обходной путь, который я нашел. Добавьте следующую строку в блок http {}
:
map "$time_local:$msec" $time_local_ms { ~(^\S+)(\s+\S+):\d+\.(\d+)$ $1.$3$2; }
Затем в строке log_format
измените [$time_local]
на [$time_local_ms ]
или создайте собственный формат журнала, например тот, который я использую для Datadog:
log_format common '$remote_addr - $remote_user [$time_local_ms] "$request" '
'$status $body_bytes_sent $request_time "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
Пример журнала доступа:
172.17.0.1 - - [23/Apr/2021:13:06:02.802 +0000] "GET /static/image.jpg HTTP/1.1" 304 0 0.000 "http://localhost/" "Mozilla" "-"
Вопрос требует ISO 8601 плюс миллисекунды — вот однострочный вариант для этого конкретного варианта использования, основанный на ответе Александра, но с использованием ISO, а не локального формата:
map "$time_iso8601 # $msec" $time_iso8601_ms { "~(^[^+]+)(\+[0-9:]+) # \d+\.(\d+)$" $1.$3$2; }
Результат создается из групп совпадения регулярных выражений следующим образом:
$1
= только часть даты и времени $time_iso8601
, например 2021-05-21T10:26:19
$2
= только часть часового пояса $time_iso8601
например. +00:00
$3
= миллисекундная часть $msec
например. 123
извлечено из 1621594635.123
Если однострочник кажется слишком непрозрачным, см. эту публикацию (с комментариями к другому ответу), в которой используется несколько map
заявления.