java日志框架笔记-log4j-springboot整合
# 日志框架slf4j log4j logback之间的关系
简答的讲就是slf4j是一系列的日志接口,而log4j logback是具体实现了的日志框架。
```java
SLF4J获得logger对象:
private static final Logger logger = LoggerFactory.getLogger(Test.class);
```
# log4j vs logback
都是日志框架的具体实现
> log4j是apache实现的一个开源日志组件。(Wrapped implementations)
> logback同样是由log4j的作者设计完成的,拥有更好的特性,用来取代log4j的一个日志框架。是slf4j的原生实现。(Native implementations)

logback是直接实现了slf4j的接口,而log4j不是对slf4j的原生实现,所以slf4j api在调用log4j时需要一个适配层。
也就是说logback实现slf4j是不消耗内存和计算开销的。
# log4j 配置
log4j支持两种配置文件格式,一种是XML格式的文件,一种是properties属性文件。
下面以properties属性文件为例介绍log4j.properties的配置。
下面开始正式讲解配置
## 配置rootLogger
```
log4j.rootLogger = [ level ] , appenderName1, appenderName2, …
```
* 第一个是日志的输出级别 比如测试环境就可以把 level 换成 DEBUG 级别。
* appenderName1 表示文件的输出“地方”。这个“地方” 需要在下面的配置上继续配置。
这是一个示例,表示开始DEBUG 级别的日志,然后输出三个日志 file,stdout,trace
```
log4j.rootLogger=DEBUG,file,stdout,trace
```
## 配置日志信息输出目的地Appender
Log4j提供的appender有以下5种,分别可以将日志信息输出到5个不同的平台
```
org.apache.log4j.ConsoleAppender(控制台)
org.apache.log4j.FileAppender(文件)
org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件)
org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)
org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)
```
下面是一个示例

