继上篇帖子之后 , 公司又要求将Druid Monitor的监控信息保存起来 , 因为Druid的监控记录在是缓存的,重启之后无法找回,所以需要做持久化,定期把监控记录转存到日志文件中 研究了半天 , 将经验贴出来 , 希望可以帮到大家 , 少走点弯路 .

首先贴出Druid官方给出的方法   https://github.com/alibaba/druid/wiki/%E6%80%8E%E4%B9%88%E4%BF%9D%E5%AD%98Druid%E7%9A%84%E7%9B%91%E6%8E%A7%E8%AE%B0%E5%BD%95

废话不多说 , 直接进入正题 .

  1. DataSource中增加配置:

    1. <!-- 每隔10分钟把监控数据输出到日志中 -->
    2. < property name ="timeBetweenLogStatsMillis" value ="600000" />
    3. <!-- 自定义实现输入监控数据到日志 -->
    4. < property name ="statLogger" ref ="localStatLogger" />
  2. 定义bean
    1. < bean id ="localStatLogger" class ="com.hyde.tracker.server.druid.LocalStatLogger" ></ bean>
  3. 类LocalStatLogger,重写API中的方法实现自定义的日志存储
    1. package com.hyde.tracker.server.druid;
    2.  
    3. import static com.alibaba.druid.util.JdbcSqlStatUtils.rtrim;
    4.  
    5. import java.net.URL;
      import java.util.ArrayList;
      import java.util.LinkedHashMap;
      import java.util.Map;
    6.  
    7. import org.apache.log4j.PropertyConfigurator;
    8.  
    9. import com.alibaba.druid.pool.DruidDataSourceStatLogger;
      import com.alibaba.druid.pool.DruidDataSourceStatLoggerAdapter;
      import com.alibaba.druid.pool.DruidDataSourceStatValue;
      import com.alibaba.druid.stat.JdbcSqlStatValue;
      import com.alibaba.druid.support.json.JSONUtils;
      import com.alibaba.druid.support.logging.Log;
      import com.alibaba.druid.support.logging.LogFactory;
    10.  
    11. /**
       * @author WangHuijie<wanghuijie@carelink.cn>
       */
      public class LocalStatLogger extends DruidDataSourceStatLoggerAdapter implements DruidDataSourceStatLogger {
    12.  
    13.     private static final Log LOGGER = LogFactory.getLog(LocalStatLogger.class);
    14.  
    15.     /**
           * @see com.alibaba.druid.pool.DruidDataSourceStatLoggerAdapter#log(com.alibaba.druid.pool.DruidDataSourceStatValue)
           */
          @Override
          public void log(DruidDataSourceStatValue statValue) {
              
              Map<String, Object> map = new LinkedHashMap<String, Object>();
    16.  
    17.         /*map.put("url", statValue.getUrl());
              map.put("dbType", statValue.getDbType());*/
              map.put("name", statValue.getName());
              map.put("activeCount", statValue.getActiveCount());
    18.  
    19.         if (statValue.getActivePeak() > 0) {
                  map.put("activePeak", statValue.getActivePeak());
                  map.put("activePeakTime", statValue.getActivePeakTime());
              }
              map.put("poolingCount", statValue.getPoolingCount());
              if (statValue.getPoolingPeak() > 0) {
                  map.put("poolingPeak", statValue.getPoolingPeak());
                  map.put("poolingPeakTime", statValue.getPoolingPeakTime());
              }
              map.put("connectCount", statValue.getConnectCount());
              map.put("closeCount", statValue.getCloseCount());
    20.  
    21.         if (statValue.getWaitThreadCount() > 0) {
                  map.put("waitThreadCount", statValue.getWaitThreadCount());
              }
    22.  
    23.         if (statValue.getNotEmptyWaitCount() > 0) {
                  map.put("notEmptyWaitCount", statValue.getNotEmptyWaitCount());
              }
    24.  
    25.         if (statValue.getNotEmptyWaitMillis() > 0) {
                  map.put("notEmptyWaitMillis", statValue.getNotEmptyWaitMillis());
              }
    26.  
    27.         if (statValue.getLogicConnectErrorCount() > 0) {
                  map.put("logicConnectErrorCount", statValue.getLogicConnectErrorCount());
              }
    28.  
    29.         if (statValue.getPhysicalConnectCount() > 0) {
                  map.put("physicalConnectCount", statValue.getPhysicalConnectCount());
              }
    30.  
    31.         if (statValue.getPhysicalCloseCount() > 0) {
                  map.put("physicalCloseCount", statValue.getPhysicalCloseCount());
              }
    32.  
    33.         if (statValue.getPhysicalConnectErrorCount() > 0) {
                  map.put("physicalConnectErrorCount", statValue.getPhysicalConnectErrorCount());
              }
    34.  
    35.         if (statValue.getExecuteCount() > 0) {
                  map.put("executeCount", statValue.getExecuteCount());
              }
    36.  
    37.         if (statValue.getErrorCount() > 0) {
                  map.put("errorCount", statValue.getErrorCount());
              }
    38.  
    39.         if (statValue.getCommitCount() > 0) {
                  map.put("commitCount", statValue.getCommitCount());
              }
    40.  
    41.         if (statValue.getRollbackCount() > 0) {
                  map.put("rollbackCount", statValue.getRollbackCount());
              }
    42.  
    43.         if (statValue.getPstmtCacheHitCount() > 0) {
                  map.put("pstmtCacheHitCount", statValue.getPstmtCacheHitCount());
              }
    44.  
    45.         if (statValue.getPstmtCacheMissCount() > 0) {
                  map.put("pstmtCacheMissCount", statValue.getPstmtCacheMissCount());
              }
    46.  
    47.         if (statValue.getStartTransactionCount() > 0) {
                  map.put("startTransactionCount", statValue.getStartTransactionCount());
                  map.put("transactionHistogram", rtrim(statValue.getTransactionHistogram()));
              }
    48.  
    49.         if (statValue.getConnectCount() > 0) {
                  map.put("connectionHoldTimeHistogram", rtrim(statValue.getConnectionHoldTimeHistogram()));
              }
    50.  
    51.         if (statValue.getClobOpenCount() > 0) {
                  map.put("clobOpenCount", statValue.getClobOpenCount());
              }
    52.  
    53.         if (statValue.getBlobOpenCount() > 0) {
                  map.put("blobOpenCount", statValue.getBlobOpenCount());
              }
    54.  
    55.         if (statValue.getSqlSkipCount() > 0) {
                  map.put("sqlSkipCount", statValue.getSqlSkipCount());
              }
    56.  
    57.         ArrayList<Map<String, Object>> sqlList = new ArrayList<Map<String, Object>>();
              if (statValue.getSqlList().size() > 0) {
                  for (JdbcSqlStatValue sqlStat : statValue.getSqlList()) {
                      Map<String, Object> sqlStatMap = new LinkedHashMap<String, Object>();
                      sqlStatMap.put("sql", sqlStat.getSql());
    58.  
    59.                 if (sqlStat.getExecuteCount() > 0) {
                          sqlStatMap.put("executeCount", sqlStat.getExecuteCount());
                          sqlStatMap.put("executeMillisMax", sqlStat.getExecuteMillisMax());
                          sqlStatMap.put("executeMillisTotal", sqlStat.getExecuteMillisTotal());
    60.  
    61.                     sqlStatMap.put("executeHistogram", rtrim(sqlStat.getExecuteHistogram()));
                          sqlStatMap.put("executeAndResultHoldHistogram", rtrim(sqlStat.getExecuteAndResultHoldHistogram()));
                      }
    62.  
    63.                 long executeErrorCount = sqlStat.getExecuteErrorCount();
                      if (executeErrorCount > 0) {
                          sqlStatMap.put("executeErrorCount", executeErrorCount);
                      }
    64.  
    65.                 int runningCount = sqlStat.getRunningCount();
                      if (runningCount > 0) {
                          sqlStatMap.put("runningCount", runningCount);
                      }
    66.  
    67.                 int concurrentMax = sqlStat.getConcurrentMax();
                      if (concurrentMax > 0) {
                          sqlStatMap.put("concurrentMax", concurrentMax);
                      }
    68.  
    69.                 if (sqlStat.getFetchRowCount() > 0) {
                          sqlStatMap.put("fetchRowCount", sqlStat.getFetchRowCount());
                          sqlStatMap.put("fetchRowCount", sqlStat.getFetchRowCountMax());
                          sqlStatMap.put("fetchRowHistogram", rtrim(sqlStat.getFetchRowHistogram()));
                      }
    70.  
    71.                 if (sqlStat.getUpdateCount() > 0) {
                          sqlStatMap.put("updateCount", sqlStat.getUpdateCount());
                          sqlStatMap.put("updateCountMax", sqlStat.getUpdateCountMax());
                          sqlStatMap.put("updateHistogram", rtrim(sqlStat.getUpdateHistogram()));
                      }
    72.  
    73.                 if (sqlStat.getInTransactionCount() > 0) {
                          sqlStatMap.put("inTransactionCount", sqlStat.getInTransactionCount());
                      }
    74.  
    75.                 if (sqlStat.getClobOpenCount() > 0) {
                          sqlStatMap.put("clobOpenCount", sqlStat.getClobOpenCount());
                      }
    76.  
    77.                 if (sqlStat.getBlobOpenCount() > 0) {
                          sqlStatMap.put("blobOpenCount", sqlStat.getBlobOpenCount());
                      }
    78.  
    79.                 sqlList.add(sqlStatMap);
                  }
    80.  
    81.             map.put("sqlList", sqlList);
              }
    82.  
    83.         String text = JSONUtils.toJSONString(map);
              
              beforeLog();
              LOGGER.info(text);
              afterLog();
          }
          
          /**
           * 在记录LOG前指定.properties文件
           */
          private void beforeLog() {
              
              propertyConfigure("/druid_log4j.properties");
          }
          
          /**
           * 在记录LOG后恢复指定本来的.properties文件
           */
          private void afterLog() {
              
              propertyConfigure("/log4j.properties");
          }
          
          /**
           * 指定.properties文件
           * @param filePath
           */
          private void propertyConfigure(String filePath) {
              
              URL resource = getClass().getResource(filePath);
              PropertyConfigurator.configure(resource);
          }
      }
  4. log4j.properties,定义转存日志文件位置及名称
    1. log4j.rootLogger=INFO, druid, logfile
    2. log4j.appender.druid.Threshold=INFO
    3. log4j.appender.druid=org.apache.log4j.ConsoleAppender
    4. log4j.appender.druid.layout=org.apache.log4j.PatternLayout
    5. log4j.appender.druid.layout.ConversionPattern=%d %p [%c]:%L - %m%n
    6.  
    7. log4j.appender.logfile.Threshold=INFO
    8. log4j.appender.logfile=org.apache.log4j.DailyRollingFileAppender
    9. log4j.appender.logfile.DatePattern='.'yyyy-MM-dd
    10. log4j.appender.logfile.File=../logs/druid/druid.log
    11. log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
    12. log4j.appender.logfile.layout.ConversionPattern=[%d] - %m%n

