010_logback中的SocketAppender

1. SocketAppender被设计为通过序列化ILoggingEvent实例把记录输出到远程实体。被序列化的事件的真实类型是LoggingEventVO, 它实现了ILoggingEvent接口。尽管如此, 就记录事件而言, 远程记录仍然是无损的。在接收和反序列化后, 事件像是从本地产生的一样被记录。运行在不同机器上的多个SocketAppender实例可以把各自的记录输出到一个格式固定的中央记录服务器。

2. SocketAppender不关联layout, 因为它把序列化的事件发送到远程服务器。SocketAppender运作在TCP层上, TCP层提供可靠、有序、流量控制的端到端的二进制流。因此, 如果远程服务器可访问, 则记录事件最终会到达那里。否则, 如果远程服务器关机或不可访问, 那么记录事件会被抛弃。当远程服务器恢复可用时, 会透明地继续传输事件。这种透明的重新连接是由一个连接器(connector)线程执行的, 它定时尝试连接服务器。

3. 记录事件被本地TCP实现自动地缓冲。这意味着如果服务器连接很慢, 但快于客户端生成事件的速度, 那么客户端不会受网络连接慢的影响。但是如果网络连接慢于生成事件的速度, 那么客户端只能按网络速度执行。特别是在服务器宕机这种极端情况下, 客户端会被阻塞。

4. 如果连接器线程仍然存在, 即使SocketAppender不再关联到任何logger, 也不会被垃圾回收。连接器线程只在当与服务器之间没有连接时存在。为避免这个垃圾回收问题, 你应当显式地关闭 SocketAppender。会创建/销毁很多SocketAppender实例的长期运行的程序应当注意这个垃圾回收问题。多数其他程序可以安全地忽略这个问题。如果宿主JVM在SocketAppender关闭之前退出了, 不管 SocketAppender被显式关闭还是交给垃圾回收, 都有可能在管道(pipe)里剩有一些未被传输的数据, 这些数据会丢失。为避免数据丢失, 一般在退出程序之前显式地调用SocketAppender的close()方法或调用LoggerContext的stop()方法就可以了。

5. SocketAppender的属性见下表

6. Logback标准发行包含一个简单的记录服务器程序"ch.qos.logback.classic.net.SimpleSocketServer", 可以支持多个SocketAppender客户端。它等待来自SocketAppender客户端的记录事件, 接收到事件后, 按照本地服务器的记录策略进行记录。

7. 例子

7.1. 新建一个名为ServerSocketAppender的Java项目, 同时添加相关jar包

7.2. 在src目录下创建logback.xml

<configuration>

	<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
		<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
		</encoder>
	</appender>

	<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
		<file>log/my.log</file>
		<prudent>true</prudent> 
		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<fileNamePattern>log/my.%d{yyyy-MM-dd}.%i.log</fileNamePattern> 
			<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> 
				<maxFileSize>10MB</maxFileSize> 
			</timeBasedFileNamingAndTriggeringPolicy>    
		</rollingPolicy>
		<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
		</encoder>
	</appender>

	<root level="debug">
		<appender-ref ref="file" />
		<appender-ref ref="stdout" />
	</root>

</configuration>

7.3. 编辑MyServer.java

package com.zr.server;

import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.net.SimpleSocketServer;

public class MyServer {
	public static void main(String[] args) {
		LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
		SimpleSocketServer sss = new SimpleSocketServer(lc, 9999);
		sss.start();
	}
}

7.4. 新建一个名为SocketAppender的Java项目, 同时添加相关jar包

7.5. 在src目录下创建logback.xml

<configuration>

	<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
		<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
		</encoder>
	</appender>

	<appender name="socket" class="ch.qos.logback.classic.net.SocketAppender">
		<remoteHost>127.0.0.1</remoteHost>
		<port>9999</port>
	</appender>

	<root level="debug">
		<appender-ref ref="socket" />
		<appender-ref ref="stdout" />
	</root>

</configuration>

7.6. 编辑MyClient.java

package com.zr.client;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyClient {
	private static final Logger logger = LoggerFactory.getLogger(MyClient.class);
	
	public static void main(String[] args) {
		for(int i = 0; i < 1000; i++) {
			logger.debug("客户端日志: " + i);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

7.7. 运行MyServer.java

7.8. 运行MyClient.java, 可以多运行几个客户端

7.9. 运行的过程中可以更改系统时间, 服务端接收到客户端的日志信息

8. SimpleSocketServer不是很强大不能打印客户端的ip和端口信息。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值