【SpringBoot探索二】SpringBoot项目集成日志记录功能

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/struggling_rong/article/details/79194411

在之前项目的基础上添加日志

1.让项目具有输出日志功能

在pom文件中加入依赖

<dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

这样也包含了日志功能,在代码中就可以使用日志输出类了

 package com.my.webapp.service.impl;

import com.my.webapp.service.LoginService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

/**
 */
@Service
public class LoginServiceImpl implements LoginService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass().getSimpleName());

    @Override
    public String login() {
        logger.debug("使用slf4j进行日志记录!");
        return "welcome to spring boot world!";
    }
}

当然这样我们还没法运行程序看到效果,还需要先编写日志配置文件logback.xml

2.配置日志

编写logback.xml
在resource目录下添加logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/2002/xmlspec/dtd/2.10/xmlspec.dtd">

<configuration>
    <!--web应用名称-->
    <contextName>webapp</contextName>
    <!--自定义变量名, 通过${name}来使用-->
    <property name="test" value="testValue"/>
    <!--获取时间戳字符串,key为名称,datePattern为格式化时间戳为指定格式字符串-->
    <timestamp key="time" datePattern="yyyyMMdd'T'HHmmss"/>

    <!--自定义输出源-->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- encoder 默认配置为PatternLayoutEncoder -->
        <encoder>
            <!--输出格式
            %n 换行
            %-5level 从左往右占5个字符,输出打印级别
            %d 输出日期,格式为HH:mm:ss
            %logger  输出该日志的类或包
            %msg 日志记录
            -->
            <pattern>%n[%-5level]-%d{HH:mm:ss}-%logger-%thread-%msg</pattern>
        </encoder>
    </appender>
    <!--根logger-->
    <root level="DEBUG">
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>

添加好后,运行项目,则会自动加载该日志配置文件
当运行了

logger.debug("使用slf4j进行日志记录!");

控制台则能看到如下效果

[DEBUG]-10:53:31-LoginServiceImpl-http-nio-8080-exec-1-使用slf4j进行日志记录!

3.自定义转义类型数据

在上面我们除了用自带的格式,如%n,%msg等等,如果我们还想要设定其它类型数据,比如每条日志上输出请求url,那么则需要自定义PatternLayoutEncoder
编写一个继承自PatternLayoutEncoderBase的类,覆盖start()方法,主要往InstanceConverterMap里添加自定义转义类型以及值

package com.my.webapp.logback;

import ch.qos.logback.classic.PatternLayout;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.pattern.PatternLayoutEncoderBase;
import com.my.webapp.logback.converter.HttpRequestConverter;

import java.util.HashMap;
import java.util.Map;

/**
 */
public class PatternLayoutEncoder extends PatternLayoutEncoderBase<ILoggingEvent> {
    @Override
    public void start() {
        PatternLayout patternLayout = new PatternLayout();
        patternLayout.getInstanceConverterMap().putAll(setPatternType());
        patternLayout.setContext(context);
        patternLayout.setPattern(getPattern());
        patternLayout.setOutputPatternAsHeader(outputPatternAsHeader);
        patternLayout.start();
        this.layout = patternLayout;
        super.start();
        super.start();
    }

    /**
     * 自定义转义类型
     * @return
     */
    private Map<String, String> setPatternType() {

        Map<String, String> map = new HashMap<String, String>();
        map.put("request", HttpRequestConverter.class.getName());

        return map;
    }
}

这里需要注意Map的value为自定义Converter的类名

编写对应类型的Converter
需要继承ClassicConverter并覆盖converter()方法

HttpRequestConverter.java

package com.my.webapp.logback.converter;

import ch.qos.logback.classic.pattern.ClassicConverter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 */
public class HttpRequestConverter extends ClassicConverter{
    @Override
    public String convert(ILoggingEvent iLoggingEvent) {

        ServletRequestAttributes requestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        if(requestAttributes == null){
            return "";
        }

        HttpServletRequest request = requestAttributes.getRequest();
        if(request == null){
            return "";
        }
        return request.getRequestURI();
    }
}

converter()方法输出的值即为输出日志时,%request对应的值

