Java 日志系统
2022-01-14 本文已影响0人
bowen_wu
概述
- 日志是有名字的对象
- 日志系统是有继承体系的 => a.b.c.d 是 a.b.c 的孩子,也是 a.b 的孩子,是 a 的孩子,是根元素的孩子,根元素是 ROOT Logger
- 调用同名的日志返回的 logger 是同一个对象
- Logger 的日志等级会向下传递
日志等级
当调用一个 logger 的日志方法时,需要传递日志等级
日志等级的意义是让不同等级的日志分门别类地管理
- TRACE => 非常零碎的事情
- DEBUG => 用于调试的详细信息
- INFO => 信息
- WARN => 警告信息
- ERROR => 错误信息
注意:并非每种日志框架都支持以上等级
输出日志
- 输入到 stdout
- 存储到文件中 => 自动压缩历史日志
- 上传到日志管理平台
日志框架
slf4j => The Simple Logging Facade for Java => facade => 并非一个日志框架,而是一个 facade => 为上层提供一个对外的门面 => 门面模式
- log4j => 太老了
- logback => spring boot 默认的日志框架,提供了对 log4j 的改进
- log4j2
logback
logback mavenlogback example
<!-- logback.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<!-- LOG_HOME 对应的值 => key - value -->
<property name="LOG_HOME" value="./logs"/>
<property name="PROJECT_NAME" value="<project_name>"/>
<!-- STDOUT 是 ConsoleAppender -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<!-- WARN 及以上等级的日志都会被打印 -->
<level>WARN</level>
</filter>
<encoder>
<!-- 打印的日志的格式 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 滚动的文件,如果文件满足了一定的条件,会被自动地切成一个文件,之后重新开一个文件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- deny all events with a level below INFO, that is TRACE and DEBUG -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<!-- 滚动策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 文件名称 -->
<fileNamePattern>${LOG_HOME}/${PROJECT_NAME}_%d{yyyy-MM-DD}.%i.log</fileNamePattern>
<!-- 最大时长:30天 -->
<MaxHistory>30</MaxHistory>
<!-- 最大容量:each file should be at most 10MB -->
<MaxFileSize>10MB</MaxFileSize>
</rollingPolicy>
<encoder>
<!-- 打印的日志的格式 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 根 logger -->
<root level="debug">
<!-- 当调用日志的时候,所有的数据会被发送给 appender,appender 会发送给 STDOUT ref(reference) -->
<appender-ref ref="STDOUT"/>
<appender-ref ref="FILE"/>
</root>
</configuration>
使用步骤
- 在 resources 文件夹中添加 logback.xml 配置文件
- 在需要的地方使用
import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class UseLog { private static final Logger logger = LoggerFactory.getLogger(UseLog.class); public static void main(String[] args) { logger.error("This is error log!"); logger.warn("This is warn log!"); logger.info("This is info log!"); } }
log4j2
注:使用时需要排除 spring-logging 依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-logging</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.17.1</version>
<scope>test</scope>
</dependency>
</dependencies>
log4j 2 maven
log4j2 sample
<!-- log4j2.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<Configuration name="XMLPerfTest" status="error">
<Properties>
<Property name="filename">logs/test.log</Property>
</Properties>
<Appenders>
<Console name="STDOUT">
<PatternLayout>
<Pattern>%d %5p [%t] %c{1} - %m%n</Pattern>
</PatternLayout>
<!-- 等级是 warn -->
<ThresholdFilter level="warn"/>
</File>
<RollingFile name="RollingFile" fileName="${filename}" filePattern="logs/test.%i.log.gz">
<PatternLayout>
<Pattern>%d %p [%t] %c{1.} %X{key1} %X{key2} - %m%n</Pattern>
</PatternLayout>
<SizeBasedTriggeringPolicy size="500"/>
</RollingFile>
</Appenders>
<Loggers>
<!-- 所有以 com 开头的 logger 日志等级是 info,所有的日志都会进入 RollingFile 中 -->
<Logger name="com" level="info" additivity="false">
<AppenderRef ref="RollingFile"/>
</Logger>
<!-- 根日志等级是 info,所有的日志都会进入 STDOUT 中 -->
<Root level="info">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
排查问题
- 首先查看日志的错误
- 如果 CPU 吃满了
- 使用 java jstack 查看当前所有线程的栈信息 => search keyword
linux shop thread consuming cpu
=> commandtop -n 1 -H -p [pid]
- 如果是疯狂GC => command
jstact gcutil
=> 查看 GC 信息
- 使用 java jstack 查看当前所有线程的栈信息 => search keyword
知识点
- JUL => java.util.logging
- logback configuration
- log4j2 configuration