У меня есть приложение Spring Boot, работающее в кластере Kubernetes, и стек EFK (например, ELK, но вместо Logstash Fluentd используется как легкая альтернатива для сбора журналов из все контейнеры kubernetes и отправляет их в elasticsearch).
Чтобы адаптировать журналы к выходу JSON, я использовал logstash-logback-encoder библиотека:
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>4.11</version>
</dependency>
И из коробки мои журналы были преобразованы в JSON (что отлично).
Я вхожу в STDOUT, все забирается и отправляется в Elasticsearch. Никакой специальной настройки для ведения журнала внутри приложения Spring Boot не требуется.
Но проблема, с которой я столкнулся прямо сейчас, заключается в том, что при чтении моих журналов в реальном времени из STDOUT модуля Kubernetes их очень трудно читать со всем форматированием JSON.
Пример:
{"@timestamp":"2018-02-08T12:49:06.080+01:00","@version":1,"message":"Mapped \"{[/error],produces=[text/html]}\" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)","logger_name":"org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping","thread_name":"main","level":"INFO","level_value":20000}
{"@timestamp":"2018-02-08T12:49:06.080+01:00","@version":1,"message":"Mapped \"{[/error]}\" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)","logger_name":"org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping","thread_name":"main","level":"INFO","level_value":20000}
{"@timestamp":"2018-02-08T12:49:06.098+01:00","@version":1,"message":"Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]","logger_name":"org.springframework.web.servlet.handler.SimpleUrlHandlerMapping","thread_name":"main","level":"INFO","level_value":20000}
{"@timestamp":"2018-02-08T12:49:06.098+01:00","@version":1,"message":"Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]","logger_name":"org.springframework.web.servlet.handler.SimpleUrlHandlerMapping","thread_name":"main","level":"INFO","level_value":20000}
{"@timestamp":"2018-02-08T12:49:06.137+01:00","@version":1,"message":"Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]","logger_name":"org.springframework.web.servlet.handler.SimpleUrlHandlerMapping","thread_name":"main","level":"INFO","level_value":20000}
{"@timestamp":"2018-02-08T12:49:06.268+01:00","@version":1,"message":"Registering beans for JMX exposure on startup","logger_name":"org.springframework.jmx.export.annotation.AnnotationMBeanExporter","thread_name":"main","level":"INFO","level_value":20000}
{"@timestamp":"2018-02-08T12:49:06.333+01:00","@version":1,"message":"Initializing ProtocolHandler [\"http-nio-8080\"]","logger_name":"org.apache.coyote.http11.Http11NioProtocol","thread_name":"main","level":"INFO","level_value":20000}
{"@timestamp":"2018-02-08T12:49:06.355+01:00","@version":1,"message":"Starting ProtocolHandler [\"http-nio-8080\"]","logger_name":"org.apache.coyote.http11.Http11NioProtocol","thread_name":"main","level":"INFO","level_value":20000}
Я хочу войти в STDOUT в «обычном формате, отличном от JSON», а затем отправить журналы в Fluentd в формате JSON.
Я пытаюсь настроить два приложения журнала (один для STDOUT, а другой в формате JSON для Fluentd), но я почти уверен, что это дублирует данные (Fluentd получит формат JSON И STDOUT).
Мой план Б - создать один образ для развертывания (без формата JSON), а другой - для производства, но это больше похоже на план Z, tbh, потому что я хочу также отслеживать эти поды в производственной среде.
У меня вопрос: Как я могу сделать это, возможно, с одним приложением журнала ИЛИ без дублирования данных во Fluentd. Может быть, есть другой подход, о котором я не думал?