spring boot下使用logback或log4j生成符合Logstash标准的JSON格式
spring boot下使用logback或log4j生成符合Logstash标准的JSON格式
一、依赖
由于配置中使用了json格式的日志输出,所以需要引入如下依赖
"net.logstash.logback:logstash-logback-encoder:4.11",
<!-- https://mvnrepository.com/artifact/net.logstash.logback/logstash-logback-encoder -->
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>4.11</version>
</dependency>
二、配置说明
1.日志的输出路径
<property name="LOG_PATH" value="phantom-log" />
- 1
2.读取spring容器中的属性,这里是获取项目名称和运行的服务器IP
<springProperty scope="context" name="appName" source="spring.application.name" />
<springProperty scope="context" name="ip" source="spring.cloud.client.ipAddress" />
- 1
- 2
3.设置日志的格式
<property name="CONSOLE_LOG_PATTERN"
value="[%d{yyyy-MM-dd HH:mm:ss.SSS} ${ip} ${appName} %highlight(%-5level) %yellow(%X{X-B3-TraceId}),%green(%X{X-B3-SpanId}),%blue(%X{X-B3-ParentSpanId}) %yellow(%thread) %green(%logger) %msg%n"/>
- 1
- 2
4.添加一个输出器,并滚动输出
<appender name="FILEERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
- 1
5.指定输出的文件位置
<file>../${LOG_PATH}/${appName}/${appName}-error.log</file>
- 1
6.指定滚动输出的策略,按天数进行切分,或者文件大小超过2M进行切分
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>../${LOG_PATH}/${appName}/${appName}-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>2MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
1
- 2
- 3
- 4
- 5
- 6
7.下面的文件中一共有四个appender, FILEERROR, FILEEWARN, FILEINFO, logstash。
其中FILEERROR, FILEEWARN, FILEINFO三个是相类似的,只是打印不同级别的日志信息。
logstash是用来生成json格式的日志文件,方便与ELK日志系统进行集成。
三、完整配置

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<contextName>${HOSTNAME}</contextName>
<property name="LOG_PATH" value="phantom-log" />
<springProperty scope="context" name="appName" source="spring.application.name" />
<springProperty scope="context" name="ip" source="spring.cloud.client.ipAddress" />
<property name="CONSOLE_LOG_PATTERN"
value="[%d{yyyy-MM-dd HH:mm:ss.SSS} ${ip} ${appName} %highlight(%-5level) %yellow(%X{X-B3-TraceId}),%green(%X{X-B3-SpanId}),%blue(%X{X-B3-ParentSpanId}) %yellow(%thread) %green(%logger) %msg%n"/> <appender name="FILEERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>../${LOG_PATH}/${appName}/${appName}-error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>../${LOG_PATH}/${appName}/${appName}-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>2MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<append>true</append>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>utf-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>error</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender> <appender name="FILEWARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>../${LOG_PATH}/${appName}/${appName}-warn.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>../${LOG_PATH}/${appName}/${appName}-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>2MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<append>true</append>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>utf-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>warn</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender> <appender name="FILEINFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>../${LOG_PATH}/${appName}/${appName}-info.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>../${LOG_PATH}/${appName}/${appName}-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>2MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<append>true</append>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>utf-8</charset>
</encoder> <filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>info</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender> <appender name="logstash" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>../${LOG_PATH}/${appName}/${appName}.json</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>../${LOG_PATH}/${appName}/${appName}-%d{yyyy-MM-dd}.json</fileNamePattern>
<maxHistory>7</maxHistory>
</rollingPolicy>
<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<timestamp>
<timeZone>UTC</timeZone>
</timestamp>
<pattern>
<pattern>
{
"ip": "${ip}",
"app": "${appName}",
"level": "%level",
"trace": "%X{X-B3-TraceId:-}",
"span": "%X{X-B3-SpanId:-}",
"parent": "%X{X-B3-ParentSpanId:-}",
"thread": "%thread",
"class": "%logger{40}",
"message": "%message",
"stack_trace": "%exception{10}"
}
</pattern>
</pattern>
</providers>
</encoder>
</appender> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>utf-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>debug</level>
</filter>
</appender> <logger name="org.springframework" level="INFO" />
<logger name="org.hibernate" level="INFO" />
<logger name="com.kingboy.repository" level="DEBUG" /> <root level="INFO">
<appender-ref ref="FILEERROR" />
<appender-ref ref="FILEWARN" />
<appender-ref ref="FILEINFO" />
<appender-ref ref="logstash" />
<appender-ref ref="STDOUT" />
</root>
</configuration>

