魔改log4j2的JsonLayout,支持自定义json格式日志

        小伙伴们,你们好,我是老寇,我又回来辣,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

如果为 true,每条日志记录后添加换行符,方便逐条处理(推荐开启)。

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!拜托啦~

我是老寇,我们下次再见

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/18234.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

机器学习—学习曲线

学习曲线是帮助理解学习算法如何工作的一种方法&#xff0c;作为它所拥有的经验的函数。 绘制一个符合二阶模型的学习曲线&#xff0c;多项式或二次函数&#xff0c;画出交叉验证错误Jcv&#xff0c;以及Jtrain训练错误&#xff0c;所以在这个曲线中&#xff0c;横轴将是Mtrai…

在MATLAB中实现自适应滤波算法

自适应滤波算法是一种根据信号特性自动调整滤波参数的数字信号处理方法&#xff0c;其可以有效处理噪声干扰和信号畸变问题。在许多实时数据处理系统中&#xff0c;自适应滤波算法得到了广泛应用。在MATLAB中&#xff0c;可以使用多种方法实现自适应滤波算法。本文将介绍自适应…

【系统编程】实验7 消息队列

设计程序 使用消息队列实现两个进程之间的信息互通 snd.c #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/msg.h> #include <unistd.h>/*消息发送者 */// 消息结构体如下&#xff1a; …

ETH钱包地址如何获取 如何购买比特币

首先我们要先注册一个交易所 Gate.io&#xff08;推荐&#xff09;: 点我注册 1、注册很简单&#xff0c;通过手机号就可以进行注册了。 2、获取ETH钱包地址 注册好之后&#xff0c;如图所示&#xff0c;点击“统一账户” 3、通过搜索栏搜索ETH&#xff0c;如下图所示 4、点…

