Java 日志系统

2022-01-14  本文已影响0人  bowen_wu

概述

  1. 日志是有名字的对象
  2. 日志系统是有继承体系的 => a.b.c.d 是 a.b.c 的孩子,也是 a.b 的孩子,是 a 的孩子,是根元素的孩子,根元素是 ROOT Logger
  3. 调用同名的日志返回的 logger 是同一个对象
  4. Logger 的日志等级会向下传递

日志等级

当调用一个 logger 的日志方法时,需要传递日志等级

日志等级的意义是让不同等级的日志分门别类地管理

注意:并非每种日志框架都支持以上等级

输出日志

日志框架

slf4j => The Simple Logging Facade for Java => facade => 并非一个日志框架,而是一个 facade => 为上层提供一个对外的门面 => 门面模式

logback

logback maven
logback 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>

使用步骤

  1. 在 resources 文件夹中添加 logback.xml 配置文件
  2. 在需要的地方使用
    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>

排查问题

  1. 首先查看日志的错误
  2. 如果 CPU 吃满了
    • 使用 java jstack 查看当前所有线程的栈信息 => search keyword linux shop thread consuming cpu => command top -n 1 -H -p [pid]
    • 如果是疯狂GC => command jstact gcutil => 查看 GC 信息

知识点

  1. JUL => java.util.logging
  2. logback configuration
  3. log4j2 configuration
上一篇下一篇

猜你喜欢

热点阅读