前言
log日志可以debug错误或者在关键位置输出想要的结果
java日志使用一般有原生logger、log4j、Slf4j等
一般的日志级别都有如下(不同日志不一样的方法参数,注意甄别)
日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL
参数 | 描述 |
---|---|
OFF、ON | 不输出或者输出所有级别信息,通常使用在setLevel方法中 |
FATAL | 致命错误 |
ERROR | 错误error |
WARN | 告警信息 |
INFO | info信息 |
DEBUG | 调试信息 |
TRACE | 运行轨迹信息 |
CONFIG | 设定配置信息 |
FINE | 级别轻微信息 |
FINER | 级别更轻微信息 |
FINEST | 级别最轻微信息 |
1. Java.util.Logger
科普一下原生日志生成工具,主要引用import java.util.logging.Logger;
源代码函数大致有如下方法:
(给定消息将被转发到所有注册的输出处理程序对象)
// 严重信息
public void severe(String msg) { log(Level.SEVERE, msg);}
// 警告信息
public void warning(String msg) { log(Level.WARNING, msg);}
// info信息
public void info(String msg) {log(Level.INFO, msg);}
// 设定配置信息
public void config(String msg) {log(Level.CONFIG, msg);}
// 级别小信息
public void fine(String msg) {log(Level.FINE, msg);}
// 级别更小信息
public void finer(String msg) {log(Level.FINE, msg);}
// 级别最小信息
public void finest(String msg) {log(Level.FINE, msg);}
具体示例如下:
package com.gaokaoli.logger;
import java.util.logging.Logger;
public class text1 {
public static void main(String []args){
Logger logger = Logger.getLogger("text1");
logger.severe("严重信息");
logger.warning("警示信息");
logger.info("info信息");
logger.config("设定配置信息");
logger.fine("级别小的信息");
logger.finer("级别更小的信息");
logger.finest("级别最小的信息");
}
}
输出截图如下:
可以看到小于info级别的信息不会在终端上显示输出
通过logger.setLevel(Level.ALL);
来控制输出的级别。
ALL则输出severe、warning以及info,OF不输出,如果设置WARNING,则只输出severe以及warning;同理可推其他设置;
方法中也有通过调用提供的供应商函数来构造消息,并将其转发到所有注册的输出处理程序对象。
// 严重信息
public void severe(Supplier<String> msgSupplier) {log(Level.SEVERE, msgSupplier);}
// 警告信息
public void warning(Supplier<String> msgSupplier) {log(Level.WARNING, msgSupplier);}
// info信息
public void info(Supplier<String> msgSupplier) {log(Level.INFO, msgSupplier); }
// 设定配置信息
public void config(Supplier<String> msgSupplier) {log(Level.CONFIG, msgSupplier);}
// 级别小信息
public void fine(Supplier<String> msgSupplier) {log(Level.FINE, msgSupplier);}
// 级别更小信息
public void finer(Supplier<String> msgSupplier) {log(Level.FINER, msgSupplier);}
// 级别最小信息
public void finest(Supplier<String> msgSupplier) {log(Level.FINEST, msgSupplier);}
2. org.apache.logging.log4j
在xml文件中导入依赖包
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.14.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.14.1</version>
</dependency>
示例代码如下:
package com.gaokaoli.logger;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class test3 {
public static void main(String []args){
Logger logger = LogManager.getLogger("text3");
logger.fatal("fatal错误");
logger.error("error错误");
logger.warn("warn警示");
logger.info("info基本信息");
logger.debug("debug调试");
logger.trace("trace 信息");
}
}
输出结果如下:
其方法大致都有如下:
具体使用什么方法可对应进行查看(此处省略)
2.1 xml配置文件
如果引入XML配置文件
和上面一样需要引入Jar包,Import类和代码
<?xml version="1.0" encoding="UTF-8"?>
<!--log4j2的一些配置信息输出-->
<!--status:输出自身内部信息,可以不设置。设置为trace,则输出各个详细输出-->
<!--monitorInterval:自动检测修改的配置文件,主要的信息是间隔秒数-->
<configuration status="DEBUG" monitorInterval="60">
<Properties>
<!-- 日志存放位置 -->
<property name="basePath">logs</property>
<!-- 也可设置为项目根路径或者绝对路径 -->
<!-- <property name="Path">.</property> -->
<!-- 控制台默认输出格式-->
<!-- "%-5level":日志级别,
"%l"(字母小写L输出行号,但会影响日志性能):输出具体的错误位置-->
<!-- %X{traceId} 自定义参数,
%C:类名,
%M:方法名,
%l:行号,
%m:错误信息,
%n:换行 -->
<property name="console_log_pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{traceId}][%thread] %-5level %l %m%n</property>
<!-- 日志文件默认输出格式 -->
<property name="log_pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{traceId}][%thread] %-5level %logger{1.} %m%n</property>
<!-- 日志默认输出级别 -->
<property name="output_log_level">INFO</property>
<!-- 同一文件夹默认可存放日志数量,默认7个(可不设置这个,除非扩充) -->
<property name="max_file">10</property>
<!-- 多久生成新日志,结合filePattern使用 -->
<!-- 为1,filePattern是 %d{yyyy-MM-dd},代表间隔一天生成一个文件
为12,filePattern是%d{yyyy-MM-dd-HH},代表间隔12小时生成一个文件 -->
<property name="timeInterval">1</property>
<!-- true:保存时间以 0点开始结算-->
<property name="timeModulate">true</property>
<!-- 控制台显示最低级别 -->
<property name="print_console_level">INFO</property>
</Properties>
<appenders>
<!-- 输出到控制台-->
<Console name="Console" target="SYSTEM_OUT">
<!-- level以上的才会输出,其他不会输出-->
<ThresholdFilter level="${print_console_level}" onMatch="ACCEPT" onMismatch="DENY"/>
<!-- 输出格式,不设置默认为:%m%n -->
<PatternLayout pattern="${log_pattern}"/>
</Console>
<!-- root 基础日志,框架,系统的日志 -->
<RollingFile name="RootFile" fileName="${basePath}/root.log" filePattern="${basePath}/root-%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout pattern="${log_pattern}"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<SizeBasedTriggeringPolicy size="500MB"/>
</Policies>
<!-- 全部清理规则都在这里 -->
<DefaultRolloverStrategy max="${max_file}">
<Delete basePath="${basePath}" maxDepth="1">
<IfFileName glob="*.log.gz"/>
<IfLastModified age="6d"/>
</Delete>
<Delete basePath="${basePath}" maxDepth="1">
<IfFileName glob="gc*.log"/>
<IfLastModified age="6d"/>
</Delete>
<Delete basePath="${basePath}" maxDepth="1">
<IfFileName glob="dump*.hprof"/>
<IfLastModified age="6d"/>
</Delete>
<Delete basePath="${basePath}" maxDepth="1">
<IfFileName glob="hs_err*.log"/>
<IfLastModified age="6d"/>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
<!-- ERROR日志文件 -->
<RollingFile name="ErrorFile" fileName="${basePath}/error.log" filePattern="${basePath}/error-%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout pattern="${log_pattern}"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<SizeBasedTriggeringPolicy size="500MB"/>
</Policies>
<DefaultRolloverStrategy max="${max_file}" />
<Filters>
<ThresholdFilter level="FATAL" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
</RollingFile>
<!-- api 摘要日志文件 -->
<RollingFile name="APIFile" fileName="${basePath}/api.log" filePattern="${basePath}/api-%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout pattern="${log_pattern}"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<SizeBasedTriggeringPolicy size="500MB"/>
</Policies>
<DefaultRolloverStrategy max="${max_file}" />
</RollingFile>
<!-- trace 切面日志文件 -->
<RollingFile name="TraceFile" fileName="${basePath}/trace.log" filePattern="${basePath}/trace-%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout pattern="${log_pattern}"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<SizeBasedTriggeringPolicy size="500MB"/>
</Policies>
<DefaultRolloverStrategy max="${max_file}" />
</RollingFile>
</appenders>
<!--定义AsyncLogger,只有定义了AsyncLogger并引入的appender,appender才会生效-->
<loggers>
<!-- 公共common包的日志 -->
<AsyncLogger name="com.xx.common" additivity="false">
<appender-ref ref="Console"/>
<appender-ref ref="ErrorFile"/>
<appender-ref ref="RootFile"/>
</AsyncLogger>
<!-- api摘要日志 -->
<AsyncLogger name="apiLogger" additivity="false">
<appender-ref ref="APIFile" />
<appender-ref ref="Console" />
</AsyncLogger>
<!-- error 日志 -->
<AsyncLogger name="errorLogger" additivity="false">
<appender-ref ref="ErrorFile" />
<appender-ref ref="Console" />
</AsyncLogger>
<!-- 设置demo业务包下的日志 -->
<AsyncLogger name="com.xx" additivity="false">
<appender-ref ref="Console"/>
<appender-ref ref="ErrorFile"/>
<appender-ref ref="RootFile"/>
</AsyncLogger>
<!--建立一个默认的root的AsyncLogger-->
<AsyncRoot level="${output_log_level}">
<appender-ref ref="Console"/>
<appender-ref ref="RootFile"/>
<appender-ref ref="ErrorFile"/>
</AsyncRoot>
</loggers>
</configuration>
3. org.slf4j.Logger
目前主流的日志框架,可以使用占位符进行参数占位
主要通过slf4j作为日志输出
在每个类的开头都加入如下:
在xml文件中引入依赖包
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.25</version>
<scope>compile</scope>
</dependency>
如果不引入或者引入错误
会出现如下问题:出现SLF4J: Failed to load class “org.slf4j.impl.StaticLoggerBinder“.的解决方法
代码中通过引用通过
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
具体示例代码如下:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class text2 {
public static final Logger logger = LoggerFactory.getLogger(text2.class);
public static void main(String []args){
logger.error("error错误");
logger.warn("warn警示");
logger.info("info基本信息");
logger.debug("debug调试");
logger.trace("trace信息");
}
}
截图如下:
通过输出结果可看到
==LoggerFactory.getLogger输出的结果带有类的相对路径,便于开发==