file 就是那个 AppenderName,第一行的就是上面的几种appender的配置,详细的每个appender配置看下文
### ConsoleAppender
```
Threshold=WARN:指定日志消息的输出最低层次。
ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立即输出。
Target=System.err:默认情况下是:System.out,指定输出控制台
```
### FileAppender
```
Threshold=WARN:指定日志消息的输出最低层次。
ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立即输出。
File=mylog.txt:指定消息输出到mylog.txt文件。
Append=false:默认值是true,即将消息增加到指定文件中,false指将消息覆盖指定的文件内容。
```
### DailyRollingFileAppender
```
Threshold=WARN:指定日志消息的输出最低层次。
ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立即输出。
File=mylog.txt:指定消息输出到mylog.txt文件。
Append=false:默认值是true,即将消息增加到指定文件中,false指将消息覆盖指定的文件内容。
DatePattern=”.”yyyy-ww:每周滚动一次文件,即每周产生一个新的文件。
当然也可以指定按月、周、天、时和分。即对应的格式如下:
1)”.”yyyy-MM: 每月
2)”.”yyyy-ww: 每周
3)”.”yyyy-MM-dd: 每天
4)”.”yyyy-MM-dd-a: 每天两次
5)”.”yyyy-MM-dd-HH: 每小时
6)”.”yyyy-MM-dd-HH-mm: 每分钟
```
### RollingFileAppender
```
Threshold=WARN:指定日志消息的输出最低层次。
ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立即输出。
File=mylog.txt:指定消息输出到mylog.txt文件。
Append=false:默认值是true,即将消息增加到指定文件中,false指将消息覆盖指定的文件内容。
MaxFileSize=100KB:后缀可以是KB, MB 或者是 GB. 在日志文件到达该大小时,将会自动滚动,即将原来的内容移到mylog.log.1文件。
MaxBackupIndex=2:指定可以产生的滚动文件的最大数。
```
## 配置日志信息的格式(布局)
注意到上面的示例中还有一个配置
```
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=${log4j.ConversionPattern}
```
这是就是布局
### Log4j提供的layout有以下几种
```
org.apache.log4j.HTMLLayout(以HTML表格形式布局),
org.apache.log4j.PatternLayout(可以灵活地指定布局模式),
org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),
org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)
```
详细讲一下 PatternLayout 模式
可以在配置文件增加下面这个配置
```
log4j.ConversionPattern=[account-service]%-d{yyyy-MM-dd HH:mm:ss SS} [%c:%L]-[%p] %m%n
```
下面是几个参数的结束
```
-X号: X信息输出时左对齐;
%p: 输出日志信息优先级,即DEBUG,INFO,WARN,ERROR,FATAL,
%d: 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,
比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921
%r: 输出自应用启动到输出该log信息耗费的毫秒数
%c: 输出日志信息所属的类目,通常就是所在类的全名
%t: 输出产生该日志事件的线程名
%l: 输出日志事件的发生位置,相当于%C.%M(%F:%L)的组合,包括类目名、发生的线程,以及行数。
举例:Testlog4.main(TestLog4.java:10)
%x: 输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像java servlets这样的多客户多线程的应用中。
%%: 输出一个”%”字符
%F: 输出日志消息产生时所在的文件名称
%L: 输出代码中的行号
%m: 输出代码中指定的消息,产生的日志具体信息
%n: 输出一个回车换行符,Windows平台为”\r\n”,Unix平台为”\n”输出日志信息换行
```
## 某个日志太多不想看咋办
log4j调整某个包的日记级别
比如现在
io.lettuce.core下面发现很多DEBUG的日志
这时候可以在配置文件中加入
```
log4j.logger.io.lettuce.core=INFO
```
这就可以把日志级别到info
## 来一波独立的业务日志
在一些场景下,想用某些特殊的业务日志记录一些问题,又不想和其他日志混在一起这时候可以采用一些独立日志文件去记录。
配置方式如下:
```
log4j.logger.traceLogger=INFO,trace
```
区别于 默认的 log4j.rootLogger。
log4j.logger.name 就是你需要记录的独立日志。
appender配置如下
```
log4j.appender.trace=org.apache.log4j.DailyRollingFileAppender
log4j.appender.trace.File=/logs/omp/service/omp-account-service-trace.log
log4j.appender.trace.DatePattern='.'yyyy-MM-dd
log4j.appender.trace.Threshold=INFO
log4j.appender.trace.layout=org.apache.log4j.PatternLayout
log4j.appender.trace.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss.SSS}] - %X{mchId} - %X{mchName}- %m%n
# 不在其他的日志文件输出里面输出
log4j.additivity.traceLogger = false
```
代码中 使用
```
private static Logger traceLogger = LoggerFactory.getLogger("traceLogger");
```
# 实战 springboot 2.0 整合 log4j
## maven
排除任何的springboot日志因为这个是 springboot是自带的logback相关日志。
```
spring-boot-starter-logging
org.springframework.boot
```
或者利用利用idea工具排查一下看看相关的日志。

添加相关log4j依赖
```
org.slf4j
slf4j-log4j12
1.7.28
```
## 配置文件
```
# 表示开启debug级别 然后配置 三种默认输出,期中stdout控制台输出
log4j.rootLogger=DEBUG,file,stdout,err
# 日志输出的格式,详细上文说明
log4j.ConversionPattern=[account-service]%-d{yyyy-MM-dd HH:mm:ss-SS} [%l]-[%t]-[%p] %m%n
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=${log4j.ConversionPattern}
log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
log4j.appender.file.File=/Applications/log/account-service.log
log4j.appender.file.DatePattern='.'yyyy-MM-dd
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=${log4j.ConversionPattern}
log4j.appender.err=org.apache.log4j.DailyRollingFileAppender
log4j.appender.err.File=/Applications/log/account-service-err.log
log4j.appender.err.DatePattern='.'yyyy-MM-dd
log4j.appender.err.Threshold=ERROR
log4j.appender.err.layout=org.apache.log4j.PatternLayout
log4j.appender.err.layout.ConversionPattern=${log4j.ConversionPattern}
# 自定义的业务日志
log4j.logger.traceLogger=INFO,trace
# 按照文件大小形式分类,没一个128M大小一共40个
log4j.appender.trace=org.apache.log4j.RollingFileAppender
log4j.appender.trace.File=/Applications/log/account-service-trace.log
log4j.appender.trace.MaxFileSize=128MB
log4j.appender.trace.Append=true
log4j.appender.trace.MaxBackupIndex=40
log4j.appender.trace.Threshold=INFO
log4j.appender.trace.layout=org.apache.log4j.PatternLayout
log4j.appender.trace.layout.ConversionPattern=${log4j.ConversionPattern}
```
假如拟采用的 lombok 可以这样在代码里面打印日志
可以这样的优雅打印日志

