我有下面的Log4J2配置XML:
<Routing name="myAppender">
<Routes pattern="$${ctx:workId}">
<Route>
<File fileName="${my-path}/sites/${ctx:workId}/${date:yyyy-MM-dd}/${ctx:employeeId}/emp.log" name="myAppender-${ctx:workId}">
<MarkerFilter marker="TELEMETRIC" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout>
<Pattern>[%date{ISO8601}][%-5level][%logger{1.}][%marker][$${ctx:employeeId}] %X%m%n</Pattern>
</PatternLayout>
</File>
</Route>
</Routes>
</Routing>
<Async name="Async">
<AppenderRef ref="myAppender" level="info"/>
</Async>
但是,每当log4j2 appender写入文件时,它在写入指定的文件路径时不会使用正确的${ctx:employeeId}
字符串。
log4j2 appender第一次写入文件时,会写入由${ctx:employeeId}
指定的正确文件路径。但是,只要将具有另一个Id的员工的信息放入线程上下文中,appender仍然会记录到旧文件路径。
例如,appender第一次记录时,它会写入正确的路径:
D:/example/logs/sites/1/2015-08-22/2/emp.log
但当记录器记录下一个员工Id(使用新的ThreadContext)时,它仍在登录
D:/example/logs/sites/1/2015-08-22/2/emp.log
例如:
D:/example/logs/sites/1/2015-08-22/3/emp.log
(请注意,员工Id不同。)
在日志输出模式中,我记录当前的雇员ID[$${ctx:雇员ID}]
,以及当前线程上下文%X
中的内容。输出显示正在使用正确的雇员ID,并且位于ThreadContext中,但是附加程序没有记录到该${ctx:雇员ID}
文件路径。
有人知道我是否遗漏了什么吗?或者如果我做错了什么?或者这可能是Log4j2的一个bug?谢谢你的帮助!
好吧,我意识到这个答案是在问题被问了很久之后才给出的,但如果这仍然对你或其他人有帮助,我将分享我的发现。
首先,我不能重现这个问题,但我有代码可以实现您想要的,所以我将分享我的代码,希望通过查看它,您可以确定哪里出了问题。如果没有,请提供一个最小的、完整的、可验证的示例,以便任何试图帮助您的人都可以重现该问题。
这是我的工作代码:
package pkg;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.MarkerManager;
import org.apache.logging.log4j.ThreadContext;
public class Log4j2DiffFilePerCtxVarMain {
private static final Marker TELEMETRIC = MarkerManager.getMarker("TELEMETRIC");
public static void main(String[] args){
Logger log = LogManager.getLogger();
ThreadContext.put("workId", "mainWorkId");
ThreadContext.put("employeeId", "mainEmployeeId");
log.info(TELEMETRIC, "Hey here's some info log from main!");
Thread t1 = new Thread(new Runnable(){
public void run(){
Logger log = LogManager.getLogger();
ThreadContext.put("workId", "thread1WorkId");
ThreadContext.put("employeeId", "thread1EmployeeId");
log.info(TELEMETRIC, "Hey here's some info log from thread1!");
}
});
t1.start();
}
}
以下是log4j2.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Routing name="myAppender">
<Routes pattern="$${ctx:workId}">
<Route>
<File
fileName="logs/${ctx:workId}/${date:yyyy-MM-dd}/${ctx:employeeId}/emp.log"
name="myAppender-${ctx:workId}">
<MarkerFilter marker="TELEMETRIC" onMatch="ACCEPT"
onMismatch="DENY" />
<PatternLayout>
<Pattern>[%date{ISO8601}][%-5level][%logger{1.}][%marker][$${ctx:employeeId}] %X %m%n</Pattern>
</PatternLayout>
</File>
</Route>
</Routes>
</Routing>
<Async name="Async">
<AppenderRef ref="myAppender" level="info" />
</Async>
</Appenders>
<Loggers>
<Root level="trace">
<appender-ref ref="Async" />
</Root>
</Loggers>
</Configuration>
当我用这个log4j2运行代码时。xml我看到了以下结果:
第一个日志包含以下内容:
[2017-04-13T20:42:49,814][INFO ][p.Log4j2DiffFilePerCtxVarMain][TELEMETRIC][mainEmployeeId] {employeeId=mainEmployeeId, workId=mainWorkId} Hey here's some info log from main!
第二个日志包含以下内容:
[2017-04-13T20:42:49,822][INFO ][p.Log4j2DiffFilePerCtxVarMain$1][TELEMETRIC][thread1EmployeeId] {employeeId=thread1EmployeeId, workId=thread1WorkId} Hey here's some info log from thread1!
希望这有帮助!
我在dropwizard yml文件中配置了日志记录以记录到文件而不是控制台,但是一些日志仍在记录到控制台。 service.yml 当我执行时,我在日志文件中获取服务日志,但我在控制台上而不是日志文件中获取请求日志 我正在使用滴滴巫师 0.7.1
问题内容: 我需要将对项目中的Oracle数据库的所有查询记录到日志文件中。 有什么 好的 解决方案来实现这一目标?一些示例用法将不胜感激。 我已经用jdbcdslog查看了SLF4J,但不确定如何使用它登录到文件。而且,我需要“过滤”一些日志(因为我不需要知道何时调用某种方法) 最好是,我更愿意使用,但这不是必需的。 谢谢。 更新 我找到了这篇Oracle文章,但是它并没有真正告诉您如何以编程方
问题内容: 我从golang开始,随着我开始建立自己的应用程序,我想从一开始就添加日志记录,这就是我遇到问题的地方。 如果我打开文件并使用标准日志记录库,则可以写入文件。像这样 我将获得带有日志行的test.log。但是,如果我尝试调整它以支持logrus https://github.com/Sirupsen/logrus这样 我只会看到错误。 写入日志失败,写入testlogrus.log:文
问题内容: 有没有一种方法可以将log4j日志事件写入到也由其他应用程序写入的日志文件中。其他应用程序可以是非Java应用程序。有什么缺点?锁定问题?格式化? 问题答案: Log4j有一个SocketAppender,它将事件发送到服务,您可以自己实现或使用与Log4j捆绑在一起的简单实现。 它还支持syslogd和Windows事件日志,这对于尝试将日志输出与非Java应用程序中的事件统一起来可
运行时,我收到以下消息: 我已经把位于下(但不在中,因为我不希望它随实际应用程序一起提供),如这里所建议的那样没有任何效果。 生成超文本标记语言报告,编写日志文件,构建成功,如上所述。我不确定错误是从哪里来的。
问题内容: 我有一个dropwizard应用程序,在该应用程序中,我配置了logger附加程序,使其文件如下: 并且,在我的应用中创建了记录器: 在main()中进行一些测试记录: 该应用程序启动并运行没有问题。但是我没有在stdout或mylogs.log文件中得到任何日志(当然,除了Jetty访问日志之外,这些日志也已正确打印到mylogs.log中)。相反,如果我删除configuratio