山海Log

基于SpringBoot 的通用业务日志记录组件

Based SpringBoot Service Log component

GitHub release (latest by date) GitHub closed issues GitHub top language
GitHub Code Size GitHub Code Lines GitHub License

# 组件能力

  • 支持基于Spring Aop+@RequestLog注解方式记录API(请求报文/响应报文/请求时间/请求用户/请求URI等)标准化日志
  • 支持Spel表达式进行动态参数获取
  • 支持自定义获取当前用户信息
  • 支持自定义日志存储方式
  • 支持日志标准化写入操作系统临时目录(日志存储默认实现)
  • 支持无感知全流量日志自动采集(参考第10章节)

# 1.引入依赖

SpringBoot2.x

 <dependency>
      <groupId>com.wangshanhai.log</groupId>
      <artifactId>shanhai-log-spring-boot-starter</artifactId>
      <version>${last.version}</version>
</dependency>

SpringBoot3.x

 <dependency>
      <groupId>com.wangshanhai.log</groupId>
      <artifactId>shanhai-log-spring-boot3-starter</artifactId>
      <version>${last.version}</version>
</dependency>

注:主线版本目前为2.x版本号,3.x版本号可以在Maven仓库中查找,每次新版本3.x都会同步升级。

参数说明

shanhai:
  log:
    consoleShow: true  #启用控制台输出
    ignoreRequestUri: #忽略请求URI
      - /v1/role/info
    ignore-request-params:  #忽略请求报文入参类型
      - cn.hutool.system.UserInfo
    req-json-pretty-format: true  #请求报文JSON美化 
    resp-json-pretty-format: true #响应报文JSON美化 

# 2.启用ShanHaiLog 组件

使用注解@EnableShanHaiLog 即可启用ShanHaiLog 组件

@Configuration
@EnableShanHaiLog
public class LogConfig {
}

# 3.@RequestLog配置参数详解

使用@RequestLog即可对需要记录的API进行日志记录,相关定义如下:

参数名称 参数类型 参数描述 备注
module String 模块名称
level String 日志级别 可自行定义日志级别然后分类处理
message String 日志内容 如动作名称,菜单名称等
currentUser String 当前用户 当前用户,可以结合spel自动获取入参参数,参考样例描述
queryUserBySelf boolean 根据报文实现自定义用户获取逻辑 如用户通过SSO登录方式登录等,加载优先级 :currentUser>queryUserBySelf>RequestLogService.getCurrentUser
fileUpload boolean 本次请求是否为文件上传请求(默认:false) 开启后会自动记录上传的文件清单
fileDownload boolean 本次请求是否为文件下载(默认:false) 开启后会自动将响应报文置空
ignoreResponse boolean 忽略本次请求响应报文
dataMasking boolean 报文脱敏开关
dataMaskingRule String 报文脱敏规则ID 根据规则定义自行实现脱敏方法
fileDownloadLog boolean 记录下载日志开关
fileDownloadLogRule String 文件下载日志处理规则ID 根据规则定义自行实现当前请求下载的文件清单

使用方式样例如下:

@RequestLog(module = "Order",currentUser ="#{#currentUser}", message = "分页查询订单-当前用户:#{#currentUser},当前页:#{#current},每页条数:#{#size}")
public HttpResponse<IPage<WorkOrder>> queryByPage(@RequestParam("currentUser") String currentUser,@RequestParam("size") Long size,@RequestParam("current")Long current){
    ……
}

注:#{#currentUser} 为Spel表达式用法,可以提取对应方法的相关参数

# 4.自定义日志存储

Log组件预留了自定义日志存储接口,可以自行进行扩展,实现自己的日志存储方式。

接口定义如下:

public interface RequestLogService {
  /**
   * 存储日志
   * @param requestLogInfo
   */
  public void saveLog(RequestLogInfo requestLogInfo);
}

# 5.自定义获取当前登录用户信息

Log组件预留了自定义获取当前登录用户信息接口,可以自行进行扩展,实现与自己系统的用户鉴权体系的无缝对接。

接口定义如下:

