Slf4j Logger 的封装——Log

时间:2022-02-16 21:51:42

很多时候我们为了在类中加日志不得不写一行,而且还要去手动改XXX这个类名

?
1
private static Logger log = LoggerFactory.getLogger(XXX. class );


第二个问题,我特别喜欢这种形式: 


?
1
log.info( "我在XXX 改了 {} 变量" , "name" );
既省去了可恶的isInfoEnabled()的判断,还避免了拼接字符串,但是呀
?
1
log.error( "错误消息" , e);


这样就不支持了,烦躁……

写多了就觉得这种厌烦的工作实在让人无法忍受,于是就封装了下。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
public class Log {
     /**
      * 获得Logger
      * @param clazz 日志发出的类
      * @return Logger
      */
     public static Logger get(Class<?> clazz) {
         return LoggerFactory.getLogger(clazz);
     }
 
     /**
      * 获得Logger
      * @param name 自定义的日志发出者名称
      * @return Logger
      */
     public static Logger get(String name) {
         return LoggerFactory.getLogger(name);
     }
     
     /**
      * @return 获得日志,自动判定日志发出者
      */
     public static Logger get() {
         StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
         return LoggerFactory.getLogger(stackTrace[ 2 ].getClassName());
     }
     
     //----------------------------------------------------------- Logger method start
     //------------------------ Trace
     /**
      * Trace等级日志,小于debug<br>
      * 由于动态获取Logger,效率较低,建议在非频繁调用的情况下使用!!
      * @param format 格式文本,{} 代表变量
      * @param arguments 变量对应的参数
      */
     public static void trace(String format, Object... arguments) {
         trace(innerGet(), format, arguments);
     }
     
     /**
      * Trace等级日志,小于Debug
      * @param log 日志对象
      * @param format 格式文本,{} 代表变量
      * @param arguments 变量对应的参数
      */
     public static void trace(Logger log, String format, Object... arguments) {
         log.trace(format, arguments);
     }
     
     //------------------------ debug
     /**
      * Debug等级日志,小于Info<br>
      * 由于动态获取Logger,效率较低,建议在非频繁调用的情况下使用!!
      * @param format 格式文本,{} 代表变量
      * @param arguments 变量对应的参数
      */
     public static void debug(String format, Object... arguments) {
         debug(innerGet(), format, arguments);
     }
     
     /**
      * Debug等级日志,小于Info
      * @param log 日志对象
      * @param format 格式文本,{} 代表变量
      * @param arguments 变量对应的参数
      */
     public static void debug(Logger log, String format, Object... arguments) {
         log.debug(format, arguments);
     }
     
     //------------------------ info
     /**
      * Info等级日志,小于Warn<br>
      * 由于动态获取Logger,效率较低,建议在非频繁调用的情况下使用!!
      * @param format 格式文本,{} 代表变量
      * @param arguments 变量对应的参数
      */
     public static void info(String format, Object... arguments) {
         info(innerGet(), format, arguments);
     }
     
     /**
      * Info等级日志,小于Warn
      * @param log 日志对象
      * @param format 格式文本,{} 代表变量
      * @param arguments 变量对应的参数
      */
     public static void info(Logger log, String format, Object... arguments) {
         log.info(format, arguments);
     }
     
     //------------------------ warn
     /**
      * Warn等级日志,小于Error<br>
      * 由于动态获取Logger,效率较低,建议在非频繁调用的情况下使用!!
      * @param format 格式文本,{} 代表变量
      * @param arguments 变量对应的参数
      */
     public static void warn(String format, Object... arguments) {
         warn(innerGet(), format, arguments);
     }
     
     /**
      * Warn等级日志,小于Error
      * @param log 日志对象
      * @param format 格式文本,{} 代表变量
      * @param arguments 变量对应的参数
      */
     public static void warn(Logger log, String format, Object... arguments) {
         log.warn(format, arguments);
     }
     
