操作日誌記錄(包括輸出至自定義日誌檔案)
1.日誌部分
1.1日誌依賴
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.30</version>
</dependency>
1.2logback.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<!-- configuration file for LogBack (slf4J implementation)
See here for more details: http://gordondickens.com/wordpress/2013/03/27/sawing-through-the-java-loggers/ -->
<!--code generator-->
<!--author Steven-->
<!--version 1.0.0-->
<configuration scan="true" scanPeriod="30 seconds">
<contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
<resetJUL>true</resetJUL>
</contextListener>
<!-- To enable JMX Management -->
<jmxConfigurator/>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/log.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- Daily rollover with compression -->
<fileNamePattern>logs/log-%d{yyyy-MM-dd}.gz</fileNamePattern>
<!-- keep 30 days worth of history -->
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%date{yyyy-MM-dd HH:mm:ss} ${PID}: %-5level %logger{0} - %msg%n</pattern>
</encoder>
</appender>
<appender name="errorAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/error-%d{yyyy-MM-dd}.log</fileNamePattern>
</rollingPolicy>
<encoder>
<pattern>%d{HH:mm:ss.SSS} %thread %X{invokeNo} %logger{40} %msg%n</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter"><!-- 只列印錯誤日誌 -->
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%date{yyyy-MM-dd HH:mm:ss} ${PID}: %-5level %logger{0} - %msg%n</pattern>
</encoder>
</appender>
<!--不同業務邏輯的日誌列印到不同檔案-->
<appender name="operationLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>logs/operation.log</File>
<append>true</append>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/operation-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder charset="UTF-8">
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] %level [%thread] %file:%line - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 不同的業務邏輯日誌列印到指定資料夾-->
<logger name="operation" additivity="false" level="INFO">
<appender-ref ref="operationLog"/>
</logger>
<!-- Specify logging levels -->
<logger name="org.springframework" level="info"/>
<logger name="org.hibernate" level="info"/>
<logger name="com.jpxx.admin" level="debug"/>
<logger name="com.jpxx.base" level="info"/>
<!--<logger name="org.springframework.transaction" level="DEBUG" />-->
<!--<logger name="org.springframework.jdbc.datasource" level="DEBUG" />-->
<!--<logger name="org.springframework.orm.jpa" level="DEBUG" />-->
<root level="info">
<appender-ref ref="console"/>
<appender-ref ref="FILE"/>
<appender-ref ref="errorAppender"/>
</root>
</configuration>
2.自定義註解配合aop實現攔截記錄使用者操作
2.1aop依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2.2開啟aop配置
spring:
#切面啟用
aop:
proxy-target-class: true
auto: true
2.3自定義註解
@Target({ElementType.PARAMETER, ElementType.METHOD})//作用在引數和方法上
@Retention(RetentionPolicy.RUNTIME)//執行時註解
@Documented//表明這個註解應該被 javadoc工具記錄
public @interface OperationLog {
String description() default "";
}
2.4切面類
import com.alibaba.fastjson.JSON;
import com.jpxx.admin.common.util.LoggerUtils;
import com.jpxx.admin.system.service.api.SysUserService;
import com.jpxx.base.utils.jwt.JwtSubject;
import com.jpxx.base.utils.jwt.JwtUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
import java.util.Enumeration;
/**
* @ClassName SystemLogAspect
* @Description
* @Author Administrator
* @Date 2020/10/15 0015 16:49
* @Version 1.0
*/
@Aspect
@Component
@SuppressWarnings("all")
public class SystemLogAspect {
//本地日誌記錄物件
private static final Logger logger = LoggerUtils.Logger("operation");
//api切點
@Pointcut("@annotation(com.jpxx.admin.system.web.annotation.OperationLog)")
public void operationAspect() {
}
/**
* @Description 前置通知
*/
@Before("operationAspect()")
public void doBefore(JoinPoint joinPoint) {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
Enumeration<String> headerNames = request.getHeaderNames();
//讀取使用者資訊
String token = request.getHeader("token");
JwtSubject decode = JwtUtils.decode(token);
Long usId = decode.getUsId();
String ip = request.getRemoteHost();
try {
//*========控制檯輸出=========*//
System.out.println("==============前置通知開始==============");
System.out.println("請求方法" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName()));
System.out.println("方法描述:" + getControllerMethodDescription(joinPoint));
System.out.println("請求人id:" + usId);
System.out.println("請求ip:" + ip);
//日誌記錄
logger.info("請求方法" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName()));
logger.info("方法描述:" + getControllerMethodDescription(joinPoint));
logger.info("請求人id:" + usId);
logger.info("請求ip:" + ip);
} catch (Exception e) {
//記錄本地異常日誌
logger.error("==前置通知異常==");
logger.error("異常資訊:{}", e.getMessage());
}
}
/**
* @Description 獲取方法描述
*/
public static String getServiceMethodDescription(JoinPoint joinPoint) throws Exception {
String targetName = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
Object[] arguments = joinPoint.getArgs();
Class targetClass = Class.forName(targetName);
Method[] methods = targetClass.getMethods();
String description = "";
for (Method method : methods) {
if (method.getName().equals(methodName)) {
Class[] clazzs = method.getParameterTypes();
if (clazzs.length == arguments.length) {
description = method.getAnnotation(SystemServiceLog.class).description();
break;
}
}
}
return description;
}
}
2.5測試新增註解的介面
執行後:
控制檯:
日誌:
相關文章
- 基於.NetCore3.1系列 —— 日誌記錄之自定義日誌元件NetCore元件
- Laravel 指定日誌檔案記錄任意日誌Laravel
- laravel5.7 不記錄 sql 報錯日誌,自定義日誌資訊LaravelSQL
- larave 日誌自定義配置格式記錄呼叫檔案路徑與行號
- Python日誌記錄中新增自定義屬性Python
- Lumen 日誌自定義
- gunicorn 自定義日誌
- springboot使用logback記錄日誌,配置檔案Spring Boot
- SLF4J記錄日誌&&日誌檔案的滾動策略__SpringBootSpring Boot
- python怎麼將列印輸出日誌檔案Python
- 自定義Nginx日誌格式Nginx
- 使用配置檔案方式記錄Python程式日誌Python
- 失敗登入行為輸出至alert日誌
- logback下日誌輸出前處理操作——以日誌脫敏為例
- 如何優雅地記錄操作日誌
- 如何優雅的記錄操作日誌?
- 如何優雅地記錄操作日誌?
- Linux系統日誌分為哪幾種?日誌檔案包括幾列內容?Linux
- 日誌記錄器
- ThinkPHP日誌記錄PHP
- python如何輸出日誌?Python
- .NET 8使用日誌功能以及自定義日誌提供程式
- Laravel 自定義日誌驅動 -支援按類+日期分割日誌Laravel
- 記錄一則clear重做日誌檔案的案例
- 【MySQL日誌】MySQL日誌檔案初級管理MySql
- SpringBoot通過yml和xml檔案配置日誌輸出Spring BootXML
- SpringBoot專案使用AOP及自定義註解儲存操作日誌Spring Boot
- 一種簡化操作日誌記錄方案
- Swoft AOP 記錄使用者操作日誌
- 微服務體系操作日誌如何記錄?微服務
- 如何記錄可讀性的操作日誌?
- django 專案日誌記錄設定Django
- Dubbo自定義日誌攔截器
- 自定義 Command 檢視 Laravel 日誌Laravel
- Yii2自定義日誌字首
- Laravel sql 日誌記錄LaravelSQL
- nginx日誌檔案按天記錄定時清理迴圈記錄Nginx
- python日誌重複輸出Python