# OperationLog 操作日志

MornBoot提供通用的注解及处理接口,完成对操作日志的声明和处理。

  • 内置日志注解
  • 支持日志变量
  • 统一处理接口
  • 支持异步存储

Since:v1.0.0

# 必要配置

SpringBootApplication

@EnableOperateLog // 开启操作日志(1.2.2版本以后,含1.2.2)

application.properties

#开启操作日志(1.2.2版本以前,不含1.2.2)
morn.operate.enabled=true

# 简易模式(Simple)

# 推荐配置

application.properties

#简易模式记录(默认)
morn.operate.mode=simple
#异步处理(默认)
morn.operate.async=true

# 操作日志注解

  1. 使用@OperateGroup注解描述模块信息。
  2. 使用@OperateAction注解描述接口信息。
  3. 使用OperateArguments线程变量记录日志变量。

@Component
@OperateGroup("用户管理") // 描述操作模块,此处为用户模块
public class TestUserController {

  @OperateAction("新增用户:{0}") // 描述操作类型,此处为新增用户
  public Map<String, Object> addUser(Map<String, Object> user) {
    OperateArguments.add(user.get("username")); // 记录日志参数
    return user;
  }

  @OperateAction("更新用户:{1},年龄:{0}") // 描述操作类型,此处为更新用户
  public Map<String, Object> updateUser(Map<String, Object> user) {
    OperateArguments.add(user.get("age")); // 记录日志参数
    OperateArguments.add(user.get("username")); // 记录日志参数
    throw new RuntimeException("异常测试"); // 抛出异常后,日志会记录为操作失败
  }
}

# 处理操作日志

实现OperationProcessor接口,以处理操作日志。

注意:必须使用@Objective或其它实体增强注解,否则OperationProcessor不会生效。


@Slf4j
@Component
@Objective
public class TestOperationProcessor implements OperationProcessor {

  @Override
  public void handle(OperateMeta operateMeta, Operation operation) {
    log.info("{},消耗时间:{}ms", operation.getContent(), operation.getDuration());
    log.info("方法参数:" + JsonParsers.parseString(operateMeta.getMethodArgs()));
    log.info("方法返回值:" + JsonParsers.parseString(operateMeta.getMethodReturned()));
    if (operateMeta.getThrowable() != null) {
      log.info("异常信息:" + JsonParsers.parseString(operateMeta.getThrowable().getMessage()));
    }
  }
}

OperateMeta中记录了上下文信息,如切点、入参、返回值等。
Operation中记录了操作实体信息,如操作时间、操作内容等。其中:
success:正常为true,业务代码抛出异常时,则为false

注意:操作日志状态与业务代码是否抛出异常直接相关,若异常被捕获,则会标记为操作成功。

# 结果示例

例一:新增用户的操作日志

新增用户:Caramel,消耗时间:17ms
方法参数:[{"password":"123456","username":"Caramel"}]
方法返回值:{"code":"success","level":"info","message":"操作成功","status":200}

例二:更新用户的操作日志

更新用户:Mocha,年龄:16,消耗时间:0ms
方法参数:[{"age":"16","username":"Mocha"}]
方法返回值:null
异常信息:异常测试

# 国际化模式(I18n)

国际化模式的日志文本在资源文件中编写,也可于日志文本和代码分离。

# 推荐配置

application.properties

#国际化模式记录
morn.operate.mode=i18n
#异步处理(默认)
morn.operate.async=true
#开启国际化
morn.translator.enabled=true
#国际化资源文件
spring.messages.basename=morn/operation

# 操作日志注解

与简易日志略有区别,模块名称和接口名称使用英文代称。


@Component // Spring容器扫描
@OperateGroup("user") // 描述操作模块,此处为用户模块
public class TestUserController {

  @OperateAction("add") // 描述操作类型,此处为新增用户
  public Map<String, Object> addUser(Map<String, Object> user) {
    OperateArguments.add(user.get("username")); // 记录日志参数
    return user;
  }

  @OperateAction("update") // 描述操作类型,此处为更新用户
  public Map<String, Object> updateUser(Map<String, Object> user) {
    OperateArguments.add(user.get("age")); // 记录日志参数
    OperateArguments.add(user.get("username")); // 记录日志参数
    throw new RuntimeException("异常测试"); // 抛出异常后,日志会记录为操作失败
  }
}

# 国际化配置

修改国际化资源文件:morn/operation.properties。若有其它语言,修改对应资源文件即可。如:

  • 英语:morn/operation_en.properties
log.user.add=新增用户:{0}
log.user.update=更新用户:{0},年龄:{1}

# 结果示例

例一:新增用户的操作日志

新增用户:Latte,消耗时间:17ms
方法参数:[{"password":"123456","username":"Latte"}]
方法返回值:{"code":"success","level":"info","message":"操作成功","status":200}

例二:更新用户的操作日志

更新用户:Latte,年龄:19,消耗时间:0ms
方法参数:[{"age":"19","username":"Latte"}]
方法返回值:null
异常信息:异常测试

# 配置说明

morn.operate.async的值为true时,OperationProcessor(日志处理接口)将另起线程异步执行。

  • 每次调用@OperateAction标注的方法,都会另起一个线程。同一时间内新增线程数与调用次数相同。
  • 一次调用触发多个OperationProcessor,不会影响线程数。
  • 默认使用SpringBoot内置线程池,具体配置参考TaskExecution (opens new window)