【5】SpringBoot日志存储路径和设置日志格式

SpringBoot日志存储路径和设置日志格式

01、分析

日志在开发过程中作用?

在开发过程这种,我们经常要调试和打印一些信息,这样的帮助和我辅助我们进行问题排查和数据的跟踪。

一般传统的方式是使用

System.out.printltn("xxxxx")

但是上面的这种方式存在如下问题:

1:仅仅只是一种控制台打印的方式。

2:不方便我后续生产环境的调试和查看。

3:性能角度,存在一定性能问题。会影响方法的执行速度。虽然影响很小,但是也不应该小觑。

02、解决方案

考虑:把打印的信息写入文件中。

也就所谓的日志

03、Springboot的日志的解决方案(掌握)

在springboot的底层日志结构中对应:spring-boot-starter-logging可以看出,它依赖了三个框架分别是:

spring-boot-starter-logging 依赖已经被

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

如下:
在这里插入图片描述

04、查看springboot的日志的整个体系

在这里插入图片描述

在springboot的底层日志结构中对应:spring-boot-starter-logging可以看出,它依赖了三个框架分别是:

  • slf4j
  • logback
  • log4j

05、slf4j、logback和log4j三者的关系

1、logback和log4j是日志实现框架,就是实现怎么记录日志的。

2、slf4j:提供了java所有的日志框架的简单抽象(使用了日志的门面设计模式),

说白了就是一个日志API(没有实现类), 它不能单独使用

必须要结logbacklog4j日志框架来实现结合使用。

06、springboot的日志搭配

springboot2.x以后默认采用了:slf4j+logback的日志搭配。
在开发过程中,我们可以采用slf4j的api去记录日志,底层的实现就是根据配置来决定使用logback还是log4j日志框架。

如:

package com.kuangstudy.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * @description:
 * @author: xuke
 * @time: 2021/6/1 19:58
 */
@RestController
public class LogController {
    private static final Logger log = LoggerFactory.getLogger(LogController.class);
    @GetMapping("/log")
    public void console(){
        log.trace("----------trace--------");
        log.debug("----------debug--------");
        log.info("----------info--------");
        log.warn("----------warn--------");
        log.error("----------error--------");
    }
}

分析核心代码


// 初始化一个日志对象
private static Logger log = LoggerFactory.getLogger(IndexController.class);

上面打印的结果是:

2021-06-21 20:49:58.686(日志时间)  INFO(日志的级别) 16448(编号) --- [nio-9999-exec-1] (线程名称)c.kuangstudy.controller.IndexController(日志打印类) : ----------info--------(日志信息)
2021-06-21 20:49:58.686  WARN 16448 --- [nio-9999-exec-1] c.kuangstudy.controller.IndexController  : ----------warn--------
2021-06-21 20:49:58.686 ERROR 16448 --- [nio-9999-exec-1] c.kuangstudy.controller.IndexController  : ----------error--------

上面为什么仅仅打印了: info > warn > error 告诉你springboot默认日志级别是:info

07、日志级别(掌握)

 log.trace("----------trace--------");
 log.debug("----------debug--------");
 log.info("----------info--------");
 log.warn("----------warn--------");
 log.error("----------error--------");

顺序是:trace>debug>info>warn>error

小结:

springboot默认日志级别是:info

springboot2.x以后默认采用了:slf4j+logback的日志搭配。

日志级别:trace>debug>info>warn>error

08、日志级别的修改(必须掌握)

你要有认识,springboot,mybatis,hibernate这些框架都是采用日志管理他们的信息的打印。

整体修改:

#  指定日志级别 把springboot的所有日志修改成为debug
logging:
  level:
    root: debug

局部修改:

#  指定日志级别 把springboot的所有日志修改成为debug
logging:
  level:
    com:
      kuangstudy: debug

09、日志输出文件和日志格式(了解)

默认情况:springboot日志打印是在console(控制台中)。方便我们开发和查看。建议大家在开发的时候使用:debug日志,在生成环境中使用:error 。(为什么?)

