当前位置: 首页 > news >正文

猿创征文|Spring Boot日志

在这里插入图片描述

目录

  • 日志介绍
    • 记录日志的好处
  • 日志框架
  • 日志的使用
    • 获取日志对象
    • 日志格式
    • 自定义日志输出
  • 替换日志框架

日志介绍

记录日志的好处

1. 记录应用系统曰志主要有三个原因:记录操作轨迹、监控系统运行状况、回溯系统故障。

记录操作行为及操作轨迹数据,可以数据化地分析用户偏好,有助于优化业务逻辑,为用户提供个性化的服务。例如,通过 access.log 记录用户的操作频度和跳转链接,有助于分析用户的后续行为。

2. 全面有效的日志系统有助于建立完善的应用监控体系,由此工程师可以实时监控系统运行状况,及时预警,避免故障发生。

监控系统运行状况,是指对服务器使用状态,如内存、CPU 等使用情况,应用运行情况,如响应时间QPS等交互状态;应用错误信息,如空指针、SQL异常等的监控。例如,在CPU使用率大于60%,四核服务器中load 大于4时发出报警,提醒工程师及时处理,避免发生故障。

3. 当系统发生线上问题时,完整的现场日志有助于工程师快速定位问题。

例如当系统内存溢出时,如果日志系统记录了问题发生现场的堆信息,就可以通过这个曰志分析是什么对象在大量产生并且没有释放内存,回溯系统故障,从而定位问题。

日志框架

日志门面日志实现
JCL(Jakarta Commons Logging)Java最早的一套日志标准 、SLF4j(Simple Logging Facade for Java)、 jboss-loggingLog4j 、JUL(java.util.logging)、 Log4j2 (兼容性不强)、 Logback

日志门面

门面设计模式是面向对象设计模式中的一种,日志框架采用的就是这种模式,类似JDBC的设计理念。它只提供一套接口规范,自身不负责日志功能的实现。目的是让使用者不需要关注底层具体是哪个日志库来负责日志打印及具体的使用细节等。目前用得最为广泛的是slf4j

日志门面是一种门面设计模式,为了提高程序的扩展性给的一套类似于JDBC的接口,只需设定规则,具体的细节都留给对应实现

日志库

负责实现日志的相关功能,主流日志库有三个,分别是

log4j、log-jdk (java.util.logging.Logger)、logback是最晚出现的,与log4j同一个作者,是log4j的升级版且本身实现了slf4j的接口。

日志适配器

老工程直接使用日志库API完成日志打印,要改成业界标准的门面模式(如slf4j+logback),但是老工程代码打印日志地方太多难以改动,这时就需要一个适配器来完成从旧日志库的API到slf4j的路由,这样在不改动原有代码的情况下也能使用slf4j来统一管理日志(如:log4j-over-slf4j),后续自由替换具体日志库也不成问题。

日志体系

在开发的时候不应该直接使用日志实现类,应该使用日志的抽象层。。具体参考SLF4J官方

下图是SLF4J结合各种日志框架的官方示例,从图中可以清晰的看出SLF4J API永远作为日志的门面,直接应用与应用程序中。

在这里插入图片描述

spring boot的底层spring-boot-starter-logging可以看出,它依赖3个日志框架:slf4j、Logback和Log4j2。

它们的区别是:

  • logback和log4j是日志实现框架,就是实现怎么记录日志的。
  • slf4j-api提供了java所有日志框架的简单规范和标准(日志的门面设计模式)说白了就是一个日志API(没有实现类),它不能单独使用;故必须结合logback和Log4j2日志框架

注意:spring Boot采用了slf4j+logback的组合形式,Spring Boot也提供对JUL、log4j2.Logback提供了默认配置

注意:由于每一个日志的实现框架都有自己的配置文件,所以在使用SLF4j之后,配置文件还是要使用实现日志框架的配置文件。

日志的使用

日志级别和格式

从上面的分析,发现 Spring Boot默认已经使用了SLF4J+LogBack 。所以我们在不进行任何额外操作的情况下就可以使用SLF4J + Logback 进行日志输出。
日志的级别分为6种:

  • TRACE:运行堆栈信息,使用率低
  • DEBUG:程序员调试代码使用
  • INFO:记录运维过程数据
  • WARN:记录运维过程报警数据
  • ERROR:记录错误堆栈信息
  • FATAL:灾难信息,合并计入ERROR

