2017-10-09 76 views
2

我有这个日志相当严重的Web应用程序。我们已经为每个请求线程实施了对MDC的调用,以便能够在我们的日志中跟踪用户。记录可选键值

一个的LogMessage可以看看如下:

INFO [2017-10-09 10:10:55,841] user_uuid=123-123-123 com.myapp.SomeClass: Some log message... 

现在的问题是,大部分的时间,没有当前用户的存在,我们没有在上面的日志例子中user_uuid现场使用。因此,相反,它会是这样的:

INFO [2017-10-09 10:10:55,841] user_uuid= com.myapp.SomeClass: Some log message... 

有没有,如果没有MDC值不写在日志中的MDC键&值的方法吗?一些日志格式我还没有找到?

我希望它看起来像这样,如果没有MDC价值发现:

INFO [2017-10-09 10:10:55,841] com.myapp.SomeClass: Some log message... 

以上(MDC)的实例配置,像这样:

%-5p [%d{ISO8601,UTC}] user_uuid=%mdc{user_uuid:-} %c: %m%n%rEx 
+0

您可以只显示完整的MDC(这当然要求您只存储重要信息),那么它只会记录存在的内容。在你的例子中,你已经对'user_uuid ='部分进行了硬编码,所以这不会去任何地方。 – Kayaman

+0

请参阅https://stackoverflow.com/questions/24616745/how-to-conditionally-add-text-from-mdc-on-a-log4j-pattern以获得重复。 – Kayaman

回答

1

此项目在您的模式...

user_uuid=%mdc{user_uuid:-} 

...由两个部分组成:

  1. 静态“根”(即,分配的左侧),这总是出现在输出中。在Logback初始化时做出决定。

  2. 值(即赋值的右侧),如果填充了MDC属性user_uuid,则该值仅出现在输出中。包含这个的决定是在运行时为每个日志事件做出的。

也许不会告诉你任何新的东西出现,但关键的一点是,左侧的包容无法通过评估您的应用程序发出的每个日志事件时踢在任何条件逻辑被撤销。 Logback的PatternLayoutBase遍历它的给定模式,每次涉及到条件或可导出的内容时,它会对其进行评估并将评估值附加到正在穿过的模式。所以,为你的模式;在甚至开始评估MDC条件之前,Logback已经为当前的StringBuilder分配了“user_uuid =”。

但是,您可以通过与填充user_uuid MDC属性达到预期的最终目标:user_uuid=<the user id>,然后改变你的登录模式只需登录该MDC值不分配。例如:

%-5p [%d{ISO8601,UTC}] %mdc{user_uuid:-}%c: %m%n%rEx 

有了以下日志调用这个模式...

logger.info("Does this include the user_uuid?"); 
MDC.put("user_uuid", "user_uuid=me "); 
logger.info("Or does this include the user_uuid?"); 

...会发出:

INFO [2017-10-09 11:15:22,420] com.stackoverflow.SomeClassTest: Does this include the user_uuid? 
INFO [2017-10-09 11:15:22,435] user_uuid=me com.stackoverflow.SomeClassTest: Or does this include the user_uuid? 

虽然这是一个有点尴尬,因为你必须记住,包括在MDC值的后面加上一个空格和该user_uuid MDC值仅适用于该特定模式中记录有用的(而简单地包括user_uuid - 没有左侧和等号运算符 - 会更普遍有用)。

如果这些缺点使这个方法unuseable你那么我认为你必须卡住成的logback的PatternLayoutBaseFormattingConverter实现某种形式的先行或修改正在进行的StringBuilder如果右手的一些方法赋值的一端返回一个空字符串。

+0

非常全面的答案!非常感谢:) 我将创建一些util类来管理MDC'put'调用。 (这将用'key = '包装它们 –