Advance together, get high salary together! Analysis of log desensitization principle of advanced Java development log4j2

I'm Tim 2021-01-24 13:12:33
advance high salary analysis log


Hello everyone , I am a tin, This is my number 5 Original articles

This paper describes the principle of log desensitization in the case of minimal invasion of business system code . The article is very long. , Including log desensitization from 、 coded 、log4j2.xml File loading principle 、log4j2 And so on , Finally, the annotation compiler processor AbstractProcessor, Realize dynamic code generation in compile time ! It's kind of like finding a treasure , After all, I haven't paid attention to annotation compiler processors before , Let's go to the previous directory first :

  • One 、 Why do log desensitization
  • Two 、log4j2 Log desensitization coding implementation
  • 3、 ... and 、 Source code exploration log4j2 Log desensitization implementation principle
    1、 What is? slf4j?
    2、log4j2 What is it again? ?
    3、slf4j and log4j2 How the binding is done ?
    4、log4j.xml How the configuration file is loaded ?
    5、 We define log4j2 Of Plugin How does the plug-in load and register ?
    6、AbstractProcessor Annotation processor
  • Four 、 Friends, please stay

One 、 Why do log desensitization

Log printing is very common and important , There is no doubt about it , But there is a situation : The logs we print contain the user's privacy information , For example, do login payment print user account and password , Do financial printing user's card number, etc , Let's not say that improper management of these logs on the disk may cause user privacy leakage , And then there's the compliance check , It doesn't pass , We have to deal with it .

How do we make a journal ? Let's start with a picture ( Print my user name and account number in the log ), Look at ourselves. That's how we use it :

No special treatment , No accident , The log output is like this :

The card number is printed out , Then this line of logs lay peacefully on our server disk .

Two 、log4j2 Log desensitization coding implementation

How to use the log framework to realize the desensitization of account coding , Without intruding into the business code ? I don't say much nonsense , Let's see what I've achieved :

This article is based on slf4j+log4j2 Realization , We don't have any changes in the output of the code log , Print out the log of the card number to do a code desensitization .

In this paper, the implementation of log code desensitization program involves the development of two places :

One is to realize log4j2 Of RewritePolicy Interface , rewrite logEvent;

Second, revise log4j2.xml file .

Look at what I wrote RewritePolicy Implementation class :

log4j2.xml modify , Here is log4j2 Configuration and rewrite To configure :

This document also details log4j2.xml The configuration is explained again , Not very clear log4j The configuration can be saved .

To make it easy to copy , hold log4j2.xml Paste a copy of the configured source code :

