普通Java项目中使用Sl4j+Log4j2打印日志

    因工作需要,采用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
<?xml version="1.0" encoding="UTF-8"?>
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
@Slf4j
12
public class DbUserNameParseBatFileLineStategy implements ParseBatFileLineStategy {
13
    /**
14
     * 解析内容,并将内容赋值到对应的TextField
15
     *
16
     * @param lineSufix
17
     * @param controller
18
     */
19
    @Override
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

    重点关注下图中红色方块内的内容
                普通Java项目中使用Sl4j+Log4j2打印日志

四、小结

    (1)普通java项目输出日志和javaweb项目也没啥大的区别,引入相关依赖并配置即可
    (2)log4j2默认读的配置文件位置为src目录下(如果是Maven项目则是resources文件夹下)的log4j2.xml
    (3)输出日志时,建议采用Sl4j日志门面,方便后续切换日志框架
上一篇:原生js实现响应式轮播图,支持电脑端点击切图,手机端滑动切图


下一篇:matlab中patch函数的用法