Java日志框架:logback详解

为什么使用logback

记得前几年工作的时候,公司使用的日志框架还是log4j,大约从16年中到现在,不管是我参与的别人已经搭建好的项目还是我自己主导的项目,日志框架基本都换成了logback,总结一下,logback大约有以下的一些优点:

  • 内核重写、测试充分、初始化内存加载更小,这一切让logback性能和log4j相比有诸多倍的提升
  • logback非常自然地直接实现了slf4j,这个严格来说算不上优点,只是这样,再理解slf4j的前提下会很容易理解logback,也同时很容易用其他日志框架替换logback
  • logback有比较齐全的200多页的文档
  • logback当配置文件修改了,支持自动重新加载配置文件,扫描过程快且安全,它并不需要另外创建一个扫描线程
  • 支持自动去除旧的日志文件,可以控制已经产生日志文件的最大数量

总而言之,如果大家的项目里面需要选择一个日志框架,那么我个人非常建议使用logback。

logback加载

我们简单分析一下logback加载过程,当我们使用logback-classic.jar时,应用启动,那么logback会按照如下顺序进行扫描:

  • 在系统配置文件System Properties中寻找是否有logback.configurationFile对应的value
  • 在classpath下寻找是否有logback.groovy(即logback支持groovy与xml两种配置方式)
  • 在classpath下寻找是否有logback-test.xml
  • 在classpath下寻找是否有logback.xml

以上任何一项找到了,就不进行后续扫描,按照对应的配置进行logback的初始化,具体代码实现可见ch.qos.logback.classic.util.ContextInitializer类的findURLOfDefaultConfigurationFile方法。

当所有以上四项都找不到的情况下,logback会调用ch.qos.logback.classic.BasicConfigurator的configure方法,构造一个ConsoleAppender用于向控制台输出日志,默认日志输出格式为”%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} – %msg%n”。

logback的configuration

logback的重点应当是Appender、Logger、Pattern,在这之前先简单了解一下logback的

  • scan:当scan被设置为true时,当配置文件发生改变,将会被重新加载,默认为true
  • scanPeriod:检测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认为毫秒,当scan=true时这个值生效,默认时间间隔为1分钟
  • debug:当被设置为true时,将打印出logback内部日志信息,实时查看logback运行信息,默认为false

先从最基本的

****。

  • name:用来指定受此logger约束的某一个包或者具体的某一个类
  • level:用来设置打印级别,五个常用打印级别从低至高依次为TRACE、DEBUG、INFO、WARN、ERROR,如果未设置此级别,那么当前logger会继承上级的级别
  • additivity:是否向上级logger传递打印信息,默认为true

Logger的构造函数为:

看到第一个参数就是Root的name,而这个Logger.ROOT_LOGGER_NAME的定义为 final public String ROOT_LOGGER_NAME = “ROOT”,由此可以看出

接着写一段代码来测试一下:

logback.xml的配置为:

root将打印级别设置为”info”级别,

logback.xml的意思是,当Test方法运行时,root节点将日志级别大于等于info的交给已经配置好的名为”STDOUT”的

接着理解一下

注意这个 name表示的是LoggerFactory.getLogger(XXX.class),XXX的包路径,包路径越少越是父级,我们测试代码里面是Object.class,即name=”java”是name=”java.lang”的父级,root是所有

出现这样的结果是因为:

*
* 没有配置additivity,那么additivity=true,表示此
* 没有配置

由此可知,

接着,我们再配置一个

如果读懂了上面的例子,那么这个例子应当很好理解:

  • LoggerFactory.getLogger(Object.class),首先找到name=”java.lang”这个
  • name=”java.lang”这个
  • name=”java”这个

由此分析,得出最终的打印结果为:

举一反三,上面的name=”java”这个

接着看一下

  • name指定
  • class指定

其中,encoder表示对参数进行格式化。我们和上一部分的例子对比一下,发现这里是有所区别的,上面使用了

*
* 最常用的FileAppender和它的子类的期望是使用

关于

它的几个节点为:

*
*
*

接着来看一下RollingFileAppender, RollingFileAppender的作用是滚动记录文件,先将日志记录到指定文件,当符合某个条件时再将日志记录到其他文件,RollingFileAppender配置比较灵活,因此使用得更多,示例为:

这种是仅仅指定了

*

向其他还有SizeBasedTriggeringPolicy,用于按照文件大小进行滚动,可以自己查阅一下资料。

异步写日志

日志通常来说都以文件形式记录到磁盘,例如使用

接着我们看下如何使用logback进行异步写日志配置:

即,我们引入了一个AsyncAppender,先说一下AsyncAppender的原理,再说一下几个参数:

从上述原理,我们就能比较清晰地理解几个参数的作用了:

  • discardingThreshold,假如等于20则表示,表示当还剩20%容量时,将丢弃TRACE、DEBUG、INFO级别的Event,只保留WARN与ERROR级别的Event,为了保留所有的events,可以将这个值设置为0,默认值为queueSize/5
  • queueSize比较好理解,BlockingQueue的最大容量,默认为256
  • includeCallerData表示是否提取调用者数据,这个值被设置为true的代价是相当昂贵的,为了提升性能,默认当event被加入BlockingQueue时,event关联的调用者数据不会被提取,只有线程名这些比较简单的数据
  • appender-ref表示AsyncAppender使用哪个具体的

  • 把日志信息转换为字节数组

  • 把字节数组写到输出流

目前PatternLayoutEncoder是唯一有用的且默认的encoder,有一个

c{length}

lo{length}

logger{length}

