logging - 使用 JSON 格式的 log4j 记录 json 字符串消息,而不用引号破坏格式

标签 logging serialization properties log4j special-characters

我正在尝试将日志格式化为 json 格式并使用模式布局来执行此操作。但是生成的输出不是正确的 json 格式,因为正在记录 msg 中的额外引号。

下面是log4j.properties文件 =======================log4j.properties==================

appender.file.layout.pattern={"level":"%p","time":"%d{ISO8601}","thread":"%t","file":"%F", "line":"%L","message":"%m"}%n
loggers=file
logger.file.name=com.ibm
logger.file.level = error
logger.file.level = debug
logger.file.appenderRefs = file
logger.file.appenderRef.file.ref = LOGFILE
rootLogger.level = error
rootLogger.level = debug
rootLogger.appenderRefs = stdout
rootLogger.appenderRef.stdout.ref = STDOUT

下面是编码格式

String msg = "!@#$%^&*()_+=~{}[]|<>?;'Text with special character /\"\'\b\f\t\r\n";
// to escape especial character, serializing msg with jackson library method
Serialize serializeMsg = objectMapper.writeValueAsString(msg);
String jsonString = "" + serializeMsg + "\", \"crn\":\"" + crn + "\", \"otherProperty\":\"" + crn + "\"";
log.debug(serializeMsg );

生成Json日志

{"level":"DEBUG","time":"2021-12-20T20:05:14,465","thread":"main","file":"App.java", "line":"81","message":""!@#$%^&*()_+=~{}[]|<>?;'Text with special character /\"'\b\f\t\r\n"", "crn":"5741af48-808a-4e55-8f37-681f025b1ce3", "otherProperty":"5741af48-808a-4e55-8f37-681f025b1ce3""}

如何从邮件中删除多余的引号?谢谢!!

最佳答案

直接回答您的问题:objectMapper.writeValueAsString(msg) 输出一个有效的 JSON,因此它是一个用双引号引起来的字符串。您在代码中构造的消息是:

"!@#$%^&*()_+=~{}[]|<>?;'Text with special character /\"'\b\f\t\r\n"", "crn":"5741af48-808a-4e55-8f37-681f025b1ce3", "otherProperty":"5741af48-808a-4e55-8f37-681f025b1ce3"

并且您的 PatternLayout 将其括在另一对双引号 ("%m") 中。您可以轻松地从代码中删除一些双引号,使其成为有效的 JSON 消息。

但是,您为解决主要问题(将日志消息格式化为 JSON)而采用的整个方法是不稳定的(这是一个大 hack):您需要应用程序中的所有日志消息都具有类似 JSON 的格式。如果您忘记正确格式化消息会怎样?如果图书馆消息肯定不符合您的格式怎么办?如果您的应用程序的用户想要更改日志记录布局会怎样?您的方法也可能容易受到 log injection attacks 的攻击如果您不注意记录的内容。

标准方法是让 Log4j 将您的消息格式化为 JSON。有一个JSON Template Layout为了那个原因。您只需要:

  1. 添加 log4j-layout-template-json对你的依赖,

  2. 在您的应用程序类路径中创建一个模板(我们称之为 logTemplate.json):

    {
        "level": {
            "$resolver": "level",
            "field": "name"
        },
        "time": {
            "$resolver": "timestamp"
        },
        "thread": {
            "$resolver": "thread",
            "field": "name"
        },
        "file": {
            "$resolver": "source",
            "field": "fileName"
        },
        "line": {
            "$resolver": "source",
            "field": "lineNumber"
        },
        "message": {
            "$resolver": "message",
            "stringified": true
        }
    }
    
  3. 更新您的 log4j2.properties 文件以使用 JSON 模板布局:

    appender.file.layout.type=JsonTemplateLayout
    appender.file.layout.eventTemplateUri=classpath:logTemplate.json
    appender.file.layout.locationInfoEnabled=true
    
  4. 通过简单地调用记录消息:

    log.debug("!@#$%^&*()_+=~{}[]|<>?;'Text with special character /\"\'\b\f\t\r\n");
    

关于logging - 使用 JSON 格式的 log4j 记录 json 字符串消息,而不用引号破坏格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70457806/

相关文章:

sql-server - 记录Sql服务器存储过程的开始和结束时间

python - 我将如何着手构建 API 转换器?

java - @JsonFormat DEFAULT_TIMEZONE 似乎不起作用

java - 动态更改从 Java JNI 连接池获取的连接的连接属性

Javascript - 为元素分配新 ID

python - 设置属性不起作用 - 愚蠢的语法错误?

logging - Golang : Does logging into file using log. Println 负责并发访问

linux - 自上次查看以来如何查看系统日志条目

tomcat - 无法使用 %S 配置 tomcat 访问日志 session ID

c++ - 在文件中存储和同步字符串列表