zoukankan      html  css  js  c++  java
  • 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("
    ");
                                    }
                                    writer.flush();
                                } finally {
                                    writer.close();
                                }
                            } catch (Exception e) {
                                logger.error(e.getMessage(), e);
                            }
                        }
                    }
                } catch (Exception e) {
                    logger.error(e.getMessage(), e);
                }
            }
        }
  • 相关阅读:
    yii2中的url美化
    一级域名301重定向到www二级域名
    使用meta来控制浏览器的渲染方式
    同一页面不同编码的提交处理
    Yii2.0 UrlManager
    sqlsever连接两个不同服务器上的数据库进行查询
    php 实现传入参数的传出
    xcode如何修改项目名称
    ios如何实现应用之间的跳转
    ios程序如何实现系统自带的分享
  • 原文地址:https://www.cnblogs.com/LQBlog/p/12504871.html
Copyright © 2011-2022 走看看