## 解决多线程log4j日志输出混乱的问题,每个线程输出独立的日志
可以注意到这里用的异步的方式在打印日志其实为了让大家看到另外的一个效果

OMP-ACTIVITY-THREAD-1 输出的就是线程名字。
当时在配置线程池的时候给线程池配置的名字。这样子在多线程场景下,某一个线程输出的日志一目了然

也就说 在多线程的场景下,可以采用配置线程名的方式,这样子就能看到多线程输出端日志了。
# 日志链路追踪
MDC(Mapped Diagnostic Context,映射调试上下文)是 log4j 和 logback 提供的一种方便在多线程条件下记录日志的功能。某些应用程序采用多线程的方式来处理多个用户的请求。在一个用户的使用过程中,可能有多个不同的线程来进行处理。典型的例子是 Web 应用服务器。当用户访问某个页面时,应用服务器可能会创建一个新的线程来处理该请求,也可能从线程池中复用已有的线程。在一个用户的会话存续期间,可能有多个线程处理过该用户的请求。这使得比较难以区分不同用户所对应的日志。当需要追踪某个用户在系统中的相关日志记录时,就会变得很麻烦。
一种解决的办法是采用自定义的日志格式,把用户的信息采用某种方式编码在日志记录中。这种方式的问题在于要求在每个使用日志记录器的类中,都可以访问到用户相关的信息。这样才可能在记录日志时使用。这样的条件通常是比较难以满足的。MDC 的作用是解决这个问题。
MDC 可以看成是一个与当前线程绑定的哈希表,可以往其中添加键值对。MDC 中包含的内容可以被同一线程中执行的代码所访问。当前线程的子线程会继承其父线程中的 MDC 的内容。当需要记录日志时,只需要从 MDC 中获取所需的信息即可。MDC 的内容则由程序在适当的时候保存进去。对于一个 Web 应用来说,通常是在请求被处理的最开始保存这些数据。
## 直接实战
一个工具类
```java
import java.util.UUID;
import org.apache.log4j.MDC;
public class TraceUtil {
public static void traceStart() {
String traceId = generateTraceId();
MDC.put("traceId", traceId);
}
public static String getTraceId() {
return String.valueOf(MDC.get("traceId"));
}
public static void traceEnd() {
MDC.clear();
}
/**
* 生成跟踪ID
*/
private static String generateTraceId() {
return UUID.randomUUID().toString();
}
}
```
演示效果

看一下打印的结果

