Spring Boot中的logback + slf4j

1什么时slf4j

  slf4j是一个日志接口,自己没有具体实现日志系统,只提供了一组标准的调用api,这样将调用和具体的日志实现分离,使用slf4j后有利于根据自己实际的需求更换具体的日志系统,比如,之前使用的具体的日志系统为log4j,想更换为logback时,只需要删除log4j相关的jar,然后加入logback相关的jar和日志配置文件即可,而不需要改动具体的日志输出方法,试想如果没有采用这种方式,当你的系统中日志输出有成千上万条时,你要更换日志系统将是多么庞大的一项工程。如果你开发的是一个面向公众使用的组件或公共服务模块,那么一定要使用slf4的这种形式,这有利于别人在调用你的模块时保持和他系统中使用统一的日志输出。

  slf4j日志输出时可以使用{}占位符,如,logger.info("testlog: {}", "test"),而如果只使用log4j做日志输出时,只能以logger.info("testlog:"+"test")这种形式,前者要比后者在性能上更好,后者采用+连接字符串时就是new 一个String 字符串,在性能上就不如前者。

2.logback

  logback同样是由log4j的作者设计完成的,拥有更好的特性,用来取代log4j的一个日志框架,是slf4j的原生实现(即直接实现了slf4j的接口,而log4j并没有直接实现,所以就需要一个适配器slf4j-log4j12.jar),logback一共有以下几个模块:

  logback-core:其它两个模块的基础模块

   logback-classic:它是log4j的一个改良版本,同时它完整实现了slf4j API使你可以很方便地更换成其它日志系统如log4j或JDK14 Logging

  logback-access:访问模块与Servlet容器集成提供通过Http来访问日志的功能

3.jar

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.3</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-core</artifactId>
    <version>1.2.3</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.25</version>
</dependency

4.spring boot配置文件中

#系统日志配置
log:
  level: info  #输出日志级别 tarce debug info wran error
  path: ./logs

5.logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

    <!-- 这里引用的application.yml的配置,在最下面root标签里用到-->
    <springProperty scope="context" name="logLevel" source="log.level"/>
    <springProperty scope="context" name="logPath" source="log.path"/>

    <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">  ##控制台日志
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出,详细请参考log4j API -->
            <pattern>[%p] %d{yyyy-MM-dd HH:mm:ss.SSS} - [%X{threadKey}] %C.%M: %m%n</pattern>
        </encoder>
    </appender>

    <!-- 所有日志 -->
    <appender name="rollingFileAppender"
              class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${logPath}/yto_server.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">  ##日志文件回滚
            <!--日志文件输出的文件名 -->
            <FileNamePattern>${logPath}_server_%d{yyyy-MM-dd}_%i.log
            </FileNamePattern>
            <maxFileSize>10MB</maxFileSize>                                                ## 10M 自动生成下一个文件
            <maxHistory>10</maxHistory>                                ## 保存10天的
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>[%p] %d{yyyy-MM-dd HH:mm:ss.SSS} - [%X{threadKey}] %C.%M: %m%n</pattern>
        </encoder>
    </appender>

    <!-- 系统日志 -->
    <appender name="syslog"
        class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 日志记录路径,可用绝对路径和相对路径 -->
        <file>${logPath}/_sys/_sys.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--日志文件输出的文件名 -->
            <FileNamePattern>${logPath}/_sys/_sys_%d{yyyy-MM-dd}_%i.log
            </FileNamePattern>
            <maxHistory>10</maxHistory>
            <maxFileSize>10MB</maxFileSize>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>[%p] %d{yyyy-MM-dd HH:mm:ss.SSS} - [%X{threadKey}] %C.%M: %m%n</pattern>
        </encoder>
    </appender>

    <!-- 操作日志 -->
    <appender name="optlog"
              class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${logPath}/_opt/_opt.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--日志文件输出的文件名 -->
            <FileNamePattern>${logPath}/_opt/_opt_%d{yyyy-MM-dd}_%i.log
            </FileNamePattern>
            <maxHistory>10</maxHistory>
            <maxFileSize>10MB</maxFileSize>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>[%p] %d{yyyy-MM-dd HH:mm:ss.SSS} - [%X{threadKey}] %C.%M: %m%n</pattern>
        </encoder>
    </appender>

    <!-- 不同的业务逻辑日志打印到指定文件夹-->
    <logger name="systemLog" additivity="false" level="${logLevel}">   ##name 日志打印的类名  additivity 是否向上级root传日志(如果是true) 根节点root 会打印两遍日志 level 输出日志的等级
        <appender-ref ref="syslog"/>                     ## 执行appenderName = syslog 中的方案
        <appender-ref ref="consoleAppender"/>
    </logger>
    <logger name="operatorLog" additivity="false" level="${logLevel}">
        <appender-ref ref="optlog"/>
        <appender-ref ref="consoleAppender"/>
    </logger>

    <root level="${logLevel}">                        ##根节点 logger 子节点  level 输出日志的等级
        <appender-ref ref="consoleAppender" />               ## 打印控制台日志
        <appender-ref ref="rollingFileAppender" />
    </root>

</configuration>

6.LogFileName:

public enum LogFileName {

    //配置到logback.xml中的logger name="systemLog"
    SYS_LOG("systemLog"),
    OPT_LOG("operatorLog");

    private String logFileName;

    LogFileName(String fileName) {
        this.logFileName = fileName;
    }

    public String getLogFileName() {
        return logFileName;
    }

    public void setLogFileName(String logFileName) {
        this.logFileName = logFileName;
    }

