Web项目配置log日志文件详解

Web项目配置日志文件详解

1、log4j.xml配置文件

1、loggers中root标签和logger标签区别作用

xml 复制代码
<Loggers>
        <!--<Logger name="task" level="DEBUG" additivity="false">
            <AppenderRef ref="task"/>
        </Logger>-->
        <!--includeLocation 属性用于控制是否在日志记录中包含日志消息的调用位置信息。调用位置信息一般包含类名、方法名和行号等,这些信息能帮助开发者快速定位日志消息的来源。设置为 false 表示不包含这些调用位置信息。 -->
        <!--additivity 属性用于控制日志记录的附加性。
            在 Log4j 2 的日志记录器层次结构中,每个日志记录器都有一个父级日志记录器,默认情况下,日志消息会同时被当前日志记录器和其父级日志记录器处理。
            设置 additivity="false" 表示该日志记录器不会将日志消息传递给其父级日志记录器进行处理,只会使用自身配置的附加器(appender)来记录日志。
         作用:
            避免日志消息被重复处理。比如,当前日志记录器配置了一个附加器将日志输出到文件,而其父级日志记录器也配置了相同的附加器,若不设置 additivity="false",日志消息就会被重复记录到文件中。
            通过设置 additivity="false",可以确保日志消息只被当前日志记录器处理一次。
        -->
        <Logger name="com.incopat.base.Interceptor.TracedInterceptor" level="info" includeLocation="false" additivity="false">
            <appender-ref ref="system_json"/>
        </Logger>
        <Root level="info">
            <!-- root将级别为"INFO"及大于"INFO"的日志信息交给已经配置好的名为"Console"的appender处理,"Console"appender将信息打印到Console; -->
            <AppenderRef ref="console"/>
            <AppenderRef ref="allLog"/>
            <!--<AppenderRef ref="system_json"/>-->
            <AppenderRef ref="info"/>
        </Root>
    </Loggers>

在 Log4j 2 的配置文件里,<Loggers> 标签用于定义日志记录器的相关配置,其中 <Logger> 标签和 <Root> 标签都有着重要的作用,下面为你详细介绍:

1、<Logger> 标签

  • 作用概述<Logger> 标签用于定义具体的日志记录器,你可以针对特定的类或者包来配置日志记录的行为,比如设置日志级别、指定附加器等。
  • 配置示例分析
xml 复制代码
<Logger name="com.incopat.base.Interceptor.TracedInterceptor" level="info" includeLocation="false" additivity="false">
    <appender-ref ref="system_json"/>
</Logger>
  • name 属性 :指定了该日志记录器所对应的类或者包的名称。在这个例子中,name="com.incopat.base.Interceptor.TracedInterceptor" 表示这个日志记录器是为 com.incopat.base.Interceptor.TracedInterceptor 类及其子类服务的。当代码中使用 LoggerFactory.getLogger(Class clazz) 方法获取该类的日志记录器时,就会使用这里配置的规则。
  • level 属性 :设置该日志记录器的日志级别。这里设置为 info,意味着该日志记录器只会记录 INFOWARNERRORFATAL 级别的日志消息,而会忽略 DEBUGTRACE 级别的日志消息。
  • includeLocation 属性 :控制是否在日志记录中包含日志消息的调用位置信息(如类名、方法名、行号等)。设置为 false 表示不包含这些信息,这样可以减少日志记录的开销。
  • additivity 属性 :控制日志记录的附加性。设置为 false 表示该日志记录器不会将日志消息传递给其父级日志记录器处理,只会使用自身配置的附加器 system_json 来记录日志,避免日志消息被重复处理。
  • <appender - ref> 标签 :引用已经定义好的附加器,指定该日志记录器将日志消息输出到哪里。这里引用了名为 system_json 的附加器。

2、<Root> 标签

  • 作用概述<Root> 标签用于定义根日志记录器,它是所有日志记录器的父级。当某个类或者包没有对应的 <Logger> 标签进行单独配置时,就会使用根日志记录器的配置。根日志记录器可以看作是一个全局的默认配置。
  • 配置示例分析
xml 复制代码
<Root level="info">
    <AppenderRef ref="console"/>
    <AppenderRef ref="allLog"/>
    <AppenderRef ref="info"/>
</Root>
  • level 属性 :设置根日志记录器的日志级别。这里设置为 info,意味着所有没有单独配置日志记录器的类和包,其日志记录器默认只会记录 INFOWARNERRORFATAL 级别的日志消息,忽略 DEBUGTRACE 级别的日志消息。
  • <AppenderRef> 标签 :引用已经定义好的附加器,指定根日志记录器将日志消息输出到哪些目标位置。这里引用了 consoleallLoginfo 这三个附加器,说明根日志记录器会将日志消息同时输出到这三个附加器所配置的目标位置(如控制台、文件等)。