保存Druid的监控记录的更多相关文章

  1. Spring Boot开启Druid数据库监控功能

    Druid是一个关系型数据库连接池,它是阿里巴巴的一个开源项目.Druid支持所有JDBC兼容的数据库,包括Oracle.MySQL.Derby.PostgreSQL.SQL Server.H2等.D ...

  2. Druid Monitor监控Java Web和Java SE项目

    Druid Monitor 对于数据源,大家已经接触了不少了.比如c3p0.dhcp.proxool等,之后又发现使用tomcat-jdbc可以大大的提高性能.但是针对于我们的高并发的系统来说,总希望 ...

  3. 云服务器 ECS Linux 保存用户登录操作命令记录

    转载自 : https://help.aliyun.com/knowledge_detail/41210.html 云服务器 ECS Linux 如果要保存用户登录操作记录,则可以通过在 /etc/p ...

  4. python之小木马(文件上传,下载,调用命令行,按键监控记录)

    window版 服务端: 开启两个线程,一个用来接收客户端的输入,一个用来监控服务端键盘的记录 客户端: get 文件(下载)put 文件(上传) window下cmd命令执行结果会直接打印出来,ke ...

  5. (15)Spring Boot使用Druid和监控配置【从零开始学Spring Boot】

    Spring Boot 系列博客] 更多查看博客:http://412887952-qq-com.iteye.com/blog Spring Boot默认的数据源是:org.apache.tomcat ...

  6. Spring Boot使用Druid和监控配置

    Spring Boot默认的数据源是:org.apache.tomcat.jdbc.pool.DataSource 整体步骤: (1)    --   Druid简单介绍,具体看官网: (2)     ...

  7. springboot中使用druid和监控配置

    如果想要监控自己的项目的访问情况及查看配置信息,druid是一个很好的选择,可能你会问druid是什么?有什么用?优点是什么? Druid简介 Druid是阿里巴巴开源的数据库连接池,号称是Java语 ...

  8. druid之监控设置及问题小记

    druid是什么注不再赘述了.想了解直接参见 https://github.com/alibaba/druid/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98 本文 ...

  9. 【转】spring boot使用Druid和监控配置

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u012100371/article/details/76602612 Druid是Java语言中最好 ...