修改encoder属性,class修改为我们刚自定义的类。
这样我们就可以在输出格式中添加%request这种类型了

  <encoder charset="UTF-8" class="com.my.webapp.logback.PatternLayoutEncoder">
        <pattern>%n[%-5level]--%d{HH:mm:ss}--%logger--%thread--%method--[%request]--%msg</pattern>
        </encoder>

日志运行效果如下:

[DEBUG]–15:09:42–LoginServiceImpl–http-nio-8080-exec-1–login–[/user/loginWithService/31]–[debug]使用slf4j进行日志记录!

4.自定义logger

刚刚的配置将所有类的输出格式都是一致的,如果需要配置特定类或包下的类,比如设置不同打印级别,就需要自定义logger

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/2002/xmlspec/dtd/2.10/xmlspec.dtd">

<configuration>
    <!--web应用名称-->
    <contextName>webapp</contextName>
    <!--自定义变量名, 通过${name}来使用-->
    <property name="test" value="testValue"/>
    <!--获取时间戳字符串,key为名称,datePattern为格式化时间戳为指定格式字符串-->
    <timestamp key="time" datePattern="yyyyMMdd'T'HHmmss"/>


    <!--自定义输出源-->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- encoder 默认配置为PatternLayoutEncoder -->
        <encoder charset="UTF-8">
            <!--输出格式
            %n 换行
            %-5level 从左往右占5个字符,输出打印级别
            %d 输出日期,格式为HH:mm:ss
            %logger  输出该日志的类或包
            %msg 日志记录
            -->
            <pattern>%n[%-5level]-%d{HH:mm:ss}-%logger-%thread-%msg</pattern>
        </encoder>
    </appender>
    <!--logger用于设置某个包或某个类的日志打印级别,以及设置appender
        name: 指定的包或类
        level: 打印级别 TRACE, DEBUG, INFO, WARN, ERROR, ALL, OFF,不区分大小写,还有特殊值INHERITED或者同义词NULL,代表强制执行上级的级别。
                如果未设置此属性,那么当前loger将会继承上级的级别。
        additivity: 是否向上级loger传递打印信息。默认是true。
    -->
    <!--<logger name="com.my.webapp" level="DEBUG" addtivity="false">-->
    <!--使用自定义的日志输出配置,比如输出到文件或者是控制台-->
    <!--ref 引用的appender 对应appender的name值-->
    <!--<appender-ref ref="STDOUT"/>-->
    <!--</logger>-->

    <!--这里指定springframework包下所有的类,日志输出级别为INFO,additivity默认为true。则将日志信息递交给上级logger(root)处理,
        要处理的日志信息为INFO及之后的级别
    -->
    <logger name="org.springframework" level="INFO"/>
    <!--http包下的日志输出到控制台,并且不会传递给上级处理-->
    <logger name="org.apache.http" level="INFO" additivity="false">
        <appender-ref ref="STDOUT"/>
    </logger>
    <!--根logger-->
    <root level="DEBUG">
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>

5.设置将日志输出到文件

添加一个新的appender,其负责将日志记录在文件中

<!--输出到文件中-->
    <appender name="LogFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--设置日志滚动策略,比如切换文件记录日志,或重命名等
        clss: 滚动策略 TimeBasedRollingPolicy为最常见滚动策略,根据时间来制定
        -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件输出的文件名-->
            <FileNamePattern>${filePath}/webapp-%d{yyyy-MM-dd}.log</FileNamePattern>
            <!--日志保留的最大个数,超过了则删除最旧的文件-->
            <MaxHistory>30</MaxHistory>
        </rollingPolicy>
        <encoder charset="UTF-8">
            <pattern>%n[%-5level]-%d{HH:mm:ss}-%logger-%thread-[%method]-%msg</pattern>
        </encoder>

        <!--日志文件最大的大小-->
        <!--class 日志通知触发策略 SizeBasedTriggeringPolicy,超过设定大小则发出通知-->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <!--单个日志文件大小限制,超过则记录在新的日志文件中-->
            <MaxFileSize>10MB</MaxFileSize>
        </triggeringPolicy>
    </appender>

