• logback自定义appender


    1、定义appender

    1.1 logback.xml配置

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <configuration>
    3. <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径 -->
    4. <!-- <property name="LOG_HOME" value="d:" /> -->
    5. <!-- ch.qos.logback.core.ConsoleAppender 控制台输出 -->
    6. <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
    7. <encoder>
    8. <pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %logger{36} - %msg%n
    9. </pattern>
    10. </encoder>
    11. </appender>
    12. <!-- 自定义文件输出-错误日志 -->
    13. <appender name="ErrorFile" class="com.ybw.logback.demo.filter.LogFileAppender">
    14. <File>${LOG_HOME:-c:/}logs/error/error.log</File>
    15. <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    16. <FileNamePattern>${LOG_HOME:-c:/}logs/error/error-%d{yyyy-MM-dd}.%i.log
    17. </FileNamePattern>
    18. <MaxHistory>30</MaxHistory>
    19. <TimeBasedFileNamingAndTriggeringPolicy
    20. class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
    21. <MaxFileSize>100MB</MaxFileSize>
    22. </TimeBasedFileNamingAndTriggeringPolicy>
    23. </rollingPolicy>
    24. <filter class="ch.qos.logback.classic.filter.LevelFilter"><!-- 只打印错误日志 -->
    25. <level>ERROR</level>
    26. <onMatch>ACCEPT</onMatch>
    27. <onMismatch>DENY</onMismatch>
    28. </filter>
    29. <encoder charset="UTF-8">
    30. <pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %logger{36} - %msg%n</pattern>
    31. </encoder>
    32. </appender>
    33. <root level="info">
    34. <appender-ref ref="stdout"/>
    35. <appender-ref ref="ErrorFile"/>
    36. </root>
    37. </configuration>

     1.2 自定义appender代码

    1. package com.ybw.logback.demo.filter;
    2. import ch.qos.logback.core.encoder.Encoder;
    3. import ch.qos.logback.core.rolling.RollingFileAppender;
    4. import ch.qos.logback.core.spi.DeferredProcessingAware;
    5. import ch.qos.logback.core.status.ErrorStatus;
    6. import com.ybw.logback.demo.constant.fs.FSConstant;
    7. import com.ybw.logback.demo.utils.FsUtils;
    8. import java.io.IOException;
    9. /**
    10. * 自定义的appender
    11. * 1.可以对接受到的event中的日志信息做任何操作处理
    12. * 2.可以在同步写日志文件的时候,存入MySQL或者es
    13. *
    14. * @author ybw
    15. * @version V1.0
    16. * @className LogFileAppender
    17. * @date 2022/9/16
    18. **/
    19. public class LogFileAppender<E> extends RollingFileAppender<E> {
    20. public void setEncoder(Encoder encoder) {
    21. //自定义的appender的父类OutputStreamAppender在启动的时候会判断是否有encoder ,无的话自定义appender启动会失败
    22. super.setEncoder(encoder);
    23. }
    24. /**
    25. * 覆盖父类OutputStreamAppender的日志记录功能,再这里面做日志切操作功能
    26. *
    27. * @param event
    28. */
    29. protected void subAppend(E event) {
    30. if (this.isStarted()) {
    31. try {
    32. if (event instanceof DeferredProcessingAware) {
    33. ((DeferredProcessingAware) event).prepareForDeferredProcessing();
    34. }
    35. //根据标签规则拿到日志字符串,这里可以再次修改日志信息
    36. byte[] byteArray = super.encoder.encode(event);
    37. //做一些日志的特殊处理
    38. sendFs(byteArray);
    39. // writeMongo(...);
    40. // writeRedis(...);
    41. // writeMq(...);
    42. //写入日志文件
    43. writeBytes(byteArray);
    44. } catch (IOException var3) {
    45. this.started = false;
    46. this.addStatus(new ErrorStatus("IO failure in appender", this, var3));
    47. }
    48. }
    49. }
    50. /**
    51. * 飞书报警
    52. *
    53. * @param byteArray
    54. * @methodName: sendFs
    55. * @return: void
    56. * @author: ybw
    57. * @date: 2022/9/15
    58. **/
    59. private void sendFs(byte[] byteArray) {
    60. if (byteArray != null && byteArray.length != 0) {
    61. this.lock.lock();
    62. try {
    63. FsUtils.sendTextMessage(FSConstant.TextContentEnum.ERROR_LOG, new String(byteArray));
    64. } finally {
    65. this.lock.unlock();
    66. }
    67. }
    68. }
    69. private void writeBytes(byte[] byteArray) throws IOException {
    70. if (byteArray != null && byteArray.length != 0) {
    71. this.lock.lock();
    72. try {
    73. this.getOutputStream().write(byteArray);
    74. if (this.isImmediateFlush()) {
    75. this.getOutputStream().flush();
    76. }
    77. } finally {
    78. this.lock.unlock();
    79. }
    80. }
    81. }
    82. }

    1.3 测试

    1. package com.ybw.logback.demo.custom;
    2. import lombok.extern.slf4j.Slf4j;
    3. import org.junit.jupiter.api.Test;
    4. /**
    5. * @className CustomLog
    6. * @author ybw
    7. * @date 2022/9/15
    8. * @version V1.0
    9. **/
    10. @Slf4j
    11. public class CustomLog {
    12. /**
    13. *
    14. * @methodName: print
    15. * @return: void
    16. * @author: ybw
    17. * @date: 2022/9/15
    18. **/
    19. @Test
    20. public void print(){
    21. log.info("aa");
    22. log.error("bb");
    23. }
    24. }

    错误日志、报警内容如下:

    [ERROR] 2022-09-17 18:07:51.577 [main] c.ybw.logback.demo.custom.CustomLog - bb
    

    2、logback.xml变量使用-spring配置

    logback的变量作用于有三种:local,context,system

    •  local 作用域在配置文件内有效;
    •  context 作用域的有效范围延伸至 logger context;
    •  system 作用域的范围最广,整个 JVM 内都有效;

    logback 在替换变量时,首先搜索 local 变量,然后搜索 context,然后搜索 system,在spring项目中,应将变量的作用域设置为context,并交给spring控制。

    2.1 spring的配置作为变量

    application.yml

    1. server:
    2. port: 8080
    3. spring:
    4. application:
    5. name: logback-online-alarm
    6. profiles:
    7. active: dev

    application-dev.yml

    1. #飞书
    2. fs:
    3. bot:
    4. webhook:
    5. suf: /aa #测试

    logback.xml配置如下,PROFILES-ACTIVE、FS-BOT-WEBHOOK-SUF为spring配置文件中的属性

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <configuration>
    3. <!--获取spring配置文件的变量-->
    4. <springProperty scope="context" name="PROFILES-ACTIVE" source="spring.profiles.active" defaultValue=""/>
    5. <springProperty scope="context" name="FS-BOT-WEBHOOK-SUF" source="fs.bot.webhook.suf" defaultValue=""/>
    6. <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径 -->
    7. <!-- <property name="LOG_HOME" value="d:" /> -->
    8. <!-- ch.qos.logback.core.ConsoleAppender 控制台输出 -->
    9. <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
    10. <encoder>
    11. <pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %logger{36} - %msg%n
    12. </pattern>
    13. </encoder>
    14. </appender>
    15. <!-- 所有日志输出 -->
    16. <appender name="AllFile"
    17. class="ch.qos.logback.core.rolling.RollingFileAppender">
    18. <File>${LOG_HOME:-c:/}logs/all/all.log</File>
    19. <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    20. <FileNamePattern>${LOG_HOME:-c:/}logs/all/all-%d{yyyy-MM-dd}.%i.log
    21. </FileNamePattern>
    22. <MaxHistory>30</MaxHistory>
    23. <TimeBasedFileNamingAndTriggeringPolicy
    24. class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
    25. <MaxFileSize>100MB</MaxFileSize>
    26. </TimeBasedFileNamingAndTriggeringPolicy>
    27. </rollingPolicy>
    28. <layout class="ch.qos.logback.classic.PatternLayout">
    29. <pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %logger{36} - %msg%n
    30. </pattern>
    31. </layout>
    32. </appender>
    33. <!-- 自定义文件输出-错误日志 -->
    34. <appender name="ErrorFile" class="com.ybw.logback.demo.config.LogFileAppender">
    35. <File>${LOG_HOME:-c:/}logs/error/error.log</File>
    36. <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    37. <FileNamePattern>${LOG_HOME:-c:/}logs/error/error-%d{yyyy-MM-dd}.%i.log
    38. </FileNamePattern>
    39. <MaxHistory>30</MaxHistory>
    40. <TimeBasedFileNamingAndTriggeringPolicy
    41. class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
    42. <MaxFileSize>100MB</MaxFileSize>
    43. </TimeBasedFileNamingAndTriggeringPolicy>
    44. </rollingPolicy>
    45. <filter class="ch.qos.logback.classic.filter.LevelFilter"><!-- 只打印错误日志 -->
    46. <level>ERROR</level>
    47. <onMatch>ACCEPT</onMatch>
    48. <onMismatch>DENY</onMismatch>
    49. </filter>
    50. <encoder charset="UTF-8">
    51. <pattern>[${PROFILES-ACTIVE}] [%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %logger{36} - %msg%n</pattern>
    52. </encoder>
    53. <fsSuf>${FS-BOT-WEBHOOK-SUF}</fsSuf>
    54. </appender>
    55. <root level="info">
    56. <appender-ref ref="stdout"/>
    57. <appender-ref ref="ErrorFile"/>
    58. <appender-ref ref="AllFile"/>
    59. </root>
    60. </configuration>

    2.2 自定义appender代码

    1. package com.ybw.logback.demo.config;
    2. import ch.qos.logback.core.encoder.Encoder;
    3. import ch.qos.logback.core.rolling.RollingFileAppender;
    4. import ch.qos.logback.core.spi.DeferredProcessingAware;
    5. import ch.qos.logback.core.status.ErrorStatus;
    6. import com.ybw.logback.demo.constant.fs.FSConstant;
    7. import com.ybw.logback.demo.utils.FsUtils;
    8. import lombok.Data;
    9. import java.io.IOException;
    10. /**
    11. * 自定义的appender
    12. * 1.可以对接受到的event中的日志信息做任何操作处理
    13. * 2.可以在同步写日志文件的时候,存入mysql或者es
    14. *
    15. * @author ybw
    16. * @version V1.0
    17. * @className LogFileAppender
    18. * @date 2022/9/16
    19. **/
    20. @Data
    21. public class LogFileAppender<E> extends RollingFileAppender<E> {
    22. private String fsSuf;
    23. @Override
    24. public void setEncoder(Encoder encoder) {
    25. //自定义的appender的父类OutputStreamAppender在启动的时候会判断是否有encoder ,无的话自定义appender启动会失败
    26. super.setEncoder(encoder);
    27. }
    28. /**
    29. * 覆盖父类OutputStreamAppender的日志记录功能,再这里面做日志切操作功能
    30. *
    31. * @param event
    32. */
    33. @Override
    34. protected void subAppend(E event) {
    35. if (this.isStarted()) {
    36. System.out.println("fsSuf:"+fsSuf);
    37. try {
    38. if (event instanceof DeferredProcessingAware) {
    39. ((DeferredProcessingAware) event).prepareForDeferredProcessing();
    40. }
    41. //根据标签规则拿到日志字符串,这里可以再次修改日志信息
    42. byte[] byteArray = super.encoder.encode(event);
    43. //做一些日志的特殊处理
    44. sendFs(byteArray);
    45. // writeMongo(...);
    46. // writeRedis(...);
    47. // writeMq(...);
    48. //写入日志文件
    49. writeBytes(byteArray);
    50. } catch (IOException var3) {
    51. this.started = false;
    52. this.addStatus(new ErrorStatus("IO failure in appender", this, var3));
    53. }
    54. }
    55. }
    56. /**
    57. * 飞书报警
    58. *
    59. * @param byteArray
    60. * @methodName: sendFs
    61. * @return: void
    62. * @author: ybw
    63. * @date: 2022/9/15
    64. **/
    65. private void sendFs(byte[] byteArray) {
    66. if (byteArray != null && byteArray.length != 0) {
    67. this.lock.lock();
    68. try {
    69. FsUtils.sendTextMessage(FSConstant.TextContentEnum.ERROR_LOG, new String(byteArray));
    70. } finally {
    71. this.lock.unlock();
    72. }
    73. }
    74. }
    75. private void writeBytes(byte[] byteArray) throws IOException {
    76. if (byteArray != null && byteArray.length != 0) {
    77. this.lock.lock();
    78. try {
    79. this.getOutputStream().write(byteArray);
    80. if (this.isImmediateFlush()) {
    81. this.getOutputStream().flush();
    82. }
    83. } finally {
    84. this.lock.unlock();
    85. }
    86. }
    87. }
    88. }
    fsSuf为logback.xml配置的属性。
    

    2.3 测试

    1. package com.ybw.logback.demo.controller;
    2. import lombok.extern.slf4j.Slf4j;
    3. import org.springframework.web.bind.annotation.GetMapping;
    4. import org.springframework.web.bind.annotation.RestController;
    5. /**
    6. * @author ybw
    7. * @version V1.0
    8. * @className LogController
    9. * @date 2022/9/16
    10. **/
    11. @RestController
    12. @Slf4j
    13. public class LogController {
    14. /**
    15. *
    16. * @methodName: getLog
    17. * @return: java.lang.String
    18. * @author: ybw
    19. * @date: 2022/9/16
    20. **/
    21. @GetMapping("/getLog")
    22. public String getLog() {
    23. log.info("aa");
    24. log.error("bb");
    25. return "OK";
    26. }
    27. }

    访问接口:http://localhost:8080/getLog

    错误日志、报警内容如下:

    [dev] [ERROR] 2022-09-17 18:30:31.513 [http-nio-8080-exec-5] c.y.l.demo.controller.LogController - bb

     [dev]为spring.profiles.active。

    3、logback.xml变量使用-配置中心

    以nacos为例

    3.1 配置文件

    bootstrap.yml配置

    1. server:
    2. port: 8080
    3. spring:
    4. application:
    5. name: logback-nacos
    6. profiles:
    7. active: dev
    8. logging:
    9. config: classpath:logback.xml #日志配置要放在nacos配置之后

    bootstrap-dev.yml配置

    1. spring:
    2. cloud:
    3. nacos:
    4. config:
    5. server-addr: localhost:8848
    6. username: nacos
    7. password: nacos
    8. namespace: nacos-config #命名空间
    9. # group: DEFAULT_GROUP #默认DEFAULT_GROUP
    10. file-extension: yml #配置中心的格式,默认为properties

    配置中心

     logback.xml

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <configuration>
    3. <!--获取spring配置文件的变量-->
    4. <springProperty scope="context" name="PROFILES-ACTIVE" source="spring.profiles.active" defaultValue=""/>
    5. <springProperty scope="context" name="FS-BOT-WEBHOOK-SUF" source="fs.bot.webhook.suf" defaultValue=""/>
    6. <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径 -->
    7. <!-- <property name="LOG_HOME" value="d:" /> -->
    8. <!-- ch.qos.logback.core.ConsoleAppender 控制台输出 -->
    9. <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
    10. <encoder>
    11. <pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %logger{36} - %msg%n
    12. </pattern>
    13. </encoder>
    14. </appender>
    15. <!-- 所有日志输出 -->
    16. <appender name="AllFile"
    17. class="ch.qos.logback.core.rolling.RollingFileAppender">
    18. <File>${LOG_HOME:-c:/}logs/all/all.log</File>
    19. <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    20. <FileNamePattern>${LOG_HOME:-c:/}logs/all/all-%d{yyyy-MM-dd}.%i.log
    21. </FileNamePattern>
    22. <MaxHistory>30</MaxHistory>
    23. <TimeBasedFileNamingAndTriggeringPolicy
    24. class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
    25. <MaxFileSize>100MB</MaxFileSize>
    26. </TimeBasedFileNamingAndTriggeringPolicy>
    27. </rollingPolicy>
    28. <layout class="ch.qos.logback.classic.PatternLayout">
    29. <pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %logger{36} - %msg%n
    30. </pattern>
    31. </layout>
    32. </appender>
    33. <!-- 自定义文件输出-错误日志 -->
    34. <appender name="ErrorFile" class="com.ybw.logback.demo.config.LogFileAppender">
    35. <File>${LOG_HOME:-c:/}logs/error/error.log</File>
    36. <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    37. <FileNamePattern>${LOG_HOME:-c:/}logs/error/error-%d{yyyy-MM-dd}.%i.log
    38. </FileNamePattern>
    39. <MaxHistory>30</MaxHistory>
    40. <TimeBasedFileNamingAndTriggeringPolicy
    41. class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
    42. <MaxFileSize>100MB</MaxFileSize>
    43. </TimeBasedFileNamingAndTriggeringPolicy>
    44. </rollingPolicy>
    45. <filter class="ch.qos.logback.classic.filter.LevelFilter"><!-- 只打印错误日志 -->
    46. <level>ERROR</level>
    47. <onMatch>ACCEPT</onMatch>
    48. <onMismatch>DENY</onMismatch>
    49. </filter>
    50. <encoder charset="UTF-8">
    51. <pattern>[${PROFILES-ACTIVE}] [%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %logger{36} - %msg%n</pattern>
    52. </encoder>
    53. <fsSuf>${FS-BOT-WEBHOOK-SUF}</fsSuf>
    54. </appender>
    55. <root level="info">
    56. <appender-ref ref="stdout"/>
    57. <appender-ref ref="ErrorFile"/>
    58. <appender-ref ref="AllFile"/>
    59. </root>
    60. </configuration>

    3.2 自定义appender代码

    与2.2一致。

    3.3 测试

    与2.3一致。

    fsSuf即配置中心的属性,会打印在控制台。

    fsSuf:/aa

  • 相关阅读:
    QT day1
    【开发方案】Android 双卡设备手动搜网功能适配
    【前端工程化】webpack使用require.context批量导入模块
    快捷输入法怎么设置
    杭州跨境电商政策支持
    csdn 格式规范
    达索智能制造解决方案,敏捷电芯制造如何赋能企业竞争力 | 百世慧®
    基于数字孪生的智慧城市是如何发展的?
    为啥小扎一直醉心于元宇宙的布局?
    4.2 数据库安全性控制
  • 原文地址:https://blog.csdn.net/xixingzhe2/article/details/126898788