日志输出文件:默认情况下关闭。

在开发中建议大家是打开,不打开也没有关闭,你可以项目发布制定日志输出的文件:(可以先不理会)

nohup java -jar xxxx.jar >>log.txt &

使用path的方式

server:
  port: 9999
logging:
  level:
    root: info
  file:
    # 默认情况下:会在项目的根目录下生成/output/logs/spring.log,默认的日志名是:spring.log
    path: output/logs
    # 如果不想把日志存放在logging.file.path目录下,可以采用name来重新定义存储的位置和日志文件的名称
    #name: d:/output/logs/console.log
  pattern:
    console: "%d{yyyy/MM/dd-HH:mm:ss} [%thread] %-5level %logger{50}- %msg%n"
    file: "%d{yyyy/MM/dd-HH:mm:ss} ---- [%thread] %-5level %logger{50}- %msg%n"

日志格式

%c 输出logger名称
%C 输出类名
%d{HH:mm:ss.SSS} 表示输出到毫秒的时间
%t 输出当前线程名称
%-5level 输出日志级别,-5表示左对齐并且固定输出5个字符,如果不足在右边补0
%logger 输出logger名称,因为Root Logger没有名称,所以没有输出
%msg 日志文本
%n 换行
其他常用的占位符有:
%F 输出所在的类文件名,如Log4j2Test.java
%L 输出行号
%M或%method 输出所在方法名
%l 输出完整的错误位置, 包括类名、方法名、文件名、行数
%p 该条日志的优先级
%replace{pattern}{regex}{substitution} 将pattern的输出结果pattern按照正则表达式regex替换成substitution

一般来说不建议大家去修改,除非有特殊场景,比如后续我们秋招课程班中要讲的:elk 收集日志的时候,很方便的去定义格式

10、日志的使用方式和注意事项(必须要掌握)

日志的的使用

package com.kuangstudy.controller;

import com.kuangstudy.entity.Course;
import com.kuangstudy.entity.User;
import com.kuangstudy.service.WeixinPayService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @description:
 * @author: xuke
 * @time: 2021/6/20 20:22
 */
@RestController
public class IndexController {


    // 初始化一个日志对象
    private static Logger log = LoggerFactory.getLogger(IndexController.class);


    @Autowired
    private WeixinPayService weixinPayService;


    @GetMapping("/index")
    public String test() {
//        weixinPayService.testvalue();
        weixinPayService.testvalue2();
        return "success";
    }


    /**
     * @return java.lang.String
     * @Author xuke
     * @Description 打印日志
     * @Date 20:54 2021/6/21
     * @Param []
     **/
    @GetMapping("/logs")
    public String consolelogs() {

        User user = new User();
        user.setId(1);

        Course course = new Course();
        course.setCourseid(100);
        course.setTitle("学相伴秋招课程班");
        course.setPrice("1999");

        weixinPayService.paycourse(user, course);
        return "success";
    }

}

具体实现

package com.kuangstudy.service;

import com.kuangstudy.config.WeixinPayProperties;
import com.kuangstudy.entity.Course;
import com.kuangstudy.entity.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

/**
 * @description:
 * @author: xuke
 * @time: 2021/6/20 21:18
 */
@Service
public class WeixinPayService {

    private static Logger log = LoggerFactory.getLogger(WeixinPayService.class);

    @Autowired
    private WeixinPayProperties weixinPayProperties;

    public void testvalue2() {
        System.out.println(weixinPayProperties.getAppid());
        System.out.println(weixinPayProperties.getApisecret());
        System.out.println(weixinPayProperties.getMcid());
        System.out.println(weixinPayProperties.getCallbackurl());
    }


    public void paycourse(User user, Course course) {
        try {
            System.out.println(1/0);
            log.info("当前支付的用户是:{},支付的课程是:{},金额是:{}", user.getId(), course.getTitle(), course.getPrice());
            log.info("支付的appid是:{},回调地址是:{}", weixinPayProperties.getAppid(), weixinPayProperties.getCallbackurl());
        } catch (Exception ex) {
            log.error("支付出异常,异常信息是:{}", ex.getMessage());
        }

    }
}

