springboot+LogBack日志整合(部分源码及应用详解)

springboot整合logback的误区

好多人在做springbott+logback整合的时候做了如下的引用

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-core</artifactId>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-to-slf4j</artifactId>
</dependency>

这并不是错的,只是这些操作多余了。

其实springboot默认已经整合了LogBack

在创建Spring Boot工程时引入的spring-boot-starter就已经包含了spring-boot-starter-logging,而spring-boot-starter-logging中引用了logback的依赖

下面翻开源码看一下

  • Ctrl+鼠标右键点击
    在这里插入图片描述
  • 继续Ctrl+鼠标右键点击进入下一层
    在这里插入图片描述
  • 向下翻到大约480行左右
    在这里插入图片描述
  • 已经出现logging,继续Ctrl+右键进入下一层
    在这里插入图片描述

下面开始介绍logback的使用

  • 首先引入springboot中logback的最佳搭档 lombok
    pom文件中增加 lombok 依赖
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
  • 然后编辑springboot启动类测试一下日志控制台打印
  • 使用@Slf4j 注解 可以直接使用log().
package com.example.demo;
 
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@Slf4j
@SpringBootApplication
@MapperScan({"com.example.demo.dao"})
public class DemoSpringbootMybatisApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(DemoSpringbootMybatisApplication.class, args);
        System.out.println("Hello Dyzz");
        log.info("大眼直转!~info");
        log.error("大眼直转!~error");
        log.warn("大眼直转!~warn");
    }
}
  • 启动springboot 观察控制台输出
    在这里插入图片描述
    OK ! 调用logback打印控制台日志成功。
    在springboot配置文件中的简单配置logback
    编辑application.yml配置文件,增加
logging:
  file: dyzz.log
  level:
    root: info
  • 启动springboot
    在这里插入图片描述

logback-spring.xml配置文件介绍

springboot是约定型框架,好多相关配置都是官方约定好的,比如说logback在springboot中的配置文件名
官方推荐为logback-spring.xml,当然这个命名不是spring官方拍脑袋随便给的,因为带spring后缀的配置文件可以使用这个标签。
下面介绍logback-spring.xml 相关配置
实现日志三级(info,warn,error)分开保存,日志10M三级切割,为期30天自动删除功能。

  • 首先编写springboot配置文件将logback配置写入application.xml
logging:
  config:
    classpath: logback-spring.xml
  • 然后在resources目录下创建logback-spring.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
    <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
    <property name="LOG_HOME" value="/home/logs/"/>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度,%line:行号,%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} Line:%line ----------------> %msg%n
            </pattern>
        </layout>
    </appender>
    <!-- 按照每天生成日志文件 INFO_FILE-->
    <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文件的路径及文件名 -->
        <file>${LOG_HOME}/zyzz-info.log</file>
        <!--日志文件最大的大小-->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>10MB</MaxFileSize>
        </triggeringPolicy>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件输出的文件名-->
            <FileNamePattern>${LOG_HOME}/zyzz-info-%d{yyyy-MM-dd}.%i.log</FileNamePattern>
            <!--日志文件保留天数-->
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文件保留天数-->
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} Line:%line ----------------> %msg%n
            </pattern>
            <!-- 设置字符集 -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>
 
    <!-- 按照每天生成日志文件 WARN_FILE-->
    <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文件的路径及文件名 -->
        <file>${LOG_HOME}/zyzz-warn.log</file>
        <!--日志文件最大的大小-->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>10MB</MaxFileSize>
        </triggeringPolicy>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>WARN</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件输出的文件名-->
            <FileNamePattern>${LOG_HOME}/zyzz-warn-%d{yyyy-MM-dd}.%i.log</FileNamePattern>
            <!--日志文件保留天数-->
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文件保留天数-->
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} Line:%line ----------------> %msg%n
            </pattern>
            <!-- 设置字符集 -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>
 
    <!-- 按照每天生成日志文件 ERROR_FILE-->
    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文件的路径及文件名 -->
        <file>${LOG_HOME}/zyzz-error.log</file>
        <!--日志文件最大的大小-->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>10MB</MaxFileSize>
        </triggeringPolicy>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件输出的文件名-->
            <FileNamePattern>${LOG_HOME}/zyzz-error-%d{yyyy-MM-dd}.%i.log</FileNamePattern>
            <!--日志文件保留天数-->
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文件保留天数-->
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} Line:%line ----------------> %msg%n
            </pattern>
            <!-- 设置字符集 -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>
    <appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
        <!--不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
        <queueSize>512</queueSize>
        <!--添加附加的appender,最多只能添加一个-->
        <appender-ref ref="ERROR_FILE"/>
    </appender>
    <root level="INFO">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="INFO_FILE"/>
        <appender-ref ref="WARN_FILE"/>
        <appender-ref ref="ERROR_FILE"/>
        <appender-ref ref="ASYNC"/>
    </root>