将想要输出日志到文件中的looger修改appender-ref引用为刚设定的appender(如”LogFile”)

 <root level="DEBUG">
        <!--输出到控制台-->
        <!--<appender-ref ref="STDOUT"/>-->
        <!--输出到指定文件-->
        <appender-ref ref="LogFile"/>
    </root>

这样日志都会记录到文件中了,路径为我设定的
E:\java\logfile\目录下

最终logback.xml文件内容:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/2002/xmlspec/dtd/2.10/xmlspec.dtd">

<configuration>
    <!--web应用名称-->
    <contextName>webapp</contextName>
    <!--自定义变量名, 通过${name}来使用-->
    <property name="test" value="testValue"/>
    <!--获取时间戳字符串,key为名称,datePattern为格式化时间戳为指定格式字符串-->
    <timestamp key="time" datePattern="yyyyMMdd'T'HHmmss"/>

    <!--定义一个日志存放目录属性,方便修改-->
    <property name="filePath" value="E:/java/logfile"/>

    <!--自定义输出源-->

    <!--输出到控制台-->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- encoder
            class 默认配置为PatternLayoutEncoder -->
        <encoder charset="UTF-8" class="com.my.webapp.logback.PatternLayoutEncoder">
            <!--输出格式
            %n 换行
            %-5level 从左往右占5个字符,输出打印级别
            %d 输出日期,格式为HH:mm:ss
            %logger  输出该日志的类或包
            %msg 日志记录
            %method 打印该日志的方法
            如果需要打印其它类型数据则需要自定义PatternLayoutEncoder方法(比如%request)
            -->
            <pattern>%n[%-5level]--%d{HH:mm:ss}--%logger--%thread--%method--[%request]--%msg</pattern>
        </encoder>
    </appender>

    <!--输出到文件中-->
    <appender name="LogFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--设置日志滚动策略,比如切换文件记录日志,或重命名等
        clss: 滚动策略 TimeBasedRollingPolicy为最常见滚动策略,根据时间来制定
        -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件输出的文件名-->
            <FileNamePattern>${filePath}/webapp-%d{yyyy-MM-dd}.log</FileNamePattern>
            <!--日志保留的最大个数,超过了则删除最旧的文件-->
            <MaxHistory>30</MaxHistory>
        </rollingPolicy>
        <encoder charset="UTF-8">
            <pattern>%n[%-5level]-%d{HH:mm:ss}-%logger-%thread-[%method]-%msg</pattern>
        </encoder>

        <!--日志文件最大的大小-->
        <!--class 日志通知触发策略 SizeBasedTriggeringPolicy,超过设定大小则发出通知-->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <!--单个日志文件大小限制,超过则记录在新的日志文件中-->
            <MaxFileSize>10MB</MaxFileSize>
        </triggeringPolicy>
    </appender>

    <!--logger用于设置某个包或某个类的日志打印级别,以及设置appender
        name: 指定的包或类
        level: 打印级别 TRACE, DEBUG, INFO, WARN, ERROR, ALL, OFF,不区分大小写,还有特殊值INHERITED或者同义词NULL,代表强制执行上级的级别。
                如果未设置此属性,那么当前loger将会继承上级的级别。
        additivity: 是否向上级loger传递打印信息。默认是true。
    -->
    <!--http包下的日志输出到控制台,不会传递给上级处理-->
    <logger name="org.apache.http" level="INFO" additivity="false">
        <appender-ref ref="STDOUT"/>
    </logger>
    <!--这里指定springframework包下所有的类,日志输出级别为INFO,additivity默认为true。则将日志信息递交给上级logger(root)处理,
        要处理的日志信息为INFO及之后的级别
    -->
    <logger name="org.springframework" level="INFO"/>

    <!--根logger-->
    <root level="DEBUG">
        <!--输出到控制台-->
        <!--<appender-ref ref="STDOUT"/>-->
        <!--输出到指定文件-->
        <appender-ref ref="LogFile"/>
    </root>
</configuration>

以上即为logback常用配置
博客参考案例已上传:

【SpringBoot探索二】SpringBoot项目集成日志记录功能

猜你喜欢

转载自blog.csdn.net/struggling_rong/article/details/79194411