操作日誌記錄(包括輸出至自定義日誌檔案)
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測試新增註解的介面
執行後:
控制檯:
日誌:
相關文章
- 記錄日誌檔案
- laravel5.7 不記錄 sql 報錯日誌,自定義日誌資訊LaravelSQL
- secureCRT記錄操作日誌Securecrt
- oracle日誌操作記錄Oracle
- Laravel 指定日誌檔案記錄任意日誌Laravel
- Laravel 中自定義日誌目錄Laravel
- php日誌,記錄日誌PHP
- 基於.NetCore3.1系列 —— 日誌記錄之自定義日誌元件NetCore元件
- larave 日誌自定義配置格式記錄呼叫檔案路徑與行號
- Lumen 日誌自定義
- gunicorn 自定義日誌
- Appfuse:記錄操作日誌APP
- 日誌模組(一標頭檔案就實現了日誌記錄)
- Python日誌記錄中新增自定義屬性Python
- 失敗登入行為輸出至alert日誌
- Oracle日誌檔案常用操作Oracle
- 【Oracle日誌】- 日誌檔案重建Oracle
- 自定義Nginx日誌格式Nginx
- Nginx訪問日誌、Nginx日誌切割、靜態檔案不記錄日誌和過期時間Nginx
- MySQL 使用tee記錄語句和輸出日誌MySql
- 日誌檔案
- MySQL資料庫中的日誌檔案---(4)配置日誌檔案輸出路徑MySql資料庫
- 日誌檔案和歸檔日誌檔案的關係以及如何切換日誌
- 如何優雅地記錄操作日誌?
- 如何優雅地記錄操作日誌
- 如何優雅的記錄操作日誌?
- python怎麼將列印輸出日誌檔案Python
- 日誌記錄器
- SLF4J記錄日誌&&日誌檔案的滾動策略__SpringBootSpring Boot
- reportbuilder 日誌輸出UI
- Python輸出日誌Python
- Laravel 自定義日誌驅動 -支援按類+日期分割日誌Laravel
- .NET 8使用日誌功能以及自定義日誌提供程式
- oracle logfile日誌檔案常規操作小記Oracle
- 刪除日誌檔案組與日誌檔案成員
- 重做日誌檔案的相關操作
- 記錄一則clear重做日誌檔案的案例
- 使用配置檔案方式記錄Python程式日誌Python