<?xml version="1.0" encoding="UTF-8"?>
<configuration monitorInterval="5">
<!-- Variable configuration -->
<Properties>
<!-- Format output :%date Indicates the date ,HH:mm:ss.SSS Represents the date format ,%thread Represents the thread name ,%-5level Indicates that the level is displayed from the left 5 Character width ,
%C{1.} Represents the class fully qualified name output precision ,%-4L The line number of the output log ,%msg Represents the log message ,%n Is a newline -->
<property name="LOG_PATTERN" value="%date{HH:mm:ss.SSS} [%thread] %-5level %C{1.} %-4L : %msg%n"/>
<!-- Define the path of log storage .${web:rootDir} Represents the current project directory , -->
<property name="FILE_PATH" value="../log/tin-example"/>
<property name="FILE_NAME" value="tin-example"/>
</Properties>
<appenders>
<!-- Console output -->
<console name="Console" target="SYSTEM_OUT">
<!-- Format of output log -->
<PatternLayout pattern="${LOG_PATTERN}"/>
<!-- Indicative output level=debug Level and above (onMatch),debug No output below level (onMismatch)-->
<ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY"/>
</console>
<Rewrite name="rewrite">
<DataMaskingRewritePolicy/>
<AppenderRef ref="Console"/>
</Rewrite>
<!-- Print out all levels of log information , And auto scroll archive -->
<RollingFile name="AllLevelRollingFile" fileName="${FILE_PATH}/${FILE_NAME}.log"
filePattern="${FILE_PATH}/${FILE_NAME}-ALL-%d{yyyy-MM-dd}_%i.log.gz">
<ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="ACCEPT"/>
<PatternLayout pattern="${LOG_PATTERN}"/>
<Policies>
<!--interval Property is used to specify how often to scroll ,interval=1 Express 1 Every hour -->
<TimeBasedTriggeringPolicy interval="1"/>
<!--size=20 Indicates that the file is larger than 20M Scroll once -->
<SizeBasedTriggeringPolicy size="20MB"/>
</Policies>
<!-- max=15 It means the most in the same folder 10 File , More will cover ,DefaultRolloverStrategy If you don't set , The default is 7 individual -->
<DefaultRolloverStrategy max="10"/>
</RollingFile>
<!-- Print out all error And above , And auto scroll archive -->
<RollingFile name="ErrorRollingFile" fileName="${FILE_PATH}/error.log"
filePattern="${FILE_PATH}/${FILE_NAME}-ERROR-%d{yyyy-MM-dd}_%i.log.gz">
<!-- Output level And above (onMatch),level The following is a direct refusal (onMismatch)-->
<ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="${LOG_PATTERN}"/>
<Policies>
<!--interval Property is used to specify how often to scroll ,interval=1 Express 1 Every hour -->
<TimeBasedTriggeringPolicy interval="1"/>
<!--size=20 Indicates that the file is larger than 20M Scroll once -->
<SizeBasedTriggeringPolicy size="20MB"/>
</Policies>
<!-- max=15 It means the most in the same folder 10 File , More will cover ,DefaultRolloverStrategy If you don't set , The default is 7 individual -->
<DefaultRolloverStrategy max="10"/>
</RollingFile>
</appenders>
<!--Logger The node is used to specify the form of the log separately , Different log printing strategies can be configured for different packages .-->
<loggers>
<logger name="com.tin.example.spring.log4j2" level="info" additivity="false">
<AppenderRef ref="rewrite"/>
</logger>
<root level="debug">
<appender-ref ref="Console"/>
<appender-ref ref="AllLevelRollingFile"/>
<appender-ref ref="ErrorRollingFile"/>
</root>
</loggers>
</configuration>

3、 ... and 、 Source code exploration log4j2 Log desensitization principle

Why the above can achieve log code desensitization ? Is there any reform ? What is the principle of implementation ? With a string of questions , Now let's start with slf4j and log4j2 The principle says , coming , The stool has been moved .

1、 What is? slf4j?

slf4j Full name simple logging facade for Java. It's a logging interface framework , Cooperate with log output system to realize log output .slf4j It's not really a system that outputs logs , It just defines a set of log specifications . There are also such log appearances as commons-logging.

private static final Logger LOGGER = LoggerFactory.getLogger(AccountTest.class);

The above Logger Namely slf4j Class .

2、log4j2 What is it again? ?

log4j2 It's a real logging system , It is the implementation of the code base for printing logs in our project . except log4j2, Our common log base is also log4j、logback、jdk-logging.

slf4j As the connection log And the middle layer of the code layer , We just use slf4j Provided interface , Don't worry about the specific implementation of the log ( The advantage is that we can use the log Library in the business system, such as log4j2 Replace with logback Also no problem ). It's kind of like jdbc, We switch different databases ,jdbc Help us do a good job .

log4j2 The dependency package of 3 individual ,slf4j and log4j2 Several jar Package relationships work as follows :

3、slf4j and log4j2 How the binding is done ?

As you can see from the picture above ,slf4j-api and log4j The related packages are not together , So what is the connection between them ?

The answer is :

slf4j Specify the path for class loading ,log4j There must be a bridge implementation class . Or define and initialize from this line Logger The code starts to look :

private static final Logger LOGGER = LoggerFactory.getLogger(AccountTest.class);

from LoggerFactory.getLogger All the way to LoggerFactory Class bind Method , find staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet(), Here is slf4j Complete the binding log4j2 The place of :

findPossibleStaticLoggerBinderPathSet() Load a... By specifying the path StaticLoggerBinder class :

Specify find org/slf4j/impl/StaticLoggerBinder.class Loading .

that StaticLoggerBinder Where it should be ?

Of course is in log4j2 It's in the bag !

