主题
日志组件
日志模块实现了登录日志及操作日志的统一采集,查询等功能。具体实现是通过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