</configuration>

编写测试类初步测试。
这里调用springboot 定时任务刷新一分钟日志后停止服务观察日志打印情况。
编写springboot启动类主要是为了增加定时任务

package com.example.demo;
 
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
 
@Slf4j
@SpringBootApplication
//定时任务
@EnableScheduling
@MapperScan({"com.example.demo.dao"})
public class DemoSpringbootMybatisApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(DemoSpringbootMybatisApplication.class, args);
        System.out.println("Hello Dyzz");
        log.info("大眼直转!~info");
        log.error("大眼直转!~error");
        log.warn("大眼直转!~warn");
    }
}

编写定时任务执行类–引用优快云大神趣味弄弄的注释画

package com.example.demo.scheduled;
 
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
 
/**
 * @author :hxg
 * @ClassName DyzzScheduledService
 * @date :Created in 2020/4/24 16:01
 */
@Async
@Component
@Slf4j
public class DyzzScheduledService {
 
    @Scheduled(cron = "0/1 * * * * *")
    public void DyzzScheduledForlog() {
 
        log.info("/*        .---.        .-----------\n" +
                "*       /     \\  __  /    ------\n" +
                "*      / /     \\(  )/    -----\n" +
                "*     //   ' \\/ `   ---\n" +
                "*     / // :    : ---\n" +
                "*   // /   /  /`    '--\n" +
                "*  //          //..\\\\\n" +
                "*         ====UU====UU====\n" +
                "*             '//||\\\\`\n" +
                "*               ''``\n" +
                "*/  \n" +
                "/*\n" +
                "*                    .-'-._\n" +
                "*                   /    e<\n" +
                "*               _.-''';  (\n" +
                "*     _______.-''-._.-'  /\n" +
                "*     ====---:_''-'     /  _  _     %%%%\n" +
                "*              '-=. .-'` _(_)(_)   %%|/%%%\n" +
                "*                _|_\\_  (_)(_)(_) %%%%%%%%%%\n" +
                "*               //\\\\//\\\\//\\\\//\\\\//\\\\%/_%%%%%%%\n" +
                "*           ____\\\\//\\\\//\\\\//\\\\//\\\\// |__|/__%%%\n" +
                "*  ________(___  \\\\/\\//\\\\//\\\\//\\\\//__//___%%%%%%%\n" +
                "*            / \\  \\_/ __ \\___//------\\--%%%%%%\n" +
                "*  _________/   \\____/  \\____/\\\\%%%%%%%%%%%%\n" +
                "*                              \\_-%%%%%%%%\n" +
                "*\n" +
                "*/\n" +
                "———————————————————————————————————————");
 
 
        log.warn("//                _,--.       ,--._\n" +
                "//                \\  > `|>o<|' <  /\n" +
                "//                 `-.         .-'\n" +
                "//                   / 'e___e` \\\n" +
                "//                  (   (o o)   )\n" +
                "//                  _\\_  `='  _/_\n" +
                "//                 / /(`-._.-')\\ \\\n" +
                "//                / /  `.___,'  \\_\\\n" +
                "//              _/ /    _____    \\ \\_\n" +
                "//             / _(_,--'     `--._)_ \\\n" +
                "//             `'  )______@______(  `'\n" +
                "//           hjw  /               \\\n" +
                "//               /_________________\\\n" +
                "//                  \\     )(     /\n" +
                "//                   \\   /  \\   /\n" +
                "//                    )  |  |  (\n" +
                "//                   /`-']  [`-'\\\n" +
                "//                   `--'    `--'\n" +
                "//\n" +
                "————————————————————————————\n");
 
        log.error("//                            _ooOoo_    \n" +
                "//                           o8888888o    \n" +
                "//                           88\" . \"88    \n" +
                "//                           (| -_- |)    \n" +
                "//                            O\\ = /O    \n" +
                "//                        ____/`---'\\____    \n" +
                "//                      .   ' \\\\| |// `.    \n" +
                "//                       / \\\\||| : |||// \\    \n" +
                "//                     / _||||| -:- |||||- \\    \n" +
                "//                       | | \\\\\\ - /// | |    \n" +
                "//                     | \\_| ''\\---/'' | |    \n" +
                "//                      \\ .-\\__ `-` ___/-. /    \n" +
                "//                   ___`. .' /--.--\\ `. . __    \n" +
                "//                .\"\" '< `.___\\_<|>_/___.' >'\"\".    \n" +
                "//               | | : `- \\`.;`\\ _ /`;.`/ - ` : | |    \n" +
                "//                 \\ \\ `-. \\_ __\\ /__ _/ .-` / /    \n" +
                "//         ======`-.____`-.___\\_____/___.-`____.-'======    \n" +
                "//                            `=---='    \n" +
                "//    \n" +
                "//         .............................................    \n" +
                "//                  佛祖保佑             永无BUG\n" +
                "————————————————--------------------------------------\n" );
    }
}