adopt StaticLoggerBinder This class completes slf4j and log4j The binding of , Look at the picture below .

After binding, it passes getLoggerFactory Method to get Log4jLoggerFactory:

log4j2 and slf4j Finished binding , that , What does it have to do with the desensitization principle mentioned in this paper ?

The realization principle of desensitization really lies in log4j2, The above is just to explain the basic association principle of the log system , For the next story log4j To pave the way for our plug-in mechanism .

log4j2 Load various components by using plug-in mechanism , such as appender, logger etc. , Our desensitization scheme code defines a class :

Realized log4j Of rewrite Policy class , This is actually a plug-in !

Make it clear Plugin The principle is divided into two parts .

One is log4j.xml How the configuration file is loaded ;

Second, we define Plugin How does the plug-in load and register .

4、log4j.xml How the configuration file is loaded ?

We still look at the source code through breakpoints , After all , There are no lies under the source code ! Let's start with the following line of code :

As mentioned above Log4jLoggerFactory, It inherited AbstractLoggerAdapter This abstract class , We go straight to getContext Method to get Logger The place of :

anchor Chinese translated into " anchor ", This is through Java The reflection gets the log class ,anchor Not for null, So go to the following statement .

Get into getContext, our Log4jContextFactory again , It's in LogManager Is initialized in the static block of code in .

Let's go on to Log4jContextFactory Look inside getContext:

Initialized selector, How to obtain internal information context If you are interested, you can do it yourself debug, We enter ctx.start In the way :

notice reconfigure() Method , You know log4j Ready to start loading configuration !!! Again from reconfigure Keep looking down :

687 Line gets a XmlConfiguration, This is because we use xml The configuration file !!! Normally, the configuration file is in addition to xml, also properties,yaml,json etc. .

Now that you have the contents of the configuration file , So let's go back and see ConfigurationFactory.getInstance().getConfiguration(this,contextName,configURI,cl).

have a look XmlConfigurationFactory class

It specifies xml suffix ,getConfiguration Actual return XmlConfiguration

according to configSource Of log4jx.xml file , Load the configuration content .

Come here xml The configuration is loaded .xml Internally defined <DataMaskingRewritePolicy/> Tags will also be loaded .

Next , Naturally, we ask , This label and code @Plugin How the plug-ins defined by annotations are related ? Or say Plugin How the plug-in is loaded ?

5、 We define Plugin How does the plug-in load and register ?

log4j Medium Plugin Annotations provide a convenient way to declare a class as log4j2 Plug in for , For example, the case I used in the single test :

stay log4j2 When you load the context, it loads Plugin,log4j Unified use PluginRegistry Registry loads and registers plug-ins , And by the PluginManager To manage .

Enter into PluginManager:

The notes are very clear , From the specified file Log4j2Plugin.dat Add plug-ins , Continue to enter loadFromMainClassLoader Method

Different modules are different jar It's possible that all the bags exist Log4j2Plugins.dat file , such as log4j-core The package exists

The plug-ins that we write our own code definitions are compiled into target Under the table of contents ( Because mine is mac, You can see it on the console ,win The system can also find the result of compilation target Folder is ok )

We compiled and generated Log4j2Plugins.dat What's in it ?

The file records the plug-in categories 、 Fully qualified class name and other information .

Speaking of this , A new question arises , Our own Log4j2Plugins.dat How is the file generated to target In the catalog ?

6、AbstractProcessor Annotation processor

We have to say that our annotation compiler processor ! There are two types of annotations , One is runtime annotations , The other is compile time annotations . The core of compile time annotations depends on APT(Annotation Processing Tools) Realization , The basic principle is in class 、 Method 、 Add notes to fields, etc , At compile time , The compiler scans AbstractProcessor Subclasses of , Pass the appropriate annotation into process function , Then we developers can do the corresponding logic processing at compile time . have a look log4j Implementation of annotation compiler processor :

We seldom use annotation compiler processor in our coding , If you are interested, you can write your own unit test , This kind of code that has never been played is quite interesting to write . But if you write it yourself, you need to make a statement javax.annotation.processing.Processor file , One more log4j The document of the declaration :

