我们在工作中无论如何都会使用到日志打印的需求,如果公司没有一个统一的日志采集平台,同时没有相关的规范的话,大家打印日志的话就会是这种方式,五花八门,例如:
对于上面这种日志的话,我们使用起来,如果系统出现问题,我们只能去服务器上查看log,并且这种log文件没有一个统一的标准,因此看起来非常的费劲,那么我们有没有什么好点的办法来统一规划一下日志,后期我们通过工具把这些日志采集到我们的平台里面去,然后通过搜索的功能,把对应的日志找出来即可。是不是很方便呢?
今天我们就来介绍下,使用日志框架统一采集日志,把日志全部做成对应的固定格式,后期我们再通过工具把日志存放到elasticsearch里面通过kibana可视化查询。下面直接进入正题。
使用的框架是:
bizlog-sdk
这个框架已经自定义了切面,我们直接拿过来用即可。下面介绍下如何使用。
一、创建一个类型为spring-boot的maven项目,并且添加如下依赖:
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.14.8</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.bgee.log4jdbc-log4j2</groupId> <artifactId>log4jdbc-log4j2-jdbc4.1</artifactId> <version>1.16</version> </dependency> <dependency> <groupId>io.github.mouzt</groupId> <artifactId>bizlog-sdk</artifactId> <version>3.0.1</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </dependency>
上面我们的依赖有点多,其实最主要的是添加bizlog-sdk这个依赖,同时由于可能会涉及到使用spring的el表达式,因此还需要添加spring-context的依赖。
二、向springboot的Application启动类添加注解
@EnableLogRecord(tenant = "com.log.demo")
添加的这个注解里面有一个tennant的值,主要是用来区分我们的项目或者业务的,常用的命名我们一般填写项目名即可。
三、在接口或者方法的地方添加注解
@LogRecord
示例如下:
@RequestMapping("/hello") @LogRecord(fail = "用户访问失败了", success = "{{#name}} 访问了hello接口,返回结果是:,{{#result}}", type = LogRecordType.HELLO, bizNo = "{{#requestId}}") public String hello(String requestId, String name) { String result = name + ",Hello World!"; LogRecordContext.putVariable("result", result); return result; }
四、启动项目,进行测试
访问:http://localhost:8080/hello?requestId=1&name=zhangsan
可以看到有具体日志打印出来。
此时我们就很容易的实现了日志打印的效果。
下面我们介绍下bizlog-sdk的详细使用教程。
1、在使用bizlog-sdk的时候,他的核心记录日志的注解是:@LogRecord,这个注解里面有哪些属性呢?
序号 | 属性 | 说明 |
1 | bizNo | 这个代表的就是流水号,一般我们一个请求默认生成一个流水号,在微服务的整体流程里面,我们需要保证数据的幂等性,因此每一个请求都应该要有一个唯一的流水号。 |
2 | type | 这个type可以自己命名,一般我们的使用主要是用来标注某一项业务,例如当前类是usercontroller,那么里面所有关联的方法都应该属于user,所以这里我们的type可以直接定义为user即可。 |
3 | success | 即代表调用成功需要输出什么,一般我们的场景里面我们可以在这里打印下请求参数,业务逻辑,流程逻辑,返回值等内容。 |
4 | fail | 即代表调用失败了需要输出什么,例如假设里面会出现异常等,我们一般可以在这里把整个方法里面的一些变量打印出来,以方便查找问题的原因 |
5 | operator | 操作人,一般假设有用户的场景的时候,我们可以在这个属性里面放用户的id |
6 | subType | 这个代表的是子类型,承接上面的type,例如:假设上面的type是用户,那么这里的subtype可以区分为,C端用户,B端用户。 |
7 | extra | 这里可以输出一些额外的值,例如我们在success里面打印的用户支付流程,那么在流程里面可能需要查询用户的当前余额,这时候余额与支付流程没有太大关系,我们就可以把余额信息打印到这个extra字段里面。 |
8 | condition | 是否记录日志的判断条件,一般我们不用这个字段。 |
9 | successCondition | 记录成功日志的条件,一般我们也不用这个字段。 |
2、打印输出的实体信息
序号 | 字段 | 说明 |
1 | id | 这个id我们一般可以不用管,几乎都是null |
2 | tenant | 这里代表的就是租户,就是我们在application里面添加@EnableLogRecord注解标记的时候填写的内容。 |
3 | type | 保存的操作日志的类型,比如:订单类型、商品类型 |
4 | subType | 日志的子类型 |
5 | bizNo | 日志绑定的业务标识 |
6 | operator | 操作人 |
7 | action | 日志内容,这里如果是成功的话,则打印的是成功的日志内容,如果是失败的话,则打印的是失败的日志内容 |
8 | fail | 这里代表的是当前日志属于成功的日志还是失败的日志 |
9 | createTime | 日志的创建时间 |
10 | extra | 额外的信息 |
11 | codeVariable | 日志的代码信息 |
3、关于取值的问题
在使用@LogRecord注解的时候,很多变量我们需要从方法里面去取值,那么怎么取呢?
1)所有的取值都必须添加 {{#变量名}},即双重大括号再加井号再加变量名为准。
2)如果去方法的传递参数可以直接取即可。
3)如果需要取方法内部的临时变量的值,则取值方式一样,但是需要在方法里面注册变量,例如:
LogRecordContext.putVariable("result", result);
4)如果变量是对象的话,需要取对象的属性值,则这么来取
{{#user.name}}
直接使用对象名.属性名即可。这也是spring的el表达式取值法。
备注:
1、使用此工具类的话,springboot需要使用2.x的版本,不然启动项目会报错 classnotfount。
当然最后我们提供下案例源码的下载,登录下即可看到
还没有评论,来说两句吧...