Spring Boot 使用 Log4j2 & Logback 输出日志到 EKL
文章目录
1、ELK 介绍
ELK 是 Elasticsearch , Logstash, Kibana 的缩写,Elasticsearch 是开源分布式搜索引擎,提供搜集、分析、存储数据等功能,Logstash 主要是用来日志的搜集、分析、过滤日志的工具,Kibana 为 Elasticsearch 提供分析和可视化的 Web 平台,可以在 Elasticsearch 的索引中查找,交互数据,并生成各种维度的表图。一句话:日志收集(Logstash),数据存储(Elasticsearch),日志可视化(Kibana),三者有机结合起来,非常方便集中式处理日志。
2、环境、软件准备
本次演示环境,我是在本机 MAC OS 上操作,以下是安装的软件及版本:
- Java: 1.8.0_211
- Elasticsearch: 7.1.0
- Logstash: 7.1.0
- Kibana: 7.1.0
- Spring Boot: 2.1.4.RELEASE
注意:本次主要演示如何在 Spring-Boot 项目中配置 Log4j2
以及 Logback
输出日志到 ELK 中,并能够在 Kibana
中可以正确检索出来,Elasticsearch
及 Spring-Boot 项目底层需要 Java 环境,所以需要提前本地安装好 Java 环境,这里忽略 Java 安装过程。
3、ELK 环境搭建
我们可以去 官网 分别下载系统对应最新版 Elasticsearch
、Logstash
、Kibana
,截止目前已更新到 7.1.0
版本,可通过以下链接获取安装包并提供默认配置启动步骤。
这里我先按照默认配置启动 Elasticsearch
服务,启动完毕,本地可以通过 http://127.0.0.1:9200
地址访问服务是否启动正常。注意:先不启动 Logstash
和 Kibana
,因为他们的配置需要更改,下边会讲到。

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
的吞吐量是 Log4j1
和 Logback
的 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 页面展示出来。需要指定 host
、port
、protocol
,这里就配置成本地 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
支持配置完毕,接下来,我们需要配置 Logstash
和 Kibana
,在 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 => rubydebug
index => "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.conf server.port: 5601
server.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
接口,制造各类日志,在 Kibana
Web 页面查看是否正确加载过来吧!
浏览器访问 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 会默认加载该配置文件。接下来,去 Logstash
config 下增加 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 => rubydebug
index => "%{[appname]}-%{+YYYY.MM.dd}"
}
}
注意:这里的 %{[appname]}
就是获取上边的 <customFields>
字段中的 json 串 key 值,我们只传了一个 appname 值,当让还可以传递其他值,例如 IP、Hostname 等关键信息,方便在 Kibana
中检索索引时区分。重启一下 Logstash
指定该配置文件。
$ cd <Logstash_path>/bin
$ ./logstash -f ../config/test-logback.conf
Elasticsearch
和 Kibana
不需要重启,再次启动 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-*
,查看下日志记录,是否能够正常加载的项目日志,也是妥妥没有问题的。