Four 、 Friends, please stay

I am a tin, An ordinary siege lion trying to make himself better . Limited experience 、 A little knowledge , If you find something wrong with the article , I am very welcome to put forward , I'll be careful to revise it .

See here, please arrange an encouragement before you leave , It's not easy to be original , Your positive feedback is the most powerful driving force for me to insist on output , Thank you very much! .

summary 、 promote
Be a happy siege lion
Build your own world
版权声明
本文为[I'm Tim]所创,转载请带上原文链接,感谢
https://javamana.com/2021/01/20210124131117087z.html

  1. 【计算机网络 12(1),尚学堂马士兵Java视频教程
  2. 【程序猿历程,史上最全的Java面试题集锦在这里
  3. 【程序猿历程(1),Javaweb视频教程百度云
  4. Notes on MySQL 45 lectures (1-7)
  5. [computer network 12 (1), Shang Xuetang Ma soldier java video tutorial
  6. The most complete collection of Java interview questions in history is here
  7. [process of program ape (1), JavaWeb video tutorial, baidu cloud
  8. Notes on MySQL 45 lectures (1-7)
  9. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  10. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  11. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  12. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  13. 【递归,Java传智播客笔记
  14. [recursion, Java intelligence podcast notes
  15. [adhere to painting for 386 days] the beginning of spring of 24 solar terms
  16. K8S系列第八篇(Service、EndPoints以及高可用kubeadm部署)
  17. K8s Series Part 8 (service, endpoints and high availability kubeadm deployment)
  18. 【重识 HTML (3),350道Java面试真题分享
  19. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  20. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  21. [re recognize HTML (3) and share 350 real Java interview questions
  22. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  23. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  24. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  25. RPC 1: how to develop RPC framework from scratch
  26. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  27. RPC 1: how to develop RPC framework from scratch
  28. 一次性捋清楚吧,对乱糟糟的,Spring事务扩展机制
  29. 一文彻底弄懂如何选择抽象类还是接口,连续四年百度Java岗必问面试题
  30. Redis常用命令
  31. 一双拖鞋引发的血案,狂神说Java系列笔记
  32. 一、mysql基础安装
  33. 一位程序员的独白:尽管我一生坎坷,Java框架面试基础
  34. Clear it all at once. For the messy, spring transaction extension mechanism
  35. A thorough understanding of how to choose abstract classes or interfaces, baidu Java post must ask interview questions for four consecutive years
  36. Redis common commands
  37. A pair of slippers triggered the murder, crazy God said java series notes
  38. 1、 MySQL basic installation
  39. Monologue of a programmer: despite my ups and downs in my life, Java framework is the foundation of interview
  40. 【大厂面试】三面三问Spring循环依赖,请一定要把这篇看完(建议收藏)
  41. 一线互联网企业中,springboot入门项目
  42. 一篇文带你入门SSM框架Spring开发,帮你快速拿Offer
  43. 【面试资料】Java全集、微服务、大数据、数据结构与算法、机器学习知识最全总结,283页pdf
  44. 【leetcode刷题】24.数组中重复的数字——Java版
  45. 【leetcode刷题】23.对称二叉树——Java版
  46. 【leetcode刷题】22.二叉树的中序遍历——Java版
  47. 【leetcode刷题】21.三数之和——Java版
  48. 【leetcode刷题】20.最长回文子串——Java版
  49. 【leetcode刷题】19.回文链表——Java版
  50. 【leetcode刷题】18.反转链表——Java版
  51. 【leetcode刷题】17.相交链表——Java&python版
  52. 【leetcode刷题】16.环形链表——Java版
  53. 【leetcode刷题】15.汉明距离——Java版
  54. 【leetcode刷题】14.找到所有数组中消失的数字——Java版
  55. 【leetcode刷题】13.比特位计数——Java版
  56. oracle控制用户权限命令
  57. 三年Java开发,继阿里,鲁班二期Java架构师
  58. Oracle必须要启动的服务
  59. 万字长文!深入剖析HashMap,Java基础笔试题大全带答案
  60. 一问Kafka就心慌?我却凭着这份,图灵学院vip课程百度云