SpringBoot 入门(十)——日志

在一个项目的调试和后期维护中,日志是很重要的一部分,在 JavaWeb 中最有名的日志组件当属 log4j 了,但是在后来 Logback 貌似更厉害,SpringBoot 默认集成了 Logback,所以要在 SpringBoot 中使用 Logback 并不需要添加特别的依赖,如果有个性化需求,我们只需要修改配置文件即可。

一 打印日志

当我们启动一个 SpringBoot 项目的时候看到的那些打印其实就是 Logback 打印出来的,默认的日志级别是 info:

SpringBoot 入门(十)——日志_第1张图片

我们在之前的一个 HelloWorldController 中使用一下 Logger 来测试一下打印:

package com.qinshou.springbootdemo.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

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

/**
 * Description:测试 Controller
 * Author: QinHao
 * Date: 2019/7/25 13:45
 */
@RequestMapping(value = "/")
@RestController
public class HelloWorldController {

    private final Logger mLogger = LoggerFactory.getLogger(this.getClass().getName());

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public Map helloWorld() {
        mLogger.debug("访问了 HelloWorld 接口");
        mLogger.info("访问了 HelloWorld 接口");
        mLogger.warn("访问了 HelloWorld 接口");
        mLogger.error("访问了 HelloWorld 接口");
        Map map = new HashMap<>();
        map.put("data", "Hello World");
        return map;
    }
}

我们在获取 Logger 对象时是通过 LoggerFactory 工厂类获取的,需要传递一个参数,这个参数相当于 Tag,这个 Tag 最好是指定为包名,这样对于后面指定特定的日志显示级别比较方便。

访问一下 localhost:8080 可以看到添加的日志打印成功打印出来了:

 

二 日志配置

在配置文件中我们可以设置日志的显示级别,通过 “logging.level.Tag 名=日志级别” 来设置:

# 设置 root 日志为 INFO 级别
logging.level.root=info
# 设置指定包名日志为 debug 级别
logging.level.com.qinshou.springbootdemo=error
# 日志输出文件
logging.file=log/qinshoublog-dev.log

重新运行一下项目访问一下 localhost:8080 ,可以看到只打印了 error 级别的日志:

除了可以在配置文件中配置,我们可以写一个 logback.xml 来统一配置级别,这个文件的基本写法如下:



    
    
    
    
    

    
    
    
        
            ${FILE_LOG_PATTERN}
        
        ${LOG_FILE}
        
            ${LOG_FILE}.%d{yyyy-MM-dd}.%i
            
            30
            
            
                10MB
            
        
    

    
        
        
    

这里面可以设置日志的切分大小,可以将大小先设置成了 10KB 来看看效果,多访问几次接口,就会看到日志分成了好几个文件:

SpringBoot 入门(十)——日志_第2张图片

 

三 面向切面记录日志

面向切面编程的思想我也不是很明白,但是利用 SpringBoot 的切面注解可以很方便的记录日志,这里记录一个例子:

package com.qinshou.springbootdemo.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Arrays;

import javax.servlet.http.HttpServletRequest;

/**
 * Description:TODO
 * Author:MrQinshou
 * Date:2018/9/19 20:38
 */
@Aspect
@Component
public class LogAspect {
    private final Logger mLogger = LoggerFactory.getLogger(this.getClass().getName());

    @Pointcut("execution(* com.qinshou.springbootdemo.controller.*.*(..))")
    public void log() {

    }

    /**
     * author:MrQinshou
     * Description:切面之前调用的方法
     * date:2018/9/19 20:42
     * param
     * return
     */
    @Before("log()")
    public void before(JoinPoint joinpoint) {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest httpServletRequest = servletRequestAttributes.getRequest();
        String url = httpServletRequest.getRequestURL().toString();
        String ip = httpServletRequest.getRemoteAddr();
        String classMethod = joinpoint.getSignature().getDeclaringTypeName() + "." + joinpoint.getSignature().getName();
        Object[] args = joinpoint.getArgs();
        RequestLog requestLog = new RequestLog(url, ip, classMethod, args);
        mLogger.info("Request--->{}", requestLog);
    }

    /**
     * author:MrQinshou
     * Description:切面之后调用的方法
     * date:2018/9/19 20:42
     * param
     * return
     */
    @After("log()")
    public void after() {
//        mLogger.info("after");
    }

    /**
     * author:MrQinshou
     * Description:捕获各个切面的返回值
     * date:2018/9/19 20:44
     * param
     * return
     */
    @AfterReturning(returning = "result", pointcut = "log()")
    public void afterReturn(Object result) {
        mLogger.info("afterReturn--->{}", result);
    }

    private class RequestLog {
        private String url;
        private String ip;
        private String classMethod;
        private Object[] args;

        public RequestLog(String url, String ip, String classMethod, Object[] args) {
            this.url = url;
            this.ip = ip;
            this.classMethod = classMethod;
            this.args = args;
        }

        @Override
        public String toString() {
            return "RequestLog{" +
                    "url='" + url + '\'' +
                    ", ip='" + ip + '\'' +
                    ", classMethod='" + classMethod + '\'' +
                    ", args=" + Arrays.toString(args) +
                    '}';
        }
    }
}

这样我们就可以在每个接口被访问时记录下日志了。

你可能感兴趣的:(JavaWeb)