小伙伴们,你们好,我是老寇,我又回来辣,1个多月不见甚是想念啊!!!跟我一起魔改源码吧
1.自定义json格式【PatternLayout】
大部分教程都是这个,因此,我就简单给个配置,没啥好说,然后,我们一起看看源码吧
配置
<PatternLayout><!--注意:真实的生产环境,日志打印的内容是五花八门,日志内容会出现一些莫名其他的特殊符号,导致json无法反序列化因此,可以利用Pattern Layout 提供的标签enc,enc支持4种转义,HTML/XML/JSON/CRLF,默认进行HTML转义目前,只对JSON处理,即%enc{%m}{JSON} => {"msg":"%enc{%m}{JSON}"}--><pattern>{"serviceId":"${SERVICE_ID}", "profile":"test", "dateTime":"%d{yyyy-MM-dd HH:mm:ss.SSS}", "traceId":"%X{traceId}", "spanId":"%X{spanId}", "address":"${sys:ip}:${sys:server.port}]", "level":"%-5level", "thread":"%thread", "logger":"%logger", "msg":"%enc{%m}{JSON}"}%n</pattern></PatternLayout>
{"serviceId":"laokou-sample-websocket","profile":"test","address":"127.0.0.1:9032","dateTime":"2024-11-17 06:37:56.501","packageName":"com.ulisesbocchio.jasyptspringboot.caching.RefreshScopeRefreshedEventListener","threadName":"main","level":"INFO","message":"Refreshing cached encryptable property sources on ServletWebServerInitializedEvent"}
源码
<PatternLayout/>是来源于 PatternLayout,用于格式化日志输出。因此,我们分析这个类即可
2.自定义json格式【JsonLayout】
这个需要魔改JsonLayout源码,因为JsonLayout无法继承,我只能全路径覆盖源码,我们修改一下源码吧
注解【@Plugin】
@Plugin
是 Log4j 提供的一个注解,用于注册和配置自定义的插件。Log4j 插件可以是各种类型,例如 Appender(输出目的地)、Layout(格式化日志的方式)等
参数名称 | 参数描述 | 参数值【举例】 |
name | 插件名称 | JsonLayout |
category | 插件类别,有以下几种常见插件类型,例如: Core => 核心插件 Layout => 日志布局 Node.CATEGORY => Log4j内部变量,通常用于解析配置 | Node.CATEGORY |
elementType | 定义插件的 XML 配置中对应的元素类型 | elementType = Layout.ELEMENT_TYPE【表示布局插件】 |
printObject | 是否将日志事件以格式化输出 | true |
魔改【全路径覆盖】
@Plugin(name = "JsonLayout", category = Node.CATEGORY, elementType = Layout.ELEMENT_TYPE, printObject = true)
public final class JsonLayout extends AbstractJacksonLayout {// 省略大部分代码// ...@Overridepublic void toSerializable(final LogEvent event, final Writer writer) throws IOException {if (complete && eventCount > 0) {writer.append(", ");}// 判断是否定义<KeyValuePair>if (additionalFields.length > 0) {objectWriter.writeValue(writer, getFieldsMap(event));writer.write(eol);if (includeNullDelimiter) {writer.write('\0');}markEvent();}else {super.toSerializable(event, writer);}}// @formatter:offprivate Map<String, String> getFieldsMap(LogEvent event) {LogEvent evt = convertMutableToLog4jEvent(event);Map<String, String> additionalFieldsMap = resolveAdditionalFields(evt);additionalFieldsMap.putAll(evt.getContextData().toMap());additionalFieldsMap.putAll(Map.of("address", System.getProperty("address", ""),"dateTime", FORMATTER.format(getLocalDateTimeOfTimestamp(evt.getTimeMillis())),"level", evt.getLevel().name(),"threadName", evt.getThreadName(),"packageName", evt.getLoggerName(),"message", evt.getMessage().getFormattedMessage(),"stacktrace", getStackTraceAsString(evt.getThrown())));return additionalFieldsMap;}// @formatter:onprivate String getStackTraceAsString(Throwable throwable) {if (ObjectUtils.isEmpty(throwable)) {return "";}StringWriter stringWriter = new StringWriter();try (PrintWriter printWriter = new PrintWriter(stringWriter)) {throwable.printStackTrace(printWriter);}return stringWriter.toString();}}
配置
<JsonLayout complete="false" compact="true" eventEol="true" properties="true" locationInfo="true" includeStacktrace="true" stacktraceAsString="false" objectMessageAsJsonObject="false"><KeyValuePair key="serviceId" value="${SERVICE_ID}"/><KeyValuePair key="profile" value="${PROFILE}" /></JsonLayout>
{"serviceId":"laokou-sample-websocket","profile":"test","threadName":"main","level":"INFO","message":"Skipping PropertySource servletConfigInitParams [class org.springframework.core.env.PropertySource$StubPropertySource","address":"198.18.0.1:9032","dateTime":"2024-11-17 09:37:28.183","packageName":"com.ulisesbocchio.jasyptspringboot.EncryptablePropertySourceConverter"}
标签【JsonLayout 】
参数名称 | 参数描述 | 默认值 |
complete | 是否输出完整的 JSON 对象,true作为单独的json文件,false逐行处理 | false |
compact | 是否紧凑输出json,true单行输出,节省空间,false多行输出方便阅读和调试 | true |
eventEol | 如果为 | false |
properties | 如果为 true ,输出上下文的键值对(MDC 和 NDC 数据) | false |
includeStacktrace | 如果为 false ,不包含堆栈跟踪信息(适用于异常日志) | true |
locationInfo | 如果为 true ,输出日志发生的位置(类名、方法名、行号等信息),可能会影响性能 | false |
charset | 设置输出文件的字符编码 | UTF-8 |
objectMessageAsJsonObject | 如果为 true ,对象消息将直接作为 JSON 对象输出,而不是作为字符串 | false |
stacktraceAsString | 是否将堆栈跟踪信息作为字符串处理 | false |
已上传GithubGitHub - KouShenhai/KCloud-Platform-IoT: KCloud-Platform-IoT(阻塞式)(老寇IoT云平台)是一个企业级微服务架构的IoT云平台。采用DDD(领域驱动设计)思想,基于Spring Boot 3.4.0、Spring Cloud 2024.0.0、Spring Cloud Alibaba 2023.0.1.3 最新版本开发的云服务多租户IoT平台,家人们,点个star!拜托啦~
我是老寇,我们下次再见