auditLog采用Audit4j进行了简单的封装。
在applicaton-.yml中添加auditLog的配置,配置参数如下:
# auditLog配置
audit4j:
db-handler:
# auditLog记录时否分表. 对于业务不是很复杂的应用,一般设置成false即可
separate: false
# 是否用内置的数据库记录.一般都是用自己的业务数据库,所以设置为false
embedded: false
# 默认的表名
default_table_name: audit
# 以下是auditLog数据库连接的一些配置;auditLog和业务的数据库不共用连接
db_connection_type: pooled
db_pool_connectionTimeout: 30000
db_pool_maximumPoolSize: 2
db_pool_minimumIdle: 1
db_driver: com.mysql.jdbc.Driver
db_url: jdbc:mysql://test.yuxisoft.cn:3306/loreal?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=true&allowMultiQueries=true
db_user: root
db_password: yuxisoft
# auditLog写日志文件的位置,app需要替换成应用的名称
log:
file:
location: var/log/app/audit
在separate设置为false情况下,Audit4j是使用默认使用名称为audit的表来记录(可以通过default_table_name来设置)。如果audit表不存在,会自动创建,创建的字段包括identifier, timestamp, actor, origin, action, elements, 字符集是utf-8格式。
建议自己先创建好audit表,并根据业务情况设置字段长度和类型。比如actor或者elements中有特殊符号,例如emoji表情,字符集需要设置成utf8mb4,如下:
CREATE TABLE `audit` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`identifier` varchar(200) NOT NULL,
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`actor` varchar(200) CHARACTER SET utf8mb4 NOT NULL COMMENT '保存账号,名称,权限ID,数据权限ID',
`origin` varchar(200) DEFAULT NULL,
`action` varchar(200) NOT NULL,
`elements` longtext CHARACTER SET utf8mb4,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8 COMMENT='auditLog';
separate设置为true情况下,在记录日志的时可以指定表前缀,例如在@Audit指定repository=login,该auditEvent就会记录在login_audit表中。
如果需要分表单独存储,建议根据业务的需要预先创建好存放auditLog的表。
注意:如果separeate=true, 记录日志时没有指定repository, 则会记录到表名为default_audit表中。
@Audit(repository = "login")
@RequestMapping("/login")
public String login() {
return "hello";
}
可以修改AuditMetaData.java
类来自定义。
MetaData主要是定义Origin和Actor。origin是指操作来源,skeleton中只记录了ip,可以根据需求修改其实现记录IP加域名等等。actor是操作者,skeleton中记录id,userName, realName,实际可以再加上角色,权限等数据。
@Audit注解可以用在方法上,可以用在类上。如果是用在类上,该类中的所有public方法调用都会记录auditLog。
例如:
@Audit
public void foo(Integer bar){
}
** @Audit属性 ** | ** 描述 ** | ** 默认值 ** |
---|---|---|
action | 自定义action名称 | Method名称 |
repository | 指定auditLog存放的表的前缀。只有separate=true时生效 | default |
@AuditField是指定auditEvent中参数的名称. 不使用@AuditField指定参数名称,记录时默认使用arg1作为参数名称。
例如:
@Audit(repository = "action")
public String foo1(@AuditField(field="stringOne") String string1, @AuditField(field="stringTwo") String string2) {
}
** @AuditField属性 ** | ** 描述 ** |
---|---|
field | 指定参数的名称 |
在class上使用了@Audit注解,但某些方法不需要审计,可以在该方法上添加@IgnoreAudit方法。
例如:
@Audit
public class UserService {
@IgnoreAudit
public void changePassword(String oldPassword, String newPassword) {
// This method will not be audited.
}
}
指定method的某个参数不被审计。
例如:
public class UserService {
@Audit
public void login(String username, @IgnoreAudit String password) {
// password parameter will not be audited.
}
}
忽略审计对象中的成员属性
例如:
public class UserService {
@Audit
public void saveUser(User user) {
// password parameter in user object will not be audited.
}
}
public class User {
private String username;
@IgnoreAudit
private String password;
//Getters and Setters
}
@DeIdentify用于匿名化特定的字段,用*代替。
例如:
@Audit
public void saveCreditCardId(@DeIdentify(left=5) int cardId){}
如果cardId是: 123456789
日志记录会变成: *****6789
** @DeIdentify属性 ** | ** 描述 ** |
---|---|
left | 匿名化左侧字符。例如,@DeIdentify(left=3) -> ***456789 |
right | 匿名化右侧字符。例如:@DeIdentify(right=3) -> 123456*** |
fromLeft | 从左侧开始匿名化所有字符。例如:@DeIdentify(fromLeft=3) -> 123****** |
fromRight | 从右侧开始匿名化所有字符。例如:@DeIdentify(fromRight=3) -> ******789 |
调用Audit4j提供的audit方法直接记录一条auditEvent;
public void myMethod(String myParam1, Object myParam2) {
String actor = MyApplicationContext.getAuthanticatedUser();
AuditManager manager = AuditManager.getInstance();
manager.audit(new AuditEvent(actor, "myMethod",
new Field("myParam1Name", myParam1),
new Field("myParam2Name", myParam2)));
}
或者用EventBuilder构造一个AuditEvent
public void myMethod(String myParam1, Object myParam2) {
String actor = MyApplicationContext.getAuthanticatedUser();
EventBuilder builder = new EventBuilder();
builder.addActor(actor).addAction("myMethod")
.addField("myParam1Name", myParam1)
.addField("myParam2Name", myParam2);
AuditManager manager = AuditManager.getInstance();
manager.audit(builder.build());
}
注意:AuditManager记录的日志,Audit4j目前都保存到default_table_name设置的表名的表中。(设置不了repository,感觉是个audit4j的bug)
AuditLogService.java
接口提供了getAuditLogList
方法,根据的关键字段进行搜索。
public class AuditQueryDTO extends BaseQueryDTO {
// 请求者的IP
private String origin;
// actor信息
private String actor;
// method信息
private String action;
// 参数信息
private String elements;
// 开始时间
private Timestamp startTime;
// 结束时间
private Timestamp endTime;
}