对阿里开源插件Durid Monitor的一些简单改造

Posted 敲代码的小小酥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了对阿里开源插件Durid Monitor的一些简单改造相关的知识,希望对你有一定的参考价值。

背景

项目中有个需求,要对所有的请求进行监控,包括内部请求和第三方软件的请求,想到Durid Monitor可以对数据库进行监测,也可以对内部的uri进行监测。而且有现成的界面。因此,初步想法是用现成的Druid Monitor,稍加改造,完成这个需求。

改造

要改造,肯定需要追源码,这里就不赘述如何找到的关键代码了。找源码用的方法就是点开druid的jar包,看每个包名,猜测哪个是相关代码,然后打断点,运行项目,验证猜测,分析其执行过程。
因为这里的需求是对Druid Monitor的界面进行改造。所以,重点看Druid Monitor提供的界面,是怎么访问到的。
关键代码如下:
StatViewServlet类:

public StatViewServlet()
        super("support/http/resources");
    

这里定义了页面的路径位置。找到对应的位置查看:

可以看到,有这些页面。
第二个核心类:
ResourceServlet:

public void service(HttpServletRequest request
                , HttpServletResponse response
                , String servletPath
                , ProcessCallback processCallback
        ) throws ServletException, IOException 
            String contextPath = request.getContextPath();
            String requestURI = request.getRequestURI();

            response.setCharacterEncoding("utf-8");

            if (contextPath == null)  // root context
                contextPath = "";
            
            String uri = contextPath + servletPath;
            String path = requestURI.substring(contextPath.length() + servletPath.length());

            if (!isPermittedRequest(request)) 
                path = "/nopermit.html";
                returnResourceFile(path, uri, response);
                return;
            

            if ("/submitLogin".equals(path)) 
                String usernameParam = request.getParameter(PARAM_NAME_USERNAME);
                String passwordParam = request.getParameter(PARAM_NAME_PASSWORD);
                if (username.equals(usernameParam) && password.equals(passwordParam)) 
                    request.getSession().setAttribute(SESSION_USER_KEY, username);
                    response.getWriter().print("success");
                 else 
                    response.getWriter().print("error");
                
                return;
            

            if (isRequireAuth() //
                    && !containsUser(request)//
                    && !checkLoginParam(request)//
                    && !("/login.html".equals(path) //
                    || path.startsWith("/css")//
                    || path.startsWith("/js") //
                    || path.startsWith("/img"))) 
                if (contextPath.equals("") || contextPath.equals("/")) 
                    response.sendRedirect("/druid/login.html");
                 else 
                    if ("".equals(path)) 
                        response.sendRedirect("druid/login.html");
                     else 
                        response.sendRedirect("login.html");
                    
                
                return;
            

            if ("".equals(path) || "/".equals(path)) 
                returnResourceFile("/index.html", uri, response);
                return;
            

            if (path.contains(".json")) 
                String fullUrl = path;
                if (request.getQueryString() != null && request.getQueryString().length() > 0) 
                    fullUrl += "?" + request.getQueryString();
                
                response.getWriter().print(processCallback.process(fullUrl));
                return;
            

            // find file in resources path

            returnResourceFile(path, uri, response);
        

这是一个servlet,上面代码是service方法。其对/druod开头的请求做了处理,如json格式的请求如何处理等。下面方法是对html文件,jpg,css等静态文件的请求做的处理的代码:

protected void returnResourceFile(String fileName, String uri, HttpServletResponse response)
                throws ServletException,
                IOException 

            String filePath = getFilePath(fileName);

            if (filePath.endsWith(".html")) 
                response.setContentType("text/html; charset=utf-8");
            
            if (fileName.endsWith(".jpg")) 
                byte[] bytes = Utils.readByteArrayFromResource(filePath);
                if (bytes != null) 
                    response.getOutputStream().write(bytes);
                

                return;
            

            String text = Utils.readFromResource(filePath);
            if (text == null) 
                return;
            

            if (fileName.endsWith(".css")) 
                response.setContentType("text/css;charset=utf-8");
             else if (fileName.endsWith(".js")) 
                response.setContentType("text/javascript;charset=utf-8");
            
            response.getWriter().write(text);
        

这样,就解释了为啥/druid的请求,为何跳转到相关页面了。剩下的,就是根据这个跳转规则,进行页面的改造即可。
改造后的界面如下:

其中,新加的功能的后台逻辑,在项目中实现即可。相关界面的请求写项目中的请求即可。无需在Druid的jar包里写代码。

以上是关于对阿里开源插件Durid Monitor的一些简单改造的主要内容,如果未能解决你的问题,请参考以下文章

Durid: 原理架构

阿里开源的那个牛X的问题排查工具——Arthas,推出IDEA插件了! | 文末福利

springBoot简单使用SpringData的jdbc和简单使用durid

阿里开源项目arthas安装使用

站点评论系统的开源插件的使用

013 Durid监控