生成的日志文件如下:

{"@timestamp":"2019-03-14T07:02:15.318+00:00","ip":"ip_IS_UNDEFINED","app":"appName_IS_UNDEFINED","level":"INFO","trace":"","span":"","parent":"","thread":"main","class":"o.apache.coyote.http11.Http11NioProtocol","message":"Starting ProtocolHandler [\"https-jsse-nio-8443\"]","stack_trace":""}
{"@timestamp":"2019-03-14T07:02:15.621+00:00","ip":"ip_IS_UNDEFINED","app":"appName_IS_UNDEFINED","level":"INFO","trace":"","span":"","parent":"","thread":"main","class":"o.apache.tomcat.util.net.NioSelectorPool","message":"Using a shared selector for servlet write/read","stack_trace":""}
{"@timestamp":"2019-03-14T07:02:15.633+00:00","ip":"ip_IS_UNDEFINED","app":"appName_IS_UNDEFINED","level":"INFO","trace":"","span":"","parent":"","thread":"main","class":"o.apache.coyote.http11.Http11NioProtocol","message":"Starting ProtocolHandler [\"http-nio-80\"]","stack_trace":""}
{"@timestamp":"2019-03-14T07:02:15.642+00:00","ip":"ip_IS_UNDEFINED","app":"appName_IS_UNDEFINED","level":"INFO","trace":"","span":"","parent":"","thread":"main","class":"o.s.b.w.embedded.tomcat.TomcatWebServer","message":"Tomcat started on port(s): 8443 (https) 80 (http) with context path ''","stack_trace":""}
{"@timestamp":"2019-03-14T07:02:15.645+00:00","ip":"ip_IS_UNDEFINED","app":"appName_IS_UNDEFINED","level":"INFO","trace":"","span":"","parent":"","thread":"main","class":"org.data.collector.Application","message":"Started Application in 5.971 seconds (JVM running for 19.807)","stack_trace":""}
filebeat.yml
1 |
#=========================== Filebeat prospectors ============================= filebeat.prospectors: - input_type: log enabled: true #半天没有日志上传,就是这里的原因!!! # Paths that should be crawled and fetched. Glob based paths. |
这里面需要注意的是
json.keys_under_root: 默认这个值是FALSE的,也就是我们的json日志解析后会被放在json键上。设为TRUE,所有的keys就会被放到根节点
json.overwrite_keys: 是否要覆盖原有的key,这是关键配置,将keys_under_root设为TRUE后,再将overwrite_keys也设为TRUE,就能把filebeat默认的key值给覆盖了
还有其他的配置
json.add_error_key:添加json_error key键记录json解析失败错误
json.message_key:指定json日志解析后放到哪个key上,默认是json,你也可以指定为log等。
logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?> <configuration debug="false" scan="true" scanPeriod="600000">
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
<property name="LOG_HOME" value="/var/log" />
<contextName>${HOSTNAME}</contextName>
<springProperty scope="context" name="appName" source="spring.application.name" />
<springProperty scope="context" name="ip" source="spring.cloud.client.ipAddress" /> <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<property name="CONSOLE_LOG_PATTERN"
value="[%d{yyyy-MM-dd HH:mm:ss.SSS} ${ip} ${appName} %highlight(%-5level) %yellow(%X{X-B3-TraceId}),%green(%X{X-B3-SpanId}),%blue(%X{X-B3-ParentSpanId}) %yellow(%thread) %green(%logger) %msg%n"/> <!-- <logger name="org.springframework.web" level="DEBUG" /> --> <!-- show parameters for hibernate sql 专为 Hibernate 定制 -->
<!--<logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="TRACE" />-->
<!--<logger name="org.hibernate.type.descriptor.sql.BasicExtractor" level="DEBUG" />-->
<!--<logger name="org.hibernate.engine.QueryParameters" level="DEBUG" />-->
<!--<logger name="org.hibernate.engine.query.HQLQueryPlan" level="DEBUG" />--> <!-- <logger name="org.hibernate.SQL" level="DEBUG" /> -->
<logger name="logging.level.com.italktv.platform" level="info" /> <!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>utf-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>debug</level>
</filter>
</appender> <!-- 按照每天生成日志文件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${LOG_HOME}/bigdata/data-api.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<FileNamePattern>${LOG_HOME}/bigdata/data-api.%d{yyyy-MM-dd}.%i.log</FileNamePattern>
<!--日志文件保留天数-->
<MaxHistory>30</MaxHistory>
<maxFileSize>1MB</maxFileSize>
<totalSizeCap>10MB</totalSizeCap>
</rollingPolicy>
<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<timestamp>
<timeZone>UTC</timeZone>
</timestamp>
<pattern>
<pattern>
{
"ip": "${ip}",
"app": "${appName}",
"level": "%level",
"trace": "%X{X-B3-TraceId:-}",
"span": "%X{X-B3-SpanId:-}",
"parent": "%X{X-B3-ParentSpanId:-}",
"thread": "%thread",
"class": "%logger{40}",
"message": "%message",
"stack_trace": "%exception{10}"
}
</pattern>
</pattern>
</providers>
</encoder>
<!--日志文件最大的大小
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10KB</MaxFileSize>
</triggeringPolicy>
-->
</appender> <!-- 日志输出级别 -->
<root level="INFO">
<!-- 生产上不输出stdout log -->
<!--appender-ref ref="STDOUT" /--> <appender-ref ref="FILE" />
</root> </configuration>
____________________________________________
application.xml:
logging:
config: logback-spring.xml
_____________________________
tomcat里面 log4j的字段值:
https://www.jianshu.com/p/a26da0c55255
spring boot下使用logback或log4j生成符合Logstash标准的JSON格式的更多相关文章
- 解决spring boot中rest接口404,500等错误返回统一的json格式
在开发rest接口时,我们往往会定义统一的返回格式,列如: { "status": true, "code": 200, "message" ...
- Spring Boot默认日志logback配置解析
前言 今天来介绍下Spring Boot如何配置日志logback,我刚学习的时候,是带着下面几个问题来查资料的,你呢 如何引入日志? 日志输出格式以及输出方式如何配置? 代码中如何使用? 正文 Sp ...
- spring boot / cloud (十六) 分布式ID生成服务
spring boot / cloud (十六) 分布式ID生成服务 在几乎所有的分布式系统或者采用了分库/分表设计的系统中,几乎都会需要生成数据的唯一标识ID的需求, 常规做法,是使用数据库中的自动 ...
- Spring Boot下Druid连接池+mybatis
目前Spring Boot中默认支持的连接池有dbcp,dbcp2, hikari三种连接池. 引言: 在Spring Boot下默认提供了若干种可用的连接池,Druid来自于阿里系的一个开源连 ...
- Java | Spring Boot Swagger2 集成REST ful API 生成接口文档
Spring Boot Swagger2 集成REST ful API 生成接口文档 原文 简介 由于Spring Boot 的特性,用来开发 REST ful 变得非常容易,并且结合 Swagg ...
- 转-Hive/Phoenix + Druid + JdbcTemplate 在 Spring Boot 下的整合
Hive/Phoenix + Druid + JdbcTemplate 在 Spring Boot 下的整合 http://blog.csdn.net/balabalayi/article/detai ...
- 【spring boot】10.spring boot下的单元测试
spring boot下的单元测试,思前想后还是需要单独用一章篇幅来看看. 然后在看了介绍和使用时候,我感觉并不想多去看了. 但是还是给后来人留下参考的路径: 官网说明:https://spring. ...
- 【ActiveMQ】2.spring Boot下使用ActiveMQ
在spring boot下使用ActiveMQ,需要一下几个条件 1.安装并启动了ActiveMQ,参考:http://www.cnblogs.com/sxdcgaq8080/p/7919489.ht ...
- Spring Boot下的一种导入Excel文件的代码框架
1.前言 Spring Boot下如果只是导入一个简单的Excel文件,是容易的.网上类似的文章不少,有的针对具体的实体类,代码可重用性不高:有的利用反射机制或自定义注解,开发了Excel导入工具 ...
随机推荐
- 05 入门 - 浅谈 ASP.NET MVC程序的工作原理
目录索引:<ASP.NET MVC 5 高级编程>学习笔记 本篇内容 1. Global.asax文件 2. RouteConfig.cs文件 3. 视图命名和寻址的规则 前面创建了一个简 ...
- pycharm中Django的安装和简单使用
一.安装: 1.点击File,找到setting选项 2.点击+号,进入下面界面 结束后,安装完成 二.创建Django项目 创建成功后,新项目左侧: templates:用于存储HTML文件 set ...
- 原生js实例对象方法
Array中的方法 ☞ toString() // 把数组转换为字符串,使用逗号分隔☞ valueOf() // 返回数组对象本身 ☞ 栈方法(先进后出)ary.push() // 该方法有一个返回值 ...
- 使用 MapTiler 进行地图切片
在GIS开发中接触比较多的就是切图与发布,通常大家使用的是GlobalMapper.ArcGIS.GDAL等. 一般在使用Leaflet.js或其他框架开发时,使用的是TMS切片格式,大佬们基本用GD ...
- 数据结构java(一)数组链表
链表是数据结构中最基础的内容,链表在存储结构上分成两种:数组形式储存,链式存储. 相比c语言需要的结构体,在java中由于有了面向对象编程,将指针‘藏’了起来,不需要分配内存. 所以只需要创建一个对象 ...
- Java:配置环境(Mac)——MySQL
1.官网下载 2.双击开始安装,一直下一步 用旧版的密码加密 自己写个密码,最少8位 3.测试 打开系统偏好设置 4.mysql需要在系统环境变量里 1)在终端输入mysql,没有指令说明.此时就还不 ...
- Postman学习之【压力测试】
Postman请自行下载 下面是在网上随便抓了一个请求地址来做演示,把请求地址填入地址栏,此请求为GET请求.点击Send发送请求,请求结果将会在下方显示出来.每次的请求历史数据,会被记录下来,但是经 ...
- Jmeter简单回顾
之前公众号推文一上手就分享如何测接口, 其实忽略了一些概念性的东西, 今天来给大家拾遗补缺, 做个回顾吧. 一. JMeter介绍 jmeter能做什么,来自官网的解释: Ability to loa ...
- SqlServer无备份下误删数据恢复
系统已上线,给客户修改bug的时候,使用delete语句删表数据,没想到库没切换成测试库.误删了正式库的数据,而且一次备份都没有做过,玩大了 不扯了,进入主题 网上很多方法,都是针对至少有一次备份的情 ...
- Ajax异步交互基础
1. ajax是什么? * asynchronous javascript and xml:异步的js和xml * 它能使用js访问服务器,而且是异步访问! * 服务器给客户端的响应一般是整个页面,一 ...