在日志中显示线程 ID 而不是线程名称

新手上路,请多包涵

我有一个带有 log4j 的 Struts 应用程序来显示有关应用程序的信息。

格式化日志输出的模式如下:

 log4j.appender.RALL.layout.ConversionPattern=[%p] %d{dd/MM/yyyy HH:mm:ss} [THREAD ID=%t] [CLASS=(%C{1}:%L)] %m%n

我需要在日志中显示 线程 ID 而不是 线程名称。显示线程名称的转换字符是%t。我没有在 log4j 文档中看到获取它的方法。

谁能帮我??

原文由 Alejandro Cuervo 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.2k
2 个回答

这是可能的,但并不像使用一些预配置的模式那么容易。

Log4j 1.X 和 Log4j 2.x 没有任何用于打印线程 ID 的预配置模式,但您始终可以使用一些“魔术”。

PatternLayout is using PatternParser class which is mark as final class and has static map of “patterns” as keys and Converters classes as values .每次当 Parses 发现用于记录模式格式的模式以 % 开头时,它都会使用与映射中此模式键匹配的转换器。

您不能将自己的规则添加到该地图,但您仍然可以编写自己的 MyOwnPatternLayout:

 public class MyOwnPatternLayout extends PatternLayout

这将在它的 format 方法中做这样的技巧:

 public String format(LoggingEvent event) {
   String log = super.format(event);
   /*
   Now you just have to replace with regex all occurences of %i or
   any mark you would like to use as mark to represent Thread ID
   with Thread ID value.
   Only thing you have to be sure to not use any mark as your Thread ID
   that already is defined by PatterParser class
   */
   return log.replaceAll("%i", someThreadID);
}

唯一的问题是您必须以某种方式获得该线程 ID。有时您所要做的就是解析您可以轻松收集的线程名称:

 String threadName = event.getThreadName();

例如 Apache-Tomcat 将线程 ID 放在线程名称 http-nio-/127.0.0.1-8084”-exec-41 的末尾。

为确保线程 ID 正确,您还可以创建自己的 LogginEvent 和 Logger(MyLoggingEvent 和 MyLogger)子类,并在 MyLogger 中创建 MyLoggingEvent 女巫也将线程 ID 作为参数,而不仅仅是线程名称。然后你可以很容易地在上面的代码中收集它。

原文由 Michał Kupisiński 发布,翻译遵循 CC BY-SA 4.0 许可协议

一种方法是使用 log4j MDC 自己添加它。我们用它来添加网络请求的用户名。我们在每个请求开始时在过滤器中执行此操作。例如。

 import org.apache.log4j.MDC;

...

  // Add username to MDC
  String username = ...;
  MDC.put("user", username);

然后将 [%X{user}] 添加到您的转换模式。

原文由 TedTrippin 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题