03、日志

  • 在 Java 中,日志(Logging)是记录程序的 运行状态调试信息错误关键工具
    • 它帮助开发者追踪代码执行流程、排查问题,并为生产环境提供监控支持
特性日志断言
用途记录程序运行状态(开发和生产环境)验证代码逻辑正确性(开发阶段)
输出控制动态调整级别,灵活过滤需通过 JVM 参数启用/禁用
性能影响可优化(异步、级别控制)禁用时无开销
错误处理记录错误,不中断程序失败时抛出 AssertionError

一、日志的核心组件


1、Logger(日志记录器)


作用
  • 生成日志事件:通过代码调用(如:logger.info(“message”))触发日志记录。
  • 层级结构:基于类或包的命名空间(如:com.example.service)形成继承关系。
    • 子 Logger 继承父 Logger 的配置(如:日志级别、Appender)。
  • 日志级别控制:决定哪些级别的日志会被记录(如:DEBUG, INFO, ERROR)。
<!-- Logback中定义Logger -->
<logger name="com.example.service" level="DEBUG" additivity="false">
    <!-- 将日志输出到文件 -->
    <appender-ref ref="SERVICE_FILE" />
    <!-- 将日志输出到控制台 -->
    <appender-ref ref="Console"/>
</logger>


<!-- Log4j2中定义Logger -->
<Logger name="com.example.dao" level="INFO" additivity="false">
    <!-- 将日志输出到文件 -->
    <AppenderRef ref="DAO_FILE"/>
    <!-- 将日志输出到控制台 -->
    <AppenderRef ref="Console"/>
</Logger>
关键点
  • 命名规则:通常使用类的全限定名(如:MyClass.class.getName())作为 Logger 名称。
  • 继承性:子包 Logger(如:com.example.service.impl)默认继承父包(如:com.example.service)的配置,除非显式覆盖。

2、Appender(日志输出器)


作用
  • 定义日志输出目标:将日志事件发送到指定位置。
    • 如:文件、控制台、数据库、消息队列等。
  • 多目标支持:一个 Logger 可绑定多个 Appender,实现日志的多路复用。
    • 如:同时输出到文件和控制台。
<!-- Log4j2中定义Logger -->
<Logger name="com.example.dao" level="INFO" additivity="false">
    <!-- 将日志输出到文件 -->
    <AppenderRef ref="DAO_FILE"/>
    <!-- 将日志输出到控制台 -->
    <AppenderRef ref="Console"/>
</Logger>

  • 常见 Appender 类型
类型描述
ConsoleAppender输出到控制台(System.out 或 System.err)。
FileAppender输出到单一文件。
RollingFileAppender支持文件滚动(按时间或大小分割),避免单个文件过大。
SocketAppender将日志发送到远程 Socket 服务器。
AsyncAppender异步输出日志,提升性能(需配合其他 Appender 使用)。
配置示例(Logback)
<!-- 输出到控制台 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
</appender>

<!-- 输出到滚动文件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>logs/app.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <fileNamePattern>logs/app-%d{yyyy-MM-dd}.log</fileNamePattern>
        <maxHistory>30</maxHistory>
    </rollingPolicy>
    <encoder>
        <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
</appender>

配置示例(log4j2)
<!-- 控制台日志输出 -->
<Console name="Console" target="SYSTEM_OUT">
    <!-- ThresholdFilter: 用于定义过滤机制 -->
    <!-- level: 日志过滤级别 -->
    <!-- onMatch="ACCEPT":保留level 及以上级别的日志 -->
    <!-- onMismatch="DENY":丢掉level 以下级别的日志-->
    <!-- onMatch 和 onMissmatch 可选值为:ACCEPT DENY NEUTRAL-->
    <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
    <!-- 输出日志的格式 -->
    <PatternLayout pattern="${LOG_PATTERN}" disableAnsi="false" noConsoleNoAnsi="false"/>
</Console>