启动服务,观察运行结果–控制台
在这里插入图片描述

  • 查看log存放路径
    在这里插入图片描述
  • 查看日志文件–error
    在这里插入图片描述
  • info
    在这里插入图片描述
  • warn
    在这里插入图片描述
    OK ,logback 集成测试成功。

转载至:大眼转转传送门

$(function(){ $.fn.extend({ SimpleTree:function(options){ //初始化参数 var option = $.extend({ click:function(a){ } },options); option.tree=this; /* 在参数对象中添加对当前菜单树的引用,以便在对象中使用该菜单树 */ option._init=function(){ /* * 初始化菜单展开状态,以及分叉节点的样式 */ this.tree.find("ul ul").hide(); /* 隐藏所有子级菜单 */ this.tree.find("ul ul").prev("li").removeClass("open"); /* 移除所有子级菜单父节点的 open 样式 */ this.tree.find("ul ul[show='true']").show(); /* 显示 show 属性为 true 的子级菜单 */ this.tree.find("ul ul[show='true']").prev("li").addClass("open"); /* 添加 show 属性为 true 的子级菜单父节点的 open 样式 */ }/* option._init() End */ /* 设置所有超链接不响应单击事件 */ this.find("a").click(function(){ $(this).parent("li").click(); return false; }); /* 菜单项 接受单击 */ this.find("li").click(function(){ /* * 当单击菜单项 * 1.触发用户自定义的单击事件,将该 标签中的第一个超链接做为参数传递过去 * 2.修改当前菜单项所属的子菜单的显示状态(如果等于 true 将其设置为 false,否则将其设置为 true) * 3.重新初始化菜单 */ option.click($(this).find("a")[0]); /* 触发单击 */ /* * 如果当前节点下面包含子菜单,并且其 show 属性的值为 true,则修改其 show 属性为 false * 否则修改其 show 属性为 true */ /* if($(this).next("ul").attr("show")=="true"){ $(this).next("ul").attr("show","false"); }else{ $(this).next("ul").attr("show","true"); }*/ /* 初始化菜单 */ option._init(); }); /* 设置所有父节点样式 */ this.find("ul").prev("li").addClass("folder"); /* 设置节点“是否包含子节点”属性 */ this.find("li").find("a").attr("hasChild",false); this.find("ul").prev("li").find("a").attr("hasChild",true); /* 初始化菜单 */ option._init(); }/* SimpleTree Function End */ }); });
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值