Skip to content

日志组件

日志模块实现了登录日志及操作日志的统一采集,查询等功能。具体实现是通过spring aop切面拦截,统一进行日志的采集及异步持久化。

组件依赖如下:

xml
<!-- 日志controller接口 -->
<dependency>
    <groupId>cn.zjtele.pubinfo.sys.log</groupId>
    <artifactId>log-api</artifactId>
</dependency>

<!-- 日志数据库存储组件 -->
<dependency>
    <groupId>cn.zjtele.pubinfo.sys.log</groupId>
    <artifactId>log-storage-db</artifactId>
</dependency>

<!-- 日志拦截核心包  -->
<dependency>
    <groupId>cn.zjtele.pubinfo.sys.log</groupId>
    <artifactId>log-core</artifactId>
</dependency>

如何使用

在controller接口上增加@OperationLog注解,代表改接口需要采集日志 示例代码如下:

java
@Tag(name = "组织接口")
@RestController
@RequestMapping(RbacApiConstant.BASE_MAPPING + "/demo")
public class OrgController {
    @OperationLog(operateType = LogOperatorType.DELETE)
    @Operation(description = "delete", summary = "删除数据")
    @RequestMapping(value = "/delete/{id}", method = RequestMethod.DELETE)
    public ResponseData remove(@PathVariable String id) {
        return ResponseData.success(pubGroupService.removeById(id));
    }
}

同时,日志组件会使用swagger3的@Tag@Operation,作为操作日志的详情信息。

@OperationLog相关属性如下:

java
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OperationLog {

    /**
     * 必填,操作的类型 INSERT、UPDATE、SELECT、DELETE、SAVE_OR_UPDATE、LOGIN、LOGOUT
     * @return
     */
    LogOperatorType operateType();

    /**
     * 选填,标题,缺省值为swagger的Operation说明summary
     * @return
     */
    String title() default "" ;

    /**
     * 选填,模块名称,缺省值为引入类swagger的Tag说明
     * @return
     */
    String moduleName() default "" ;//模块名称

    /**
     *  选填,脱敏字段,多个逗号隔开
     * @return
     */
    String[] sensitiveField() default {};

    /**
     * 选填,对应字段的脱敏策略
     * @return
     */
    SensitiveStrategy[] sensitiveStrategy() default  {};
}

相关配置

配置文件新增配置如下:

yaml
pubinfo:
  log:
    # 是否启用日志信息记录
    enable: true
    # 排除接口列表
    exclude-url:
      - /**
    # 全局存储时间
    global-valid-day: 30
    # 全局请求参数是否落库
    save-param: true
    # 按接口个性化定制,保留天数、请求参数是否落库等
    save-config:
      - valid-day: 7
        url: /pubSys/c1/c2
        save-param: true

二、拓展

提供了日志存储的接口拓展,目前已支持数据库存储,详见LogDbStorageService

java
public interface LogStorageService {

    /**
     * 日志信息的保存
     *
     * @param logDetail
     */
    void save(LogDetail logDetail);

    /**
     * 日志信息删除
     *
     * @param logDetail
     */
    void delete(LogDetail logDetail);

    /**
     * 登录日志信息列表查询
     *
     * @param pageBase
     * @return
     */
    PageData<PubLoginLogDto> pageLoginList(PubLoginLogQuery pageBase);

    /**
     * 登录信息详情
     *
     * @param id
     * @return
     */
    PubLoginLogDto detailLogin(String id);

    /**
     * 操作日志信息列表查询
     *
     * @param pageBase
     * @return
     */
    PageData<PubOperateLogDto> pageOperationList(PubOperateLogQuery pageBase);

    /**
     * 操作日志详情
     *
     * @param id
     * @return
     */
    PubOperateLogDto detailOperation(String id);

}

三、注意事项

获取客户端真实的操作IP,场景如下:

1、nginx示例配置如下:

        location /pubinfo-sys {
            proxy_set_header Host $host:$server_port;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Remote_addr $remote_addr;
            proxy_pass http://127.0.0.1:8080;
        }

目前我们按照如下顺序记录请求头真实ip:

    public static String getClientIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

目前我们支持记录客户端使用的浏览器如下:Mozilla Firefox、Google Chrome、Apple Safari、Microsoft Edge、Internet Explorer