loback 中的 socketAppender 的配置及使用

配置文件都是用官网的示例

server

<?xml version="1.0" encoding="UTF-8" ?>

<!-- ==================================================================== -->
<!-- This config file is intended to be used by a SocketServer that logs  -->
<!-- events received from various clients on the console and to a file    -->
<!-- that is rolled over when appropriate. The interesting point to note  -->
<!-- is that it is a configuration file like any other.                   -->
<!-- ==================================================================== -->

<configuration>

  <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">

    <layout class="ch.qos.logback.classic.PatternLayout">
      <Pattern>%date %-5level [%thread] %logger - %message%n</Pattern>
    </layout>

  </appender>

  <appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <File>rolling.log</File>
                <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
                        <FileNamePattern>rolling.%i.log.gz</FileNamePattern>
                        <MinIndex>1</MinIndex>
                </rollingPolicy>

                <triggeringPolicy
                        class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
                        <MaxFileSize>100MB</MaxFileSize>
                </triggeringPolicy>

    <layout class="ch.qos.logback.classic.PatternLayout">
      <Pattern>%relative %-5level %logger - %message%n</Pattern>
    </layout>
  </appender>

  <root>
    <level value ="debug"/>
    <appender-ref ref="ROLLING" />
  </root>
</configuration>

server 端的启动

java -Dport=6000 -DincludeCallerData=false -cp "/home/yourname/test/lib/*:.:"  ch.qos.logback.classic.net.SimpleSocketServer 6000 logback.xml

其中 /home/yourname/test/lib/ 目录下, 存放了logback所依赖的 jar 包文件.

client

client 端(官网的例子) 的 logback.xml

<configuration>

    <appender name="SOCKET" class="ch.qos.logback.classic.net.SocketAppender">
        <remoteHost>${host}</remoteHost>
        <port>${port}</port>
        <reconnectionDelay>10000</reconnectionDelay>
        <includeCallerData>${includeCallerData}</includeCallerData>
    </appender>

    <root level="DEBUG">
        <appender-ref ref="SOCKET"/>
    </root>

</configuration>

启动时要添加的参数

java -Dhost=logback服务器的IP地址 -Dport=logback服务器的监听端口 -DincludeCallerData=false -jar demo-rabbit-0.0.1-SNAPSHOT.jar.original

与 RabbitMQ 的性能对比

线上系统利用 rabbitmq 作为日志中转站. 所以想对比一下性能. 测试代码

package com.example.demo.demorabbit;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

@Component
public class TestPerformance {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    private ObjectMapper objectMapper = new ObjectMapper();

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

    @PostConstruct
    public void init() throws JsonProcessingException {
        System.out.println("init test ....");
        long s = System.currentTimeMillis();
        final int total = 20000;
        for (int i = 0; i < total; i++) {
            rabbitTemplate.convertAndSend("test.performance.quque", objectMapper.writeValueAsString(new BidLog()));
        }
        System.out.println("rabbi mq cost " + (System.currentTimeMillis() - s) + " ms");


        s = System.currentTimeMillis();
        for (int i = 0; i < total; i++) {
            log.info("entry {}", objectMapper.writeValueAsString(new BidLog()));
        }
        System.out.println("logback socket cost " + (System.currentTimeMillis() - s) + " ms");
        System.out.println("all done");
    }
}

结果

init test ....
rabbi mq cost 3419 ms
logback socket cost 327 ms
all done

经多次执行发现结果是, socket 的方式比 mq 的高 10 倍左右.

rabbitmq vs socket appender vs local file

    @PostConstruct
    public void init() throws JsonProcessingException {
        System.out.println("init test ....");
        long s = System.currentTimeMillis();
        final int total = 20000;
        for (int i = 0; i < total; i++) {
            rabbitTemplate.convertAndSend("test.performance.quque", objectMapper.writeValueAsString(new BidLog()));
        }
        System.out.println("rabbi mq cost " + (System.currentTimeMillis() - s) + " ms");


        s = System.currentTimeMillis();
        for (int i = 0; i < total; i++) {
            log.info("entry {}", objectMapper.writeValueAsString(new BidLog()));
        }
        System.out.println("logback socket cost " + (System.currentTimeMillis() - s) + " ms");


        s = System.currentTimeMillis();
        for (int i = 0; i < total; i++) {
            fileLogger.info("entry {}", objectMapper.writeValueAsString(new BidLog()));
        }
        System.out.println("local logger cost " + (System.currentTimeMillis() - s) + " ms");

        System.out.println("all done");
    }

结果

init test ....
rabbi mq cost 2533 ms
logback socket cost 253 ms
local logger cost 405 ms
all done


init test ....
rabbi mq cost 2924 ms
logback socket cost 514 ms
local logger cost 365 ms
all done

init test ....
rabbi mq cost 2964 ms
logback socket cost 405 ms
local logger cost 436 ms
all done

init test ....
rabbi mq cost 2436 ms
logback socket cost 379 ms
local logger cost 385 ms
all done