打日志那些事儿

打日志那些事儿

1 SLF4J

1.1 门面(外观)模式

门面模式(Facade Pattern),隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性。
在这里插入图片描述

1.2 SLF4J介绍

SLF4J(Simple Logging Facade for Java)是Java的一个日志门面,提供了一组通用的接口,但未提供实现。常用的实现有Logback、log4j等。使用门面模式的好处是,我们不需要关注日志底层是怎么实现的,只需要会调用接口就行。另外,在系统更换底层日志实现类时,无须修改项目代码。例如,从Logback切换到Log4j。

2 Logback

Logback is intended as a successor to the popular log4j project, picking up where log4j 1.x leaves off.(Logback 旨在作为流行的 log4j 项目的继承者,在 log4j 1.x 停止的地方接手。)这是Logback官网的第一句话,目的很明显。作为SpringBoot自带的日志框架,与Log4j相比肯定有其过人之处,比如性能更好、内存占用更小、流畅地实现了slf4j等,如果没有更好的选择,那么用Logback就行了。

2.1 引入

如果是SpringBoot项目,无需单独引入,spring-boot-starter下的spring-boot-starter-logging已经引入Logback相关jar包。
在这里插入图片描述

2.2 配置

2.2.1 Logback启动步骤
  1. Logback 尝试在 classpath中找到一个名为 logback-test.xml的文件。
  2. 如果没有找到这样的文件,它会检查 类路径中的文件 logback.xml
  3. 如果没有找到这样的文件,则 使用服务提供者加载工具(在 JDK 1.6 中引入) 通过查找文件 META-INF\services\ch.qos.logback.classic.spi.Configurator来解析接口 的实现类路径。其内容应指定所需实现的完全限定类名。 com.qos.logback.classic.spi.ConfiguratorConfigurator。
  4. 如果以上都没有成功,logback 会自动配置自己,BasicConfigurator 这将导致日志输出被定向到控制台。
2.2.2 使用自动配置

如果只引入而不加任何配置,则默认规则是:按%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n模板输出debug级别的日志到控制台。

18:08:10.016 [main] DEBUG com.loyoi.LogTest - 输出一些debug日志

与自动配置对应配置规则如下:

<configuration>
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <!-- encoders are assigned the type
         ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
  </appender>
  <root level="debug">
    <appender-ref ref="STDOUT" />
  </root>
</configuration>
2.2.3 使用.xml配置文件

如果使用的是maven,将logback.xmllogback-test.xml分别放在src/main/resources和src/test/resources目录下,Logback将会加载对应的配置文件用于生产和测试。也可以使用系统属性-Dlogback.configurationFile=/path/to/config.xml来指定配置文件位置。
├─src
│ ├─main
│ │ ├─java
│ │ ├─resources
│ │ │ └─logback.xml
│ └─test
│ │ ├─java
│ │ ├─resources
│ │ │ └─logback-test.xml
配置文件的基本结构可以描述为<configuration>元素,包含零个或多个<appender>元素,后跟零个或多个<logger>元素,后跟最多一个<root>元素,如下图所示:
图片来源于logback官网
其中,<logger>负责定义要记录什么内容,日志的级别。<appender>定义日志输出到哪里,如控制台、文件、关系型数据库、非关系型数据库、其他日志系统等。

2.2.3.1 配置logger

<logger>配置参数

参数描述可选性可选值
name记录器名称,指定记录日志的某个包或者类的全类名来控制其日志输出必选例子:org.xxx、org.xxx.AClass,下面所说的层级可以依据此来判断
level日志级别可选不区分大小写的TRACE、DEBUG、INFO、WARN、ERROR、ALL 或 OFF 之一。如果指定为不区分大小写的INHERITED或者NULL,那么记录器的级别会从层次结构中的更高层继承,默认值就是上层的级别。根据“精确原则”来取类或者包下的日志级别。
additivity可加性可选true或false,默认是true,控制当前层级的日志是否传递到上层级别进行输出
<root>只支持level属性,默认DEBUG级别,不支持INHERITED或者NULL,作为最顶层的记录器。
<configuration>
  <appender name="STDOUT"
    class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>
        %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
     </pattern>
    </encoder>
  </appender>

  <!-- 未指定level,使用父级root的DEBUG -->
  <logger name="chapters" additivity="false"/>
  <!-- additivity设置为false,避免输出多次 -->
  <logger name="chapters.configuration" level="INFO" additivity="false"/>
  <!-- 虽然父层的包指定了INFO级别,但是Foo类指定的更精确,因此Foo类会使用DEBUG级别 -->
  <logger name="chapters.configuration.Foo" level="DEBUG" additivity="false"/>

  <root level="DEBUG">
    <!-- 可包含一个或者多个append-ref,指定输出 -->
    <appender-ref ref="STDOUT" />
  </root>
</configuration>
2.2.3.2 配置appender

使用<appender>标签来配置附加器,它有两个必要的参数:name为附加器的名称,被logger引用时使用;class属性指定要实例化的 appender 类的全类名,该类负责输出相关的工作。<appender>元素可以包含零个或一个<layout>元素、零个或多个 <encoder>元素和零个或多个 <filter>元素。除了这三个公共元素之外,<appender>元素还可以包含任意数量的与 appender 类的 JavaBean 属性相对应的元素。下图说明了appender的通用结构。
图片来源于logback官网
下图为附加器相关类图
在这里插入图片描述

下面是一个定义附加器并引用的例子,例子中定义了两个附加器,一个输出到文件,一个输出到控制台,对应不同的处理类。对每一个附加器,<encoder>是不共享的,必须单独定义。

