Dubbo源码分析(AccessLogFilter)

 

 上一篇博客简单的介绍了一下Dubbo中的Filter,下面几篇博客来找其中的几个filter来分析一下。


 首先来看一下Filter接口


 

public interface Filter {
	Result invoke(Invoker<?> invoker,Invocation invocation) throws RpcException;
}
 就一个方法,用来作为Invoker的代理,其中Invocation封装了所需要的参数信息等。


 

 AccessLogFilter实现类

 该类用来记录,每一次调用的信息,格式如下所示

 


 如果要用该filter的话,需要在提供方中配置以下信息,如果不配置的话,日志会打到类似

  dubbo.accesslog.interfacename的文件中


 

  


 AccessLogFilter源码分析

 在LogFilter的内部维护了一个map结构,key为日志的名称,value是一个set集合,维护了日志的每一次调用的详细信息。内部通过一个线程,隔一段时间都会把日志给输出出去。代码如下所示

 

private final ConcurrentMap<String, Set<String>> logQueue = new ConcurrentHashMap<String, Set<String>>();

	private final ScheduledExecutorService logSchedule = Executors
			.newScheduledThreadPool(2, new NamedThreadFactory(
					"Dubbo-Access-Log", true));

	private volatile ScheduledFuture<?> logFuture = null;

	private class LogTask implements Runnable {
		public void run() {
			try {
				if (logQueue != null && logQueue.size() > 0) {
					for (Map.Entry<String, Set<String>> entry : logQueue
							.entrySet()) {
						try {
							
							//..创建目录
							//..并对日期做判断,第二题的日志会以日期结尾
							FileWriter writer = new FileWriter(file, true);
							try {
								for (String msg : logSet) {
									writer.write(msg);
									writer.write("\r\n");
								}
								writer.flush();
							} finally {
								writer.close();
							}
							logSet.clear();
						} catch (Exception e) {
							logger.error(e.getMessage(), e);
						}
					}
				}
			} catch (Exception e) {
				logger.error(e.getMessage(), e);
			}
		}
	}

	private void init() {
		if (logFuture == null) {
			synchronized (logSchedule) {
				// 这个判断保证了只初始化一次
				//需要加锁,防止并发
				if (logFuture == null) {
					logFuture = logSchedule.scheduleWithFixedDelay(
							new LogTask(), LOG_OUTPUT_INTERVAL,
							LOG_OUTPUT_INTERVAL, TimeUnit.MILLISECONDS);
				}
			}
		}
	}

	/* log输出日志操作 */
	private void log(String accesslog, String logmessage) {
		init();
		Set<String> logSet = logQueue.get(accesslog);
		if (logSet == null) {
			logQueue.putIfAbsent(accesslog, new ConcurrentHashSet<String>());
			logSet = logQueue.get(accesslog);
		}

		if (logSet.size() < LOG_MAX_BUFFER) {
			logSet.add(logmessage);
		}
	}

	public Result invoke(Invoker<?> invoker, Invocation inv)
			throws RpcException {

		try {
			
			//。。。。拼接日志信息操作
				if (ConfigUtils.isDefault(accesslog)) {
				//没有设置的话,会以默认形式进行
					LoggerFactory.getLogger(
							ACCESS_LOG_KEY + "."
									+ invoker.getInterface().getName()).info(
							msg);
				} else {
					//每次调用前都会输出日志
					log(accesslog, msg);
				}
			}
		} catch (Throwable t) {
			logger.warn("Exception in AcessLogFilter of service(" + invoker
					+ " -> " + inv + ")", t);
		}
		return invoker.invoke(inv);
	}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值