zoukankan      html  css  js  c++  java
  • Maven项目配置Logback输出JSON格式日志

    最近,项目提出需求,日志需要固定输出为JSON格式,以便后端Flink程序解析.

    项目背景

    项目为简单的Maven项目,日志由Filebeat采集,因此不需要配置输出至Logstash.
    下面为pom.xml文件中配置的依赖,此处使用logstash-logback-encoder完成日志格式转换操作.

           <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>1.7.28</version>
            </dependency>
            <dependency>
                <groupId>net.logstash.logback</groupId>
                <artifactId>logstash-logback-encoder</artifactId>
                <version>6.1</version>
            </dependency>
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-classic</artifactId>
                <version>1.2.3</version>
            </dependency>
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-access</artifactId>
                <version>1.2.3</version>
            </dependency>
    

    Logback配置

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration scan="true" scanPeriod="60 seconds" debug="false">
        <contextName>probe</contextName>
    
       <!-- 配置文件存储地址  -->
        <property name="LOG_PATH" value="./logs"/>
    
        <!-- 读取应用程序配置文件中内容,获取下文所需要的region属性 --->
        <property resource="application.properties"/>
    
        <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
                <providers class="net.logstash.logback.composite.loggingevent.LoggingEventJsonProviders">
                    <pattern>
                        <pattern>
                            {
                            "date":"%d{yyyy-MM-dd HH:mm:ss.SSS}",
                            "level":"%level",
                            <!-- system属性由程序动态确定,通过Slf4j提供的MDC进行具体设置 -->
                            "system":"%X{system} ",
                            <!-- 读取配置文件中的属性,并设置至日志中  -->
                            "region":"${application.region}",
                            "filepath":"%class:%line",
                            "msg":"%msg"
                            }
                        </pattern>
                    </pattern>
                </providers>
                <charset>UTF-8</charset>
            </encoder>
            <append>true</append>
    
            <!--  配置日志文件滚动存储策略 -->
            <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
                <fileNamePattern>${LOG_PATH}/probe.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
                <MaxHistory>10</MaxHistory>
                <maxFileSize>10MB</maxFileSize>
                <totalSizeCap>300MB</totalSizeCap>
            </rollingPolicy>
        </appender>
    
        <root level="FILE">
            <appender-ref ref="console"/>
        </root>
    </configuration>
    

    上述即为logback.xml文件中的配置内容,需要注意日志中的region从配置文件application.properties中获取,而system属性则同msg字段一样由程序动态设置.

    MDC设置system属性

        /**
         * 衡量单次http请求的时延
         *
         * @param url 请求地址
         */
        private static void measureHttpTimeDelay(String url, Platform platform) {
            // MDC中设置system属性
            MDC.put("system", platform.toString());
            OkHttpClient client = new OkHttpClient();
            client.newBuilder().connectTimeout(5, TimeUnit.SECONDS)
                    .readTimeout(5, TimeUnit.SECONDS)
                    .build();
            Request request = new Request.Builder().url(url).build();
            Instant before = Instant.now();
            try (Response response = client.newCall(request).execute()) {
                Instant after = Instant.now();
                if (response.isSuccessful()) {
                    long duration = Duration.between(before, after).toMillis();
                    log.info("请求成功!" + response.message() + "时延 = " + duration + "ms");
                } else {
                    log.info("请求失败!" + response.message());
                }
            } catch (IOException e) {
                log.error("get http response failed, url: {}, ex: {}", url, e.getMessage());
            }
            // MDC中清除system属性设置
            MDC.remove("system");
        }
    

    上述程序,模拟一个简单的http请求,并记录相应日志.
    需要注意,MDCThreadLocal实现,因此在多线程环境下使用需要注意.

    最终日志

    最终日志如下图所示:

    {"date":"2019-09-05 21:16:44.643","level":"INFO","system":"ALI_YUN ","region":"HUABEI","filepath":"com.test.Application:38","msg":"请求成功!OK时延 = 439ms"}
    {"date":"2019-09-05 21:16:45.326","level":"INFO","system":"HUAWEI_YUN ","region":"HUABEI","filepath":"com.test.Application:38","msg":"请求成功!OK时延 = 165ms"}
    {"date":"2019-09-05 21:16:46.513","level":"INFO","system":"ALI_YUN ","region":"HUABEI","filepath":"com.test.Application:38","msg":"请求成功!OK时延 = 485ms"}
    {"date":"2019-09-05 21:16:56.130","level":"INFO","system":"HUAWEI_YUN ","region":"HUABEI","filepath":"com.test.Application:38","msg":"请求成功!OK时延 = 419ms"}
    

    PS:
    如果您觉得我的文章对您有帮助,请关注我的微信公众号,谢谢!
    程序员打怪之路

  • 相关阅读:
    二叉树知识拓展
    【2014年鄞州区】小幸福(e.pas/c/cpp)
    【2017年常州市】小X与队列 (queue)
    【2018年南海区甲组】扑克游戏(poker)
    【2018年南海区甲组】拆除桥墩(remove)
    【NOIP普及组模拟赛3】投影(skyline)
    常用正则表达式
    asp.net访问母版页控件方法
    C#文件读写操作
    C#读取csv格式文件
  • 原文地址:https://www.cnblogs.com/jason1990/p/11469881.html
Copyright © 2011-2022 走看看