Slf4j with cloud log system

Posted by Buyocat on Thu, 20 Jan 2022 14:23:12 +0100

Basic concepts

performance

These key points should be met:

(1) Easy to use, one line of code may be a problem.

(2) Easy integration, Ctrl C/V two minutes to get the kind.

(3) High performance can not affect the business itself, or the impact is the lowest when necessary. If a business takes 10 milliseconds and 9 milliseconds are spent on logs, don't talk about it.

(4) It is easy to maintain, easy to manage and not easy to lose. A single host is stored in the host, and the cluster is stored in a unified place.

(5) Easy to check, can quickly locate the place in case of problems.

classification

(1) TREC - long winded log (most of which can be directly ignored)

(2) DEBUG - DEBUG log

(3) INFO - daily log

(4) WARN - warning log

(5) ERROR - ERROR log

standard

It seems that there is no unified standard. Just do a good job in grading, and then the log collection should be as detailed and clear as possible. As for the form of expression, there are no special requirements.

Acquisition mode

Slf4j and other mainstream frameworks have realized printing to the console on demand and writing to the specified file according to the specified file format, so this is not the case.

Because Tencent cloud's log system is adopted (cloud or self built, both of which have the same logic), there is also a relevant SDK, so you only need to upload the log in the appropriate place.

(1) Upload before Slf4j. To put it bluntly, it is to encapsulate another layer and write a Log,ALog or something.

(2) Uploading in Slf4j mainly inherits its original filter and then uploads in the filter.

The first way feels like there's nothing to say. Here's the second way.

Open up

Guide Package

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.8</version>
            <scope>provided</scope>
        </dependency>

This gadget is a toolkit that integrates Slf4j and other practical things. After integrating this gadget, you only need log Info(), which is very convenient.

to configure

Create a new logconfig directory under the resources directory of the project, which contains four files, logconfig_dev.xml,logconfig_test.xml,logconfig_prod.xml,logconfig_pre.xml, corresponding to four different environments.

Then in application XML the appropriate location plus configuration

logging:
  level:
    com.alibaba.nacos.client.config.impl: WARN
    root: INFO
    org.hibernate: INFO
    org.hibernate.type.descriptor.sql.BasicExtractor: INFO
    com.ys.adage.mapper: INFO
    org.springframework: INFO
  config: classpath:logconfig/logconfig_dev.xml

Level - specifies the log level of some libraries

config - path to the configuration file

Paste a logconfig_xxx.xml configuration file

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <!--Output log format-->
    <appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>
                %d - %msg%n
            </pattern>
        </layout>
    </appender>
    <!--Save only info journal-->
    <appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <encoder>
            <pattern>
                %d - %msg%n
            </pattern>
        </encoder>
        <!--Rolling output strategy-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--route-->
            <fileNamePattern>/root/logs/email/info/info.%d.log</fileNamePattern>
        </rollingPolicy>
    </appender>

    <!--Save only warn journal-->
    <appender name="fileWarnLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>WARN</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <encoder>
            <pattern>
                %d - %msg%n
            </pattern>
        </encoder>
        <!--Rolling output strategy-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--route-->
            <fileNamePattern>/root/logs/email/warn/warn.%d.log</fileNamePattern>
        </rollingPolicy>
    </appender>

    <!--Save only error journal-->
    <appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
        <encoder>
            <pattern>
                %d - %msg%n
            </pattern>
        </encoder>
        <!--Rolling output strategy-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--route-->
            <fileNamePattern>/root/logs/email/error/error.%d.log</fileNamePattern>
        </rollingPolicy>
    </appender>

    <root level="info">
        <appender-ref ref="consoleLog"/>
        <appender-ref ref="fileInfoLog"/>
        <appender-ref ref="fileWarnLog"/>
        <appender-ref ref="fileErrorLog"/>
    </root>

</configuration>

Here we mainly define the file rules of log files, which log types need to be printed and written to the file, and which do not.

It is divided into three levels (error/info/warn). These three levels are the levels of writing files. Specifically, you can define the level of logs to be printed at these three levels. For example, in the development environment, info can print logs of info level and debug level.

filter

The core is in the logconfig configuration file. Some logs unrelated to the level need to be filtered. Therefore, two log filters, LevelFilter and ThresholdFilter, are configured. The difference between the two is that LevelFilter only prints logs of the specified level, and ThresholdFilter prints logs higher than the current setting level.

Therefore, we only need to rewrite the two filtering classes (one is enough) and send the log to Tencent's SDK before printing it.

Rewritten classes are actually very simple

public class LogFilter extends LevelFilter {

    @Override
    public FilterReply decide(ILoggingEvent event) {
        FilterReply filterReply = super.decide(event);
        if (FilterReply.DENY != filterReply) {
            //Determine the log level to print
            TencentLog.putLog(event.getLevel().levelStr, event.getMessage());//Transfer to SDK
        }
        return filterReply;
    }
}

Then change ipconfig_ xxx. The filter tag in the XML configuration file can specify the path of the filter to the LogFilter class we rewrite.

Finally, it is better to open a thread pool to process the code transferred to the SDK.

Topics: Java Back-end slf4j