public interface RequestLogService {
  /**
   * 获取当前登录用户
   * @return
   */
  public String getCurrentUser(HttpServletRequest request);
}

注:对于登录等非鉴权的场景,可以使用@RequestLog中的currentUser 并结合Spel进行使用。

当@RequestLog中的currentUser 存在Spel表达式时,表达式的优先级高于自定义接口实现的优先级。

# 6.自定义参数写入通用RequestLogInfo

Log组件预留了自定义参数写入接口,方便用户在APILOG进行日志存储时,写入自定义参数。

接口定义如下:

public interface RequestLogService {
  /**
   * 补充自定义扩展日志信息
   * @return
   */
  public Map<String,Object> getExtLogInfo(HttpServletRequest request);
}

此扩展会在执行saveLog之前自动调用并写入RequestLogInfo->extLogInfo 字段

# 7.自定义实现源IP获取方法

Log组件预留了自定义源IP获取方法,方便用户自定义实现源IP获取策略。

public interface RequestLogService {
  /**
   * 自定义源IP获取方法
   * @return
   */
  public String getReqSourceIp(HttpServletRequest request);
}

# 8.启用API Log 控制台输出

由于Log组件提供了默认存储实现(存储于操作系统临时目录),因此API LOG的控制台输出默认是被关闭的。

在开发阶段,可以考虑打开API LOG 控制台输出查看相关报文。生产环境在自定义存储实现时,也可以考虑打开控制台输出,做日志存储灾备。

shanhai.log.consoleShow=true

# 9.标准化日志对象参数详解(RequestLogInfo)

参数名称 参数类型 参数描述 备注
currentUser String 当前用户
message String 接口日志
level String 日志级别
module String 所属模块
reqTime Date 请求开始时间
respTime Date 请求结束时间
agentInfo String 浏览器信息
reqSourceIp String 用户ip
reqUrl String 请求url
reqInfo String 请求报文
respInfo String 响应报文
httpMethod String HTTP请求类型

# 10.启用ShanHaiTraceLog组件

使用注解@EnableShanHaiTraceLog即可启用ShanHaiTraceLog 组件,该组件自动对SpirngBoot的Get/POST/DELETE/PUT等请求注解进行AOP扫描,无感知生成全流量报文。

@Configuration
@EnableShanHaiTraceLog
public class LogConfig {
}

应用场景:老旧系统接口记录及出入参数据采集

# 11.SSO方式登录接口获取当前用户信息

/**
 * 获取当前登录用户(通过请求报文或响应报文)
 * @return
 */
default String getCurrentUser(RequestLogInfo requestLogInfo){ return "-";};

自行实现该方法即可

# 12.日志报文进行脱敏

/**
 * 存储日志(日志需要脱敏)
 */
default void saveLog(RequestLogInfo requestLogInfo,String dataMaskingRule){};

自行实现该方法即可,注意要在注解@RequestLog自行定义规则dataMaskingRule 标识ID。

# 13.记录文件下载请求下载的文件清单

/**
 * 获取文件下载日志
 * @param requestLogInfo 日志信息
 * @param fileDownloadLogRule 获取文件下载日志处理规则
 * @return
 */
default String getFileDownLoadLog(RequestLogInfo requestLogInfo,String fileDownloadLogRule){ return "-";};

自行实现该方法即可,注意要在注解@RequestLog自行定义规则fileDownloadLogRule 标识ID。

# 14.请求响应报文JSON美化输出

启用配置

req-json-pretty-format: true  #请求报文JSON美化 
resp-json-pretty-format: true #响应报文JSON美化 

从RequestLogInfo中获取美化参数信息:

/**
 * 请求报文美化版本(开启respJsonPrettyFormat可用)
 */
private JsonNode reqInfoPretty;
/**
 * 响应报文美化版本(开启reqJsonPrettyFormat可用)
 */
private JsonNode respInfoPretty;
/**
 * 文件上传清单美化版本(开启reqJsonPrettyFormat可用)
 */
private JsonNode fileReqInfoPretty;

JsonNode可以在最终保存环节直接作为对象进行序列化即可。