    public static LogFileName getAwardTypeEnum(String value) {
        LogFileName[] arr = values();
        for (LogFileName item : arr) {
            if (null != item && StringUtils.isNotBlank(item.logFileName)) {
                return item;
            }
        }
        return null;
    }
}

  7.CustomLoggerFactory

public class CustomLoggerFactory {

    public static Logger SystemLogger(){
        return CustomLoggerFactory.Logger(LogFileName.SYS_LOG);
    }

    public static Logger OperateLogger(){
        return CustomLoggerFactory.Logger(LogFileName.OPT_LOG);
    }

    public static <T> Logger Logger(Class<T> clazz) {
        return LoggerFactory.getLogger(clazz);
    }

    /**
     * 打印到指定的文件下
     *
     * @param desc 日志文件名称
     * @return
     */
    public static Logger Logger(LogFileName desc) {
        return LoggerFactory.getLogger(desc.getLogFileName());
    }
}

原文地址:https://www.cnblogs.com/huoyufei/p/11510977.html

时间: 2024-08-01 08:20:09

Spring Boot中的logback + slf4j的相关文章

Spring Boot中实现logback多环境日志配置

在Spring Boot中,可以在logback.xml中的springProfile标签中定义多个环境logback.xml: <springProfile name="production"> <root level="DEBUG"> <appender-ref ref="STDOUT"/> </root> </springProfile> <springProfile nam

Spring Boot中Starter是什么

比如我们要在Spring Boot中引入Web MVC的支持时,我们通常会引入这个模块spring-boot-starter-web,而这个模块如果解压包出来会发现里面什么都没有,只定义了一些POM依赖. 经过研究,Starter主要用来简化依赖用的.比如我们之前做MVC时要引入日志组件,那么需要去找到log4j的版本,然后引入,现在有了Starter之后,直接用这个之后,log4j就自动引入了,也不用关心版本这些问题. 部分starters的依赖: Starter(Group ID: org.

Spring boot中使用log4j

我们知道,Spring Boot中默认日志工具为logback,但是对于习惯了log4j的开发者,Spring Boot依然可以很好的支持,只是需要做一些小小的配置功能.Spring Boot使用log4j只需要一下几步 引入log4j依赖 在创建Spring Boot工程时,我们引入了spring-boot-starter,其中包含了spring-boot-starter-logging,该依赖内容就是Spring Boot默认的日志框架Logback,所以我们在引入log4j之前,需要先排除

spring boot中log4j冲突问题和解决办法

Spring Boot中自带了log4j日志管理.写法应该是: private static final Logger logger = Logger.getLogger(XXX.class); 而不是: private Logger logger = LoggerFactory.getLogger(XXX.class); 这两个类属于的包不同,前者属于log4j-over-slf4j-1.7.25.jar:后者属于slf4j-api-1.7.25.jar.两个jar包都属于org.slf4j下

spring boot 中AOP的使用

一.AOP统一处理请求日志 也谈AOP 1.AOP是一种编程范式 2.与语言无关,是一种程序设计思想 面向切面(AOP)Aspect Oriented Programming 面向对象(OOP)Object Oriented Programming 面向过程(POP) Procedure Oriented Programming 再谈AOP 1.面向过程到面向对象 2.换个角度看世界,换个姿势处理问题 3.将通用逻辑从业务逻辑中分离出来 二.处理过程 个人理解,其实就是日志体系为了方便使用,可以

3.Spring Boot中使用Swagger2构建强大的RESTful API文档

原文:http://www.jianshu.com/p/8033ef83a8ed 由于Spring Boot能够快速开发.便捷部署等特性,相信有很大一部分Spring Boot的用户会用来构建RESTful API.而我们构建RESTful API的目的通常都是由于多终端的原因,这些终端会共用很多底层业务逻辑,因此我们会抽象出这样一层来同时服务于多个移动端或者Web前端. 这样一来,我们的RESTful API就有可能要面对多个开发人员或多个开发团队:IOS开发.Android开发或是Web开发

spring-boot实战【10】【转】:Spring Boot中使用@Async实现异步调用

什么是"异步调用"? "异步调用"对应的是"同步调用",同步调用指程序按照定义顺序依次执行,每一行程序都必须等待上一行程序执行完成之后才能执行:异步调用指程序在顺序执行时,不等待异步调用的语句返回结果就执行后面的程序. 同步调用 下面通过一个简单示例来直观的理解什么是同步调用: 定义Task类,创建三个处理函数分别模拟三个执行任务的操作,操作消耗时间随机取(10秒内) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

spring-boot实战【07】【转】:Spring Boot中Web应用的统一异常处理

我们在做Web应用的时候,请求处理过程中发生错误是非常常见的情况.Spring Boot提供了一个默认的映射:/error,当处理中抛出异常之后,会转到该请求中处理,并且该请求有一个全局的错误页面用来展示异常内容. 选择一个之前实现过的Web应用(Chapter3-1-2)为基础,启动该应用,访问一个不存在的URL,或是修改处理内容,直接抛出异常,如: 1 2 3 4 @RequestMapping("/hello") public String hello() throws Exce

spring-boot实战【09】【转】:Spring Boot中使用@Scheduled创建定时任务

我们在编写Spring Boot应用中经常会遇到这样的场景,比如:我需要定时地发送一些短信.邮件之类的操作,也可能会定时地检查和监控一些标志.参数等. 创建定时任务 在Spring Boot中编写定时任务是非常简单的事,下面通过实例介绍如何在Spring Boot中创建定时任务,实现每过5秒输出一下当前时间. 在Spring Boot的主类中加入@EnableScheduling注解,启用定时任务的配置 1 2 3 4 5 6 7 8 9 10 @SpringBootApplication @E