成都专业网站设计免费咨询,下载天眼查企业查询官网,闽侯网站建设,网站开发维护合同书插#xff1a; AI时代#xff0c;程序员或多或少要了解些人工智能#xff0c;前些天发现了一个巨牛的人工智能学习网站#xff0c;通俗易懂#xff0c;风趣幽默#xff0c;忍不住分享一下给大家(前言 – 人工智能教程 ) 坚持不懈#xff0c;越努力越幸运#xff0c;大家… 插 AI时代程序员或多或少要了解些人工智能前些天发现了一个巨牛的人工智能学习网站通俗易懂风趣幽默忍不住分享一下给大家(前言 – 人工智能教程 ) 坚持不懈越努力越幸运大家一起学习鸭~~~ 一、配置入口
Logback支持XML、Groovy的配置方式以XML来说它会默认查找resources目录下的logback-test.xml用于测试/logback.xml文件。
而如果你使用的Spring Boot那么你还可以使用logback-spring.xml文件进行配置。这两者的区别是
logback-spring.xml是由 Spring Boot 找到插入自己的上下文信息[1]并做进一步处理后再传递给Logback的你可以在其中使用springProfile区分环境配置也可以使用springProperty拿到Spring上下文信息比如spring.application.name。logback.xml是由Logback自己找到的自然不会有Spring Boot相关的能力。
二、配置文件介绍
接下来我们以logback-spring.xml为例进行介绍。一个Logback配置文件主要有以下几个标签
confinuration最外层的父标签其中有几个属性配置但项目中较少使用就不啰嗦了property定义变量appender负责日志输出一般是写到文件我们可以通过它设置输出方案logger用来设置某个LoggerName的打印级别rootlogger的兜底配置从而我们不必配置每个LoggerNameconversionRule定义转换规则参考【四、Java API】 2.1 springProperty 和 property 前文提到springProperty用来插入Spring上下文那property就是 Logback 自己定义变量的标签。直接看示例
springProperty scopecontext nameAPP_NAME sourcespring.application.name/property nameLOG_PATH value${user.home}/${APP_NAME}/logs/
property nameAPP_LOG_FILE value${LOG_PATH}/application.log/
property nameAPP_LOG_PATTERNvalue%date{yyyy-MM-dd HH:mm:ss.SSS}|%-5level|%X{trace_id}|%thread|%logger{20}|%message%n%exception/
我们首先用springProperty插入APP_NAME这个变量来表示应用名随后用它拼出LOG_PATH变量。示例中还用到了${user.home}这个Logback内建支持的上下文变量[2]。APP_LOG_FILE是log文件路径APP_LOG_PATTERN是日志格式请参考【三、占位符】节。 2.2 appender 这一节涉及到的知识点很多但一码胜千言先直接给出示例
appender nameAPPLICATION classch.qos.logback.core.rolling.RollingFileAppenderfile${APP_LOG_FILE}/fileencoderpattern${APP_LOG_PATTERN}/pattern/encoderrollingPolicy classch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicyfileNamePattern${APP_LOG_FILE}.%d{yyyy-MM-dd}.%i/fileNamePatternmaxHistory30/maxHistorymaxFileSize200MB/maxFileSizetotalSizeCap10GB/totalSizeCap/rollingPolicy
/appender
appender nameAPPLICATION-async classch.qos.logback.classic.AsyncAppenderqueueSize256/queueSizediscardingThreshold0/discardingThresholdneverBlocktrue/neverBlockappender-ref refAPPLICATION/
/appender
示例中涉及的变量在上一节已经提到这里不啰嗦了。需要关注的是以下几个点
ch.qos.logback.core.rolling.RollingFileAppender负责将日志滚动打印避免单文件体积过大。具体的滚动策略都在rollingPolicy中指定各配置项都还算好理解。ch.qos.logback.classic.AsyncAppender负责将日志异步打印避免大量打印日志时阻塞线程。
除了上边这两个还有如ch.qos.logback.core.ConsoleAppender是用来将日志输出到控制台如果你用到了建议参考【下一篇九、不要将日志输出至Console】节。
更多Appender和RollingPolicy相关的介绍可以参考官方文档Chapter 4: Appenders[3]。 2.3 logger和root logger用来设置某个LoggerName的打印级别。比如
logger levelINFO additivityfalse namecom.foo.barappender-ref refAPPLICATION-async/
/logger
root levelINFOappender-ref refAPPLICATION-async/
/root
上面的配置指定所有LoggerName为com.foo.bar的日志以INFO级别进行打印TRACE和DEBUG级别将不会输出此配置绑定的输出器appender为APPLICATION-async。
其中LoggerName会以 . 为分隔符逐级向上匹配比如实际LoggerName为com.foo.bar.service.ExampleService那么它的查找过程依次为
com.foo.bar.service.ExampleServicecom.foo.bar.servicecom.foo.bar此时命中了我们示例中的logger另外因为配置了additivityfalse 所以停止继续向下查找com.foocomroot
而 root就是兜底配置了当LoggerName没匹配到任何一项logger 时就会使用 root所以它是没有additivity和name属性的。
一般实际业务场景中所有logger都建议加上additivityfalse 否则日志就会因查找到多个logger或root而打印多份。 2.4 springProfile Spring还提供了springProfile标签用来根据Spring Profiles[4]即 spring.profiles.active的值动态调整日志信息比如我们希望线上环境使用INFO级别而预发、日常使用TRACE级别
springProfile nameproductionroot levelINFOappender-ref refAPPLICATION-async//root
/springProfile
springProfile namestaging,testingroot levelTRACEappender-ref refAPPLICATION-async//root
/springProfile
三、占位符 3.1 Conversion Word Logback提供了大量有用的占位符给大家使用官方文档在Conversion Word[5]。
比如一些常用的占位符大部分占位符都有缩写形式比如%logger可以简写为%c我不在这里一一列举了具体可以查看上边给出的官方文档 占位符 说明 %logger 输出LoggerName参考【第三篇1.1 工厂函数】节 %message 输出你实际要打印的日志信息参考【第三篇3.1 info方法】节 %exception 输出异常堆栈对应通过Slf4j传入的异常参考【第三篇3.1 info方法】节 %level 输出日志级别即TRACE/DEBUG/INFO/WARN/ERROR/FATAL。 注意这里有别于Slf4j参考【第三篇二、日志级别】多了个FATAL级别这是为了适配Log4j而存在的。 %xException 输出异常堆栈同时包含每行堆栈所归属的JAR包名 %marker 输出通过Marker参考【第三篇四、Marker】节传入的字符串 %mdc 输出MDC参考【第三篇五、MDC】节中对应的值 %kvp 输出通过addKeyValue参考【第三篇六、Fluent API 链式调用】节传入的KV对 %date 输出时间可以添加符合ISO 8601[6]的参数指定输出格式比如我们常用的yyyy-MM-dd HH:mm:ss %thread 输出打印日志方法所在的线程名 %n 输出一个换行符 %replace(p){r, t} 将p中的r替换为tr为正则。请参考【第五篇七、将堆栈合并为一行】节 %nopex 忽略传入的堆栈不打印。请参考【第五篇七、将堆栈合并为一行】节 Logback会判断你的日志pattern如果没有输出堆栈会默认追加%exception以保证传入的异常信息不会丢。这个占位符就是明确要求不做追加。
另外针对%logger额外做一下补充。%logger的参数中可以传一个正整数用于指定输出长度当LoggerName长度超过限制时Logback会以 . 为分隔智能缩短。假设LoggerName是com.example.foo.bar.ExampleService这个字符串长度为34那么 配置 输出结果 说明 [%logger] [com.example.foo.bar.ExampleService] 原样输出 [%logger{32}] [c.example.foo.bar.ExampleService] 实际长度32与限制值一致 [%logger{30}] [c.e.foo.bar.ExampleService] 实际长度26比限制值小。因为每一级 package要么保留原样要么只取第一个字符 [%logger{10}] [c.e.f.b.ExampleService] 实际长度20比限制值大。因为每一级 package至少会保留一个字符且最后一级不会被缩短 [%logger{0}] [ExampleService] 0比较特殊表示只保留最后一级且不会被缩短 3.2 Format modifiers 从前边我们可以看到占位符的基本使用方式是%占位符{参数}但其实还有一个用于控制格式的可选配置可以放在%与占位符之间叫作Format modifiers[7]。一个完整的格式配置包含五个部分比如-10.-20我们分别解释
-第一个-表示不足最小长度时在右侧填充空格即输出内容左对齐默认是在左侧填充空格即右对齐10第一个数字表示输出最小长度不足的补空格.与后边两项配置的分隔符本身没有含义-第二个-表示超过最大长度时先裁剪右侧即保留左侧字符默认先裁剪左侧即保留右侧字符20第二个数字表示输出最大长度超出部分会做裁剪
举个几个例子 配置 文本 输出结果 说明 [%5level] INFO [ INFO] 最小5个字符右对齐 [%-5level] INFO [INFO ] 最小5个字符左对齐 [%.-1level] INFO [I] 最大1个字符优先保留左侧字符 [%-5,-10logger] com.foo.bar.Service [com.foo.ba] 最大10个字符优先保留左侧字符 [%-5,10logger] com.foo.bar.Service [ar.Service] 最大10个字符优先保留右侧字符
四、Java API
除了使用XML配置文件外Logback还提供了大量的Java API[8]以支持更复杂的业务诉求。我们通过三个非常实用的场景来简单介绍一下。
场景一使用log.info(obj{}, obj) 时如何将obj统一转JSON String后输出场景二日志中涉及到的手机号、身份证号如何脱敏后再记录日志场景三Logback配置基于XML如何不改代码不发布也可以动态修改日志级别
其中前两个问题都可以通过MessageConverter[9]实现因为篇幅原因具体介绍可关注后续文章。
第三个问题可以借助LoggerContext[10]及Logger[11]同样因为篇幅原因具体介绍可关注后续文章。
五、MDC 中的 traceId
单独拿出一节讲这个是因为我发现有很多同学会手动记录traceId比如
log.info(traceId{}, blah blah blah, Span.current().getSpanContext().getTraceId());
其实OpenTelemetry[12]已经自动将traceId加到了MDC对应的Key是trace_id使用%mdc{trace_id}参考【第三篇五、MDC】节即可打印出traceId。比如我们在【2.1 springProperty和property】一节的示例中就使用了这个Key。
六、后记
以上只是简单介绍了Logback的常用功能如需进一步了解可以参考官方文档Logback documentation[13]。特别是其中很多例子是结合Slf4j一起介绍的非常易懂。