无需注册和短信即可在本地进行Spring Boot和Filebeat

在本教程中,我们将研究在Spring Boot项目中连接和配置日志记录系统,以及使用Filebeat将日志发送到ELK本指南适用于入门级开发人员。



记录以及为什么需要



当我刚开始从事程序员工作时,我的一位资深同事喜欢重复一遍:“如果您没有日志,那么您将一无所有确实,当遇到测试台上的第一个错误或在工业环境中遇到更严重的错误时,我们需要的第一件事是应用程序日志和易于访问的日志。应用程序的开发人员自己负责日志,他们必须确保以某种方式记录系统的行为,以便在任何时候都可以了解系统正在发生的事情,最重要的是,它有什么问题。



下一个问题是访问日志的便利性。通常,在本地测试期间,我们会在应用程序控制台和测试平台上看到日志-在服务器上的特殊日志文件中。每次都连接到支架,搜索所需目录并从那里读取日志文件是否方便,安全?实践证明不是,这是许多产品要解决的第二个问题,可以方便地访问日志并在其中搜索重要信息。今天,我们将非常简短地讨论这类产品中的一种,即所谓的ELK堆栈(Elasticsearch-Logstash-Kibana),以及有关Filebeat的更多细节,Filebeat是一种开放源代码产品,提供了将日志传送到ELK的便捷机制



关于ELK的三行



  • Logstash-接收,修改日志
  • Elasticsearch-存储和搜索
  • Kibana-显示


Filebeat与它有什么关系?



Filebeat将数据传输到ELK,并将被部署在我们的应用程序旁边,这通常比配置Logstash从日志文件或其他通道读取数据更方便



一个好的方法是为一组微服务部署一个通用的ELK,并为每个微服务部署自己的Filebeat(尤其是因为它不那么容易),该文件将读取微服务日志并将其发送到通用ELK



我们稍后将尝试在本地环境中实施此解决方案。





实践



Java 8

ApacheMaven3.6

Spring Boot 2.3.4.RELEASE

Docker



Spring Boot App



Spring Boot , . /



Spring Boot Spring Initalizr





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

<dependency>
    <groupId>net.logstash.logback</groupId>
    <artifactId>logstash-logback-encoder</artifactId>
    <version>6.4</version>
</dependency>

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>


  • spring-boot-starter-web — ..
  • logstash-logback-encoder
  • lombok — ,


pom.xml



Spring Boot :



@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}


:



@Slf4j
@Service
public class LogGenerator {

    public void generate(int count) {
        log.info("Start generating logs");
        LongStream.range(0, count)
                .forEach(i -> log.info("Log {}", i));
    }
}


0 count



, :



@Slf4j
@RestController
@RequiredArgsConstructor
public class LogController {
    private final LogGenerator generator;

    @GetMapping("/generate")
    public ResponseEntity test(@RequestParam(name = "count", defaultValue = "0") Integer count) {
        log.info("Test request received with count: {}", count);
        generator.generate(count);
        return ResponseEntity.ok("Success!");
    }
}


GET :

http://localhost:8080/generate?count=10



. resources logback-spring.xml



<?xml version="1.0" encoding="UTF-8"?>
<configuration>

    <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d [%thread] %-5level  %logger{35} - [%mdc] - %msg%n</pattern>
        </encoder>
    </appender>

    <appender name="filebeatAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>./log/application.log</file>
        <append>true</append>
        <encoder class="net.logstash.logback.encoder.LogstashEncoder"/>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>./log/application.%d.%i.log.gz</fileNamePattern>
            <maxFileSize>10MB</maxFileSize>
        </rollingPolicy>
    </appender>

    <root level="INFO">
        <appender-ref ref="consoleAppender" />
        <appender-ref ref="filebeatAppender" />
    </root>
</configuration>


:



  • consoleAppender
  • filebeatAppender — , LogstashEncoder logstash-logback-encoder

    JSON , Logstash. Logstash .


, ./log/application.log log . . maxFileSize



Filebeat .



:



@Slf4j
@Component
public class LogFilter extends OncePerRequestFilter {

    private static final String REQUEST_ID = "requestId";

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        String requestId = request.getHeader(REQUEST_ID);
        if (requestId == null) {
            requestId = UUID.randomUUID().toString();
        }

        MDC.put(REQUEST_ID, requestId);

        try {
            log.info("Started process request with {} : {}", REQUEST_ID, requestId);
            filterChain.doFilter(request, response);
        } finally {
            MDC.clear();
        }
    }
}


, ( requestId), MDC (Mapped Diagnostic Context)



MDC.put(REQUEST_ID, requestId);


finally MDC



MDC.clear();


, , . Kibana .



, , :



mvn spring-boot:run


, application.log



curl "localhost:8080/generate?count=10"


Success!, application.log :



{
   "@timestamp":"2020-10-17T22:39:45.595+03:00",
   "@version":"1",
   "message":"Writing [\"Success!\"]",
   "logger_name":"org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor",
   "thread_name":"http-nio-8080-exec-3",
   "level":"INFO",
   "level_value":10000,
   "requestId":"77abe5ac-4458-4dc3-9f4e-a7320979e3ae"
}


Filebeat



Filebeat

7.9.2 macOS

.

Filebeat filebeat.xml



, inputs output:



  inputs:
  - enabled: true
    encoding: utf-8
    exclude_files: ['\.gz$']
    json:
      add_error_key: true
      keys_under_root: true
      overwrite_keys: true
    paths:
    - {     }/*.log
    scan_frequency: 10s
    type: log


, Filebeat . :



  • keys_under_rootjson json, Filebeat Logstash
  • overwrite_keys
  • add_error_keyFilebeat error.message error.type: json json .


output:
  logstash:
    hosts:
    - localhost:5044
    ssl:
      certificate_authorities:
      - {    }/logstash-beats.crt


, Filebeat . Logstash ( )

ssl.certificate_authorities Logstash ( ), .



Filebeat, , .. ELK .

ELK . , docker ELK sebp/elk logstash-beats.crt. certificate_authorities filebeat.xml



docker-compose :



version: '3.7'
services:
  elk:
    image: sebp/elk
    ports:
      - "5601:5601" #kibana
      - "9200:9200" #elastic
      - "5044:5044" #logstash


ELK Filebeat , macOS :



./filebeat -e run


? , LogstashEncoder JSON application.log, Filebeat , Logstash. Kibana.



Kibana :

http://localhost:5601/



Discover:





:





Kibana index ELK . ! Filebeat , . :



curl "localhost:8080/generate?count=100"


:





:





. requestId MDC :





现在,在索引的“发现”选项卡中,您可以配置字段的显示,并看到一个请求中的所有日志都由相同的requestId合并您可以展开JSON字段,并查看从Filebeat收到的消息的全文






All Articles