【问题标题】:How to send Spring Boot logs directly into Elasticsearch server?如何将 Spring Boot 日志直接发送到 Elasticsearch 服务器?
【发布时间】:2021-12-10 00:31:15
【问题描述】:

我正在寻找一种将 Spring Boot 应用程序日志直接发送到 Elasticsearch 服务器而不使用 Filebeats 或 Logstash 的最佳/最新方法。我怎样才能做到这一点? Spring Boot 中是否有一种简单/现代的方式,或者使用任何好的/知名的库来实现这一点?

我需要的是直接将日志从 Spring Boot 发送到 Elasticsearch,而不需要像 Logstash 这样的任何中间服务。如果可以添加到pom.xml 的第三方库并且完全可以这样做,那很好。我需要 Spring 应用程序本身来处理这个问题。我在 Stack Overflow 中检查了一些类似的问题。

但有些库现在已弃用,有些库很长时间没有更新。我想知道一个新的图书馆或现在这样做的方法?基本上它写入控制台的内容应该发送到 Elasticsearch。

【问题讨论】:

  • 业务应用旨在解决业务问题,而不是监控,因此最佳实践是配置 log4j 并推送到日志文件。这将是应用程序中不依赖于 elasticsearch 的轻量级进程。使用 logstash 管道将日志索引到 elasticsearch。
  • 让您的应用程序将日志文件直接推送到 ES 不是一个好主意的另一个原因是,如果 ES 因维护而停机,您会丢失日志,如果 ES 很慢,您的应用程序会也很慢。
  • 这个已经回答了,请看:stackoverflow.com/a/45627472/5659521

标签: java spring-boot elasticsearch logging


【解决方案1】:

您可以在 pom.xml 中包含 logback-elastic-appender 库,并在 logback.xml 文件中的日志记录配置中使用包含的 com.internetitem.logback.elasticsearch.ElasticsearchAppender 类作为附加程序

<dependency>
    <groupId>com.internetitem</groupId>
    <artifactId>logback-elasticsearch-appender</artifactId>
    <version>1.6</version>
</dependency>

这是您因为最近没有更新而不想使用的库之一吗?如果是这样,您可以编写一个自定义附加程序并在logback.xml 文件中指向它。 appender 的简单实现如下所示:

package com.example.demo;

import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.springframework.web.reactive.function.client.WebClient;

import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
import reactor.core.publisher.Mono;

public class ElasticSearchAppender extends AppenderBase<ILoggingEvent> {
    private static final String ELASTIC_SEARCH_API_HOST = "http://localhost:9200";
    private static final String ELASTIC_SEARCH_INDEX_NAME = "dummy-index";
    private static final WebClient webClient = WebClient.create(ELASTIC_SEARCH_API_HOST);
    private static final Logger LOGGER = Logger.getLogger(ElasticSearchAppender.class.getName());
    public static final DateTimeFormatter ISO_8601_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
            .withZone(ZoneId.systemDefault());

    @Override
    protected void append(ILoggingEvent eventObject) {
        Map<String, Object> loggingEvent = new LinkedHashMap<>();
        loggingEvent.put("@timestamp", 
                ISO_8601_FORMAT.format(Instant.ofEpochMilli(eventObject.getTimeStamp())));
        loggingEvent.put("message", eventObject.getMessage());
        
        // Add additional fields like MDC
        
        webClient.post()
            .uri("/{logIndex}/_doc", ELASTIC_SEARCH_INDEX_NAME)
            .bodyValue(loggingEvent)
            .retrieve()
            .bodyToMono(Void.class)
            .onErrorResume(exception -> {
                LOGGER.log(Level.SEVERE, "Unable to send log to elastic", exception);
                return Mono.empty();
            })
            .subscribe();
    }

}

logback.xml:

<configuration>
    <appender name="ELASTIC" class="com.example.demo.ElasticSearchAppender" />
    <root level="INFO">
        <appender-ref ref="ELASTIC"/>
    </root>
</configuration>

【讨论】:

  • 这里将两个答案合二为一,但请注意,如果您自己编写必须处理所有故障情况,例如连接断开或连接缓慢。
【解决方案2】:

可以使用Spring boot提供的LOGGER:

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
    
private static final Logger LOGGER = LogManager.getLogger(yourClass.class);

LOGGER.info("PRINT THIS OUT");

这应该显示在弹性 beanstalk 中名为“Messages”的文件中。

这来自 spring-boot-starter-web 依赖。

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

【讨论】:

  • 我还需要推送所有日志,包括 Spring Boot 的日志。都会这样寄吗?
【解决方案3】:

创建您的自托管 Elastic 服务器,将 elastic.jar 添加到项目并将 Elastic 配置添加到您的 Dockerfile

java -javaagent:elastic-apm-agent-1.0.jar \
 -Delastic.apm.service_name=project_name \
 -Delastic.apm.server_urls=http://elastic_server_url \
 -Delastic.apm.secret_token= \
 -Delastic.apm.environment=$ACTIVE_PROFILE \
 -Delastic.apm.application_packages=package_name \

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-15
    • 2019-11-29
    • 2019-11-09
    • 2017-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-24
    相关资源
    最近更新 更多