编写测试类测试

package com.example.springboot.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    //获取日志对象 Logger
    Logger logger = LoggerFactory.getLogger(HelloController.class);

    @GetMapping("/hello")
    public String hello(){
        logger.debug("debug...");
        logger.info("info...");
        logger.warn("warn...");
        logger.error("error...");

        return "Hello SpringBoot!";
    }
}

application.yml

server:
  port: 80

# 设置日志级别会给root根节点设置,代表整体应用的级别
#logging:
#  level:
#    root: debug
# 设置组的日志级别或包的日志级别
logging:
  group:
    mygroup: com.example.springboot.controller
  level:
    root: warn
    # 给组设置日志级别
    mygroup: debug

获取日志对象

  • 导入Lombok依赖
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>
  • 添加@Slf4j注解
package com.example.springboot.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@RestController
public class HelloController {

    @GetMapping("/hello")
    public String hello(){
    
        log.debug("debug...");
        log.info("info...");
        log.warn("warn...");
        log.error("error...");

        return "Hello SpringBoot!";
    }
}

哪里需要用到日志,那里添加注解即可

日志格式

Spring Boot默认输出的日志格式如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7WIc5PPR-1662713658756)(C:\Users\19737\AppData\Local\Temp\1662687149165.png)]

  • 日期和时间:毫秒精度,易于排序
  • 日志级别:ERRORWARNINFODEBUGTRACE
  • 进程标识
  • — :用于区分实际日志开始的分隔符
  • 线程名称:在方括号内
  • 记录器名称:通常为源类名称
  • 日志消息

日志格式配置

# 修改日志级别
logging:
  # 设置日志格式
  pattern:
    #控制台输出格式
    #格式化输出: %d :表示日期   %thread:表示线程名  
    # %-5level:级别从左显示5个字符宽度   %msg :日志消息   %n :是换行符
    console: "[console]==%d{yyyy-MM-dd HH:mm:ss:SSS} [%thread] %-5level %logger - %msg%n"
    # 文件输出格式
    file: "[file]===%d{yyyy-MM-dd HH:mm:ss:SSS} [%thread] %-5level %logger - %msg%n"

日志格式配置信息如下:

  • %d或者%date:指定日志的日期。默认是ISO8601的标准日期,相当于yyyy-MM-dd HH:mm:ss:SSS
  • %level:指定日志的级别: Trace > Debug > Info> Warn> Error
  • %logger:指定日志输出的包名+类名,{n}可以限定长度,比如: %logger{50}
  • %M:指定日志发生时的方法名
  • %L:指定日志调用时所在的行。线下运行的时候不建议使用此参数,因为获取代码的行号对性能有损耗
  • %m或者%msg:表示日志的输出的内容
  • %n :日志是否换行
  • %thread:打印线程的名字

彩色编码输出

如果您的终端支持ANSI,则使用颜色输出来提高可读性。您可以设置spring.output.ansi.enabled为支持的值以覆盖自动检测。
使用%clr转换字配置颜色编码。在最简单的形式中,转换器根据日志级别为输出着色,如以下所示:
%clr(%5p)
下表描述了日志级别到颜色的映射:

等级颜色
FATAL红色
ERROR红色
WARN黄色
INFO绿色
DEBUG绿色
TRACE绿色

或者,您可以通过将其作为转换选项提供来指定应使用的颜色或样式。例如,要使文本变黄,请使用以下设置:

%clr(%d{yyyy-MM-dd HH:mm:ss:SSS}){yello}

支持的颜色有:blue cyan faint green magenta red yellow

因此我们可以自己编写日志的输出格式如下:

logging:
  pattern:
    console: "%d %clr(%p){green} ---[%16t] %m%n"

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xGuFfC2h-1662713658756)(C:\Users\19737\AppData\Local\Temp\1662692874120.png)]

自定义日志输出

日志不能仅显示在控制台上,要把日志记录到文件中,方便后期维护查阅。

对于日志文件的使用存在各种各样的策略,例如每日记录,分类记录,报警后记录等。这里主要研究日志文件如何记录。

