记录可选键值
Logging optional key values
我有这个 web 应用程序,它的日志记录非常多。我们已经为每个请求线程实现了对 MDC
的调用,以便能够在我们的日志中跟踪用户。
日志消息可能如下所示:
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 key & value写入日志?有些日志格式我还没找到?
我希望它看起来像这样,如果没有找到 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
您的模式中的这个条目...
user_uuid=%mdc{user_uuid:-}
...由两部分组成:
A static 'root'(即赋值的左侧)始终出现在输出中。在 Logback 初始化自身时决定包含它。
一个值(即赋值的右侧),只有填充了 MDC 属性 user_uuid
时才会出现在输出中。包含它的决定是在运行时为每个日志事件做出的。
可能不会告诉你任何新的东西,但关键是左侧的包含不能被在评估应用程序发出的每个日志事件时启动的任何条件逻辑撤消。 Logback 的 PatternLayoutBase
遍历它给定的模式,每次遇到有条件的或可推导的东西时,它都会对其进行评估,并将评估值附加到它正在遍历的模式中。所以,对于你的模式; Logback 甚至在开始评估 MDC 条件之前就已经将 "user_uuid=" 分配给当前的 StringBuilder。
但是,您 可以 通过使用以下内容填充 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.Whosebug.SomeClassTest: Does this include the user_uuid?
INFO [2017-10-09 11:15:22,435] user_uuid=me com.Whosebug.SomeClassTest: Or does this include the user_uuid?
尽管这有点尴尬,因为您必须记住在 MDC 值的末尾包含一个 space,并且此 user_uuid
MDC 值仅对在此特定模式中记录有用(而简单地包括 user_uuid
- 没有左侧和等号运算符 - 会更有用。
如果这些缺点使这种方法对您无法使用,那么我认为您将不得不陷入 Logback 的 PatternLayoutBase
或 FormattingConverter
以实现某种形式的前瞻或某种修改方式如果赋值的右侧 returns 为空字符串,则正在进行中的 StringBuilder。
如果缺少值,您可以使用 %replace
将 user_uuid=
替换为空字符串(注意正则表达式中尾随的 $
,意思是 "end of input"):
%-5p [%d{ISO8601,UTC}]%replace( user_uuid=%mdc{user_uuid}){' user_uuid=$', ''} %c: %m%n%rEx
作为奖励,如果缺少值,以上内容还将删除前导 space,因此如果缺少值,您不会在日志消息中看到两个连续的 space .
我有这个 web 应用程序,它的日志记录非常多。我们已经为每个请求线程实现了对 MDC
的调用,以便能够在我们的日志中跟踪用户。
日志消息可能如下所示:
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 key & value写入日志?有些日志格式我还没找到?
我希望它看起来像这样,如果没有找到 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
您的模式中的这个条目...
user_uuid=%mdc{user_uuid:-}
...由两部分组成:
A static 'root'(即赋值的左侧)始终出现在输出中。在 Logback 初始化自身时决定包含它。
一个值(即赋值的右侧),只有填充了 MDC 属性
user_uuid
时才会出现在输出中。包含它的决定是在运行时为每个日志事件做出的。
可能不会告诉你任何新的东西,但关键是左侧的包含不能被在评估应用程序发出的每个日志事件时启动的任何条件逻辑撤消。 Logback 的 PatternLayoutBase
遍历它给定的模式,每次遇到有条件的或可推导的东西时,它都会对其进行评估,并将评估值附加到它正在遍历的模式中。所以,对于你的模式; Logback 甚至在开始评估 MDC 条件之前就已经将 "user_uuid=" 分配给当前的 StringBuilder。
但是,您 可以 通过使用以下内容填充 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.Whosebug.SomeClassTest: Does this include the user_uuid?
INFO [2017-10-09 11:15:22,435] user_uuid=me com.Whosebug.SomeClassTest: Or does this include the user_uuid?
尽管这有点尴尬,因为您必须记住在 MDC 值的末尾包含一个 space,并且此 user_uuid
MDC 值仅对在此特定模式中记录有用(而简单地包括 user_uuid
- 没有左侧和等号运算符 - 会更有用。
如果这些缺点使这种方法对您无法使用,那么我认为您将不得不陷入 Logback 的 PatternLayoutBase
或 FormattingConverter
以实现某种形式的前瞻或某种修改方式如果赋值的右侧 returns 为空字符串,则正在进行中的 StringBuilder。
如果缺少值,您可以使用 %replace
将 user_uuid=
替换为空字符串(注意正则表达式中尾随的 $
,意思是 "end of input"):
%-5p [%d{ISO8601,UTC}]%replace( user_uuid=%mdc{user_uuid}){' user_uuid=$', ''} %c: %m%n%rEx
作为奖励,如果缺少值,以上内容还将删除前导 space,因此如果缺少值,您不会在日志消息中看到两个连续的 space .