开发者

Spring Boot 日志概念及使用详解

目录
  • 一、为什么要学习日志
  • 二、认识日志格式
  • 三、日志使用
    • 打印日志
      • 步骤
    • 日志框架介绍
      • 门面模式(外观模式)
      • 门面模式的实现
      • 门面模式的优点
  • 四、日志级别
    • 日志级别分类
      • 日志级别的使用
        • 日志配置
          • 配置日志级别
          • 日志持久化
          • 日志持久化有两种方式
          • 配置日志文件分割
      • 五、更简单的日志输出

        一、为什么要学习日志

        日志对我们来说并不陌生,从JavaSE部分,我们就在使用 System.out.print 来打印日志了.通过打

        印日志来发现和定位问题,或者根据日志来分析程序的运行过程.在 Spring 的学习中,也经常根据控制台的日志来分析和定位问题.

        随着项目的复杂度提升,我们对日志的打印也有了更高的需求,而不仅仅是定位排查问题.

        比如需要记录一些用户的操作记录(一些审计公司会要求),也可能需要使用日志来记录用户的一些喜好,把日志持久化,后续进行数据分析等.但是 System.out.print 不能很好的满足我们的需求,我们就需要使用一些专门日志框架(专业的事情交给专业的人去做).

        二、认识日志格式

        Spring Boot 日志概念及使用详解

        1️⃣时间日期:精确到毫秒

        2️⃣日志级别:ERROR,WARN,INFO,DEBUG或TRACE

        3️⃣进程 ID

        4️⃣线程名

        5️⃣Logger 名(通常使用源代码的类名)

        6️⃣日志内容

        三、日志使用

        SpringBoot 内置了日志框架 Slf4j ,我们可以直接在程序中调用 Slf4j 来输出日志

        打印日志

        步骤

        • 在程序中得到日志对象.

        需要使用志工厂  LoggerFactory

        private static Logger logger = LoggerFactory.getLogger(CaptchaController.class);

        LoggerFactory.getLogger 需要传递⼀个参数, 标识这个日志的名称. 这样可以更清晰的知道是哪个类输出的日志. 当有问题时, 可以更方便直观的定位到问题类 

        • 使用日志对象输出要打印的内容.

        日志对象的打印方法有很多种,我们可以先使用 info() 方法来输出日志

        logger.info("Logger生成验证码: " + code);

        日志框架介绍

        Spring Boot 日志概念及使用详解

        SLF4J不同于其他日志框架, 它不是一个真正的日志实现, 而是一个抽象层, 对日志框架制定的一种规范, 标准, 接口. 所有SLF4J并不能独立使用, 需要和具体的日志框架配合使用.

        门面模式(外观模式)

        SLF4J是门面模式的典型应用(但不仅仅使用了门面模式).

        门面模式(Facade Pattern)又称为外观模式,提供了一个统一的接口,用来访问子系统中的一群接口.其主要特征是定义了一个高层接口,让子系统更容易使用.

        Spring Boot 日志概念及使用详解

        Spring Boot 日志概念及使用详解

        门面模式主要包含2种角色:

        外观角色(Facade):也称门面角色,系统对外的统一接口.

        子系统角色(SubSystem):可以同时有一个或多个SubSystem.每个SubSytem都不是一个单独的类,

        而是一个类的集合.SubSystem并不知道Facade的存在,对于SubSystem而言,Facade只是另一个客户端而已(即Facade对SubSystem透明)

        Spring Boot 日志概念及使用详解

        Spring Boot 日志概念及使用详解

        门面模式的实现

        场景: 回家, 我们会开各个屋的灯. 离开家时, 会关闭各个屋的灯. 如果家里设置⼀个总开关, 来控制整个屋的灯就会很方便.

        没建门面前

        package com.example.demo.facade;
        import org.slf4j.Logger;
        import org.slf4j.LoggerFactory;
        public interface Light {
            void on();
            void off();
        }
        public HallLight implements Light {
            private static Logger logger = LoggerFactory.getLogger(HallLightjavascript.class);
            @Override
            public void on() {
                logger.info("打开走廊灯");
            }
            @Override
            public void off() {
                logger.info("关闭走廊灯");
            }
        }
        public LivingRoomLight implements Light {
            private static Logger logger = LoggerFactory.getLogger(LivingRoomLight.class);
            @Override
            public void on() {
                logger.info("打开客厅灯");
            }
            @Override
            public void off() {
                logger.info("关闭客厅灯");
            }
        }
        public BedRoomLight implements Light {
            private static Logger logger = LoggerFactory.getLogger(BedRoomLight.class);
            @Override
            public void on() {
                logger.info("打开卧室灯");
            }
            @Override
            public void off() {
                logger.info("关闭卧室灯");
            }
        }
        public class Main {
            public static void main(String[] args) {
                HallLight hallLight = new HallLight();
                LivingRoomLight livingRoomLight = new LivingRoomLight();
                BedRoomLight bedRoomLight = new BedRoomLight();
                hallLight.on();
                livingRoomLight.on();
                bandroidedRoomLight.on();
            }
        }

        我们使用门面模式的实现

        package com.example.demo.facade;
        public class LightFacade {
            void lightOn() {
                HallLight hallLight = new HallLight();
                LivingRoomLight livingRoomLight = new LivingRoomLight();
                BedRoomLight bedRoomLight = new BedRoomLight();
                hallLight.on();
                livingRoomLight.on();
                bedRoomLight.on();
            }
            void lightOff() {
                HallLight hallLight = new HallLight();
                LivingRoomLight livingRoomLight = new LivingRoomLight();
                BedRoomLight bedRoomLight = new BedRoomLight();
                hallLight.off();
                livingRoomLight.off();
                bedRoomLight.off();
            }
        }
        package com.example.demo.facade;
        public class Main {
            public static void main(String[] args) {
                LightFacade lightFacade = new LightFacade();
                lightFacade.lightOn();
                lightFacade.lightOff();
            }
        }

        门面模式的优点

        ●减少了系统的相互依赖,实现了客户端与子系统的耦合关系,这使得子系统的变化不会影响到调用它的客户端.

        ●提高了灵活性,简化了客户端对子系统的使用难度,客户端无需关心子系统的具体实现方式,而只需要和门面对象交互即可.

        ●提高了安全性,可以灵活设定访问权限,不在门面对象中开通方法,就无法访问.

        SLF4J 就是其他日志框架的门面. SLF4J 可以理解为是提供日志服务的统一API接口, 并不涉及到具体的日志逻辑实现.

        四、日志级别

        日志级别代表着日志信息对应问题的严重性, 为了更快的筛选符合目标的日志信息.

        日志级别分类

        日志的级别从高到低依次为:FATAL、ERROR、WARN、INFO、DEBUG、TRACE

        FATAL: 致命信息,表示需要立即被处理的系统级错误.

        ERROR: 错误信息,级别较高的错误日志信息,但仍然不影响系统的继续运行.

        WARN: 警告信息,不影响使用,但需要注意的问题.

        INFO: 普通信息,用于记录应用程序正常运行时的一些信息,例如系统启动完成、请求处理完成等.

        DEBUG: 调试信息,需要调试时候的关键信息打印.

        TRACE: 追踪信息,比 DEBUG 更细粒度的信息事件(除非有特殊用意,否则请使用 DEBUG级别替代).

        Spring Boot 日志概念及使用详解

        日志级别的使用

        package com.example.demo.controller;
        import org.slf4j.Logger;
        import org.slf4j.LoggerFactory;
        import org.springframework.web.bind.annotation.RequestMapping;
        import org.springframework.web.bind.annotation.RestController;
        @RequestMapping("/logger")
        @RestController
        public class LoggerLevelController {
            private static Logger logger = LoggerFactory.getLogger(LoggerLevelController.class);
            @RequestMapping("/print")
            public String print() {
                logger.trace("trace级别日志......");
                logger.debug("debug级别日志......");
                logger.info("info级别日志......");
                logger.warn("warn级别日志......");
                logger.error("error级别日志......");
                return "打印日志";
            }
        }

        Spring Boot 日志概念及使用详解

        Spring Boot 日志概念及使用详解

        结果发现, 只打印了info, warn和error级别的日志.

        这与日志级别的配置有关, 日志的输出级别默认是 info 级别, 所以只会打印大于等于此级别的日志, 也就是 info, warn和error.

        日志配置

        配置日志级别

        logging:
          level:
            root: debug

        Spring Boot 日志概念及使用详解

        日志级别也可以分类来设置

        logging:
          level:
            root: info
            com:
              example:
                demo:wkcOwqaBJ
                  controller: trace

        Spring Boot 日志概念及使用详解

        日志持久化

        以上的日志都是输出在控制台上的, 然日在线上环境中, 我们需要把日志保存下来, 以便出现问题之后追溯问题. 把日志保存下来就叫持久化.

        日志持久化有两种方式

        Spring Boot 日志概念及使用详解

        1️⃣配置日志文件名

        logging:
          file:
            name: logger/springboot.log

        后⾯可以跟绝对路径或者相对路径

        Spring Boot 日志概念及使用详解

        2️⃣配置日志的存储目录

        logging:
          file:
            path: D:/temp

        Spring Boot 日志概念及使用详解

        logging:
          file:
            path: D:/temp/aaa/springboot.log

        Spring Boot 日志概念及使用详解

        这种方式只能设置日志的路径, 文件名为固定的 spring.log

        ⚠️logging.file.name 和 logging.file.path 两个都配置的情况下, 只生效其一, 编程客栈以 logging.file.name 为准.

        配置日志文件分割

        如果我们的日志都放在一个文件中, 随着项目的运行, 日志文件会越来越大, 需要对日志文件进行分割.

        logging:
          file:
            #path: D:/temp/aaa/springboot.log
            name: logger/springboot.log
          logback:
            rollingpolicy:
              max-file-size: 1KB
              file-name-pattern: ${LOG_FILE}.%d{yyyy-MM-dd}.%i

        Spring Boot 日志概念及使用详解

        1.日志文件超过 1KB 就分割(设置 1KB 是为了更好展示.企业开发通常设置为200M,500M等,此处没有明确标准)

        2.分割后的日志文件名为:日志名.日期.索引

        五、更简单的日志输出

        每次都使用 LoggerFactory.getLogger(xxx.class) 很繁琐, 且每个类都添加一遍, lombok 给我们提供了⼀种更简单的方式.

        1️⃣添加 lombok 框架支持

        2️⃣使用 @Slf4j 注解输出日志

        lombok 提供的 @Slf4j 会帮我们提供⼀个日志对象 log, 我们直接使用就可以.

        package com.example.demo.controller;
        import lombok.extern.slf4j.Slf4j;
        import org.slf4j.Logger;
        import org.slf4j.LoggerFactory;
        import org.spjsringframework.web.bind.annotation.RequestMapping;
        import org.springframework.web.bind.annotation.RestController;
        @Slf4j
        @RequestMapping("/logger2")
        @RestController
        public class LoggerLevelController2 {
            //private static Logger logger = LoggerFactory.getLogger(LoggerLevelController2.class);
            @RequestMapping("/print")
            public String print() {
                log.trace("trace级别日志......");
                log.debug("debug级别日志......");
                log.info("info级别日志......");
                log.warn("warn级别日志......");
                log.error("error级别日志......");
                return "打印日志";
            }
        }

        到此这篇关于Spring Boot 日志的文章就介绍到这了,更多相关Spring Boot 日志内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

        0

        上一篇:

        下一篇:

        精彩评论

        暂无评论...
        验证码 换一张
        取 消

        最新开发

        开发排行榜