为什么 log4j 2 不记录应用程序和单元测试的方法名称
Why log4j 2 does not log method name for app and unit tests
我的 Log4j2 配置文件如下所示:
<Appenders>
<RollingRandomAccessFile name="APP_LOG_APPENDER" fileName="${sys:baseLogPath}/${appLogFileName}.log"
filePattern="${sys:baseLogPath}/backups/$${date:yyyy-MM}/${appLogFileName}-%d{yyyy-MM-dd}-%i.log.gz" immediateFlush="false">
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [Thread: %t] %level [%c][%M] - %msg%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="50 MB" />
</Policies>
<DefaultRolloverStrategy max="20"/>
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<Root level="debug" additivity="false">
<AppenderRef ref="APP_LOG_APPENDER" />
</Root>
</Loggers>
classMyClass
中的记录器语句
public class MyClass {
private final static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(MyClass.class);
public void someMethod() {
logger.debug("Some sample string at DEBUG level....");
logger.info("Some sample string at INFO level....");
logger.warn("Some sample string at WARN level....");
logger.error("Some sample string at ERROR level....");
}
}
日志消息显示为:
2016-04-11 12:32:31.245 [Thread: main] DEBUG [com.demo.MyClass][] - Some sample string at DEBUG level....
2016-04-11 12:32:31.245 [Thread: main] INFO [com.demo.MyClass][] - Some sample string at INFO level....
2016-04-11 12:32:31.245 [Thread: main] WARN [com.demo.MyClass][] - Some sample string at WARN level....
2016-04-11 12:32:31.245 [Thread: main] ERROR [com.demo.MyClass][] - Some sample string at ERROR level....
我使用的是log4j2-2.5版本和对应的SLF4JAPI.
谁能帮我理解为什么会这样?
您是否开启了异步记录器? (例如,通过系统 属性 -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
)
如果是,则属于未包含位置信息的情况之一。 (参考:https://logging.apache.org/log4j/2.x/manual/layouts.html#LocationInformation)。您可以通过
明确打开位置信息
<Root level="debug" includeLocation="true">
....
但是,我强烈建议不要在您的日志消息中包含方法名称,因为从堆栈跟踪中获取此类信息既昂贵又缓慢
对我来说,下一个配置运行良好(未启用 includeLocation="true"
选项):
src/main/resources/log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Properties>
<Property name="PID">%5X{pid}</Property>
<Property name="LOG_EXCEPTION_CONVERSION_WORD">%xEx</Property>
<Property name="LOG_LEVEL_PATTERN">%5p</Property>
<Property name="LOG_PATTERN">%style{%d{yyyy-MM-dd HH:mm:ss.SSS}}{dim} %highlight{${LOG_LEVEL_PATTERN}} %style{${sys:PID}}{magenta} %style{---}{dim} %style{[%15.15t]}{dim} %style{%-40.40c{1.}}{cyan} %style{%22.22M}{magenta} %style{:}{faint} %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD}</Property>
</Properties>
<Appenders>
<Console name="ConsoleAppender" target="SYSTEM_OUT" follow="true">
<PatternLayout pattern="${LOG_PATTERN}" />
</Console>
</Appenders>
<Loggers>
<logger name="com.github.daggerok" level="ALL" additivity="false">
<appender-ref ref="ConsoleAppender"/>
</logger>
<Root level="ALL">
<AppenderRef ref="ConsoleAppender"/>
</Root>
</Loggers>
</Configuration>
build.gradle
dependencies {
implementation(platform('org.apache.logging.log4j:log4j-bom:2.12.1'))
implementation 'org.apache.logging.log4j:log4j-api'
implementation 'org.apache.logging.log4j:log4j-core'
// ...
}
checkout this Travis CI build log output
> Task :test
com.github.daggerok.usermanagement.domain.user.UserEventSourcedRepositoryTest > should save user STANDARD_OUT
2019-08-17 18:23:53.358 DEBUG --- [ Test worker] u.d.u.UserInMemoryEventSourcedRepository save : about to save User(efb230a1-679e-4aac-b6c2-7eb25142de30) aggregate...
2019-08-17 18:23:53.375 DEBUG --- [ Test worker] u.d.u.UserInMemoryEventSourcedRepository save : cleared User(efb230a1-679e-4aac-b6c2-7eb25142de30) aggregate events.
2019-08-17 18:23:53.388 DEBUG --- [ Test worker] u.d.u.UserInMemoryEventSourcedRepository save : aggregate User(efb230a1-679e-4aac-b6c2-7eb25142de30) saved.
2019-08-17 18:23:53.392 DEBUG --- [ Test worker] u.d.u.UserInMemoryEventSourcedRepository find : start rebuild process for aggregate: efb230a1-679e-4aac-b6c2-7eb25142de30
下面的代码片段也用于获取 方法名称、时间戳、特定 class 中的行号以及 class 名称。
这是用于登录控制台的代码段
您基本上需要将它放在 log4j2.properties 文件中,该文件应该出现在 Maven 项目的 资源级别
rootLogger.level = debug
appenders = console
appender.console.type = Console
appender.console.name = STDOUT
appender.console.layout.type = PatternLayout
appender.console.layout.pattern =%d{yyyy-MM-dd HH:mm:ss} (%F:%L) %M()- %m%n
这是用于登录文件的代码段
rootLogger.level = debug
property.filename = {path to log file}
appenders = R
appender.R.type = RollingFile
appender.R.name = File
appender.R.fileName = ${filename}
appender.R.filePattern = ${filename}.%d{yyyy-MM-dd}
appender.R.layout.type = PatternLayout
appender.R.layout.pattern = %d{yyyy-MM-dd HH:mm:ss} (%F:%L) %M()- %m%n
appender.R.policies.type = Policies
appender.R.policies.time.type = TimeBasedTriggeringPolicy
appender.R.policies.time.interval = 1
rootLogger.appenderRef.console.ref = STDOUT
rootLogger.appenderRef.R.ref = File
这是示例输出
WaitForPageToLoad() 是存在记录器语句的方法
2021-12-24 05:51:47 (Utils.java:201) waitForPageToLoad() - Waiting for page to load
我的 Log4j2 配置文件如下所示:
<Appenders>
<RollingRandomAccessFile name="APP_LOG_APPENDER" fileName="${sys:baseLogPath}/${appLogFileName}.log"
filePattern="${sys:baseLogPath}/backups/$${date:yyyy-MM}/${appLogFileName}-%d{yyyy-MM-dd}-%i.log.gz" immediateFlush="false">
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [Thread: %t] %level [%c][%M] - %msg%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="50 MB" />
</Policies>
<DefaultRolloverStrategy max="20"/>
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<Root level="debug" additivity="false">
<AppenderRef ref="APP_LOG_APPENDER" />
</Root>
</Loggers>
classMyClass
public class MyClass {
private final static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(MyClass.class);
public void someMethod() {
logger.debug("Some sample string at DEBUG level....");
logger.info("Some sample string at INFO level....");
logger.warn("Some sample string at WARN level....");
logger.error("Some sample string at ERROR level....");
}
}
日志消息显示为:
2016-04-11 12:32:31.245 [Thread: main] DEBUG [com.demo.MyClass][] - Some sample string at DEBUG level....
2016-04-11 12:32:31.245 [Thread: main] INFO [com.demo.MyClass][] - Some sample string at INFO level....
2016-04-11 12:32:31.245 [Thread: main] WARN [com.demo.MyClass][] - Some sample string at WARN level....
2016-04-11 12:32:31.245 [Thread: main] ERROR [com.demo.MyClass][] - Some sample string at ERROR level....
我使用的是log4j2-2.5版本和对应的SLF4JAPI.
谁能帮我理解为什么会这样?
您是否开启了异步记录器? (例如,通过系统 属性 -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
)
如果是,则属于未包含位置信息的情况之一。 (参考:https://logging.apache.org/log4j/2.x/manual/layouts.html#LocationInformation)。您可以通过
明确打开位置信息<Root level="debug" includeLocation="true">
....
但是,我强烈建议不要在您的日志消息中包含方法名称,因为从堆栈跟踪中获取此类信息既昂贵又缓慢
对我来说,下一个配置运行良好(未启用 includeLocation="true"
选项):
src/main/resources/log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Properties>
<Property name="PID">%5X{pid}</Property>
<Property name="LOG_EXCEPTION_CONVERSION_WORD">%xEx</Property>
<Property name="LOG_LEVEL_PATTERN">%5p</Property>
<Property name="LOG_PATTERN">%style{%d{yyyy-MM-dd HH:mm:ss.SSS}}{dim} %highlight{${LOG_LEVEL_PATTERN}} %style{${sys:PID}}{magenta} %style{---}{dim} %style{[%15.15t]}{dim} %style{%-40.40c{1.}}{cyan} %style{%22.22M}{magenta} %style{:}{faint} %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD}</Property>
</Properties>
<Appenders>
<Console name="ConsoleAppender" target="SYSTEM_OUT" follow="true">
<PatternLayout pattern="${LOG_PATTERN}" />
</Console>
</Appenders>
<Loggers>
<logger name="com.github.daggerok" level="ALL" additivity="false">
<appender-ref ref="ConsoleAppender"/>
</logger>
<Root level="ALL">
<AppenderRef ref="ConsoleAppender"/>
</Root>
</Loggers>
</Configuration>
build.gradle
dependencies {
implementation(platform('org.apache.logging.log4j:log4j-bom:2.12.1'))
implementation 'org.apache.logging.log4j:log4j-api'
implementation 'org.apache.logging.log4j:log4j-core'
// ...
}
checkout this Travis CI build log output
> Task :test
com.github.daggerok.usermanagement.domain.user.UserEventSourcedRepositoryTest > should save user STANDARD_OUT
2019-08-17 18:23:53.358 DEBUG --- [ Test worker] u.d.u.UserInMemoryEventSourcedRepository save : about to save User(efb230a1-679e-4aac-b6c2-7eb25142de30) aggregate...
2019-08-17 18:23:53.375 DEBUG --- [ Test worker] u.d.u.UserInMemoryEventSourcedRepository save : cleared User(efb230a1-679e-4aac-b6c2-7eb25142de30) aggregate events.
2019-08-17 18:23:53.388 DEBUG --- [ Test worker] u.d.u.UserInMemoryEventSourcedRepository save : aggregate User(efb230a1-679e-4aac-b6c2-7eb25142de30) saved.
2019-08-17 18:23:53.392 DEBUG --- [ Test worker] u.d.u.UserInMemoryEventSourcedRepository find : start rebuild process for aggregate: efb230a1-679e-4aac-b6c2-7eb25142de30
下面的代码片段也用于获取 方法名称、时间戳、特定 class 中的行号以及 class 名称。
这是用于登录控制台的代码段 您基本上需要将它放在 log4j2.properties 文件中,该文件应该出现在 Maven 项目的 资源级别
rootLogger.level = debug
appenders = console
appender.console.type = Console
appender.console.name = STDOUT
appender.console.layout.type = PatternLayout
appender.console.layout.pattern =%d{yyyy-MM-dd HH:mm:ss} (%F:%L) %M()- %m%n
这是用于登录文件的代码段
rootLogger.level = debug
property.filename = {path to log file}
appenders = R
appender.R.type = RollingFile
appender.R.name = File
appender.R.fileName = ${filename}
appender.R.filePattern = ${filename}.%d{yyyy-MM-dd}
appender.R.layout.type = PatternLayout
appender.R.layout.pattern = %d{yyyy-MM-dd HH:mm:ss} (%F:%L) %M()- %m%n
appender.R.policies.type = Policies
appender.R.policies.time.type = TimeBasedTriggeringPolicy
appender.R.policies.time.interval = 1
rootLogger.appenderRef.console.ref = STDOUT
rootLogger.appenderRef.R.ref = File
这是示例输出
WaitForPageToLoad() 是存在记录器语句的方法
2021-12-24 05:51:47 (Utils.java:201) waitForPageToLoad() - Waiting for page to load