具体访问查看:

http://localhost:9999/logs

11、lombok优化日志的定义(必须掌握)

在lombok中提供了两个日志注解的支持:@Slf4j@Log4j2 建议在开发过程中就默认选择:@Slf4j

前提:必须要安装lombok的插件和依赖

 <dependency>
     <groupId>org.projectlombok</groupId>
     <artifactId>lombok</artifactId>
     <version>1.18.20</version>
</dependency>
package com.kuangstudy.service;

import com.kuangstudy.config.WeixinPayProperties;
import com.kuangstudy.entity.Course;
import com.kuangstudy.entity.User;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

/**
 * @description:
 * @author: xuke
 * @time: 2021/6/20 21:18
 */
@Service
@Slf4j // 相当于: private static Logger log = LoggerFactory.getLogger(WeixinPayService.class);
public class WeixinPayService {

    @Autowired
    private WeixinPayProperties weixinPayProperties;

    public void testvalue2() {
        System.out.println(weixinPayProperties.getAppid());
        System.out.println(weixinPayProperties.getApisecret());
        System.out.println(weixinPayProperties.getMcid());
        System.out.println(weixinPayProperties.getCallbackurl());
    }


    public void paycourse(User user, Course course) {
        try {
            System.out.println(1/0);
            log.info("当前支付的用户是:{},支付的课程是:{},金额是:{}", user.getId(), course.getTitle(), course.getPrice());
            log.info("支付的appid是:{},回调地址是:{}", weixinPayProperties.getAppid(), weixinPayProperties.getCallbackurl());
        } catch (Exception ex) {
            log.error("支付出异常,异常信息是:{}", ex.getMessage());
        }
    }
}

查看编译以后的结果:

在这里插入图片描述

12、在开发中日志级别隔离(必须要掌握)

因为在开发中,我们分为生成环境和开发环境。开发环境的级别一般建议大家使用:debug或者info 。但是在生产环境中建议大家使用:error .所有我们可以使用起那么学习的环境隔离的机制,进行解决

application-dev.yml

开发环境:一般就在控制台打印即可,写文件着实没有任何意义。 日志级别是:debug

server:
  port: 9999

#自定义属性
ksd:
  weixin:
    appid: 456453sdfsd52342
    mcid: 48878787
    callbackurl: https://www.kuangstudy.com/pay/callback
    apisecret: SDFLKSDJFKLSJKLJ23423423


#  指定日志级别 把springboot的所有日志修改成为debug
logging:
  level:
    root: debug
  pattern:
    # console是控制台的日志的格式
    console: "【KuangStudy-console】%d{yyyy/MM/dd-HH:mm:ss} [%thread] %-5level %logger{50} --%M- %msg%n"

####application-prod.yml

开发环境:一般就在控制台打印即可,写文件着实没有任何意义。 日志级别是:error

server:
  port: 80

#  指定日志级别 把springboot的所有日志修改成为debug
logging:
  level:
    root: error
  file:
    # 如果不想把日志存放在logging.file.path目录下,可以采用name来重新定义存储的位置和日志文件的名称
    name: /www/logs/kuangstudypro.log
  pattern:
    # file 是指日志文件中日志的格式
    file: "【KuangStudy-file】%d{yyyy/MM/dd-HH:mm:ss} -- [%thread] %-5level %logger{50} -- %M - %msg%n"

日志输出文件:默认情况下关闭。

在开发中建议大家是打开,不打开也没有关闭,你可以项目发布制定日志输出的文件:(可以先不理会)

nohup java -jar xxxx.jar >>log.txt &
application.yml
# 环境激活
spring:
  profiles:
    active: dev

log学习方式:20分钟(建议复制粘贴)

1:基本使用

2:证明日志的优先级

3:使用lombok去优化日志定义

4:定义真实一点的日志输出规范,去明白占位符{}的含义。

5:了解一些日志输出

6:环境隔离

补充学习:

logback.xml
  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值