1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > Spring Boot 使用 Log4j2 Logback 输出日志到 EKL

Spring Boot 使用 Log4j2 Logback 输出日志到 EKL

时间:2024-01-26 01:36:47

相关推荐

Spring Boot 使用 Log4j2  Logback 输出日志到 EKL

文章目录

1、ELK 介绍2、环境、软件准备3、ELK 环境搭建4、Spring Boot 配置示例4.1、Log4j2 方式配置4.2、Logback 方式配置

1、ELK 介绍

ELK 是 Elasticsearch , Logstash, Kibana 的缩写,Elasticsearch 是开源分布式搜索引擎,提供搜集、分析、存储数据等功能,Logstash 主要是用来日志的搜集、分析、过滤日志的工具,Kibana 为 Elasticsearch 提供分析和可视化的 Web 平台,可以在 Elasticsearch 的索引中查找,交互数据,并生成各种维度的表图。一句话:日志收集(Logstash),数据存储(Elasticsearch),日志可视化(Kibana),三者有机结合起来,非常方便集中式处理日志。

2、环境、软件准备

本次演示环境,我是在本机 MAC OS 上操作,以下是安装的软件及版本:

Java: 1.8.0_211Elasticsearch: 7.1.0Logstash: 7.1.0Kibana: 7.1.0Spring Boot: 2.1.4.RELEASE

注意:本次主要演示如何在 Spring-Boot 项目中配置Log4j2以及Logback输出日志到 ELK 中,并能够在Kibana中可以正确检索出来,Elasticsearch及 Spring-Boot 项目底层需要 Java 环境,所以需要提前本地安装好 Java 环境,这里忽略 Java 安装过程。

3、ELK 环境搭建

我们可以去 官网 分别下载系统对应最新版ElasticsearchLogstashKibana,截止目前已更新到7.1.0版本,可通过以下链接获取安装包并提供默认配置启动步骤。

ElasticsearchLogstashKibana

这里我先按照默认配置启动Elasticsearch服务,启动完毕,本地可以通过http://127.0.0.1:9200地址访问服务是否启动正常。注意:先不启动LogstashKibana,因为他们的配置需要更改,下边会讲到。

4、Spring Boot 配置示例

使用 Idea 创建一个 Spring Boot 项目,我们先添加Log4j2支持,演示如何使用Log4j2将日志直接输出到本地的 ELK 中,然后演示下通过Logback动态输出索引名称到日志中,方便分类检索日志。

4.1、Log4j2 方式配置

首先修改pom.xml增加Log4j2日志框架支持,注意spring-boot-starter默认使用Logback作为日志框架,所以需要先移除默认日志配置spring-boot-starter-logging

pom.xml增加如下配置:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId></dependency><dependency><groupId>com.lmax</groupId><artifactId>disruptor</artifactId><version>3.4.2</version></dependency>

注意:disruptor是一个轻量的高性能并发框架,Log4j2包含了基于LMAX Disruptor(高性能线程间消息通信库)的下一代Asynchronous Loggers。在多线程环境下Asynchronous Loggers的吞吐量是Log4j1Logback的 18 倍,而延迟时间也要低一个数量级。如果使用异步日志时,添加disruptor支持,会大大提高效率,当然不添加也是没有问题的。

增加log4j2-spring.xml配置输出到 ELK 中,大概配置如下:

<?xml version="1.0" encoding="UTF-8"?><Configuration status="OFF" monitorInterval="60"><Appenders><!-- Console 日志,只输出 level 及以上级别的信息,并配置各级别日志输出颜色 --><Console name="Console" target="SYSTEM_OUT"><!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)--><ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/><PatternLayout pattern="%highlight{%d{yyyy.MM.dd 'at' HH:mm:ss z} %-5level %class{36} %M() @%L - %msg%n}{FATAL=Bright Red, ERROR=Bright Magenta, WARN=Bright Yellow, INFO=Bright Green, DEBUG=Bright Cyan, TRACE=Bright White}"/></Console><!-- socket 日志,输出日志到 Logstash 中做日志收集 --><Socket name="Socket" host="127.0.0.1" port="4560" protocol="TCP"><JsonLayout properties="true" compact="true" eventEol="true" /><PatternLayout pattern="%d{yyyy.MM.dd 'at' HH:mm:ss z} %-5level %class{36} %M() @%L - %msg%n"/></Socket></Appenders><Loggers><Root level="INFO"><appender-ref ref="Socket"/><appender-ref ref="Console"/></Root></Loggers></Configuration>