输出日志的logger名称,可有一个整型参数来缩短

1、不输入表示输出完整的

2、输入0表示只输出

3、输入其他数字表示输出小数点最后边点号之前的字符数量

C{length}

class{length}

d{pattern}

date{pattern}

msg

message

level

relative

thread

看到最后一列是”是否避免使用”,这是因为这些信息是无法直接拿到的(比如请求行号、调用方法名),logback必须通过一些特殊手段去获取这些数据(比如在日志打印出产生一个堆栈信息),这种操作会比较影响效率,因此除非必要,否则不建议打印这些数据。

Filter

最后来看一下

看一下输出:

看到尽管

再看一下ThresholdFilter,配置为:

看一下输出为:

因为ThresholdFilter的策略是,会将日志级别小于

Original: https://www.cnblogs.com/xrq730/p/8628945.html
Author: 五月的仓颉
Title: Java日志框架:logback详解

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/538345/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 自定义MyBatis

    一. 原生 JDBC 1. 原生JDBC使用 public static void main(String[] args) { Connection conn = null; Pr…

    Java 2023年6月5日
    095
  • 你不知道的PageContext

    你不知道的PageContext 最近在文艺复兴,学习JSP和Servlet,此文为笔者学习记录。 本文分为以下几个部分: 前言 环境搭建 正文 总结 前言 在我们使用的项目中,存…

    Java 2023年6月5日
    090
  • druid数据源手动创建

    手动创建druid数据源,可以使用jdbc或者通过aspect进行多数据源的动态切换 通过md5加密创建唯一key,在key重复时不进行创建, 创建的数据源可以通过dataSour…

    Java 2023年6月16日
    059
  • Java指令重排序在多线程环境下的应对策略

    指令重排在单线程环境下有利于提高程序的执行效率,不会对程序产生负面影响;在多线程环境下,指令重排会给程序带来意想不到的错误。 本文对多线程指令重排问题进行复原,并针对指令重排给出相…

    Java 2023年6月6日
    086
  • RabbitMQ

    RabbitMQ 六大模式 Hello Word 消息提供者 消息消费者 Work Queues 抽取工具类 Consumer 消息发送者 消息应答 自动应答 手动应答 消息重新入…

    Java 2023年6月13日
    080
  • spring boot RocketMQ 集成

    RocketMQ学习 1.基本概念 RocketMQ是阿里巴巴团队使用java语言开发的一款分布式消息中间件,是一款低延迟,高可用,拥有海量消息堆积能力和灵活拓展性的消息队列。 r…

    Java 2023年6月5日
    082
  • 数据结构——稀疏数组

    数据结构——稀疏数组 棋局存档问题:如何将一局五子棋保存下来,并实现读档 利用稀疏数组进行数据保存,IO流写入/读取文件,实现读档。 简单代码实现: /** * @author 萝…

    Java 2023年6月9日
    087
  • 通过route , tracert , traceroute 查看本地路由配置及访问ip或域名时经过的路由信息

    转载请注明出处: 1.路由器和交换机的区别和过程 在windows 系统或linux 系统访问 外网ip 或域名时,都会通过层层的路由器,然后将请求转发到最终的目标服务器;因为互联…

    Java 2023年6月8日
    067
  • 抵达心之自由

    如水涟漪,如树伫立,如草柔韧。 自由来自智慧。 你眼前所见即为真,所不见亦为真。假从何来?假并不存在于事物中,而是存在于标准中。 挣脱了标准的枷锁,就获得了第一层自由; 当深明生命…

    Java 2023年6月9日
    084
  • 网络编程(TCP协议)

    TCP协议发送数据 A:创建Socket对象—利用Socket对象 B:获取输出流,写数据 C:释放资源 TCP协议接受数据 A:创建Socket接受对象 B:监听客户…

    Java 2023年6月5日
    089
  • 最长公共子序列

    很久之前就有研究这个算法 结果忘记上传了 哈哈 前天看到好多同学需要这个算法 所以 来吧 写一写 先来看下 什么是公共子序列 我直接来一张图 相信大家就明白了 当然 图片是百度到的…

    Java 2023年6月5日
    0101
  • Spring Boot + Spring Cloud 实现权限管理系统 后端篇(二十三):配置中心(Config、Bus)

    在线演示 演示地址:http://139.196.87.48:9002/kitty 用户名:admin 密码:admin 技术背景 如今微服务架构盛行,在分布式系统中,项目日益庞大…

    Java 2023年5月30日
    094
  • java发送post请求,使用multipart/form-data的方式传递参数–《优化》

    /** * 测试上传图片 * */ public static void testUploadImage(){ String url = "http://xxxtest/…

    Java 2023年5月29日
    0102
  • java中线程的几种实现方式

    继承Thread类来实现 由于在java中采用单继承的模式,因此继承Thread类有一个明显的缺点就是占用了唯一的extends,是的我们无法在继承其它的类,因此一般不会采用这种方…

    Java 2023年6月6日
    089
  • 链表算法题解题技巧归纳总结

    最近集中刷了一批链表的题型,在这里总结一下解题技巧,以及对应题目的解题思路。 解题思路并不会细致入微,主要是为了总结归类,并且希望用几句话来激发灵感,权当是没思路时的指引以及以后复…

    Java 2023年6月5日
    066
  • Windows 下 Nginx 配置 多个conf 文件的过程与注意事项

    Windows 下配置 Nginx 使用多个conf 文件的Include 路径与Linux 有所不同。 如上: Windows : include ../conf.d/*.con…

    Java 2023年5月30日
    084
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球