日志

业务系统通常会对用户的操作进行记录,大多系统的设计会把日志的记录部分直接放到业务逻辑里,concrete提出按照AOP的思想剥离用户操作日志与业务的耦合。

Note

日志这部分的设计,我个人始终不太满意,希望各位读者有好的建议在github上给我提issue,或者mail

体验

截止到目前的示例代码中,只有RBAC部分涉及到了用户操作,我们就以此为例进行演示。

package org.coodex.concrete.demo.api.excepted;

import org.coodex.concrete.api.ConcreteService;
import org.coodex.concrete.api.LogAtomic;

@ConcreteService
public interface DemoLoginService {

    @LogAtomic(message = "登录", loggingType = LogAtomic.LoggingType.ALWAYS)
    void login(String id);
}
package org.coodex.concrete.demo.api.excepted;

import org.coodex.concrete.api.AccessAllow;
import org.coodex.concrete.api.ConcreteService;
import org.coodex.concrete.api.Description;
import org.coodex.concrete.api.LogAtomic;
import org.coodex.concrete.demo.pojo.Book;

@ConcreteService(
        value = "Books",
        nonspecific = true // 抽象的服务,此服务不会直接发布,concrete只会发布具体的服务
)
@AccessAllow(roles = "图书管理员") // 此服务的接口需要图书管理员角色,AccessAllow也可以用来修饰具体服务接口
public interface AbstractLibrary<B extends Book> {

    @Description(name = "销毁一本书", description = "够狠")
    @ConcreteService("{name}")
    @LogAtomic(category = "library", subClass = "delete") // <- log定义
    void delete(String name);

    @Description(name = "整理书架")
    @LogAtomic(category = "library", subClass = "sort") // <- log定义
    void sort();
}

i18n/library.yml

library:
  delete: "${book.name} 被删除了"
  sort: "整理并摧毁了 ${count} 本书"

我们这次用到的是Freemarker的渲染模板,所以,需要把这个插件加入进来

        <!-- freemarker 的 formatter 插件 -->
        <dependency>
            <groupId>org.coodex</groupId>
            <artifactId>concrete-formatters-freemarker</artifactId>
        </dependency>

concrete.yml

interceptors:
  log: true # 开启限流拦截器
    // 使用 freemarker 的 formatter
    @Bean
    public FreemarkerLogFormatter freemarkerLogFormatter(){
        return new FreemarkerLogFormatter();
    }

实现中把数据放入到Log上下文里

    @Override
    public void delete(String name) {
        if (getBooks().containsKey(name)) {
            Book book = getBooks().remove(name);
            getLoggingData().put("book", book);
            log.info("{} {} 把 {} 图书[{}]销毁了。", getAttr(), getAccountName(), getType(), book);
        } else {
            log.info("nothing happened.");
        }
    }

    @Override
    public void sort() {
        int count = getBooks().size();
        getBooks().clear();
        if(count > 0){
            getLoggingData().put("count", count);
        }
        log.info("哦嚯,{} {} 把 {} 图书全部销毁了。", getAttr(), getAccountName(), getType());
    }

默认的Log使用slf4j的INFO级别输出信息,我们只看OperationLogInterceptor的信息如下

2019-08-08 20:04:10.331  INFO 17012 --- [vice.executor-1] o.c.c.c.i.OperationLogInterceptor        : accountId: A; accountName: 大侠A; category: null; subClass: login; message: 登录
2019-08-08 20:04:10.461  INFO 17012 --- [vice.executor-2] o.c.c.c.i.OperationLogInterceptor        : accountId: A; accountName: 大侠A; category: library; subClass: delete; message: A1 被删除了
2019-08-08 20:04:10.478  INFO 17012 --- [vice.executor-3] o.c.c.c.i.OperationLogInterceptor        : accountId: A; accountName: 大侠A; category: library; subClass: sort; message: 整理并摧毁了 8 本书
2019-08-08 20:04:10.708  INFO 17012 --- [vice.executor-6] o.c.c.c.i.OperationLogInterceptor        : accountId: B; accountName: 大侠B; category: null; subClass: login; message: 登录
2019-08-08 20:04:10.783  INFO 17012 --- [vice.executor-8] o.c.c.c.i.OperationLogInterceptor        : accountId: B; accountName: 大侠B; category: library; subClass: delete; message: B1 被删除了
2019-08-08 20:04:10.794  INFO 17012 --- [vice.executor-9] o.c.c.c.i.OperationLogInterceptor        : accountId: B; accountName: 大侠B; category: library; subClass: sort; message: 整理并摧毁了 8 本书
2019-08-08 20:04:10.822  INFO 17012 --- [ice.executor-11] o.c.c.c.i.OperationLogInterceptor        : accountId: C; accountName: 特权大佬; category: null; subClass: login; message: 登录

注意一下,我们并没有看到特权大佬除了登录以外的日志,因为这两个LogAtomic的设置里是有数据才记录,而实现逻辑上,他并没有操作任何数据,所以没有需要记录的日志数据产生。

扩展

  • LogFormatter: 基于指定模板进行数据格式化
  • OperationLogger: 如何记录日志
(ɔ) coodex.org 2016 - 2020            修订时间: 2020-03-09 02:56:41

results matching ""

    No results matching ""