因工作需要,采用JavaFx開發了一個windows窗口程序。在開發過程中,由於沒有引入日志框架,只能自己手動在控制台打印些信息,給調試帶來了很多麻煩;因此決定引入日志框架。由於之前接觸的項目大部分都是javaWeb項目,web項目的日志輸出已經難不倒我了。但普通java項目日志輸出配置還是第一次接觸,因此記錄下整個過程,方便后續借鑒。
技術概述:采用Sl4j作為日志門面,Log4j2作為日志輸出的具體實現;同時結合lombok插件,減少代碼的書寫。
一、相關Maven依賴
由於copy jar包是非常麻煩的一件事,因此本次的這個普通java項目也是用Maven來構建的。
采用Sl4j作為日志門面,Log4j2作為日志的實現,Lombok插件減少代碼的書寫。具體依賴如下:
<!--lombok 依賴-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.6</version>
</dependency>
<!--##### log4j2 start ####-->
<!--log4j2核心包-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.11.1</version>
</dependency>
<!-- Web項目才需要添加 -->
<!-- <dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-web</artifactId>
<version>2.11.1</version>
</dependency>-->
<!--用於與slf4j保持橋接(里面自動依賴了slf4j-api)-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.11.1</version>
</dependency>
<!-- slf4j核心包,由於上面的橋接包里自動依賴進來了,因此不用加了-->
<!-- <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>-->
<!--##### log4j2 end ####-->
34
34
1
<!--lombok 依賴-->
2
<dependency>
3
<groupId>org.projectlombok</groupId>
4
<artifactId>lombok</artifactId>
5
<version>1.18.6</version>
6
</dependency>
7
8
<!--##### log4j2 start ####-->
9
<!--log4j2核心包-->
10
<dependency>
11
<groupId>org.apache.logging.log4j</groupId>
12
<artifactId>log4j-core</artifactId>
13
<version>2.11.1</version>
14
</dependency>
15
<!-- Web項目才需要添加 -->
16
<!-- <dependency>
17
<groupId>org.apache.logging.log4j</groupId>
18
<artifactId>log4j-web</artifactId>
19
<version>2.11.1</version>
20
</dependency>-->
21
<!--用於與slf4j保持橋接(里面自動依賴了slf4j-api)-->
22
<dependency>
23
<groupId>org.apache.logging.log4j</groupId>
24
<artifactId>log4j-slf4j-impl</artifactId>
25
<version>2.11.1</version>
26
</dependency>
27
<!-- slf4j核心包,由於上面的橋接包里自動依賴進來了,因此不用加了-->
28
<!-- <dependency>
29
<groupId>org.slf4j</groupId>
30
<artifactId>slf4j-api</artifactId>
31
<version>1.7.25</version>
32
</dependency>-->
33
<!--##### log4j2 end ####-->
34
二、log4j2.xml的配置
在加入依賴完成后,我們開始Lo4j2進行配置,這里重點關注log4j2的配置文件的讀取位置
說明:log4j2默認讀取配置文件的位置如下
(1)非Maven項目,src目錄下的log4j2.xml
(2)Maven項目,resouces目錄下的log4j2.xml
我這里是Maven項目,因此在resources目錄下建了個log4j2.xml。xml中具體內容如下
<?xml version="1.0" encoding="UTF-8"?>
<!--
status : 這個用於設置log4j2自身內部的信息輸出,可以不設置,當設置成trace時,會看到log4j2內部各種詳細輸出。
因此我們直接設置成OFF
-->
<Configuration status="OFF">
<!-- 配置輸出端 -->
<Appenders>
<!-- 輸出到控制台 -->
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="[%-level]%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %logger{36} - %msg%n"/>
</Console>
<!-- 輸出到文件 -->
<!--
name: 輸出端的名字
fileName: 指定當前日志文件的位置和文件名稱
filePattern: 指定當發生自動封存日志時,文件的轉移和重命名規則
這個filePatten結合下面的TimeBasedTriggeringPolicy一起使用,可以實現控制日志按天生成文件.
自動封存日志的策略可以設置時間策略和文件大小策略(見下面的Policies配置)
時間策略:
文件名_%d{yyyy-MM-dd}_%i.log 這里%d表示自動封存日志的單位是天
如果下面的TimeBasedTriggeringPolicy的interval設為1,
表示每天自動封存日志一次;那么就是一天生成一個文件。
文件大小策略:
如果你設置了SizeBasedTriggeringPolicy的size的話,
超過了這個size就會再生成一個文件,這里的%i用來區分的
%d{yyyy-MM-dd}會自動替代為日期,如2017-06-30
-->
<RollingFile name="RollingFileInfo" fileName="/log/guitool_info.log"
filePattern="/log/%d{yyyy-MM-dd}/guitool_%d{yyyy-MM-dd}_%i.log">
<!-- 只輸出level及以上級別的信息(onMatch),其他的直接拒絕(onMismatch) -->
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
<!-- 輸出的格式 -->
<PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<!--
Policies:自動封存日志策略,表示日志什么時候應該產生新日志,
可以有時間策略和大小策略等,並且:只有滿足一個策略,就好生成一個新的文件。
這里使用的是時間和大小都使用了,每隔1天產生新的日志文件
如果果今天的文件大小到了設定的size,則會新生成一個文件,上面的%i就表示今天的第幾個文件
-->
<Policies>
<TimeBasedTriggeringPolicy interval="1"/>
<SizeBasedTriggeringPolicy size="20MB"/>
</Policies>
<!--
DefaultRolloverStrategy屬性如不設置,
則默認為最多同一文件夾下7個文件,這里設置了20
-->
<DefaultRolloverStrategy max="20"/>
</RollingFile>
</Appenders>
<!-- 配置Loggers -->
<Loggers>
<!--
Logger: 用於指定部分包的日志級別
日志級別局部的會覆蓋全局的
比如這里hibernate的級別設為debug,而控制台沒有設級別,那么控制台會打印debug級別的日志
而輸出到文件這個輸出端設置了info級別,那么hibernate的debug級別的日志還是看不了。
所以最終輸出的級別和輸出端設置的級別是有關系的。
name: 包名
level:日志級別
additivity:是否冒泡,既在當前logger的輸出端輸出日志后
是否需要在父輸出端上輸出該日志,默認為 true。
如果設為false,則必須配置AppendRef。
-->
<Logger name="org.hibernate" level="debug" additivity="true"/>
<!-- 這個root是配置全局日志級別和輸出端功能和老版的log4j中根的配置是一樣的 -->
<Root level="info">
<!-- 這里引用上面定義的輸出端,千萬不要漏了。 -->
<AppenderRef ref="Console"/>
<!--<AppenderRef ref="RollingFileInfo"/>-->
</Root>
</Loggers>
</Configuration>
76
76
1
2
<!--
3
status : 這個用於設置log4j2自身內部的信息輸出,可以不設置,當設置成trace時,會看到log4j2內部各種詳細輸出。
4
因此我們直接設置成OFF
5
-->
6
<Configuration status="OFF">
7
<!-- 配置輸出端 -->
8
<Appenders>
9
<!-- 輸出到控制台 -->
10
<Console name="Console" target="SYSTEM_OUT">
11
<PatternLayout pattern="[%-level]%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %logger{36} - %msg%n"/>
12
</Console>
13
14
<!-- 輸出到文件 -->
15
<!--
16
name: 輸出端的名字
17
fileName: 指定當前日志文件的位置和文件名稱
18
filePattern: 指定當發生自動封存日志時,文件的轉移和重命名規則
19
這個filePatten結合下面的TimeBasedTriggeringPolicy一起使用,可以實現控制日志按天生成文件.
20
自動封存日志的策略可以設置時間策略和文件大小策略(見下面的Policies配置)
21
時間策略:
22
文件名_%d{yyyy-MM-dd}_%i.log 這里%d表示自動封存日志的單位是天
23
如果下面的TimeBasedTriggeringPolicy的interval設為1,
24
表示每天自動封存日志一次;那么就是一天生成一個文件。
25
文件大小策略:
26
如果你設置了SizeBasedTriggeringPolicy的size的話,
27
超過了這個size就會再生成一個文件,這里的%i用來區分的
28
%d{yyyy-MM-dd}會自動替代為日期,如2017-06-30
29
-->
30
<RollingFile name="RollingFileInfo" fileName="/log/guitool_info.log"
31
filePattern="/log/%d{yyyy-MM-dd}/guitool_%d{yyyy-MM-dd}_%i.log">
32
<!-- 只輸出level及以上級別的信息(onMatch),其他的直接拒絕(onMismatch) -->
33
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
34
<!-- 輸出的格式 -->
35
<PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
36
<!--
37
Policies:自動封存日志策略,表示日志什么時候應該產生新日志,
38
可以有時間策略和大小策略等,並且:只有滿足一個策略,就好生成一個新的文件。
39
這里使用的是時間和大小都使用了,每隔1天產生新的日志文件
40
如果果今天的文件大小到了設定的size,則會新生成一個文件,上面的%i就表示今天的第幾個文件
41
-->
42
<Policies>
43
<TimeBasedTriggeringPolicy interval="1"/>
44
<SizeBasedTriggeringPolicy size="20MB"/>
45
</Policies>
46
<!--
47
DefaultRolloverStrategy屬性如不設置,
48
則默認為最多同一文件夾下7個文件,這里設置了20
49
-->
50
<DefaultRolloverStrategy max="20"/>
51
</RollingFile>
52
</Appenders>
53
<!-- 配置Loggers -->
54
<Loggers>
55
<!--
56
Logger: 用於指定部分包的日志級別
57
日志級別局部的會覆蓋全局的
58
比如這里hibernate的級別設為debug,而控制台沒有設級別,那么控制台會打印debug級別的日志
59
而輸出到文件這個輸出端設置了info級別,那么hibernate的debug級別的日志還是看不了。
60
所以最終輸出的級別和輸出端設置的級別是有關系的。
61
name: 包名
62
level:日志級別
63
additivity:是否冒泡,既在當前logger的輸出端輸出日志后
64
是否需要在父輸出端上輸出該日志,默認為 true。
65
如果設為false,則必須配置AppendRef。
66
-->
67
<Logger name="org.hibernate" level="debug" additivity="true"/>
68
69
<!-- 這個root是配置全局日志級別和輸出端功能和老版的log4j中根的配置是一樣的 -->
70
<Root level="info">
71
<!-- 這里引用上面定義的輸出端,千萬不要漏了。 -->
72
<AppenderRef ref="Console"/>
73
<!--<AppenderRef ref="RollingFileInfo"/>-->
74
</Root>
75
</Loggers>
76
</Configuration>
如果對這些配置有疑問,可以參考我很久之前寫的博客
https://www.cnblogs.com/zeng1994/p/9296562.html
三、代碼中的使用
由於這里有引入了lombok插件(如果不懂可以百度或谷歌),在類上面添加@Sl4j的注解,然后下面就可以直接使用log輸出日志了;具體的見下面代碼
package com.jwx.digital.strategy.parse.impl;
import lombok.extern.slf4j.Slf4j;
/**
* DbUserNameParseBatFileLineStategy
*
* @author ZENG.XIAO.YAN
* @version 1.0
* @Date 2019-07-20
*/
@Slf4j
public class DbUserNameParseBatFileLineStategy implements ParseBatFileLineStategy {
/**
* 解析內容,並將內容賦值到對應的TextField
*
* @param lineSufix
* @param controller
*/
@Override
public void parseLineAndInitTextFieldText(String lineSufix, BaseController controller) {
log.info("db userName: [{}]", lineSufix);
CheckJdbcAndOtherController checkJdbcAndOtherController = (CheckJdbcAndOtherController) controller;
checkJdbcAndOtherController.getDbUserNameField().setText(lineSufix);
}
}
26
26
1
package com.jwx.digital.strategy.parse.impl;
2
import lombok.extern.slf4j.Slf4j;
3
4
/**
5
* DbUserNameParseBatFileLineStategy
6
*
7
* @author ZENG.XIAO.YAN
8
* @version 1.0
9
* @Date 2019-07-20
10
*/
11
12
public class DbUserNameParseBatFileLineStategy implements ParseBatFileLineStategy {
13
/**
14
* 解析內容,並將內容賦值到對應的TextField
15
*
16
* @param lineSufix
17
* @param controller
18
*/
19
20
public void parseLineAndInitTextFieldText(String lineSufix, BaseController controller) {
21
log.info("db userName: [{}]", lineSufix);
22
CheckJdbcAndOtherController checkJdbcAndOtherController = (CheckJdbcAndOtherController) controller;
23
checkJdbcAndOtherController.getDbUserNameField().setText(lineSufix);
24
}
25
}
26
重點關注下圖中紅色方塊內的內容

四、小結
(1)普通java項目輸出日志和javaweb項目也沒啥大的區別,引入相關依賴並配置即可
(2)log4j2默認讀的配置文件位置為src目錄下(如果是Maven項目則是resources文件夾下)的log4j2.xml
(3)輸出日志時,建議采用Sl4j日志門面,方便后續切換日志框架