dubbo源码阅读-Filter默认实现(十一)之TokenFilter
文档
http://dubbo.apache.org/zh-cn/docs/user/demos/accesslog.html
AccessLogFilter
@Override public Result invoke(Invoker<?> invoker, Invocation inv) throws RpcException { try { //获取消费者的accesslog配置 String accesslog = invoker.getUrl().getParameter(Constants.ACCESS_LOG_KEY); //如果有配置 if (ConfigUtils.isNotEmpty(accesslog)) { //拼接日志信息 RpcContext context = RpcContext.getContext(); String serviceName = invoker.getInterface().getName(); String version = invoker.getUrl().getParameter(Constants.VERSION_KEY); String group = invoker.getUrl().getParameter(Constants.GROUP_KEY); StringBuilder sn = new StringBuilder(); sn.append("[").append(new SimpleDateFormat(MESSAGE_DATE_FORMAT).format(new Date())).append("] ").append(context.getRemoteHost()).append(":").append(context.getRemotePort()) .append(" -> ").append(context.getLocalHost()).append(":").append(context.getLocalPort()) .append(" - "); if (null != group && group.length() > 0) { sn.append(group).append("/"); } sn.append(serviceName); if (null != version && version.length() > 0) { sn.append(":").append(version); } sn.append(" "); sn.append(inv.getMethodName()); sn.append("("); Class<?>[] types = inv.getParameterTypes(); if (types != null && types.length > 0) { boolean first = true; for (Class<?> type : types) { if (first) { first = false; } else { sn.append(","); } sn.append(type.getName()); } } sn.append(") "); Object[] args = inv.getArguments(); if (args != null && args.length > 0) { sn.append(JSON.toJSONString(args)); } String msg = sn.toString(); // 【方式一】配置的true 使用日志组件,例如 Log4j 等写 if (ConfigUtils.isDefault(accesslog)) { LoggerFactory.getLogger(ACCESS_LOG_KEY + "." + invoker.getInterface().getName()).info(msg); } else { //<1>否则写入日志文件 log(accesslog, msg); } } } catch (Throwable t) { logger.warn("Exception in AcessLogFilter of service(" + invoker + " -> " + inv + ")", t); } return invoker.invoke(inv); }
<1>log
private void log(String accesslog, String logmessage) { init();//<2> Set<String> logSet = logQueue.get(accesslog); if (logSet == null) { logQueue.putIfAbsent(accesslog, new ConcurrentHashSet<String>()); logSet = logQueue.get(accesslog); } //如果set小于5000则add if (logSet.size() < LOG_MAX_BUFFER) { logSet.add(logmessage); } }
<2>init
private void init() { //为空的时候才初始化 if (logFuture == null) { synchronized (logScheduled) { if (logFuture == null) { //初始化定时任务 LogTask为内部类<3> logFuture = logScheduled.scheduleWithFixedDelay(new LogTask(), LOG_OUTPUT_INTERVAL, LOG_OUTPUT_INTERVAL, TimeUnit.MILLISECONDS); } } } }
<3>LogTask
//遍历list 写入日志文件 线程安全的 private final ConcurrentMap<String, Set<String>> logQueue = new ConcurrentHashMap<String, Set<String>>(); private class LogTask implements Runnable { @Override public void run() { try { if (logQueue != null && logQueue.size() > 0) { for (Map.Entry<String, Set<String>> entry : logQueue.entrySet()) { try { //可以直接配置输出路径 String accesslog = entry.getKey(); Set<String> logSet = entry.getValue(); File file = new File(accesslog); File dir = file.getParentFile(); if (null != dir && !dir.exists()) { dir.mkdirs(); } if (logger.isDebugEnabled()) { logger.debug("Append log to " + accesslog); } if (file.exists()) { String now = new SimpleDateFormat(FILE_DATE_FORMAT).format(new Date()); String last = new SimpleDateFormat(FILE_DATE_FORMAT).format(new Date(file.lastModified())); if (!now.equals(last)) { File archive = new File(file.getAbsolutePath() + "." + last); file.renameTo(archive); } } FileWriter writer = new FileWriter(file, true); try { for (Iterator<String> iterator = logSet.iterator(); iterator.hasNext(); iterator.remove()) { writer.write(iterator.next()); writer.write("\r\n"); } writer.flush(); } finally { writer.close(); } } catch (Exception e) { logger.error(e.getMessage(), e); } } } } catch (Exception e) { logger.error(e.getMessage(), e); } } }