总结

<Logger> 标签用于对特定的类或包进行个性化的日志记录配置,而 <Root> 标签则提供了一个全局的默认日志记录配置。当代码中获取某个类的日志记录器时,会先检查是否有对应的 <Logger> 标签配置,如果有则使用该配置;如果没有,则使用 <Root> 标签的配置。

2、AsyncLogger和Logger的区别

AsyncLogger是Logger的子类

异步日志记录器(AsyncLogger)是一款专为实现高吞吐量和低延迟日志记录而设计的日志记录器。 它不会在调用(应用程序)线程中执行任何输入 / 输出操作,而是会尽快将工作交给另一个线程来处理。实际的日志记录操作是在后台线程中执行的。它使用 LMAX Disruptor 来进行线程间通信。 要使用异步日志记录器,在获取日志记录器之前,请指定系统属性

-DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector,并且由 LogManager.getLogger 返回的所有日志记录器都将是异步日志记录器。 请注意,出于性能方面的考虑,此日志记录器默认情况下不包含源位置信息。你需要在配置中指定 includeLocation="true",否则在你的 log4j.xml 配置中,任何 %class、%location 或 %line 转换模式要么会输出一个 "?" 字符,要么根本不会有任何输出。 为了获得最佳性能,将异步日志记录器与 RandomAccessFileAppender(随机访问文件追加器)或 RollingRandomAccessFileAppender(滚动随机访问文件追加器)配合使用,并将 immediateFlush 设置为 false。这些追加器对 Disruptor 库所使用的批处理机制提供了内置支持,并且它们会在每批处理结束时将数据刷新到磁盘。这意味着,即使 immediateFlush 设置为 false,缓冲区中也永远不会残留任何数据项;所有的日志事件都将以非常高效的方式写入磁盘。

java 复制代码
​
public class AsyncLogger extends Logger implements EventTranslatorVararg<RingBufferLogEvent> {
    // Implementation note: many methods in this class are tuned for performance. MODIFY WITH CARE!
    // Specifically, try to keep the hot methods to 35 bytecodes or less:
    // this is within the MaxInlineSize threshold and makes these methods candidates for
    // immediate inlining instead of waiting until they are designated "hot enough".
​
    private static final StatusLogger LOGGER = StatusLogger.getLogger();
    private static final Clock CLOCK = ClockFactory.getClock(); // not reconfigurable
    private static final ContextDataInjector CONTEXT_DATA_INJECTOR = ContextDataInjectorFactory.createInjector();
​
    private static final ThreadNameCachingStrategy THREAD_NAME_CACHING_STRATEGY = ThreadNameCachingStrategy.create();
​
    private final ThreadLocal<RingBufferLogEventTranslator> threadLocalTranslator = new ThreadLocal<>();
    private final AsyncLoggerDisruptor loggerDisruptor;
​
    private volatile boolean includeLocation; // reconfigurable
    private volatile NanoClock nanoClock; // reconfigurable
​
    /**
     * Constructs an {@code AsyncLogger} with the specified context, name and message factory.
     *
     * @param context context of this logger
     * @param name name of this logger
     * @param messageFactory message factory of this logger
     * @param loggerDisruptor helper class that logging can be delegated to. This object owns the Disruptor.
     */
    public AsyncLogger(final LoggerContext context, final String name, final MessageFactory messageFactory,
            final AsyncLoggerDisruptor loggerDisruptor) {
        super(context, name, messageFactory);
        this.loggerDisruptor = loggerDisruptor;
        includeLocation = privateConfig.loggerConfig.isIncludeLocation();
        nanoClock = context.getConfiguration().getNanoClock();
    }
​
    /*
     * (non-Javadoc)
     *
     * @see org.apache.logging.log4j.core.Logger#updateConfiguration(org.apache.logging.log4j.core.config.Configuration)
     */
    @Override
    protected void updateConfiguration(final Configuration newConfig) {
        nanoClock = newConfig.getNanoClock();
        includeLocation = newConfig.getLoggerConfig(name).isIncludeLocation();
        super.updateConfiguration(newConfig);
    }
​
    // package protected for unit tests
    NanoClock getNanoClock() {
        return nanoClock;
    }
​
    private RingBufferLogEventTranslator getCachedTranslator() {
        RingBufferLogEventTranslator result = threadLocalTranslator.get();
        if (result == null) {
            result = new RingBufferLogEventTranslator();
            threadLocalTranslator.set(result);
        }
        return result;
    }
}

