大家好,欢迎来到IT知识分享网。
日志级别:
Log4j 中日志级别有8种: 从低至高依次为 ALL、TRACE、DEBUG、INFO、WARN、ERROR、FATAL、OFF。
Log4j 建议只使用四个级别,优先级从低至高分别是DEBUG、INFO、WARN、ERROR。
日志框架演化:
- Log4j
Apache Log4j 是一种基于 Java 的日志记录工具,它是 Apache 软件基金会的一个项目。在 jdk1.3 之前,还没有现成的日志框架,Java 工程师只能使用原始的 System.out.println(), System.err.println() 或者 e.printStackTrace()。通过把 debug 日志写到 StdOut 流,错误日志写到 ErrOut 流,以此记录应用程序的运行状态。这种原始的日志记录方式缺陷明显,不仅无法实现定制化,而且日志的输出粒度不够细。鉴于此,1999 年,大牛 Ceki Gülcü 创建了 Log4j 项目,并几乎成为了 Java 日志框架的实际标准。
- JUL
Log4j 作为 Apache 基金会的一员,Apache 希望将 Log4j 引入 jdk,不过被 sun 公司拒绝了。随后,sun 模仿 Log4j,在 jdk1.4 中引入了 JUL(java.util.logging)。
- Commons Logging
为了解耦日志接口与实现,2002 年 Apache 推出了 JCL(Jakarta Commons Logging),也就是 Commons Logging。Commons Logging 定义了一套日志接口,具体实现则由 Log4j 或 JUL 来完成。Commons Logging 基于动态绑定来实现日志的记录,在使用时只需要用它定义的接口编码即可,程序运行时会使用 ClassLoader 寻找和载入底层的日志库,因此可以自由选择由 log4j 或 JUL 来实现日志功能。
- Slf4j&Logback
大牛 Ceki Gülcü 与 Apache 基金会关于 Commons-Logging 制定的标准存在分歧,后来,Ceki Gülcü 离开 Apache 并先后创建了 Slf4j 和 Logback 两个项目。Slf4j 是一个日志门面,只提供接口,可以支持 Logback、JUL、log4j 等日志实现,Logback 提供具体的实现,它相较于 log4j 有更快的执行速度和更完善的功能。
- Log4j 2
为了维护在 Java 日志江湖的地位,防止 JCL、Log4j 被 Slf4j、Logback 组合取代 ,2014 年 Apache 推出了 Log4j 2。Log4j 2 与 log4j 不兼容,经过大量深度优化,其性能显著提升。
日志门面与日志系统:
日志框架的使用选择:
Logback 和 Slf4j 是同一个作者,其兼容性不言而喻。
依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </dependency>
spring-boot 集成 logback,spring-boot-starter-logging依赖包括日志门面和日志系统,并且做了连接适配。额外只需要在yml或properties配置文件中添加如下配置:
logging: config: classpath:logback-cbssproxy.xml #日志配置文件地址 #config: http://${nacos.config.server-addr}/nacos/v1/cs/configs?group=cbss&tenant=${nacos.config.namespace}&dataId=logback-spring.xml level: com.eastcom: debug #指定包路径下的日志输出级别,默认info,排查问题时可改为debug org.springframework.cloud.bus: debug #指定特定类的日志级别,方便查看问题
logback.xml文件具体配置示例:
示例1:
<?xml version="1.0" encoding="UTF-8"?> <!-- debug:打印logback内部日志信息,实时查看logback的运行状态,默认为false --> <!-- scan:配置文件如果发生改变,是否被重新加载,默认为true。 --> <!-- scanPeriod:设置检测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒,默认的时间间隔为1分钟,默认为true。 --> <configuration debug="false" scan="false" scanPeriod="30 seconds"> <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径,可以使用系统变量 此处设置为程序运行目录--> <!-- <property name="LOG_HOME" value="${app.home}/log" /> --> <property name="LOG_HOME" value="logdir"/> <!-- 时间戳定义,timeReference:使用日志产生日期为时间基准 --> <timestamp key="byDay" datePattern="yyyy-MM-dd" timeReference="contextBirth"/> <springProperty scope="context" name="springApplicationName" source="spring.application.name"/> <contextName>${springApplicationName}</contextName> <!-- 引入springboot的控制台日志输出格式-彩色便于分析 --> <include resource="org/springframework/boot/logging/logback/defaults.xml"/> <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度,%msg:日志消息,%n是换行符 --> <property name="CONSOLE_LOG_PATTERN_1" value="%d{yyyy-MM-dd} %d{HH:mm:ss.SSS} %-5level [%thread] [%X{traceId}] %logger{36} - %msg%n"/> <property name="CONSOLE_LOG_PATTERN_2" value="%d{yyyy-MM-dd} %d{HH:mm:ss.SSS} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} [%15.15thread] [%X{traceId}] %clr(%-40.40logger{39}){cyan} %clr(:){faint} %msg%n"/> <property name="CONSOLE_LOG_PATTERN_3" value="${CONSOLE_LOG_PATTERN:-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/> <!-- 控制台输出,生产环境将请stdout去掉 --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>${CONSOLE_LOG_PATTERN_2}</pattern> </encoder> </appender> <!-- file for all --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 日志输出文件 --> <file>${LOG_HOME}/logback_${springApplicationName}_${byDay}.log</file> <!-- 追加日志到原文件结尾 --> <append>true</append> <!-- timebasedrollingpolicy:演示时间和大小为基础的日志文件归档 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 归档的日志文件的路径,例如今天是2013-12-21日志,当前写的日志文件路径为file节点指定。 --> <!--可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。 --> <!--而2013-12-21的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 --> <!-- 文件滚动日期格式:每天:.YYYY-MM-dd(默认);每星期:.YYYY-ww;每月:.YYYY-MM --> <!-- 每隔半天:.YYYY-MM-dd-a;每小时:.YYYY-MM-dd-HH;每分钟:.YYYY-MM-dd-HH-mm --> <fileNamePattern>${LOG_HOME}/logback_${springApplicationName}_%d{yyyy-MM-dd}.%i.log</fileNamePattern> <!-- 控制归档文件的最大数量的保存,删除旧的文件,默认单位天数 --> <maxHistory>7</maxHistory> <!-- 设置当前日志的文件的大小,决定日志翻滚 --> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <!-- 除按日志记录之外,还配置了日志文件不能超过10M(默认),若超过10M,日志文件会以索引0开始, --> <maxFileSize>10MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <encoder> <!-- <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern> --> <pattern>%d{yyyy-MM-dd} %d{HH:mm:ss.SSS} [%thread] [%X{traceId}] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <!--输出到logstash的appender--> <appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender"> <!--可以访问的logstash日志收集端口--> <destination>10.8.29.171:9252</destination> <encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder"> <!-- 在elasticsearch的index中追加applicationName字段 --> <customFields>{"applicationName":"ahsa"}</customFields> </encoder> </appender> <!-- 输出至 logStash 的意愿日志--> <logger name="logStashWishLog" level="INFO" additivity="true"> <appender-ref ref="LOGSTASH"/> </logger> <!-- 输出至 logStash 的策略日志--> <logger name="logStashStrategyLog" level="INFO" additivity="true"> <appender-ref ref="LOGSTASH"/> </logger> <logger name="com.eastcom.*" level="INFO" additivity="false"> <appender-ref ref="FILE"/> </logger> <root level="INFO"> <appender-ref ref="STDOUT"/> <appender-ref ref="FILE"/> </root> </configuration>
示例2:
<?xml version="1.0" encoding="UTF-8"?> <!-- debug:打印logback内部日志信息,实时查看logback的运行状态,默认为false --> <!-- scan:配置文件如果发生改变,是否被重新加载,默认为true。 --> <!-- scanPeriod:设置检测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒,默认的时间间隔为1分钟,默认为true。 --> <configuration debug="false" scan="false" scanPeriod="30 seconds"> <contextName>Application</contextName> <!-- 时间戳定义,timeReference:使用日志产生日期为时间基准 --> <timestamp key="byDay" datePattern="yyyy-MM-dd" timeReference="contextBirth" /> <!-- 定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径,可以使用系统变量 --> <!-- <property name="LOG_HOME" value="${app.home}/log" /> --> <!-- 日志会放在项目根路径下的 logdir 目录 --> <property name="LOG_HOME" value="logdir" /> <!-- 控制台输出,生产环境将请stdout去掉 --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度,%msg:日志消息,%n是换行符 --> <pattern> %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n </pattern> </encoder> </appender> <!-- file for all 打印所有日志 --> <appender name="FILE-ALL" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 日志输出文件 --> <file>${LOG_HOME}/LoggingBack-${byDay}.log</file> <!-- 追加日志到原文件结尾 --> <append>true</append> <!-- timebasedrollingpolicy:演示时间和大小为基础的日志文件归档 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 归档的日志文件的路径,例如今天是2013-12-21日志,当前写的日志文件路径为file节点指定。 --> <!--可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。 --> <!--而2013-12-21的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 --> <!-- 文件滚动日期格式:每天:.YYYY-MM-dd(默认);每星期:.YYYY-ww;每月:.YYYY-MM --> <!-- 每隔半天:.YYYY-MM-dd-a;每小时:.YYYY-MM-dd-HH;每分钟:.YYYY-MM-dd-HH-mm --> <fileNamePattern>${LOG_HOME}/log-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <!-- 控制归档文件的最大数量的保存,删除旧的文件,默认单位天数 --> <maxHistory>7</maxHistory> <!-- 设置当前日志的文件的大小,决定日志翻滚 --> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <!-- 除按日志记录之外,还配置了日志文件不能超过10M(默认),若超过10M,日志文件会以索引0开始, --> <maxFileSize>10MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n </pattern> </encoder> </appender> <!-- file for info 只打印 info 级别的日志(通过过滤器实现)--> <appender name="FILE-INFO" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 这里添加一个过滤器 --> <file>${LOG_HOME}/LoggingBack-info.log</file> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>INFO</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_HOME}/LOG-INFO-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <maxHistory>7</maxHistory> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>10MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n </pattern> </encoder> </appender> <!-- file for error 只打印 error 级别的日志--> <appender name="FILE-ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_HOME}/LoggingBack-error.log</file> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_HOME}/LOG-ERROR-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <maxHistory>7</maxHistory> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>10MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n </pattern> </encoder> </appender> <!--输出到logstash的appender--> <appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender"> <!--可以访问的logstash日志收集端口--> <destination>10.8.29.171:9252</destination> <encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder"> <!-- 在elasticsearch的index中追加applicationName字段 --> <customFields>{"applicationName":"ahsa"}</customFields> </encoder> </appender> <!-- 输出至 logStash 的意愿日志--> <logger name="logStashWishLog" level="INFO" additivity="true"> <appender-ref ref="LOGSTASH"/> </logger> <!-- 输出至 logStash 的策略日志--> <logger name="logStashStrategyLog" level="INFO" additivity="true"> <appender-ref ref="LOGSTASH"/> </logger> <!-- 业务日志级别:项目com.eastcom包下的所有日志输出到以下appender。 additivity 为false代表日志在以下 appender 不会重复 --> <!-- <logger name="com.eastcom" level="INFO" additivity="false"> <appender-ref ref="STDOUT" /> <appender-ref ref="FILE" /> <appender-ref ref="FILE-INFO" /> <appender-ref ref="FILE-ERROR" /> </logger> --> <!-- additivity 为false 表示不向 root 标签传递日志打印信息,即日志不会重复打印。 为true,则 root 标签下的 appender 都会重复打印该日志--> <logger name="playLog" level="INFO" additivity="true"> <appender-ref ref="playLog" /> </logger> <!-- root,所有logger标签的父类,若 logger标签中的additivity=false,则日志不重复输出,以子类为准。 --> <root level="INFO"> <appender-ref ref="STDOUT" /> <appender-ref ref="FILE" /> <appender-ref ref="FILE-INFO" /> <appender-ref ref="FILE-ERROR" /> </root> </configuration>
示例3:(最新)
TimeBasedRollingPolicy 和 SizeAndTimeBasedFNATP 合并为 SizeAndTimeBasedRollingPolicy,SizeAndTimeBasedFNATP 已弃用。
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 日志输出文件 --> <file>${LOG_HOME}/logback_${springApplicationName}_${byDay}.log</file> <!-- 追加日志到原文件结尾 --> <append>true</append> <!-- timebasedrollingpolicy:演示时间和大小为基础的日志文件归档 --> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <!-- 归档的日志文件的路径,例如今天是2013-12-21日志,当前写的日志文件路径为file节点指定。 --> <!--可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。 --> <!--而2013-12-21的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 --> <!-- 文件滚动日期格式:每天:.YYYY-MM-dd(默认);每星期:.YYYY-ww;每月:.YYYY-MM --> <!-- 每隔半天:.YYYY-MM-dd-a;每小时:.YYYY-MM-dd-HH;每分钟:.YYYY-MM-dd-HH-mm --> <fileNamePattern>${LOG_HOME}/logback_${springApplicationName}_%d{yyyy-MM-dd}.%i.log</fileNamePattern> <!-- 控制归档文件的最大数量的保存,删除旧的文件,默认单位天数 --> <maxHistory>7</maxHistory> <!-- 设置当前日志的文件的大小,决定日志翻滚 --> <!-- 除按日志记录之外,还配置了日志文件不能超过10M(默认),若超过10M,日志文件会以索引0开始, --> <maxFileSize>1KB</maxFileSize> </rollingPolicy> <encoder> <!-- <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern> --> <pattern>%d{yyyy-MM-dd} %d{HH:mm:ss.SSS} [%thread] [%X{traceId}] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender>
LoggerFactory.getLogger(“name”) 和 LoggerFactory.getLogger(类.class) 的区别:
使用LoggerFactory.getLogger(“name”) 获取日志,需要在 name属性中填写需要获取的日志的名称。
注意:若logback.xml文件中未配置appender和logger,获者只添加了appender,而没有该名称的logger标签,则日志未指定输出目的地,按root指定输出。
若只添加了logger,并且里面指定了未添加的appender,则启动时会报找不到appender的错误。
<logger name="name" level="INFO" additivity="true"> <appender-ref ref="LOGSTASH"/> </logger>
使用LoggerFactory.getLogger(类.class) 获取日志,需要在 name属性中填写该类的全限定名称。注意:若该类的包路径发生改变时,对应的日志也要做改动。
<logger name="com.ryxx.User" level="INFO" additivity="true"> <appender-ref ref="LOGSTASH"/> </logger>
appender标签:
作用:
①控制打印日志的地方、②打印日志的输出格式。
root标签:
是所有logger的祖先元素,所有的logger都继承与root元素,相当于java中的object对象。
每一个logger标签都可以指定一个级别(TRACE,DEBUG,INFO,WARN,ERROR五种,他们是在 ch.qos.logback.classic.Level class中定义的)。
如果一个指定的logger标签没有指定规则的话,就会继承离他最近的祖先的级别。
因为所有的logger都是继承root标签,所以为了确保所有的logger都有一个级别,root标签有一个默认的级别,默认值为DEBUG。
logger标签:
概述:
会继承距离自己最近的 root 标签。
任何一个logger对象都有五种级别,所以就对应有五种打印日志方法:logger.info(字符串),logger.debug(字符串)。
如果使用logger.info(字符串)的话,那么logger打印级别就是INFO。
有效级别是最低级别,高于有效级别的信息都能打印出来,低于有效级别都不能打印出来。
结构:
示例:
<!-- additivity 为false 表示不向 root 标签传递日志打印信息,即日志不会重复打印。 为true,则 root 标签下的 appender 都会重复打印该日志--> <logger name="playLog" level="INFO" additivity="true"> <appender-ref ref="playLog" /> </logger> <!-- root,所有logger标签的父类,若 logger标签中的additivity=false,则日志不重复输出,以子类为准。 --> <root level="INFO"> <appender-ref ref="STDOUT" /> <appender-ref ref="FILE" /> <appender-ref ref="FILE-INFO" /> <appender-ref ref="FILE-ERROR" /> </root>
参考:
全面梳理 Java 日志框架 – 知乎 (zhihu.com)
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/123052.html