可以看到三行日志输出,在同一个线程最后释放后,日志链路id 是没有了。
当然配合常用的一个过滤器,或者aop,就能跟踪到全链路的日志了。
# 更多文章进入
个人网站 [http://www.soulcoder.tech](http://www.soulcoder.tech)

java日志框架笔记-log4j-springboot整合的更多相关文章
- 【SpringBoot】Logback日志框架介绍和SpringBoot整合实战
========================11.Logback日志框架介绍和SpringBoot整合实战 2节课================================ 1.新日志框架L ...
- 11、Logback日志框架介绍和SpringBoot整合实战 2节课
1.新日志框架LogBack介绍 简介:日志介绍和新日志框架Logback讲解 1.常用处理java的日志组件 slf4j,log4j,logback,common-logging 等 ...
- Java日志框架 (commons-logging,log4j,slf4j,logback)
转自:http://blog.csdn.net/kobejayandy/article/details/17335407 如果对于commons-loging.log4j.slf4j.LogBack等 ...
- Java日志框架Slf4j+Log4j入门
一.日志系统介绍 slf4j,即简单日志门面(Simple Logging Facade for Java),不是具体的日志解决方案,它只服务于各种各样的日志系统.简答的讲就是slf4j是一系列的日志 ...
- 小D课堂 - 零基础入门SpringBoot2.X到实战_第11节 Logback日志框架介绍和SpringBoot整合实战_45、SpringBoot2.x日志讲解和Logback配置实战
笔记 2.SpringBoot2.x日志讲解和自定义Logback配置实战 简介:讲解SpringBoot2.x整合Logback配置实战 1.官网介绍:https://docs.spring ...
- 拨云见日,彻底弄清楚Java日志框架 log4j, logback, slf4j的区别与联系
log4j 以及 logback, slf4j 官网 日志框架的困惑 作为一个正常的项目,是必须有日志框架的存在的,没有日志,很难追踪一些奇奇怪怪的系统问题. 但是,我们经常在项目的依赖中,见到奇奇怪 ...
- Java学习笔记(十九)——Java 日志记录 AND log4j
[前面的话] 学习的进度应该稍微在快一点. Java日志到了必须学习怎么使用的时候了,因为在项目中要进行使用.基础性文章,选择性阅读. [结构] java日志对调试,记录运行,问题定位都起到了很重要的 ...
- Java 日志框架概述(slf4j / log4j / JUL / Common-logging(JCL) / logback)
一.简介 JAVA日志在初期可能官方并没有提供很好且实用的规范,导致各公司或OSS作者选择自行造轮子,这也导致了目前初学者觉得市面上 Java 日志库繁杂的局面. 现在市面流行以 slf4j(Simp ...
- Java日志框架那些事儿
文章首发于[博客园-陈树义],点击跳转到原文Java日志框架那些事儿. 在项目开发过程中,我们可以通过 debug 查找问题.而在线上环境我们查找问题只能通过打印日志的方式查找问题.因此对于一个项目而 ...
随机推荐
- django中ORM的model对象和querryset 简单解析
欢迎大家查看我的博客,我会不定时的用大白话发一些看了就能懂的文章,大家多多支持!如您对此文章内容有独特见解,欢迎与笔者练习一起探讨学习!原创文创!转载请注明出处! ORM是干嘛的? 介绍orm之前我应 ...
- Servlet的介绍
Servlet由来 做过BS项目的人都知道,浏览器能够根据HTML静态标记语言来显示各式各样的网页.但是如果我们需要在网页上完成一些业务逻辑:比如登陆验证.或者说网页显示的内容在服务器的数据库中.如果 ...
- get解决乱码的方式
//自定义的解决乱码方式
- 一份关于.NET Core云原生采用情况调查
调查背景 Kubernetes 越来越多地在生产环境中使用,围绕 Kubernetes 的整个生态系统在不断演进,新的工具和解决方案也在持续发布.云原生计算的发展驱动着各个企业转向遵循云原生原则(启动 ...
- 【iOS】Ineligible Devices || “无法下载应用程序”
今天遇到了这个问题,Xcode 显示如图所示: 还有真机测试无法安装的问题,如图: 究其原因,都是 版本不匹配 的问题!在 Xcode 中的 PROJECT 和 TARGETS 设置下版本就行了,如下 ...
- maven添加oracle驱动包
问题描述 项目用到了oracle,但由于oracle商业版权问题,maven在中心资源库直接下载jar包是要收费的 解决方法 第一步: 下载ojdbc6.jar 第二步: 将下载的jar放入项目的li ...
- 最小化docker镜像
kubernetes离线安装包,仅需三步 如何让镜像尽可能小 很容器想到from scratch, 就是没任何基础镜像 FROM scratch COPY p / ENTRYPOINT [" ...
- Cobbler 自动安装CentOS7
1. Cobbler介绍 Cobbler是一个Linux服务器安装的服务,可以通过网络启动(PXE)的方式来快速安装.重装物理服务器和虚拟机,同时还可以管理DHCP,DNS等.Cobbler可以使用命 ...
- Iphone使用过程中遇到的问题
Q1:同一个Apple ID不同设备之间的通话记录保持同步 解决方法: Step1:"设置"--"电话"--"在其他设备上通话"--选择关闭 ...
- asp.net core系列 70 即时通迅-WebSocket+Redis发布订阅
一.概述 在asp.net core 中可以用WebSocket 或asp.net core SignalR来开发即时通迅.在项目中由于开发前后端分离,对于SignalR前端技术人员不想依赖juqer ...