Log4j配置理解与日志优化相关技术问题咨询
1. 如何关闭Netflix微服务产生的日志?
在log4j2.xml中给Netflix相关包(通常是com.netflix开头的路径)添加Logger配置,将日志级别设为OFF即可,示例:
<Logger name="com.netflix" level="OFF" additivity="false"> </Logger>
其中additivity="false"用于切断该Logger向父级(包括Root)传递日志的链路,确保彻底关闭这类日志输出。
2. 教程称Logger需通过appender-ref关联Appender,但当前log4j2.xml中多数Logger无对应Appender,是否正确?原理是什么?
这是完全正确的。Log4j的Logger遵循继承机制:未配置专属Appender的Logger,会自动继承父级Logger(包括上层包的Logger或Root Logger)的Appender。只有当你需要该Logger使用独立的输出目标时,才需要显式配置appender-ref;否则直接沿用父级的Appender即可。
3. <appender-ref ref="${sys:logger.out.type}"/>中的${sys:logger.out.type}含义是什么?
这是Log4j的系统属性占位符,表示读取JVM启动时通过-D参数传入的logger.out.type系统属性值,并用该值作为要引用的Appender名称。比如启动应用时添加参数-Dlogger.out.type=FileAppender,这里就会引用名为FileAppender的Appender。如果未设置该系统属性,可能会使用配置中预设的默认值,或因找不到对应Appender报错,具体取决于配置的兜底逻辑。
4. 每个Logger定义对应包的日志规则,若包未定义Logger,是否默认归Root处理?
是的。Log4j的Logger是层级树状结构:如果某个包没有定义专属Logger,日志会向上匹配更上层的包Logger(比如com.example.service无定义时,会找com.example的Logger),直到找到Root Logger。所有未被上层Logger匹配的日志,最终都会由Root Logger处理。
5. configuration的status设为OFF,但仍有日志输出,这是为什么?
configuration的status属性仅控制Log4j自身的内部日志(比如配置加载、组件初始化的调试信息),和应用业务日志、第三方框架日志无关。即使设为OFF,应用代码、Netflix、MyBatis等产生的日志依然会正常输出。
6. 如何关闭MyBatis接口产生的日志?(该接口无实现类但可注入)
MyBatis的日志分为核心框架日志和Mapper接口日志,分别对应不同的包,直接针对对应包添加Logger并设为OFF即可:
- 关闭MyBatis核心框架日志:
<Logger name="org.apache.ibatis" level="OFF" additivity="false"> </Logger>
- 关闭自定义Mapper接口的日志(假设接口在
com.example.mapper包下):
<Logger name="com.example.mapper" level="OFF" additivity="false"> </Logger>
MyBatis的Mapper动态代理类日志会归属于接口所在的包,因此上述配置可以覆盖这类日志。
7. src下的log4j2.xml是配置文件,build下的log4j.properties是编译产物吗?
不一定,具体看项目构建工具(Maven/Gradle)的配置:
- src目录下的
log4j2.xml是源码级配置文件,通常会被构建工具复制到build目录的classpath下,作为运行时的配置来源。 - build目录下的
log4j.properties大概率是项目resources目录下的同名文件被构建工具复制过来的;少数情况下可能是构建插件生成的,但更常见的是项目中原本就存在的配置文件。
注意:Log4j2有配置文件加载优先级,log4j2.xml的优先级高于log4j.properties,如果build目录下同时存在两者,需要确认实际生效的是哪一个。
内容的提问来源于stack exchange,提问作者waffledood

