Java日志体系

对于任何一个编程语言或者框架来说,在编写代码时,日志都是必不可少的内容。日志不仅可以帮助开发者了解系统中出现的问题,也能够帮助开发者了解框架、程序是如何运行的。

比如,在Spring框架中,基本上大家都会用log日志来跟踪filter的执行顺序、spring的启动顺序等等。

但是日志并不代表是一种简单的文本输出,在很多场景下,程序对日志的输出目标、格式、位置、色彩、速度都有要求。因此,市面上有很多出名的框架,例如log4jlog4j2logbackjdk log等等。虽然他们当中最出名的几个,都是同一个人写的。。。

当种类变多功能变强的时候,选择就成为了一个问题。如何选择一个好用的、好记的日志框架,以及如何快速的适配各种系统需要开发人员去考虑。

此篇将会记录Java的日志体系,一些场景下的选择和常用配置。


什么是日志体系

那么什么是日志体系呢?我们都知道面向接口编程,由大佬们定义接口规范,小的们去实现。这样程序跑起来的时候,可以不在意究竟是哪一个实现承担的任务。举个例子。

就像你拨打别人的手机,你只需要拨出号码,不需要在意对方是电信、移动、联通或者是小米之类的通讯商。这就是他们都符合可拨打的规范带来的好处。

日志系统也是这样,不需要在意你用了什么日志框架,无论是log4jlogback或者是jdk原生的java.util.logger,都能够被log日志的规范所兼容。

那么,你想要打印日志的时候,你只需要调用log.info("hello")就可以打印"hello"。**而且,当你需要从一个框架迁移到另外一个日志框架的时候,只需要把依赖的日志框架jar包换进来,就立即生效。

而这个规范、规范的实现加上日志框架,就成为了日志体系。

在日常,最常见的和最著名的两种日志体系分别是基于JCL的日志体系和基于Slf4j的日志体系。


基于jcl日志体系

jcl日志体系的接口规范由commons-logging提供,这是apache commons系列的工具包之一。Apache commons系列的工具包都非常有用,比如流操作、文件复制、加密解密之类的常用操作,都可以直接找到完善的解决方案。。。具体的操作晚上有很多的介绍,如果你想要知道他一共有多少种,可以直接去Maven仓库中搜索一下org.apache.commons看看。

commons-logging已经停止更新,最后的状态如下所示:

jcl architecture

具体的使用。。。因为我已经不用了,所以可以参考其他的使用教程:

需要注意的是jcl是存在一定缺陷的,这也是为什么现在大多数都使用slf4j作为接口规范。


基于slf4j日志体系

slf4j的历程也是非常的传奇,有兴趣的可以去搜索看看。
写了log4j、log4j2、slf4j、logback的传奇日志作者。。。Ceki

slf4j的全称为Simple Logging Facade For Java,从下图可见,slf4j的能耐比jcl大得多,基本上覆盖了所有出名的(自己写的...)日志框架。

slf4j architecture.png

slf4j的使用和jcl的使用没有太大的差异,如下所示:

    //声明日志对象,Logger的全限定名为
 org.slf4j.Logger 而不是 java.util.Logger
    static  Logger log = LoggerFactory.getLogger(Log02Application.class);
    //简单的测试方法
    public static void main(String[] args) {
        log.info("hello log");
    }

具体的案例我们通过整合来介绍:

整合springboot

在springboot中,默认使用了logback作为日志框架。默认的输出如下所示:

2017-11-29 12:58:17.757  INFO 47280 --- [  restartedMain] cn.hhchat.log02.Log02Application         : hello log

但是当然你可以自己配置,配置文件放在resources文件目录下即可,springboot会自动按顺序搜寻下列文件。

  • Logback:logback-spring.xml, logback-spring.groovy, logback.xml, logback.groovy
  • Log4j:log4j-spring.properties, log4j-spring.xml, -
    log4j.properties, log4j.xml
  • Log4j2:log4j2-spring.xml, log4j2.xml
  • JDK (Java Util Logging):logging.properties

使用log4j2

由于springboot默认使用了logback,因此当你试图使用log4j2的时候,你需要先剔除logback

<!--从spring-boot-starter中剔除logging,该依赖如果没有的话,可以直接把整个依赖粘上,如果依赖已经存在,只需要添加<exclustions>中间的内容即可。-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<!--引入log4j2-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

整合spring

log4j2配置

日志的配置一直是一个大麻烦,因为每次都要导出翻博客来找,虽然之前看过官方的文档,但是现在也记不太清了,所以整理一下思路,记录一个普遍可用的方式供以后复制使用。

下面是配置的基本步骤:

log4j2配置

首先,你需要先配置一个Logger,logger定义了该logger配置使用的包和日志级别、输出到什么位置等等内容,之后配置Appender,appender表示的是你需要将日志输出到什么文件以及输出的格式。

logback配置

<configuration>
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss} [%thread] [%-5level] %logger{36} - %msg%n</pattern>
            <charset>utf8</charset>
        </encoder>
    </appender>
    <appender name="fileLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <File>log/base.log</File>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>log/base.log.%d.%i</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <!-- or whenever the file size reaches 64 MB -->
                <maxFileSize>64 MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>                       
        </rollingPolicy>
        <encoder>
            <pattern>
                %d %p (%file:%line\)- %m%n
            </pattern>
            <charset>UTF-8</charset> <!-- 此处设置字符集 -->
        </encoder>
    </appender>
    <root level="info">
        <appender-ref ref="CONSOLE" />  
    </root>
    <!--<logger name="com.example" level="DEBUG">-->
    <!--<appender-ref ref="baselog" />-->
    <!--</logger>-->
</configuration>

如果后续用到更多的日志需求,再回来补充,最近看到黄勇的架构探险上对于日志体系的分析,有很多很有意思的东西

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,295评论 6 512
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,928评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,682评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,209评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,237评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,965评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,586评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,487评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,016评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,136评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,271评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,948评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,619评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,139评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,252评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,598评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,267评论 2 358

推荐阅读更多精彩内容