[Docker#11] 容器编排 | .yml | up | 实验: 部署WordPress

目录 1. 什么是 Docker Compose 生活案例 2. 为什么要使用 Docker Compose Docker Compose 的安装 Docker Compose 的功能 使用步骤 核心功能 Docker Compose 使用场景 Docker Compose 文件&#xff08;docker-compose.yml&#xff09; 模仿示例 文件基本结构及常见…

OpenCV基础(1)

1.图像读写与窗口显示 1.1.imread读取图像文件 Mat cv::imread(const string &filename,int flags IMREAD_COLOR); filename&#xff1a;要读取的图像文件名flags&#xff1a;读取模式&#xff0c;可以从枚举cv::ImreadModes中取值&#xff0c;默认取值是IMREAD_COLOR&am…

【优选算法篇】分治乾坤,万物归一:在重组中窥见无声的秩序

文章目录 分治专题&#xff08;二&#xff09;&#xff1a;归并排序的核心思想与进阶应用前言、第二章&#xff1a;归并排序的应用与延展2.1 归并排序&#xff08;medium&#xff09;解法&#xff08;归并排序&#xff09;C 代码实现易错点提示时间复杂度和空间复杂度 2.2 数组…

生产环境centos8 Red Hat8部署ansible and 一键部署mysql两主两从ansible脚本预告

一、各节点服务器创建lvm逻辑卷组 1.初始化磁盘为物理卷&#xff08;PV&#xff09; 命令&#xff1a;sudo pvcreate /dev/vdb 2.创建卷组&#xff08;VG&#xff09; 命令&#xff1a;sudo vgcreate db_vg /dev/vdb 3.创建逻辑卷&#xff08;LV&#xff09; 命令&#xff1a;s…

CNN神经网络

CNN 一 基本概述二 基础知识三 经典案例 今天跟大家聊聊人工智能中的神经网络模型相关内容。神经网络内容庞大,篇幅有限本文主要讲述其中的CNN神经网络模型。 一 基本概述 深度学习(Deep Learning)特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网…

【Ubuntu24.04】VirtualBox安装ubuntu-live-server24.04

目录 0 背景1 下载镜像2 安装虚拟机3 安装UbuntuServer24.044 配置基本环境5 总结0 背景 有了远程连接工具之后,似乎作为服务器的Ubuntu24.04桌面版有点备受冷落了,桌面版的Ubuntu24.04的优势是图形化桌面,是作为一个日常工作的系统来用的,就像Windows,如果要作为服务器来…

【策略模式】最佳实践——Spring IoC实现策略模式全流程深度解析

简介 策略模式是一种行为型设计模式&#xff0c;它定义了一系列算法&#xff0c;并将每一个算法封装起来&#xff0c;使它们可以互相替换&#xff0c;并且使算法的变化不会影响使用算法的客户端。策略模式通过将具体的业务逻辑从上下文&#xff08;Context&#xff09;中剥离出…

企业项目级IDEA设置类注释、方法注释模板(仅增加@author和@date)

文章目录 前言一 设置类注释1.1 添加模板1.2 复制配置 二 设置方法注释2.1 添加模版2.2 设置模版2.3 设置参数变量2.4 配置对应快捷键2.5 配置对应作用域2.6 使用方式 说明 前言 公司代码规范中&#xff0c;需要在标准JavaDoc注释的基础上加上作者和日期。网上虽然有很多现成的…

单片机学习笔记 2. LED灯闪烁

目录 0、实现的功能 1、Keil工程 2、代码实现 0、实现的功能 LED灯闪烁 1、Keil工程 闪烁原理&#xff1a;需要进行软件延时达到人眼能分辨出来的效果。常用的延时方法有软件延时和定时器延时。此次先进行软件延时 具体操作步骤和之前的笔记一致。此次主要利用无符号整型的范…

编辑器vim 命令的学习

1.编辑器Vim 1.vim是一个专注的编辑器 2.是一个支持多模式的编辑器 1.1见一见&#xff1a; vim 的本质也是一条命令 退出来&#xff1a;-> Shift:q 先创建一个文件 再打开这个文件 进入后先按 I 然后就可以输入了 输入完后&#xff0c;保存退出 按Esc --> 来到最后一…

调用门提权

在我写的2.保护模式&#xff0b;段探测这篇文章中&#xff0c;我们提到了S位对于段描述符的控制&#xff0c;之前我们已经介绍了代码段和数据段&#xff0c;现在我们来把目光转到系统段 在这么多中结构里面&#xff0c;我们今天要介绍的就是编号为12的&#xff0c;32位调用门 结…

langchain模型及I/O的封装

langchain安装&#xff1a;pip install langchain-openai https://python.langchain.com/v0.2/docs/integrations/platforms/openai/ 注意&#xff1a;安装后&#xff0c;我们需要在环境变量中配置OPENAI_API_KEY&#xff0c;langchain会自动获取 1.模型的封装 指令生成式模…

阿里斑马智行 2025届秋招 NLP算法工程师

文章目录 个人情况一面/技术面 1h二面/技术面 1h三面/HR面 20min 个人情况 先说一下个人情况&#xff1a; 学校情况&#xff1a;211本中9硕&#xff0c;本硕学校都一般&#xff0c;本硕都是计算机科班&#xff0c;但研究方向并不是NLP&#xff0c;而是图表示学习论文情况&…

谈一谈QThread::CurrentThread和this->thread

QThread::CurrentThread是指的当前函数调用者者所在的线程 this->thread是指的当前对象所在的线程&#xff08;对象创建出来的时候所在的线程&#xff09; Qt文档说明 CurrentThread返回一个指向管理当前执行线程的QThread的指针 thread返回对象所在的线程 这两个函数所…

深度学习实验十一 卷积神经网络(2)——基于LeNet实现手写体数字识别实验

目录 一、数据 二、模型构建 三、模型训练及评价 四、打印参数量和计算量 五、模型预测 附&#xff1a;完整可运行代码 实验大致步骤&#xff1a; 一、数据 下载网站&#xff1a;MNIST数据集 之前的官网不能下载数据集了&#xff0c;403了&#xff0c;所以找到一个类似…

Python语法便捷查询

一、Python基础语法&#xff1a; (1)注释&#xff1a; (2)标识符&#xff1a; 简介&#xff1a;标识符的格式限制和C语言一样 (3)字符串定义方法&#xff1a; (4)字符串拼接&#xff1a; (5)字符串的格式化&#xff08;占位拼接&#xff09;&#xff1a; 和C语言的printf类…