log json string message using log4j in JSON format without breaking the format with quotes

log json string message using log4j in JSON format without breaking the format with quotes

我正在尝试将日志格式化为 json 格式并使用模式布局来实现。但是生成的输出不是正确的 json 格式,因为正在记录消息中的额外引号。

下面是 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");