随机推荐

  1. BM25和Lucene Default Similarity比较 (原文标题:BM25 vs Lucene Default Similarity)

    原文链接: https://www.elastic.co/blog/found-bm-vs-lucene-default-similarity 原文 By Konrad Beiske 翻译 By 高家 ...

  2. mysql中 date datetime time timestamp 的区别

    MySQL中关于时间的数据类型:它们分别是 date.datetime.time.timestamp.year date :"yyyy-mm-dd"  日期     1000-01 ...

  3. PipedInputStream和PipedOutputStream详解

    PipedInputStream类与PipedOutputStream类用于在应用程序中创建管道通信.一个PipedInputStream实例对象必须和一个PipedOutputStream实例对象进 ...

  4. smarty的学习计划(2)

    连接数据库时,处理数据用原生态的PHP函数???NO,我们用phplib里的DB类,它文件小.加载速度快而备受人们喜爱. copy一个目录表: web(站点根目录) |-----libs(Smarty ...

  5. 【收藏】15个常用的javaScript正则表达式

    1 用户名正则 //用户名正则,4到16位(字母,数字,下划线,减号) var uPattern = /^[a-zA-Z0-9_-]{4,16}$/; //输出 true console.log(uP ...

  6. IO回忆录之怎样过目不忘(BIO/NIO/AIO/Netty)

    有热心的网友加我微信,时不时问我一些技术的或者学习技术的问题.有时候我回微信的时候都是半夜了.但是我很乐意解答他们的问题.因为这些年轻人都是很有上进心的,所以在我心里他们就是很优秀的,我愿意多和努力的 ...

  7. 写给Android App开发人员看的Android底层知识(4)

    (八)App内部的页面跳转 在介绍完App的启动流程后,我们发现,其实就是启动一个App的首页. 接下来我们看App内部页面的跳转. 从ActivityA跳转到ActivityB,其实可以把Activ ...

  8. python 计算两个日期相差多少个月

    近期,由于业务需要计算两个日期之前相差多少个月.我在网上找了很久,结果发现万能的python,居然没有一个模块计算两个日期的月数,像Java.C#之类的高级语言,都会有(date1-date2).mo ...

  9. Elasticsearch与Solr

    公司之前有个用Lucene实现的伪分布式项目,实时性很差,后期数据量逐渐增大的时候,数据同步一次需要十几小时.当时项目重构考虑到的是Solr和ES,我参与的是Solr技术的预研.因为项目实时性要求很高 ...

  10. Github+Hexo,搭建专属网站

    前言 记得从大二开始,就一直想搭个专属网站,当时使劲抠页面[前端页面是从QQ空间抠的,现在想抠估计没这么容易了],写代码,忙活半天才把程序弄好. 可惜最终项目还是没上线,因为当时有两问题绕不开 需要购 ...