3、AsyncLogger 中name="类的完全限定名"方式

xml 复制代码
<AsyncLogger name="com.incoshare.base.tracer.TracedAspect" level="info" includeLocation="false" additivity="false">
    <appender-ref ref="system"/>
    <appender-ref ref="daily"/>
</AsyncLogger>

1.1、name="类的完全限定名"作用

com.incoshare.base.tracer.TracedAspect 这是我的一个类 这个配置用name=类名 表示什么意思 还有其他属性使用含义

这段配置是 Log4j 2 中 AsyncLogger 的配置,下面详细解释 name 属性以及其他属性的含义。

name 属性

name 属性指定了该 AsyncLogger 所对应的日志记录器的名称。在 Java 代码里,当你使用 LoggerFactory.getLogger(Class clazz) 方法获取日志记录器时,如果传入的类是 com.incoshare.base.tracer.TracedAspect 或者其子类,就会使用这个配置的异步日志记录器。

例如,在 Java 代码中这样获取日志记录器:

java 复制代码
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
​
public class TracedAspect {
    private static final Logger logger = LoggerFactory.getLogger(TracedAspect.class);
​
    public void someMethod() {
        logger.info("This is a log message");
    }
}

这里获取的 logger 就会按照 <AsyncLogger> 中配置的规则来处理日志记录,因为 LoggerFactory.getLogger(TracedAspect.class) 得到的日志记录器名称与 <AsyncLogger>name 属性的值相匹配。

其他属性含义

level="info"

level 属性设置了该日志记录器的日志级别为 info。日志级别决定了哪些日志消息会被记录,哪些会被忽略。Log4j 2 支持的日志级别从低到高依次为 TRACEDEBUGINFOWARNERRORFATAL。设置为 info 意味着只有日志级别为 INFOWARNERRORFATAL 的日志消息才会被记录,而 DEBUGTRACE 级别的日志消息将被忽略。

includeLocation="false"

includeLocation 属性用于控制是否在日志记录中包含日志消息的调用位置信息(如类名、方法名、行号等)。设置为 false 表示不包含这些信息,这样可以减少日志记录的开销,提高性能。如果设置为 true,日志记录中会包含调用日志记录方法的具体位置,方便调试和问题排查,但会增加一定的性能开销。

additivity="false"

additivity 属性用于控制日志记录的附加性。设置为 false 表示该日志记录器不会将日志消息传递给其父级日志记录器进行处理,只会使用自身配置的附加器(appender)来记录日志。在 Log4j 2 的日志记录器层次结构中,每个日志记录器都有一个父级日志记录器,默认情况下,日志消息会同时被当前日志记录器和其父级日志记录器处理。设置 additivity="false" 可以避免日志消息被重复处理。

<appender-ref ref="system"/><appender-ref ref="daily"/>

<appender-ref> 标签用于引用已经定义好的附加器(appender)。ref 属性指定了要引用的附加器的名称,这里引用了名为 systemdaily 的附加器。这意味着该日志记录器会将日志消息同时输出到 systemdaily 这两个附加器所配置的目标位置(如文件、控制台等)。

综上所述,这段配置的作用是为 com.incoshare.base.tracer.TracedAspect 类及其子类的日志记录器配置异步日志记录功能,日志级别为 INFO,不包含调用位置信息,不将日志消息传递给父级日志记录器,并且将日志消息同时输出到 systemdaily 两个附加器所配置的目标位置。

相关推荐
GoGeekBaird20 分钟前
69天探索操作系统-第53天:高级分布式操作系统算法和共识协议
后端·操作系统
小杨4042 小时前
springboot框架项目实践应用八(validation自定义校验)
spring boot·后端·架构
Cloud_.2 小时前
Spring Boot整合Sa-Token极简指南
java·后端·springboot·登录校验
冬冬小圆帽2 小时前
防止手机验证码被刷:React + TypeScript 与 Node.js + Express 的全面防御策略
前端·后端·react.js·typescript
陈明勇3 小时前
chromem-go:Go 语言 RAG 应用的高效轻量级向量数据库
后端·go
掘金詹姆斯3 小时前
从Guava缓存源码提炼业务开发心法:Get方法暗藏的12个高并发设计哲学
后端
零零壹113 小时前
理解Akamai EdgeGrid认证在REST API中的应用
前端·后端
uhakadotcom3 小时前
DataWorks邮件外发完全指南:从零开始实现数据自动推送(2025最新实践)
后端·面试·github
qq_5470261793 小时前
Spring Boot 实现多数据源配置
java·spring boot·后端