SLF4j的功能就是充当一个门面,有点类似于jdbc,用class.forName的方式加载当前pom文件中引入的实现类。可以看看这个blog的分析,省的自己看源码了(https://blog.csdn.net/u010644448/article/details/50298275)
springBoot不用引入依赖,logback和slf4j的jar被依赖传递过来了。只需要配置一个logback.xml文件即可。
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="warContextName" value="gateway"/>
<contextName>${warContextName}</contextName>>
<appender name="logfile_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<Prudent>true</Prudent>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>
logs/error/${HOSTNAME}.${CONTEXT_NAME}.%d{yyyy-MM-dd-HH}.error.log
</FileNamePattern>
</rollingPolicy>
<encoder>
<Pattern>
%d{HH:mm:ss.SSS} [%thread] %.-1level %logger{32} - %msg %n
</Pattern>
</encoder>
</appender>
<appender name="logfile_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<Prudent>true</Prudent>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>
logs/info/${HOSTNAME}.${CONTEXT_NAME}.%d{yyyy-MM-dd-HH}.info.log
</FileNamePattern>
</rollingPolicy>
<encoder>
<Pattern>
%d{HH:mm:ss.SSS} [%thread] %.-1level %logger{32} - %msg %n
</Pattern>
</encoder>
</appender>
<appender name="logfile_debug" class="ch.qos.logback.classic.AsyncAppender">
<queueSize>512</queueSize>
<appender name="_logfile_debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
<Prudent>true</Prudent>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>
logs/debug/${HOSTNAME}.${CONTEXT_NAME}.%d{yyyy-MM-dd-HH}-%i.debug.log
</FileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>800MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<Pattern>
%d{HH:mm:ss.SSS} [%thread] %.-1level %logger{32} - %msg %n
</Pattern>
</encoder>
</appender>
</appender>
<appender name="logfile_console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<Pattern>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
</Pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>ACCEPT</onMismatch>
</filter>
</appender>
<logger name="com.mpt.mylog" level="DEBUG"/>
<logger name="root" level="INFO">
<appender-ref ref="logfile_error"/>
<appender-ref ref="logfile_debug"/>
<appender-ref ref="logfile_info"/>
<appender-ref ref="logfile_console"/>
</logger>
</configuration>
Logger根节点与其他logger的关系
-
<logger>
中没配置level时,会继承父级的level - 没有配置additivity属性时,默认该属性为true,表示此
<logger>
的打印信息向父级传递 - 没有配置
<appender-ref>
,表示此去<logger>
不会打印出任何信息
logger的子父级关系
例子 : <logger>
中 name="java" 是 name ="java.lang"的父级,<root>
是所有<logger>
的父级。
shang
appender
<appender>
是<configuration>
的子节点,是负责写日志的组件。<appender>
有两个必要属性name和class:
- name指定
<appender>
的名称 - class指定
<appender>
的权限定名
其子节点的介绍:
-
<file>
表示写入的文件名,可以使相对目录也可以是绝对目录,如果上级目录不存在则自动创建 -
<appender>
如果为true表示日志被追加到文件结尾,如果是false表示清空文件 -
<prudent>
如果为true表示日志会被安全地写入文件,即使其他的FileAppender也在向此文件做写入操作,效率低,默认为false
多种appender(基于时间的)可以看这篇blog**https://juejin.im/post/5a39c91cf265da4327185d10
参考blog : https://www.cnblogs.com/xrq730/p/8628945.html
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.mpt</groupId>
<artifactId>mylog</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mylog</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
springBoot内置了slf4j和logback,不需要引入额外的jar包
application.properties
server.port=9099
server.servlet.context-path=/log
### 持久化专用数据库 ###
spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.datasource.url=jdbc:sqlserver://localhost;databaseName=SmartDP
spring.datasource.username=sa
spring.datasource.password=1367127820hu
mybatis.mapper-locations=mappers/*
WebLogAspect.java
package com.mpt.mylog.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Map;
/**
* @author huangQiChang
* @date 2019/7/23
*/
@Aspect
@Component
public class LogAspect {
private Logger logger = LoggerFactory.getLogger(getClass());
@Pointcut("execution(public * com.mpt.mylog.controller.*.*(..))")
public void mvcPointCut() {}
@Around("mvcPointCut()")
public Object mvcPointCut_around(ProceedingJoinPoint pjp) throws Throwable {
try {
logInfo(pjp);
} catch (Exception e) {
logger.error(e.getMessage());
}
return pjp.proceed(pjp.getArgs());
}
private void logInfo(ProceedingJoinPoint pjp) {
// 这里暂时不知道这个强转意味这什么
MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
Method method = methodSignature.getMethod();
String className = method.getDeclaringClass().getName();
String methodName = method.getName();
Object[] params = pjp.getArgs();
String paramStr = null;
if (method.getAnnotation(PostMapping.class) != null) {
Map map = (Map) params[0];//post请求中 params数组第一个为linkedhashMap
paramStr = map.toString();
}
if (method.getAnnotation(GetMapping.class) != null) {
paramStr = Arrays.toString(params);
}
String deBugInfo = "====>方法:" + className + "." +methodName;
if (params != null) {
deBugInfo = deBugInfo + " 参数:" + paramStr;
}
logger.debug( deBugInfo);
}
}
网友评论