In diesem Tutorial werden wir uns mit dem Verbinden und Konfigurieren eines Protokollierungssystems in einem Spring Boot- Projekt und dem Senden von Protokollen an ELK mithilfe von Filebeat befassen . Dieses Handbuch richtet sich an Einsteiger.
Protokollierung und warum wird es benötigt
Als ich anfing, als Programmierer zu arbeiten, wiederholte einer meiner älteren Kollegen gern: "Wenn Sie keine Protokolle haben, haben Sie nichts . " Wenn wir mit dem allerersten Fehler auf Prüfständen oder noch schlimmer in einer industriellen Umgebung konfrontiert sind, brauchen wir als erstes Anwendungsprotokolle und einen einfachen Zugriff darauf. Die Entwickler der Anwendung sind für die Protokolle selbst verantwortlich. Sie müssen sicherstellen, dass das Verhalten des Systems so protokolliert wird, dass jederzeit verstanden werden kann, was mit dem System geschieht und vor allem, was daran falsch ist.
Die nächste Frage ist die Bequemlichkeit des Zugriffs auf Protokolle. Normalerweise sehen wir während lokaler Tests das Protokoll in der Anwendungskonsole und auf dem Prüfstand - in speziellen Protokolldateien auf dem Server. Ist es bequem und sicher, jedes Mal eine Verbindung zum Stand herzustellen, nach dem erforderlichen Verzeichnis zu suchen und von dort aus Protokolldateien zu lesen? Die Praxis zeigt, dass dies nicht der Fall ist, und dies ist das zweite Problem, das durch eine Reihe von Produkten gelöst werden soll, die einen bequemen Zugriff auf Protokolle und die Suche nach wichtigen Informationen in diesen Protokollen ermöglichen. Heute werden wir sehr kurz über eine der Gruppen solcher Produkte sprechen, den sogenannten ELK- Stack (Elasticsearch - Logstash - Kibana ) und ausführlicher über Filebeat - ein Open Source- Produkt, das einen bequemen Mechanismus für die Übermittlung von Protokollen an ELK bietet .
Drei Zeilen über 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 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 — ,
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_root — json json, Filebeat Logstash
- overwrite_keys —
- add_error_key — Filebeat 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 :

Jetzt, im Entdecken Registerkarte für unseren Index, können Sie die Anzeige von Feldern konfigurieren und sehen , dass alle Protokolle innerhalb einer Anforderung durch die gleiche Kombination requestId . Sie können das JSON- Feld erweitern und den vollständigen Text der von Filebeat empfangenen Nachricht anzeigen :
