概述
ReadAudit 是一项功能,其中出于审计目的记录了读取访问。你可以使用 @ReadAudit 注释实体 Bean,然后记录对这些 Bean 的读取事件(查询和 L2 缓存中的命中)。
通常需要实现 ReadAuditPrepare 接口。readAuditPrepare.prepare() 方法应使用用户上下文信息(用户 ID、用户 IP 地址等)填充 ReadEvent。
限制
SqlQuery 查询当前未记录到读取审计日志(RawSql 查询包含在读取审计中)。
开始
步骤 1:添加 @ReadAudit
向应该进行读取审计的所有实体 Bean 添加 @ReadAudit 注释。
@ReadAudit
@Entity
@Table(name = "customer")
public class Customer {
...
步骤 2:实现 ReadAuditPrepare
如果你跳过此步骤且不提供 ReadAuditPrepare 实现,则会使用“无操作”实现,并且不会填充用户上下文信息(用户 ID、用户 IP 地址等)。
class MyReadAuditPrepare implements ReadAuditPrepare {
@Override
public void prepare(ReadEvent event) {
// get user context information typically from a
// ThreadLocal or similar mechanism
String currentUserId = ...;
event.setUserId(currentUserId);
String userIpAddress = ...;
event.setUserIpAddress(userIpAddress);
event.setSource("myApplicationName");
// add arbitrary user context information to the
// userContext map
event.getUserContext().put("some", "thing");
}
}
步骤 3:注册 ReadAuditPrepare 实现
如果启用了类路径扫描,则可以自动检测 ReadAuditPrepare 的实现(就像找到实体 Bean 等一样)。也就是说,如果启用了扫描,则无需显式注册 ReadAuditPrepare 实现,而是会找到并实例化它。
如果未使用扫描或 ReadAuditPrepare 实现具有依赖项,并且其实例化应在 Ebean 外部执行,则可以使用 DatabaseConfig 显式注册它。
// example code explicitly registering the ReadAuditPrepare implementation
MyReadAuditPrepare readAuditPrepare = ...;
DatabaseConfig config = new DatabaseConfig();
...
// register explicitly here
config.setReadAuditPrepare(readAuditPrepare);
...
Database database = DatabaseFactory.create(config);
步骤 4:配置日志记录
ReadAuditLogger 的默认实现将查询计划条目记录到 io.ebean.ReadAuditQuery
,并将读取事件记录到 io.ebean.ReadAudit
。查询计划包含完整的 SQL,将这些内容单独记录意味着读取事件不必包含已执行的完整 SQL,而是可以使用 Bean 类型和查询键来引用/查找关联的 SQL。这减少了读取事件日志的体积/大小。
以下 logback xml 配置中有 2 个附加程序。READAUDIT_QUERY_LOG
用于记录查询计划,READAUDIT_LOG
用于记录读取 Bean 事件。
<!-- LOGBACK configuration: separate loggers for the read auditing -->
<appender name="READAUDIT_QUERY_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>log/readAuditQuery.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>log/readAuditQuery.log.%d{yyyy-MM-dd}</FileNamePattern>
<MaxHistory>90</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{HH:mm:ss.SSS} %msg%n</pattern>
</encoder>
</appender>
<appender name="READAUDIT_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>log/readAudit.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>log/readAudit.log.%d{yyyy-MM-dd}</FileNamePattern>
<MaxHistory>90</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{HH:mm:ss.SSS} %msg%n</pattern>
</encoder>
</appender>
<logger name="io.ebean.ReadAuditQuery" level="TRACE" additivity="false">
<appender-ref ref="READAUDIT_QUERY_LOG"/>
</logger>
<logger name="io.ebean.ReadAudit" level="TRACE" additivity="false">
<appender-ref ref="READAUDIT_LOG"/>
</logger>
可选:ReadAuditLogger 实现
如果默认日志不适合您,您可以实现 ReadAuditLogger 来控制如何记录事件。将日志记录到消息队列、直接记录到数据存储等。
Query.setDisableReadAuditing()
对于特定查询,您可以明确地将其从读取审核中排除。典型的用例是查询在应用程序内部用于填充缓存或处理海量数据,而您不希望将其写入读取审核日志。