Spring Boot 使用 Log4j2 & Logback 输出日志到 EKL的更多相关文章
- spring boot:使用log4j2做异步日志打印(spring boot 2.3.1)
一,为什么要使用log4j2? log4j2是log4j的升级版, 升级后更有优势: 性能更强/吞吐量大/支持异步 功能扩展/支持插件/支持自定义级别等 这些优 ...
- Spring Boot(三):logback打印日志
springboot对logback的支持是非常好的,不需要任何配置,只需要在resource下加logback.xml就可以实现功能直接贴代码: <?xml version="1.0 ...
- Spring Boot系列教程六:日志输出配置log4j2
一.前言 spring boot支持的日志框架有,logback,Log4j2,Log4j和Java Util Logging,默认使用的是logback日志框架,笔者一直在使用log4j2,并且 ...
- Spring Boot 使用 Log4j2
Java 中比较常用的日志工具类,有 Log4j.SLF4j.Commons-logging(简称jcl).Logback.Log4j2(Log4j 升级版).Jdk Logging. Spring ...
- spring boot下使用logback或log4j生成符合Logstash标准的JSON格式
spring boot下使用logback或log4j生成符合Logstash标准的JSON格式 一.依赖 由于配置中使用了json格式的日志输出,所以需要引入如下依赖 "net.logst ...
- springboot的日志框架slf4j (使用logback输出日志以及使用)
1.为什么使用logback? ——在开发中不建议使用System.out因为大量的使用会增加资源的消耗.因为使用System.out是在当前线程执行的,写入文件也是写入完毕之后才继续执行下面的程序. ...
- 记一次项目上线后Log4j2不输出日志的坑
公司项目采用了Log4j2来输出日志,在开发环境和测试环境下均可以输出日志,但在生成环境就没有日志输出.开始毫无头绪,后来通过不断的排查,终于解决了这个问题.在此记录下该问题的解决过程,便于后 ...
- Spring boot启动成功后输出提示
添加logback-spring.xml,将log输出到文件,控制台输出的level改为error因此只会出处banner src/main/resources/banner.txt的内容为 star ...
- Spring Boot 2 中的默认日志管理与 Logback 配置详解
Spring Boot在所有内部日志中使用Commons Logging,但是对底层日志的实现是开放的.在Spring Boot生态中,为Java Util Logging .Log4J2 和Logb ...
随机推荐
- Android native进程间通信实例-binder篇之——解决实际问题inputreader内建类清楚缓存
我在实际开发中,遇到一个问题,在电容屏驱动中没有发送input_sync 给上层,导致电容屏有的数据缓存在inputreader 中,会导致系统一系列奇怪问题发生, 至于为什么驱动不发送input_s ...
- Mysql—用户表详解(mysql.user)
MySQL是一个多用户管理的数据库,可以为不同用户分配不同的权限,分为root用户和普通用户,root用户为超级管理员,拥有所有权限,而普通用户拥有指定的权限. MySQL是通过权限表来控制用户对数据 ...
- [PHP] 现代化PHP之路:composer的安装和升级
1.下载一个脚本文件 wget https://getcomposer.org/installer 2.php执行下这个php脚本 php installer 3.把下载的文件转移到一个PATH环境变 ...
- Anaconda3使用
1.使用conda安装各种包到指定路径下的环境, conda install --prefix=/home/xxx/PycharmProjects/project_01/env numpy 2.安装指 ...
- SpringBoot2.x项目pom.xml第一行报错
原来使用的是2.1.4 后来改成2.1.3 保存自动从新下载就好了 毕竟使用人数多 maven地址:https://mvnrepository.com/artifact/org.springfr ...
- Node.js连接数据库取值,简单接口的实现
第一步:先安装Node.js,这里不做介绍 第二步:新建一个文件夹,打开cmd,进入该文件夹 执行npm init命令生成page.json文件 第三步:安装如下模块,打开cmd,进入第二步的文件夹, ...
- Linux学习(四) 忘记密码解决方法
很多朋友经常会忘记Linux系统的root密码,linux系统忘记root密码的情况该怎么办呢?重新安装系统吗?当然不用!进入单用户模式更改一下root密码即可. 步骤如下: 重启linux系统 3 ...
- 43 树莓派安装pytorch
狗狗 https://www.pytorchtutorial.com/pytorch-c-api-4-cat-dog-classifier-2/ 鲜花分类器 https://www.pytorchtu ...
- 【CodeForces】CodeForcesRound576 Div1 解题报告
点此进入比赛 \(A\):MP3(点此看题面) 大致题意: 让你选择一个值域区间\([L,R]\),使得序列中满足\(L\le a_i\le R\)的数的种类数不超过\(2^{\lfloor\frac ...
- django restful framework教程大全
一. 什么是RESTful REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移” REST从资源的角 ...