<!-- 每次大小超过 size,则这 size 大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档 -->
<RollingRandomAccessFile name="DebugLog" immediateFlush="true" fileName="${LOG_HOME}/${DEBUG_LOG_FILE_NAME}.log" filePattern="${LOG_HOME}/${DEBUG_LOG_FILE_NAME}.log.%d{yyyy-MM-dd}-%i">
    <Filters>
        <ThresholdFilter level="TRACE"/>
        <ThresholdFilter level="INFO" onMatch="DENY" onMismatch="NEUTRAL"/>
    </Filters>
    <!-- 输出日志的格式 -->
    <PatternLayout pattern="${LOG_PATTERN}"/>
    <Policies>
        <!-- 这个配置需要和 filePattern 结合使用,注意 filePattern 中配置的文件重命名规则是 -->
        <!-- interval:表示历史日志封存间隔时间,单位为filePattern设置的单位值
             modulate:表示是否历史日志生成时间纠偏,纠偏以零点为基准进行。比如:15:16生成了msg.2017041715.zip文件,那么纠偏后会在16:00生成msg.2017041716.zip -->
        <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
        <!-- 指定当文件体积大于size指定的值时,触发Rolling -->
        <SizeBasedTriggeringPolicy size="${every_file_size}"/>
    </Policies>
    <!-- 指定最多保存的文件个数 -->
    <DefaultRolloverStrategy max="${file_count}"/>
</RollingRandomAccessFile>

最佳实践
  • 按需选择Appender:生产环境推荐使用 RollingFileAppender 结合异步输出。
  • 避免资源竞争:高频日志场景使用 AsyncAppender 减少 I/O 阻塞。

3、Layout(日志格式化器)


作用
  • 定义日志格式:将日志事件转换为特定格式的字符串(如:包含时间戳、线程名、日志级别等)。
  • 自定义扩展:支持通过占位符或自定义类实现复杂格式(如:JSON、XML)。

常用格式占位符
占位符描述
%d{pattern}日期时间(如:%d{yyyy-MM-dd})
%level日志级别(如:INFO, ERROR)
%logger{length}Logger 名称(%logger{36} 截断)
%msg日志消息内容
%n换行符
%thread线程名

配置示例(Log4j2 的 JSON 格式)
<Console name="CONSOLE" target="SYSTEM_OUT">
    <JsonLayout compact="true">
        <KeyValuePair key="timestamp" value="$${date:yyyy-MM-dd HH:mm:ss}" />
        <KeyValuePair key="level" value="%level" />
        <KeyValuePair key="message" value="%message" />
    </JsonLayout>
</Console>

配置示例(Log4j2 )
<!-- 控制台日志输出 -->
<Console name="Console" target="SYSTEM_OUT">
    <!-- ThresholdFilter: 用于定义过滤机制 -->
    <!-- level: 日志过滤级别 -->
    <!-- onMatch="ACCEPT":保留level 及以上级别的日志 -->
    <!-- onMismatch="DENY":丢掉level 以下级别的日志-->
    <!-- onMatch 和 onMissmatch 可选值为:ACCEPT DENY NEUTRAL-->
    <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
    <!-- 输出日志的格式 -->
    <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight{%-6level}[%t] %highlight{%logger{36}.%M} %-5line: %msg%xEx%n" disableAnsi="false" noConsoleNoAnsi="false"/>
</Console>

4、Filter(日志过滤器)


作用
  • 条件过滤:根据规则决定是否记录某条日志(如:按级别、关键词、来源类名过滤)。
  • 多级过滤:支持链式过滤(如:先按级别过滤,再按关键词过滤)。

  • 常见过滤器类型