logging:
  file:
    name: tomcat.log

虽然使用上述格式可以将日志记录下来了,但是面对线上的复杂情况,一个文件记录肯定是不能够满足运维要求的,通常会每天记录日志文件,同时为了便于维护,还要限制每个日志文件的大小。下面给出日志文件的常用配置方式:

logging:
  logback:
    rollingpolicy:
      max-file-size: 2MB
      file-name-pattern: server.%d{yyyy-MM-dd}.%i.log

以上格式是基于logback日志技术设置每日日志文件的设置格式,要求容量到达2MB以后就转存信息到第二个文件中。文件命名规则中的%d标识日期,%i是一个递增变量,用于区分日志文件。

替换日志框架

查看官方文档,可以看到我们可以在 Log4j 和 logging 之间二选一。

官方是这样描述Log4j的:An alternative to spring-boot-starter-logging

翻译过来就是:spring-boot-starter-logging的替代方案。

在这里插入图片描述

所以下面来展示如何将 logging 替换为 Log4j

  • 第一步:排除spring-boot-starter-logging依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>
  • 第二步:添加spring-boot-starter-Log4j2依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

相关文章:

  • Blue Prism 异常处理
  • PCL 环境下安装配置CGAL 5.5
  • Code For Better 谷歌开发者之声——盘点大家用过的Google 产品
  • Android基本界面控件、部分属性方法解析
  • Qt5开发从入门到精通——第六篇二节( 图像与图片——基础图形的绘制 )
  • Hive学习笔记2
  • 【zabbix监控四】zabbix之监控tomcat服务报警案例
  • JavaScript endsWith() 方法
  • 软件测试(用例2)
  • C++11重写muduo网络库——预备知识
  • frp内网穿透—将kali代理在公网中进行渗透测试
  • charles + proxifier 抓包配置(踩坑记录)
  • 【分享】MySQL安装、配置环境、创建数据库的方法
  • java毕业设计产品销售管理系统Mybatis+系统+数据库+调试部署
  • 移植u-boot和linux3.4.2内核到s3c2440——<1>:编写uboot
  • 4. 路由到控制器 - Laravel从零开始教程
  • Android路由框架AnnoRouter:使用Java接口来定义路由跳转
  • iOS编译提示和导航提示
  • Javascript设计模式学习之Observer(观察者)模式
  • Java到底能干嘛?
  • java架构面试锦集:开源框架+并发+数据结构+大企必备面试题
  • js
  • JS基础之数据类型、对象、原型、原型链、继承
  • Linux CTF 逆向入门
  • React as a UI Runtime(五、列表)
  • Vue.js-Day01
  • 复杂数据处理
  • 基于webpack 的 vue 多页架构
  • 聊一聊前端的监控
  • 每天10道Java面试题,跟我走,offer有!
  • 前端每日实战:70# 视频演示如何用纯 CSS 创作一只徘徊的果冻怪兽
  • 数据可视化之 Sankey 桑基图的实现
  • 智能情侣枕Pillow Talk,倾听彼此的心跳
  • # 手柄编程_北通阿修罗3动手评:一款兼具功能、操控性的电竞手柄
  • # 透过事物看本质的能力怎么培养?
  • ### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException
  • #NOIP 2014#Day.2 T3 解方程
  • #Ubuntu(修改root信息)
  • $ is not function   和JQUERY 命名 冲突的解说 Jquer问题 (
  • (33)STM32——485实验笔记
  • (6)设计一个TimeMap
  • (C语言)共用体union的用法举例
  • (echarts)echarts使用时重新加载数据之前的数据存留在图上的问题
  • (vue)页面文件上传获取:action地址
  • (附源码)计算机毕业设计高校学生选课系统
  • (个人笔记质量不佳)SQL 左连接、右连接、内连接的区别
  • (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境
  • (一)SpringBoot3---尚硅谷总结
  • (转)德国人的记事本
  • .NET 6 在已知拓扑路径的情况下使用 Dijkstra,A*算法搜索最短路径
  • .net 7 上传文件踩坑
  • .NET 8.0 发布到 IIS
  • .Net Winform开发笔记(一)
  • .NET 中 GetProcess 相关方法的性能
  • .Net的C#语言取月份数值对应的MonthName值