configuration>

  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>myApp.log</file>
    <encoder>
      <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
    </encoder>
  </appender>

  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
    </encoder>
  </appender>

  <root level="debug">
    <appender-ref ref="FILE" />
    <appender-ref ref="STDOUT" />
  </root>
</configuration>

附加器class种类:

名称作用
ConsoleAppender输出到控制台
FileAppender输出到文件
RollingFileAppender扩展FileAppender,拥有翻转日志文件的能力
SocketAppender明文传输日志到远程日志服务器
SSLSocketAppender安全通道传输日志到远程日志服务器
ServerSocketAppender等待来自远程客户端的传入连接,日志被分发到连接客户端,无客户端时日志将被丢弃
SSLServerSocketAppenderServerSocketAppender的安全版,使用安全通道
SMTPAppender将日志累积在一个或多个固定大小的缓冲区中,并在用户指定的事件发生后将相应缓冲区的内容发送到电子邮件中。
DBAppender将日志写入关系型数据库
SyslogAppender将日志发送到远程 syslog 守护进程
SiftingAppender根据给定的运行时属性分离(或筛选)日志记录
AsyncAppender异步记录日志,它仅充当事件调度程序,因此必须引用另一个附加程序才能执行任何有用的操作。
详细使用参考官方文档
2.2.3.3定义变量

变量使用<property>标签定义,除了在logback.xml中定义以外,变量可以来自系统变量,如java -DUSER_HOME="/home/my" XXX定义的变量,可以来自文件,如var.properties,引用变量使用${}变量首先在本地范围中查找属性,然后在上下文范围中查找,然后在系统属性范围中查找,最后在 OS 环境中查找。

<configuration>

  <!-- 自定义变量 -->
  <property name="USER_HOME" value="/home/my" />
  <!-- 引用外部配置文件 -->
  <property file="/home/my/var.properties" />
  <!-- 引用类路径下的资源 -->
  <property resource="application.properties" />

  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
     <!-- 使用系统变量 -->
     <file>${USER_HOME}/myApp.log</file>
     <encoder>
       <pattern>%msg%n</pattern>
     </encoder>
   </appender>

   <root level="debug">
     <appender-ref ref="FILE" />
   </root>
</configuration>
2.2.4 状态监听器

注册状态监听器用于排查Logback出现的问题,简单配置如下:

<configuration debug="true">
...
</configuration>

通常会将内容输出到控制台,但Logback-classic 附带一个名为 ViewStatusMessagesServlet 的 servlet。将其注册到web程序中,访问注册路径可在网页端看到状态信息。下面是一个示例输出:

17:44:58,578 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback-test.xml]
17:44:58,671 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - debug attribute not set
17:44:58,671 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
17:44:58,687 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [STDOUT]
17:44:58,812 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Popping appender named [STDOUT] from the object stack
17:44:58,812 |-INFO in ch.qos.logback.classic.joran.action.LevelAction - root level set to DEBUG
17:44:58,812 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[root]
2.2.5 自动更新配置文件

开启此项,修改配置文件后会周期性地检查配置文件是否有更新,如果不指定scanPeriod,默认1分钟检查一次,如果不指定单位,默认为毫秒。另外,如果修改的配置文件有错误,会自动回退到上个没错的版本。

<configuration scan="true" scanPeriod="30 seconds" >
  ...
</configuration>
2.2.6 释放logback-classic使用的资源

在程序退出时,可以配置释放logback-classic使用的资源,简单配置如下:

<configuration debug="true">
   <!-- in the absence of the class attribute, assume
   ch.qos.logback.core.hook.DefaultShutdownHook -->
   <shutdownHook/>
  ....
</configuration>

2.3 使用

在代码中可以看到如下两种使用方式,静态与非静态,官方推荐静态使用方式。那么这两种有什么区别呢?下面是一个验证二者区别的例子:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LogControllerTest {
    static final Logger loggerStatic = LoggerFactory.getLogger(LogControllerTest.class);
    final Logger loggerEntity = LoggerFactory.getLogger(LogControllerTest.class);

    public static void main(String[] args) {
        Logger loggerEntity1 = new LogControllerTest().loggerEntity;
        Logger loggerEntity2 = new LogControllerTest().loggerEntity;
        System.out.println("静态与实例: " + (loggerStatic == loggerEntity1));
        System.out.println("实例与实例: " + (loggerEntity1 == loggerEntity2));
    }
}

输出:

静态与实例: true
实例与实例: true

也就是说,静态和非静态获取到的是同一个对象,但是,静态只需要初始化一次。

2 Log4j2

由于Log4j 1.x版本已经过时,所以推出了Log4j2的版本,该版本并不是对1.x版的升级,相当于是重写。学会Logback的使用,对于Log4j2来说,使用上基本类似,具体细节可在使用时参考官方文档。Log4j2和Logback都出自Ceki Gülcü之手,在Logback官网上,可以很明显地看到 _log4j.properties to logback.xml Translator_和 Canonical form for logback.xml files (requires logback 1.3) 两个导航栏,为Log4j迁移到Logback提供了方便的转换。

3 ELK

“ELK”是三个开源项目的首字母缩写,这三个项目分别是:Elasticsearch、Logstash 和 Kibana。在分布式云上,可以使用ELK来采集容器的日志,方便管理和查看日志。

  1. Elasticsearch 是一个搜索和分析引擎。
  2. Logstash 是服务器端数据处理管道,能够同时从多个来源采集数据,转换数据,然后将数据发送到诸如 Elasticsearch 等“存储库”中。
  3. Kibana 则可以让用户在 Elasticsearch 中使用图形和图表对数据进行可视化。
    在这里插入图片描述
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值