当前位置: 首页 > 知识库问答 >
问题:

记录可选键值

谢阳曜
2023-03-14

我有一个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值:

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

共有2个答案

微生嘉
2023-03-14

如果缺少值,您可以使用%替换user_uuid=替换为空字符串(请注意正则表达式中尾随的$,意思是“输入结束”):

%-5p [%d{ISO8601,UTC}]%replace( user_uuid=%mdc{user_uuid}){' user_uuid=$', ''} %c: %m%n%rEx

作为奖励,如果缺少值,上面的命令也会删除前导空格,因此如果缺少值,日志消息中不会连续出现两个空格。

乐正烨熠
2023-03-14

你模式中的这个条目...

user_uuid=%mdc{user_uuid:-}

... 由两部分组成:

>

  • 一个静态的root(即赋值的左侧),它总是存在于输出中。当Logback初始化自己时,会做出包含此内容的决定。

    一个值(即赋值的右侧),只有在填充了MDC属性user_uuid时,该值才会出现在输出中。对于每个日志事件,都会在运行时决定是否包含它。

    可能不会告诉您任何新的东西,但关键点是,左侧的包含不能被任何条件逻辑撤消,这些条件逻辑在评估应用程序发出的每个日志事件时起作用。Logback的PattranLayoutBase遍历其给定的模式,每次遇到有条件的或可导出的东西时,它都会计算它,并将计算值附加到正在遍历的模式中。因此,对于您的模式;Logback已经为当前StringBuilder分配了user_uuid=,甚至在它开始评估MDC条件之前。

    但是,通过将user_uuidMDC属性填充为:user_uuid,可以实现所需的最终目标=

    %-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_uuidMDC值只对在这个特定模式中登录有用(而简单地包含user_uuid——没有左手边和equals操作符——通常会更有用)。

    如果这些缺点使这种方法对您不可用,那么我认为您将不得不陷入Logback的Pattern LayoutBaseFormatingConzer中,以实现某种形式的前瞻性或某种方式来修改正在进行的StringBuilder,如果右手边返回一个空的String。

  •  类似资料:
    • 这使得日志难以读取、冗长和不必要的复杂(在大多数情况下,其他参数都不存在)。 我想处理所有的案件,只保留必要的数据。例子: 我可以手工编码: 它应该支持可选参数,用给定的字符串替换boolean/condition,支持用和分隔空格、逗号和单词。 也许有这样的图书馆吗?或者也许至少有一种更简单的编码方式? 如果不是这样,我就没有其他办法为日志记录中的消息编写自己的库了。此外,这种库将提供所有日志的

    • 请使用以下的方法筛选网格中的数据: 右击一个单元格并在弹出式菜单选择“筛选”->“字段 xxx 值”来用当前单元格的值筛选记录。 “自定义筛选” 对话框能快速创建一个简单的筛选。只需简单地右击网格并在弹出式菜单选择“筛选”->“自定义筛选”。你可以使用字符“_”来代表在条件中任何单一符号,和使用字符“%”来代表在条件中任何一组符号。 你还可以使用更复杂的方式自定义你的筛选,右击字段并在弹出式菜单选

    • 请使用以下的方法筛选网格中的数据: 点击单元格进入编辑模式。按住 Control 键并点按单元格,然后在弹出式菜单选择“筛选”->“字段 xxx 值”来用当前单元格的值筛选记录。 你还可以使用更复杂的方式自定义你的筛选,在工具栏点击 。筛选向导会出现在网格的上方,你可以看到现有的筛选条件,简易地点击左侧的复选框来启用或禁用它。

    • 请使用以下的方法筛选网格中的数据: 右击一个单元格并在弹出式菜单选择“筛选”->“字段 xxx 值”来用当前单元格的值筛选记录。 “自定义筛选” 对话框能快速创建一个简单的筛选。只需简单地右击网格并在弹出式菜单选择“筛选”->“自定义筛选”。你可以使用字符“_”来代表在条件中任何单一符号,和使用字符“%”来代表在条件中任何一组符号。 你还可以使用更复杂的方式自定义你的筛选,右击字段并在弹出式菜单选

    • 大家好,我需要为下面的示例创建AVRO模式; 当我按照建议更改所有者对象时,avro-tool返回错误。 ]} 测试:

    • 本章提供了有关如何使用JDBC应用程序从表中选择/获取记录的示例。 在执行以下示例之前,请确保您具备以下示例 - 要执行以下示例,您可以使用实际用户名和密码替换用户名和密码。 您的MySQL或您使用的任何数据库已启动并正在运行。 所需的步骤 (Required Steps) 使用JDBC应用程序创建新数据库需要以下步骤 - Import the packages:要求包含包含数据库编程所需的JDB