日志脱敏之Log4j源码分析(一)_我的世界只有code的博客-程序员秘密

技术标签: layout  log4j源码  日志脱敏  appender  源码  log4j  

日志脱敏之log4j源码分析(一)

这篇博客提供了一种日志脱敏的实现方式-利用log4j进行脱敏,本文基于log4j 1.2版本。
日志脱敏的几种方式:

  • 业务简单,少量日志记录的情况下,可以去手动替换敏感信息
  • 大量日志记录的时候,每次调用logger.info都要去考虑脱敏太过麻烦,可以在pojo类里修改toString方法,将敏感数据脱敏
  • 大量日志,并且pojo类里有Map类型参数,没办法判断map的value是否是敏感数据。或者日志记录点太多,就需要一种方法,在底层进行脱敏,做到调用方无感知

实际工作中公司可能会使用自己的组件进行日志采集,所以在底层加入脱敏的支持是最好的选择。
这是一个最简单的log4j的demo

import org.apache.log4j.Logger;

public class Demo {
    
    private static Logger logger = Logger.getLogger(Demo.class);
    public static void main(String[] args) {
    
        logger.info("start");
        // ..do something
        logger.info("end");
    }
}

首先了解下log4j的结构,log4j的核心类
Logger:提供记录日志的各种api,是最核心的类。
Category:Logger类的爸爸,Logger类继承自父类Category的各种属性,用来做到封装细节,暴露简单api。
Category类中有两个关键类属性:

  • 1.LoggerRepository,维护了全部的logger的单例对象(为什么这么做?记录日志的动作是同步得,会影响服务性能,单例对象可以复用,提升服务器性能)他的默认实现是Hierarchy,这个类维护了一个HashTable对象,存放你无数个Controller或者Service里面的静态logger。(同时这个类也实现了log4j的一个关键特性,日志继承,有兴趣的可以看下官方文档,对今天大的分析用处不大,不在赘述)
  • 2.AppenderAttachableImpl 好长的名字,不过看意思应该是‘可连接的追加器’,什么意思呢?就是他属于一个管理类,用来管理你的各种Appender,比如ConsoleAppender,FileAppender等等,同时他可以在老的Appender列表后面追加、删除Appender,所以就有了这个名字,个人见解。其实叫AppenderManager,或者AppenderHolder不是更符合常规的命名习惯吗?个性化的命名不太适合开源项目。

OK,关键类了解之后,来看看logger4j的工作流程,下面是从网上找的调用logger.info的时序图,这个是最简单的版本,适合新手学习。先看一眼,不用完全明白,后面再讲。
在这里插入图片描述

  1. 我的工程的依赖
<dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.17</version>
</dependency>
  1. 调用logger.info(“hello”)
  2. 进入info方法,判断logger级别达到需要记录的级别后,就记录日志,找到forcedLog这行。
  3. 进入forcedLog方法,他创建了一个新的LoggingEvent对象,调用了callAppenders方法。(这里留心一下,每次都创建新的LoggingEvent对象,是性能不友好的,感兴趣的可以了解下,号称性能优越的Log4j是如何处理LoggingEvent这个类的。)
  4. 进入callAppenders方法,判断AppenderAttachableImpl 他维护的appenderList不为空后,进入appendLoopOnAppenders这一行
  5. 进入appendLoopOnAppenders方法。重头戏来了,遍历appenderList的每个appender,进行doAppender操作(这里用到了两种设计模式,有没有人知道?答案在下一篇博客揭晓日志脱敏之Log4j源码分析(二)
  6. Appender的默认实现AppenderSkeleton(appender骨架。。命名真是特别)doAppender方法实际调用了append方法,在此之前经过了一些Filter的判断,这里的判断就是其中一种设计模式的佐证。
  7. Appender的实现太多,我们随便选择一个,进入SyslogAppender实现,无视上面的层层判断,看下这行layout.format(event);这里使用Appender对应的layout对event进行了format,后面的操作是这个appender的业务实现,不用太关注。

OK,目前为止,我们已经知道了整个流程,不要忘了我们最初的目的,是要用logger4j的特性进行日志脱敏。

  • 首先我们能想到的是自定义Appender,然后在里面自己想怎么脱都行,但是有时候我们使用的是自带的Appender,或者公司自己的Appender组件(比如说flume Appender来做日志收集),重写或者继承这些Appender都会给你的代码带来bad smell。
  • 其次,在event处理时,会使用appender对应的layout进行处理。我们可以在layout.format方法里进行脱敏,自定义一个layout太简单不过。
    比如对手机号进行脱敏:
public class PhoneMaskLayout extends Layout {
    
    
    private static Pattern pattern = Pattern.compile("(1[0-9]{2})[0-9]{4}([0-9]{3})");
    private static String replace = "$1****$2";
    public String format(LoggingEvent event) {
    
        String msg = event.getMessage().toString();
        Matcher matcher = pattern.matcher(msg);
        if (matcher.find()) {
    
            msg = matcher.replaceAll(replace);
        }
        return msg;
    }
    //...
}

至此,看似好像可以了,但是在工作中仅仅实现功能是不可以的,性能,安全都要考虑到,上面说过了,appender的appende方法是同步操作,用正则去匹配手机号会造成严重的性能问题,在下一篇我会写下如何提升性能。

系列博客:

感兴趣的可以看下我的其他博客,包学包会,药到病除…

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_36451151/article/details/100605449

智能推荐

3GPP 协议导读_dolphin98629的博客-程序员秘密

24.008 Mobile radio interface Layer 3 specification; Core network protocols; Stage 3 Must Have 這是我最常用到的spec之一,對我而言也是最入門的一份。大多數spec是用來查的,但是這份從第四章開始是可以一頁 頁讀過的。它定義了Mobility Man...

Tensorflow的那些坑-lib\site-packages\tensorflow\contrib\rnn\python\ops_gru_ops.dll not found_管牛牛的博客-程序员秘密

今天在使用使用cpu版的tensorflow跑卷积神经网络的时候非常慢,整整一天一夜6000次迭代还没有跑完。于是我就想把cpu版本的tensorflow换成gpu版本的。首先CUDA和cudnn已经安装完成,CUDA安装的是8.0版本,cudnn安装的是5.1版本,这两个版本要对应上不然也会报错。安装完成后在命令行里可以输出CUDA的信息,说明安装成功。这里安装的时候最好查看一下自己的显卡支持的...

【VUE3】refs笔记_ref<number>_Yomuki的博客-程序员秘密

refref (文档)对我们的值创建了一个响应式引用。接受一个内部值并返回一个响应式且可变的 ref 对象。常用于定义 基本类型 的响应式数据import { ref } from 'vue'const myName = ref&lt;string&gt;('yomuki')console.log(myName)操作数据的值使用 RefImpl.value&lt;template&gt; &lt;h1&gt;Ref&lt;/h1&gt; &lt;h2&gt;{{ my

基础-Unity蒙版替换_unity 蒙版_我的名字叫就叫D的博客-程序员秘密

在网上逛面试题的时候看到这样一道题 给三张图片a,b,c 有三个按钮x,y,z,分别对应涂抹的颜料a,b,c 用鼠标在图片上进行涂抹,如果选择的是x,则在原来的图片上涂上a图片对应位置像素的颜色 看起来很简单,但是很多Unity基本的东西自己都忘了,导致中间遇到很多小坑参考作者:XMMATRIX 链接:https://www.zhihu.com/question/393755789/answer/1229796849自己把这位仁兄的实现方法自己跑了一遍,..

基于CUDA的三维VTI介质逆时偏移与ADCIGs提取_rtoax的博客-程序员秘密

“CUDA”、“C语言”、“nvcc”、“VTI介质”、“RTM”、“中间激发两边接收”、“全孔径接收”、“照明”、“拉普拉斯滤波”、“角度域共成像点道集”、“Poynting矢量”、“三维”;在此做个备份!直接上代码吧!//a#########################################################//a##

了解如何在Java中创建线程池以及如何重用线程_码出星海的博客-程序员秘密

了解线程池以及如何从头开始在Java中创建线程池。这篇文章包括简单线程池版本的介绍、实现和测试。创建和运行线程线程创建是一个众所周知的过程,有两种方法可以创建它:扩展线程并重写Run方法 将Runnable提供给线程构造函数让我们实现这两个选项: public static void main(String[] args) throws Exception { // Thread from runnable Thread thread = new Thread(

随便推点

fatal error C1189: #error : "This file was generated using the moc from 4.4.3. It_Rain-晴天的博客-程序员秘密

编译工程时,出现错误 "fatal error C1189: #error : "This file was generated using the moc from 4.4.3. It" ",一开始并不明白是怎么一回事,后来在高人指点下明白。原来,我建立的工程是用Qt4.5.0建立的, 而我后来却用Qt4.4.3的运行环境去编译它。解决办法:1.找到错误的根源在工

电机速度曲线规划1:梯形速度曲线设计与实现_梯形速度规划时间间隔_foxclever的博客-程序员秘密

  电机驱动是很常见的应用,在很多系统中我们都会碰到需要改变电机的速度以实现相应的控制功能,这就涉及到电机速度曲线规划的问题。在这篇中我们就来简单讨论一下电机的梯形曲线规划的问题。1、基本原理  梯形速度曲线控制算法是工业控制领域应用最为广泛的加减速控制策略之一。所谓梯形速度曲线将整个运动过程分为匀加速、匀速和匀减速三个阶段,在变速过程中加速度保持不变。  从变速过程中加速度保持不变这特点来说,其加减速过程其实是一个线性过程。我们可以采用一个线性函数来描述它。  这一线性函数,具体到我们的加减速

SpringBoot-yaml配置注入(三)_yml 多个consumer怎么注入_Code1667的博客-程序员秘密

SpringBoot-yaml配置注入(三)一、配置文件SpringBoot使用一个全局的配置文件 , 配置文件名称是固定的application.properties语法结构 :key=valueapplication.yml语法结构 :key:空格 value**配置文件的作用 :**修改SpringBoot自动配置的默认值,因为SpringBoot在底层都给我们自动配置好了;二、yaml概述YAML是 “YAML Ain’t a Markup Language”

MATLAB 加入相噪进行频谱分析_matlab 添加相位噪声_Gkbytes的博客-程序员秘密

用实时编辑器,先定义时域图,如下图图一。再得到采样频谱,如图2。最后将平谱图的零频分量移动到数组中心,重新排列得到图三。clc% 时域图f = 10T = 1fs = 100n = T*fst = linspace(0,T,n)y = 2*cos(2*pi*f*t)figure(1)plot(t,y)xlabel('时间/s')ylabel('幅度')% 得到的是采样频率的频谱% 可以看到10Hz处有峰值,90Hz的峰值是-10Hz的峰值向右频谱搬移fs=100Hz得到

MFC处理bmp图像—滤波_读取bmp图像并进行中值滤波_Bleach_Fei的博客-程序员秘密

滤波 无论是直接获取的灰度图像,还是由彩色图像转换得到的灰度图像,里面都有噪声的存在,噪声对图像质量有很大的影响。进行中值滤波不仅可以去除孤点噪声,而且可以保持图像的边缘特性,不会使图像产生显著的模糊,比较适合于实验中的人脸图像。引用一段文字描述一下滤波的特点,通过上一篇文章的学习,我们已经学会了怎样用MFC实现基本的图像处理算法,这次我们需要实现的是中值滤波,这个算法的原理和上一篇文章的O

推荐文章

热门文章

相关标签