过滤器描述
ThresholdFilter仅允许≥指定级别的日志通过(如:只记录 ERROR 及以上)。
LevelFilter精确匹配某个日志级别(如:仅记录 INFO 级别)。
RegexFilter通过正则表达式匹配日志消息内容。
MarkerFilter根据日志标记(Marker)过滤。
配置示例(Log4j2 )
<!-- 每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档 -->
<RollingRandomAccessFile name="ErrorLog" immediateFlush="true" fileName="${LOG_HOME}/${ERROR_LOG_FILE_NAME}.log" filePattern="${LOG_HOME}/${ERROR_LOG_FILE_NAME}.log.%d{yyyy-MM-dd}-%i">
    <!-- 只接受程序中 error 级别的日志进行处理 -->
    <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
    <!-- 输出日志的格式 -->
    <PatternLayout pattern="${LOG_PATTERN}"/>
    <Policies>
        <!-- 这个配置需要和 filePattern 结合使用,注意 filePattern 中配置的文件重命名规则是 -->
        <!-- interval:表示历史日志封存间隔时间,单位为filePattern设置的单位值
             modulate:表示是否历史日志生成时间纠偏,纠偏以零点为基准进行。比如:15:16生成了msg.2017041715.zip文件,那么纠偏后会在16:00生成msg.2017041716.zip -->
        <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
        <!-- 指定当文件体积大于size指定的值时,触发Rolling -->
        <SizeBasedTriggeringPolicy size="${every_file_size}"/>
    </Policies>
    <!-- 指定最多保存的文件个数 -->
    <DefaultRolloverStrategy max="${file_count}"/>
</RollingRandomAccessFile>

5、Logger 上下文(Logger Context)


作用
  • 全局管理:统一管理所有 Logger、Appender、Filter 等组件的生命周期和配置。
  • 动态调整:支持运行时修改日志级别或重新加载配置(如:Log4j2 的 ConfigurationAdmin)

Log4j2 动态调整示例
// 动态修改Logger级别
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
Configuration config = ctx.getConfiguration();
LoggerConfig loggerConfig = config.getLoggerConfig("com.example.service");
loggerConfig.setLevel(Level.DEBUG);
ctx.updateLoggers(config);

6、异步日志处理(Async Logging)


作用
  • 提升性能:将日志I/O操作与业务线程分离,减少阻塞。
  • 实现方式
    • Logback:使用 AsyncAppender 包裹其他Appender。
    • Log4j2:直接配置 AsyncLogger 或全局异步模式。

配置示例(Log4j2异步日志)
<!-- 定义名字为 com.qiaoqiao 的 Logger,其日志级别为info,additivity为false -->
<AsyncLogger name="com.qiaoqiao" level="info" includeLocation="true" additivity="false">
    <appender-ref ref="InfoLog"/>
    <appender-ref ref="ErrorLog"/>
    <!-- Root Logger的Appender引用上面定义的Console -->
    <appender-ref ref="Console"/>
</AsyncLogger>

7、日志门面(SLF4J)


作用
  • 统一接口:提供与具体日志框架无关的API(如:LoggerFactory.getLogger())。
  • 桥接器:通过适配器兼容旧框架(如:log4j-over-slf4j 将 Log4j1.x 调用路由到 SLF4J)。

8、小结


  • Java 日志系统的核心组件通过分工协作,提供了灵活、高效的日志管理能力:
    • Logger 负责生成日志事件。
    • Appender 决定日志输出目标。
    • Layout 格式化日志内容。
    • Filter 过滤无关日志。
    • 异步机制 优化性能。
    • SLF4J 实现框架解耦

  • 合理配置这些组件(如:按包分离日志、按级别过滤、异步输出),可显著提升系统的可维护性和稳定性。
  • 在生产环境中,推荐结合 RollingFileAppender、异步日志和 JSON 格式化,以满足监控和分析需求。

二、日志级别(Level)和 常见日志框架


1、日志级别(Level)


  • 日志级别按严重性从低到高排序,常用级别如下:
级别描述
TRACE最详细的调试信息,通常用于追踪代码执行路径。
DEBUG调试信息,用于开发阶段的问题定位。
INFO程序运行的关键流程信息(如:启动、配置加载)。
WARN潜在问题,不影响程序运行但需关注(如:参数不合法)。
ERROR严重错误,导致功能中断(如:数据库连接失败)。
FATAL致命错误,可能导致程序崩溃(如:内存溢出)。

2、常见日志框架


  • JUL (Java Util Logging)
    • Java 原生日志框架(java.util.logging),功能简单,但扩展性较弱。
  • Log4j 1.x/2.x
    • 高性能、灵活的日志框架,支持多种输出格式和异步日志。
  • Logback
    • Log4j 的继承者,性能更优,原生支持 SLF4J。
  • SLF4J (Simple Logging Facade for Java)
    • 日志门面(抽象层),允许动态切换底层日志框架(如:Log4j、Logback、JUL)。