     /**
      * Warn等级日志,小于Error<br>
      * 由于动态获取Logger,效率较低,建议在非频繁调用的情况下使用!!
      * @param e 需在日志中堆栈打印的异常
      * @param format 格式文本,{} 代表变量
      * @param arguments 变量对应的参数
      */
     public static void warn(Throwable e, String format, Object... arguments) {
         warn(innerGet(), e, format(format, arguments));
     }
     
     /**
      * Warn等级日志,小于Error
      * @param log 日志对象
      * @param e 需在日志中堆栈打印的异常
      * @param format 格式文本,{} 代表变量
      * @param arguments 变量对应的参数
      */
     public static void warn(Logger log, Throwable e, String format, Object... arguments) {
         log.warn(format(format, arguments), e);
     }
     
     //------------------------ error
     /**
      * Error等级日志<br>
      * 由于动态获取Logger,效率较低,建议在非频繁调用的情况下使用!!
      * @param format 格式文本,{} 代表变量
      * @param arguments 变量对应的参数
      */
     public static void error(String format, Object... arguments) {
         error(innerGet(), format, arguments);
     }
     
     /**
      * Error等级日志<br>
      * @param log 日志对象
      * @param format 格式文本,{} 代表变量
      * @param arguments 变量对应的参数
      */
     public static void error(Logger log, String format, Object... arguments) {
         log.error(format, arguments);
     }
     
     /**
      * Error等级日志<br>
      * 由于动态获取Logger,效率较低,建议在非频繁调用的情况下使用!!
      * @param e 需在日志中堆栈打印的异常
      * @param format 格式文本,{} 代表变量
      * @param arguments 变量对应的参数
      */
     public static void error(Throwable e, String format, Object... arguments) {
         error(innerGet(), e, format(format, arguments));
     }
     
     /**
      * Error等级日志<br>
      * 由于动态获取Logger,效率较低,建议在非频繁调用的情况下使用!!
      * @param log 日志对象
      * @param e 需在日志中堆栈打印的异常
      * @param format 格式文本,{} 代表变量
      * @param arguments 变量对应的参数
      */
     public static void error(Logger log, Throwable e, String format, Object... arguments) {
         log.error(format(format, arguments), e);
     }
     //----------------------------------------------------------- Logger method end
     
     //----------------------------------------------------------- Private method start
     /**
      * 格式化文本
      * @param template 文本模板,被替换的部分用 {} 表示
      * @param values 参数值
      * @return 格式化后的文本
      */
     private static String format(String template, Object... values) {
         return String.format(template.replace( "{}" , "%s" ), values);
     }
     
     /**
      * @return 获得日志,自动判定日志发出者
      */
     private static Logger innerGet() {
         StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
         return LoggerFactory.getLogger(stackTrace[ 3 ].getClassName());
     }
     //----------------------------------------------------------- Private method end
}
Demo:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import org.slf4j.Logger;
 
import xxx.Log;
 
public class Test {
     private static Logger log = Log.get();
     
     public static void main(String[] args) {
         //第一种使用方法(效率低)
         Log.debug( "我是一条debug消息" );
         
         //第二种使用方法
         Log.debug(log, "我是一条debug消息 {} {}" , "参数1" , "参数2" );
         
         RuntimeException e = new RuntimeException( "错误" );
         
         //第一种使用方法(效率低)
         Log.error( "我是一条error消息" );
         
         //第二种使用方法
         Log.error(log, e, "<-异常对象放前面, 我是一条带参数的error消息 {} {}" , "参数1" , "参数2" );
     }
}
总结下来如果日志比较少,可以直接使用静态方法Log.xxx,如果日志量很大,那么首先要构建好Logger,使用:
?
1
private static Logger log = Log.get();
 比之前简短了很多,而且随便复制。 
调用Logger.xxx(log, "消息");

 对于不能使用format的情况,我把Throwable放在前面了,这样就可以使用动态参数了 Object... argument

好吧,就到这里,欢迎批评指正以及提供意见~~~