注意:这里配置 Socket 输出方式,输出日志到本地Logstash做日志收集,格式化处理后自动输出到本地Elasticsearch中存储,最后通过Kibana检索索引通过 Web 页面展示出来。需要指定hostportprotocol,这里就配置成本地Logstash指定配置的端口和地址即可。

同时可以在application.properties中配置日志输出级别,注意这里可以不指定加载log4j2-spring.xml文件,Spring Boot 会默认加载该配置文件。

logging.level.root=info

最后,代码中在 Controller 写入一些特定日志和异常信息,方便在Kibana中查看验证。

@RestController@RequestMapping("/test")public class LogController {private Logger logger = LogManager.getLogger(LogController.class);@RequestMapping(value = "/log4j2", method = RequestMethod.GET)public String testLog(){try {logger.info("Hello 这是 info message. 信息");logger.error("Hello 这是 error message. 报警");logger.warn("Hello 这是 warn message. 警告");logger.debug("Hello 这是 debug message. 调试");logger.fatal("Hello 这是 fatal message. 严重");List<String> list = new ArrayList<>();System.out.println(list.get(2));} catch (Exception e) {logger.error("testLog", e);}return "";}}

OK,Spring Boot 工程添加Log4j2支持配置完毕,接下来,我们需要配置LogstashKibana,在Logstash安装目录下 config 目录,新建test-log4j2.conf配置文件,配置如下:

input {tcp {host => "127.0.0.1"port => "4560"mode => "server"type = json}stdin {}}filter {}output {stdout {codec => rubydebug}elasticsearch {hosts => ["127.0.0.1:9200"]action => "index"codec => rubydebugindex => "log4j2-%{+YYYY.MM.dd}"}}

注意:这里配置 tcp 的 host 和 port 要跟上边log4j2-spring.xml中配置一致,否则无法进行日志收集, output 下的 elasticsearch 的 host 配置要跟上边启动的本地Elasticsearch配置一致,index 指定为固定的log4j2-yyyy.MM.dd格式,方便在Kibana中检索索引使用。使用该配置文件启动Logstash,命令如下:

$ cd <Logstash_path>/bin$ ./logstash -f ../config/test-log4j2.conf

最后,启动Kibana,可以使用默认配置,不过这里我稍微修改一些配置如下:

$ vim <Kibana_path>/config/kibana.confserver.port: 5601server.host: "127.0.0.1"elasticsearch.hosts: ["http://127.0.0.1:9200"]i18n.locale: "zh-CN"

同理,这里elasticsearch.hosts配置要跟上边一致,同时指定Kibana启动端口为5601,并且修改显示默认英文为中文,方便查看,启动Kibana直到日志输出显示状态为Green即启动完毕。

一切都准备完毕,最后启动 Spring Boot 工程,并触发/test/log4j2接口,制造各类日志,在KibanaWeb 页面查看是否正确加载过来吧!

浏览器访问http://127.0.0.1:4560即可打开Kibana页面,首先我们查看下Elasticsearch索引管理里面,是否已存在上边配置的log4j2-yyyy.MM.dd格式索引。

OK,显示已存在,那么接下来我们在Kibana索引模式下创建索引模式,输入log4j2-*即可正确匹配到Elasticsearch中的指定的索引,接着在时间筛选字段名称处选择@timestamp,方便我们后边按照时间段筛选数据,创建过程如下:

创建完毕,我们就可以在Kibana中筛选并显示日志了,比如我增加了message字段,过滤完后,就显示出来上边工程示例代码中的各种类型日志以及异常日志了,非常直观方便!

4.2、Logback 方式配置

上边使用Log4j2日志框架可以正确输出日志到 ELK,但是有一个地方需要我们注意,就是启动Logstash时指定Elasticsearch的 index 索引为固定值(log4j2-*)了,如果有多个 project 同时往 ELK 中输出日志,那么使用同一个索引名称的话,会造成日志混乱,不方便区分排查各个项目的日志,所以,我们希望能够通过动态输出索引名称到Elasticsearch中,例如 Project A 输出到索引projectA-*下,Project B 输出到索引projectB-*下,这样就方便我们在Kibana下根据项目匹配对应的索引值了,当然使用 Spring Boot 默认日志框架Logback可以很轻松的办到。

