Как SLF4J справляется со структурированной регистрацией
Кто-нибудь знает, как структурированное ведение журнала обычно реализуется с помощью slf4j? Есть ли какой-нибудь открытый исходный код, уже работающий с этим?
Спасибо!
2 ответа
Slf4j добавил поддержку структурированного ведения журнала (и свободного API) с v2.0.0 (альфа по состоянию на октябрь 2019 г.):
- http://www.slf4j.org/api/org/slf4j/event/KeyValuePair.html
- http://www.slf4j.org/api/org/slf4j/event/LoggingEvent.html
http://www.slf4j.org/apidocs/org/slf4j/spi/LoggingEventBuilder.html
int newT = 15; int oldT = 16; // using classical API logger.debug("oldT={} newT={} Temperature changed.", newT, oldT); // using fluent API logger.atDebug() .addKeyValue("oldT", oldT) .addKeyValue("newT", newT) .log("Temperature changed.");
Если вы используете SLF4J в сочетании с Logback, структурированное ведение журнала поддерживается StructuredArguments
, Вы можете найти документацию по этому вопросу на странице входа на Github.
Простой пример того, как это работает. Эта строка журнала..
log.debug("Retrieved file {}", StructuredArguments.value("filename", upload.getOriginalFilename()))
..yays выводит следующий лог json:
{
"filename": "simple.zip",
"@timestamp": "2019-02-12T14:31:31.631+00:00",
"severity": "DEBUG",
"service": "upload",
"thread": "http-nio-9091-exec-1",
"logger": "some.great.ClassName",
"message": "Retrieved file simple.zip"
}
К вашему сведению - я только что открыл оболочку структурированного журналирования для SLF4J. Мы используем его в моей повседневной работе для входа в Splunk, и это стало большим улучшением. Может быть, вам это пригодится.
https://github.com/Randgalt/maple
Вы определяете "схему", а затем обертываете регистратор SLF4J. Например
public interface LoggingSchema {
LoggingSchema name(String name);
LoggingSchema date(Instant date);
... etc ...
}
...
MapleLogger<LoggingSchema> logger = MapleFactory.getLogger(slf4j, LoggingSchema.class);
logger.info("my message", s -> s.name("john doe").date(Instant.now());
Создает журнал slf4j ala:
slf4j.info("my message name=\"john doe\" date=2019-10-08T18:52:15.820177Z");
В github есть пример, который реализован с использованием SLF4J
, Надеюсь, это поможет вам.
Для получения дополнительной информации вы можете пройти этот урок.
Для тех, кто сталкивается с этим довольно старым вопросом: в качестве альтернативного подхода, более удобного для разработчика, чем ручная установка каждого параметра в MDC, вы можете использовать структурированный регистратор, такой как https://github.com/jacek99/structlog4j идеале вместе с форматирование yaml или json. Тогда действительно легко передать журналы в стек ELK и запросить все журналы на основе параметров (вам не нужно создавать парсер записей журнала вручную, так как все соответствующие поля будут уже в структурированной форме). Или создайте свой собственный простой регистратор поверх slf4j, который будет принимать любые переменные, переданные .log
метод и автоматически создавать пары ключ-значение в MDC, а затем вы можете связать его со структурированным форматером, например, если ваша среда выполнения использует Logstash: https://github.com/logstash/logstash-logback-encoder
Вы можете попробовать использовать Logstage в Scala https://izumi.7mind.io/latest/release/doc/logstage/index.html
У нас есть эффективный адаптер для slf4j, и мы выполняем структурирование с нулевой стоимостью для ваших журналов.
Кроме того, вы можете обнаружить, что у нас есть много преимуществ, несмотря на замену MDC. Для библиотеки эффектов у нас есть контекст для Fiber и FiberLocal. У нас есть автоматические структурные идентификаторы для лучшей обработки в структурированных базах данных.