三、log4j2 的配置模板


<?xml version="1.0" encoding="UTF-8"?>

<!-- 日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL  Asynchronous -->
<Configuration status="error" monitorInterval="1800" packages="org.apache.logging.log4j.core,io.sentry.log4j2">
    <!-- 变量配置 -->
    <properties>
        <!-- 日志输出格式 -->
        <property name="LOG_PATTERN" value="%highlight{%d{yyyy-MM-dd HH:mm:ss.SSS} %-6p[%-16t]  [%X{traceId}]  %logger{36}.%M %-5L  :  %msg%xEx%n}" />
        <property name="LOG_HOME">logs</property>
        <property name="DEBUG_LOG_FILE_NAME">settlecenter-debug</property>
        <property name="INFO_LOG_FILE_NAME">settlecenter-info</property>
        <property name="ERROR_LOG_FILE_NAME">settlecenter-error</property>
        <property name="DRUID_LOG_FILE_NAME">settlecenter-druid-sql</property>
        <property name="DUBBO_LOG_FILE_NAME">settlecenter-dubbo</property>
        <!-- 国美支付日志输出文件名 -->
        <property name="GOMEPAY_LOG_FILE_NAME">settlecenter-gomepay</property>
        <!-- 汇付支付日志输出文件名 -->
        <property name="ADAPAY_LOG_FILE_NAME">settlecenter-adapay</property>
        <!-- 结算网日志输出文件名 -->
        <property name="SETTLE_NETWORK_LOG_FILE_NAME">settlecenter-settle-network</property>
        <!-- 日志切割的最小单位 -->
        <property name="every_file_size">500M</property>
        <!-- 保留的文件个数 -->
        <property name="file_count">10</property>
        <!-- 日志输出级别 -->
        <property name="output_log_level">info</property>
    </properties>

    <!-- appender 就是一个管道,定义了日志内容的去向(保存位置) -->
    <Appenders>
        <!-- 把日志输出到控制台中,输出方式:SYSTEM_OUT【默认】、SYSTEM_ERR -->
        <Console name="Console" target="SYSTEM_OUT">
            <!-- 输出 trace 到 error 级别的日志
                    确保每个Appender的过滤规则互斥(如 LevelFilter 的 onMismatch=DENY),防止同一日志被多个Appender记录。-->
            <LevelRangeFilter minLevel="error" maxLevel="trace" onMatch="ACCEPT" onMismatch="DENY" />

            <!-- Layout 控制日志的输出格式 -->
            <PatternLayout pattern="%highlight{%d{MM-dd HH:mm:ss.SSS} %-6p[%-16t]  [%X{traceId}]  %logger{1.}.%M %-6L :  %msg%xEx%n}" disableAnsi="false" noConsoleNoAnsi="false"/>
        </Console>

        <!-- debug 级别的日志信息写入到文件。 实现日志的切分和归档 -->
        <RollingRandomAccessFile name="DebugLog" immediateFlush="true" fileName="${LOG_HOME}/${DEBUG_LOG_FILE_NAME}.log" filePattern="${LOG_HOME}/${DEBUG_LOG_FILE_NAME}.log.%d{yyyy-MM-dd}-%i">
            <!-- 输出 trace 和 debug 级别的日志 -->
            <LevelRangeFilter minLevel="debug" maxLevel="trace" onMatch="ACCEPT" onMismatch="DENY" />

            <!-- Layout 控制日志的输出格式 -->
            <PatternLayout pattern="${LOG_PATTERN}"/>

            <!-- Policies 控制日志何时(When)进行滚动 -->
            <Policies>
                <!--设置每天打包日志一次-->
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <!-- 设置日志文件满 ${every_file_size} 后打包 -->
                <SizeBasedTriggeringPolicy size="${every_file_size}"/>
            </Policies>

            <!-- 最多保存 file_count 个 -%i 文件,文件就开始滚动覆盖最早的日志文件,比如: settlecenter-info.log.2021-07-05-1 文件 -->
            <DefaultRolloverStrategy max="${file_count}">
                <Delete basePath="${LOG_HOME}/" maxDepth="1">
                    <IfFileName glob="*debug.log.*-*" />
                    <IfLastModified age="2d" />
                </Delete>
            </DefaultRolloverStrategy>
        </RollingRandomAccessFile>

        <!-- 每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档 -->
        <RollingRandomAccessFile name="InfoLog" immediateFlush="true" fileName="${LOG_HOME}/${INFO_LOG_FILE_NAME}.log" filePattern="${LOG_HOME}/${INFO_LOG_FILE_NAME}.log.%d{yyyy-MM-dd}-%i">
            <!-- 从大到小:error, warn, info, debug, trace -->
            <LevelRangeFilter minLevel="error" maxLevel="info" onMatch="ACCEPT" onMismatch="DENY" />

            <!-- 输出日志的格式 -->
            <PatternLayout pattern="${LOG_PATTERN}"/>

            <!-- Policies 控制日志何时(When)进行滚动 -->
            <Policies>
                <!--设置每天打包日志一次-->
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <!-- 设置日志文件满 ${every_file_size} 后打包 -->
                <SizeBasedTriggeringPolicy size="${every_file_size}"/>
            </Policies>

            <!-- 指定最多保存的文件个数 -->
            <DefaultRolloverStrategy max="${file_count}">
                <Delete basePath="${LOG_HOME}/" maxDepth="1">
                    <IfFileName glob="*info.log.*" />
                    <IfLastModified age="10d" />
                </Delete>
            </DefaultRolloverStrategy>
        </RollingRandomAccessFile>

        <!-- 每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档 -->
        <RollingRandomAccessFile name="ErrorLog" immediateFlush="true" fileName="${LOG_HOME}/${ERROR_LOG_FILE_NAME}.log" filePattern="${LOG_HOME}/${ERROR_LOG_FILE_NAME}.log.%d{yyyy-MM-dd}-%i">
            <!-- 从大到小:error, warn, info, debug, trace -->
            <LevelRangeFilter minLevel="error" maxLevel="warn" onMatch="ACCEPT" onMismatch="DENY" />

            <!-- 输出日志的格式 -->
            <PatternLayout pattern="${LOG_PATTERN}"/>

            <!-- Policies 控制日志何时(When)进行滚动 -->
            <Policies>
                <!--设置每天打包日志一次-->
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <!-- 设置日志文件满 ${every_file_size} 后打包 -->
                <SizeBasedTriggeringPolicy size="${every_file_size}"/>
            </Policies>

            <!-- 指定最多保存的文件个数 -->
            <DefaultRolloverStrategy max="${file_count}">
                <Delete basePath="${LOG_HOME}/" maxDepth="1">
                    <IfFileName glob="*error.log.*" />
                    <IfLastModified age="10d" />
                </Delete>
            </DefaultRolloverStrategy>
        </RollingRandomAccessFile>

        <!--druid的日志记录追加器-->
        <!-- 每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档 -->
        <RollingRandomAccessFile name="DruidLog" immediateFlush="true" fileName="${LOG_HOME}/${DRUID_LOG_FILE_NAME}.log" filePattern="${LOG_HOME}/${DRUID_LOG_FILE_NAME}.log.%d{yyyy-MM-dd}-%i">
            <!-- 输出日志的格式 -->
            <PatternLayout pattern="${LOG_PATTERN}"/>

            <!-- Policies 控制日志何时(When)进行滚动 -->
            <Policies>
                <!--设置每天打包日志一次-->
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <!-- 设置日志文件满 ${every_file_size} 后打包 -->
                <SizeBasedTriggeringPolicy size="${every_file_size}"/>
            </Policies>

            <!-- 指定最多保存的文件个数 -->
            <DefaultRolloverStrategy max="${file_count}">
                <Delete basePath="${LOG_HOME}/" maxDepth="1">
                    <IfFileName glob="*sql.log.*" />
                    <IfLastModified age="5d" />
                </Delete>
            </DefaultRolloverStrategy>
        </RollingRandomAccessFile>


        <!-- 每次大小超过 size,则这 size 大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档 -->
        <RollingRandomAccessFile name="DubboLog" immediateFlush="true" fileName="${LOG_HOME}/${DUBBO_LOG_FILE_NAME}.log" filePattern="${LOG_HOME}/${DUBBO_LOG_FILE_NAME}.log.%d{yyyy-MM-dd}-%i">
            <!-- 只输出 info 级别的日志 -->
            <Filters>
                <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>

            <!-- 输出日志的格式 -->
            <PatternLayout pattern="${LOG_PATTERN}"/>

            <!-- Policies 控制日志何时(When)进行滚动 -->
            <Policies>
                <!--设置每天打包日志一次-->
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <!-- 设置日志文件满 ${every_file_size} 后打包 -->
                <SizeBasedTriggeringPolicy size="${every_file_size}"/>
            </Policies>

            <!-- 指定最多保存的文件个数 -->
            <DefaultRolloverStrategy max="${file_count}">
                <Delete basePath="${LOG_HOME}/" maxDepth="1">
                    <IfFileName glob="*dubbo.log.*" />
                    <IfLastModified age="5d" />
                </Delete>
            </DefaultRolloverStrategy>
        </RollingRandomAccessFile>

        <!-- 每次大小超过 size,则这 size 大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档 -->
        <RollingRandomAccessFile name="GoMePayLog" immediateFlush="true" fileName="${LOG_HOME}/payment/${GOMEPAY_LOG_FILE_NAME}.log" filePattern="${LOG_HOME}/payment/${GOMEPAY_LOG_FILE_NAME}.log.%d{yyyy-MM-dd}-%i">
            <Filters>
                <!-- 从大到小:error, warn, info, debug, trace -->
                <LevelRangeFilter minLevel="error" maxLevel="info" onMatch="ACCEPT" onMismatch="DENY" />
            </Filters>

            <!-- 输出日志的格式 -->
            <PatternLayout pattern="${LOG_PATTERN}"/>

            <!-- Policies 控制日志何时(When)进行滚动 -->
            <Policies>
                <!--设置每天打包日志一次-->
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <!-- 设置日志文件满 ${every_file_size} 后打包 -->
                <SizeBasedTriggeringPolicy size="${every_file_size}"/>
            </Policies>

            <!-- 指定最多保存的文件个数 -->
            <DefaultRolloverStrategy max="30">
                <Delete basePath="${LOG_HOME}/payment/" maxDepth="1">
                    <IfFileName glob="*gomepay.log.*" />
                    <IfLastModified age="30d" />
                </Delete>
            </DefaultRolloverStrategy>
        </RollingRandomAccessFile>

        <!-- 每次大小超过 size,则这 size 大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档 -->
        <RollingRandomAccessFile name="AdaPayLog" immediateFlush="true" fileName="${LOG_HOME}/payment/${ADAPAY_LOG_FILE_NAME}.log" filePattern="${LOG_HOME}/payment/${ADAPAY_LOG_FILE_NAME}.log.%d{yyyy-MM-dd}-%i">
            <Filters>
                <!-- 从大到小:error, warn, info, debug, trace -->
                <LevelRangeFilter minLevel="error" maxLevel="info" onMatch="ACCEPT" onMismatch="DENY" />
            </Filters>

            <!-- 输出日志的格式 -->
            <PatternLayout pattern="${LOG_PATTERN}"/>

            <!-- Policies 控制日志何时(When)进行滚动 -->
            <Policies>
                <!--设置每天打包日志一次-->
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <!-- 设置日志文件满 ${every_file_size} 后打包 -->
                <SizeBasedTriggeringPolicy size="${every_file_size}"/>
            </Policies>

            <!-- 指定最多保存的文件个数 -->
            <DefaultRolloverStrategy max="30">
                <Delete basePath="${LOG_HOME}/payment/" maxDepth="1">
                    <IfFileName glob="*adapay.log.*" />
                    <IfLastModified age="30d" />
                </Delete>
            </DefaultRolloverStrategy>
        </RollingRandomAccessFile>
        <RollingRandomAccessFile name="SettleNetworkLog" immediateFlush="true" fileName="${LOG_HOME}/payment/${SETTLE_NETWORK_LOG_FILE_NAME}.log" filePattern="${LOG_HOME}/payment/${SETTLE_NETWORK_LOG_FILE_NAME}.log.%d{yyyy-MM-dd}-%i">
            <Filters>
                <!-- 从大到小:error, warn, info, debug, trace -->
                <LevelRangeFilter minLevel="error" maxLevel="info" onMatch="ACCEPT" onMismatch="DENY" />
            </Filters>

            <!-- 输出日志的格式 -->
            <PatternLayout pattern="${LOG_PATTERN}"/>

            <!-- Policies 控制日志何时(When)进行滚动 -->
            <Policies>
                <!--设置每天打包日志一次-->
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <!-- 设置日志文件满 ${every_file_size} 后打包 -->
                <SizeBasedTriggeringPolicy size="${every_file_size}"/>
            </Policies>

            <!-- 指定最多保存的文件个数 -->
            <DefaultRolloverStrategy max="30">
                <Delete basePath="${LOG_HOME}/payment/" maxDepth="1">
                    <IfFileName glob="*settle-work.log.*" />
                    <IfLastModified age="30d" />
                </Delete>
            </DefaultRolloverStrategy>
        </RollingRandomAccessFile>

        <Sentry name="Sentry" />

        <!-- Setting minimumBreadcrumbLevel modifies the default minimum level to add breadcrumbs from INFO to DEBUG  -->
        <!-- Setting minimumEventLevel the default minimum level to capture an event from ERROR to WARN  -->
        <!--
        <Sentry name="Sentry" dsn="http://d0352aedfa2b497b995a43df1dcd4a77@172.20.0.157:9000/4" environment="development"/>
        <Sentry name="Sentry"
                dsn="https://examplePublicKey@o0.ingest.sentry.io/0"
                minimumBreadcrumbLevel="DEBUG"
                minimumEventLevel="WARN"
        /> -->
    </Appenders>

    <!-- logger 就是一个路由器,指定类,包中的日志流向哪个管道【appender】,以及控制他们的流量(日志级别)-->
    <Loggers>

        <!--记录druid-sql的记录。
            引用了多个 Appender(如 Console、DebugLog),若其他 Logger(如 AsyncLogger)未设置 additivity="false",会导致日志重复记录。 -->
        <AsyncLogger name="druid.sql.Statement" level="error" additivity="false">
            <appender-ref ref="DruidLog"/>
            <appender-ref ref="Console"/>
            <appender-ref ref="Sentry" level="ERROR" />
        </AsyncLogger>

        <!--log4j2 自带过滤日志-->
        <AsyncLogger name="org.apache.catalina.startup.DigesterFactory" level="error" />
        <AsyncLogger name="org.apache.catalina.util.LifecycleBase" level="error" />
        <AsyncLogger name="org.apache.coyote.http11.Http11NioProtocol" level="warn" />
        <AsyncLogger name="org.apache.sshd.common.util.SecurityUtils" level="warn"/>
        <AsyncLogger name="org.apache.tomcat.util.net.NioSelectorPool" level="warn" />
        <AsyncLogger name="org.crsh.plugin" level="warn" />
        <AsyncLogger name="org.crsh.ssh" level="warn"/>
        <AsyncLogger name="org.eclipse.jetty.util.component.AbstractLifeCycle" level="error" />
        <AsyncLogger name="org.hibernate.validator.internal.util.Version" level="warn" />
        <AsyncLogger name="org.springframework.boot.actuate.autoconfigure.CrshAutoConfiguration" level="warn"/>
        <AsyncLogger name="org.springframework.boot.actuate.endpoint.jmx" level="warn"/>
        <AsyncLogger name="org.thymeleaf" level="warn"/>

        <!-- dubbo日志单独打印一个文件
            启用位置信息(includeLocation)
                代价:获取调用位置(类名、方法名、行号)需要访问堆栈信息,轻微影响性能。
                建议:仅在调试时启用,生产环境关闭:-->
        <AsyncLogger name="com.qiaoqiao.common.web.exception.DubboExceptionAspect" level="info" includeLocation="true" additivity="false">
            <appender-ref ref="DubboLog"/>
            <appender-ref ref="Sentry" level="ERROR" />
            <!-- Root Logger的Appender引用上面定义的Console -->
            <appender-ref ref="Console"/>
        </AsyncLogger>

        <!--国美支付日志单独打印一个文件-->
        <AsyncLogger name="com.qiaoqiao.payment.gomepay.util" level="info" includeLocation="true" additivity="false">
            <appender-ref ref="GoMePayLog"/>
            <appender-ref ref="Sentry" level="ERROR" />
            <!-- Root Logger的Appender引用上面定义的Console -->
            <appender-ref ref="Console"/>
        </AsyncLogger>

        <!--汇付支付日志单独打印一个文件-->
        <AsyncLogger name="com.qiaoqiao.payment.adapay.util" level="info" includeLocation="true" additivity="false">
            <appender-ref ref="AdaPayLog"/>
            <appender-ref ref="Sentry" level="ERROR" />
            <!-- Root Logger的Appender引用上面定义的Console -->
            <appender-ref ref="Console"/>
        </AsyncLogger>

        <!--结算网支付日志单独打印一个文件-->
        <AsyncLogger name="com.qiaoqiao.settlecenter.biz.payment.ziyoutong.service.impl" level="info" includeLocation="true" additivity="false">
            <appender-ref ref="SettleNetworkLog"/>
            <appender-ref ref="Sentry" level="ERROR" />
            <!-- Root Logger的Appender引用上面定义的Console -->
            <appender-ref ref="Console"/>
        </AsyncLogger>

        <AsyncLogger name="org.springframework.jms.listener.DefaultMessageListenerContainer" level="error" includeLocation="true" additivity="false">
            <appender-ref ref="ErrorLog"/>
            <appender-ref ref="Sentry" level="ERROR" />
            <!-- Root Logger的Appender引用上面定义的Console -->
            <appender-ref ref="Console"/>
        </AsyncLogger>
        <AsyncLogger name="org.springframework.transaction.support.TransactionSynchronizationManager" level="error" includeLocation="true" additivity="false">
            <appender-ref ref="ErrorLog"/>
            <appender-ref ref="Sentry" level="ERROR" />
            <!-- Root Logger的Appender引用上面定义的Console -->
            <appender-ref ref="Console"/>
        </AsyncLogger>

        <!-- 定义名字为 com.qiaoqiao 的 Logger,其日志级别为info,additivity为false -->
        <AsyncLogger name="com.qiaoqiao" level="info" includeLocation="true" additivity="false">
            <appender-ref ref="InfoLog"/>
            <appender-ref ref="ErrorLog"/>
            <appender-ref ref="Sentry" level="ERROR" />
            <!-- Root Logger的Appender引用上面定义的Console -->
            <appender-ref ref="Console"/>
        </AsyncLogger>

        <AsyncLogger name="com.qiaoqiao.settlecenter.dal" level="error" includeLocation="true"  additivity="false">
            <appender-ref ref="DebugLog"/>
            <!-- Root Logger的Appender引用上面定义的Console -->
            <appender-ref ref="Console"/>
        </AsyncLogger>

        <AsyncLogger name="com.qiaoqiao.common.web.config" level="debug" includeLocation="true"  additivity="false">
            <appender-ref ref="DebugLog"/>
            <!-- Root Logger的Appender引用上面定义的Console -->
            <appender-ref ref="Console"/>
        </AsyncLogger>

        <!-- 定义Root Logger,其日志级别为error -->
        <AsyncRoot level="${output_log_level}" includeLocation="true">
            <!-- Root Logger的Appender引用上面定义的Console -->
            <appender-ref ref="Console"/>
            <appender-ref ref="DebugLog"/>
            <appender-ref ref="InfoLog"/>
            <appender-ref ref="ErrorLog"/>
            <appender-ref ref="Sentry" level="ERROR" />
        </AsyncRoot>

    </Loggers>
</Configuration>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值