那么改造项目来支持Logback日志框架,首先修改pom.xml配置文件如下:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><!-- <exclusions>--><!-- <exclusion>--><!--<groupId>org.springframework.boot</groupId>--><!--<artifactId>spring-boot-starter-logging</artifactId>--><!-- </exclusion>--><!-- </exclusions>--></dependency><dependency><groupId>net.logstash.logback</groupId><artifactId>logstash-logback-encoder</artifactId><version>5.3</version></dependency>

注意:这里将移除的spring-boot-starter-logging重新添加进来,同时依赖logstash-logback-encoder该插件,该插件起到 Socket 通过 TCP 方式向Logstash进行日志输送的作用。

接着增加logback-spring.xml配置文件如下:

<?xml version="1.0" encoding="UTF-8"?><configuration debug="false"><property name="LOG_HOME" value="logs/demo.log" /><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern></encoder></appender><appender name="logstash" class="net.logstash.logback.appender.LogstashTcpSocketAppender"><destination>127.0.0.1:4560</destination><encoder class="net.logstash.logback.encoder.LogstashEncoder" ><customFields>{"appname": "demo-elk"}</customFields></encoder></appender><root level="INFO"><appender-ref ref="STDOUT" /><appender-ref ref="logstash" /></root></configuration>

注意:这里的 destination 依旧要配置对应上本地Logstash配置,着重说下<customFields>{"appname": "demo-elk"}</customFields>字段配置,该自定义字段配置,Logstash收集日志时,每条日志记录均会带上该字段,而且在Logstash配置文件中可以通过变量的方式获取到字段,这样就能达到我们说的动态输出索引名称到Elasticsearch中的功能了。同样,application.properties可以不指定加载logback-spring.xml文件,Spring Boot 会默认加载该配置文件。接下来,去Logstashconfig 下增加test-logback.conf配置文件,配置如下:

input {tcp {host => "127.0.0.1"port => "4560"mode => "server"type => json}stdin {}}filter {}output {stdout {codec => rubydebug}elasticsearch {hosts => ["127.0.0.1:9200"]action => "index"codec => rubydebugindex => "%{[appname]}-%{+YYYY.MM.dd}"}}

注意:这里的%{[appname]}就是获取上边的<customFields>字段中的 json 串 key 值,我们只传了一个 appname 值,当让还可以传递其他值,例如 IP、Hostname 等关键信息,方便在Kibana中检索索引时区分。重启一下Logstash指定该配置文件。

$ cd <Logstash_path>/bin$ ./logstash -f ../config/test-logback.conf

ElasticsearchKibana不需要重启,再次启动 Spring Boot 工程,去 Kibana 下查看 !查看下Elasticsearch索引管理里面,是否已存在上边配置的demo-elk-yyyy.MM.dd格式索引。

What? 怎么没有获取到传递过去的 appname 值呢?原样配置到Elasticsearch索引中去了,但是我在后台Logstash控制台日志中可以明显看到,打印的每条 Json 串中是有该字段的呀!各种搜索,发现大家也是这么配置的呢!即使将type => json改为codec => json依旧不行!百思不得解的时候,查看了下 logstash-logback-encoder 文档说明 这里明确指出要使用codec => json_lines方式,好吧!test-logbash.conf配置修改如下并重启Logstash

input {tcp {host => "127.0.0.1"port => "4560"mode => "server"codec => json_lines}stdin {}}filter {}output {stdout {codec => rubydebug}elasticsearch {hosts => ["127.0.0.1:9200"]action => "index"index => "%{[appname]}-%{+YYYY.MM.dd}"}}

这下妥妥没有问题了,在去查看下Elasticsearch索引管理,这下就有了。

那么接着建一个索引模式名称为demo-elk-*,查看下日志记录,是否能够正常加载的项目日志,也是妥妥没有问题的。

参考资料

elasticsearchlogstashkibanalogstash-logback-encoder

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。