Druid开启可视化监控和慢Sql-log

Druid开启可视化监控和慢Sql-log
雪诺!!!!

Druid概述

是阿里巴巴开源平台上的一个项目,整个项目由数据库连接池、插件框架和 SQL 解析器组成,该项目主要是为了扩展 JDBC 的一些限制,可以让实现一些特殊的需求,比如向密钥服务请求凭证、统计 SQL 信息、SQL 性能收集、SQL 注入检查、SQL 翻译等,开发者可以通过定制来实现自己需要的功能。

首先它是一个数据库连接池,但它不仅仅是一个数据库连接池,还包含了一个 ProxyDriver,一系列内置的 JDBC 组件库,一个 SQL Parser。在 Java 的世界中 Druid 是监控做的最好的数据库连接池,在功能、性能、扩展性方面,也有不错的表现。

  • 替换其他 Java 连接池,Druid 提供了一个高效、功能强大、可扩展性好的数据库连接池。
  • 可以监控数据库访问性能,Druid 内置提供了一个功能强大的 StatFilter 插件,能够详细统计 SQL 的执行性能,这对于线上分析数据库访问性能有很大帮助。
  • 数据库密码加密。直接把数据库密码写在配置文件中,这是不好的行为,容易导致安全问题,DruidDruiver 和 DruidDataSource 都支持 PasswordCallback。
  • SQL 执行日志,Druid 提供了不同的 LogFilter,能够支持 Common-Logging、Log4j 和 JdkLog,可以按需要选择相应的 LogFilter,监控应用的数据库访问情况。
  • 扩展 JDBC,如果你要对 JDBC 层有编程的需求,可以通过 Druid 提供的 Filter 机制,很方便编写 JDBC 层的扩展插件。

与SpringBoot集成

与SpringBoot的集成非常简单,只需要引入依赖和简单配置一下即可:

引入依赖:
<dependency>
     <groupId>com.alibaba</groupId>
     <artifactId>druid-spring-boot-starter</artifactId>
     <!-- 版本不能太低容易出错 -->
     <version>1.1.10</version>
</dependency>
配置application.yml :
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/db1?useUnicode=true&amp;useSSL=false&amp;characterEncoding=utf-8
    username: xCW2az2YmV2w3rfDry543D01dNWo==
    password: ta9INTvbFddwsd+4==
    druid:
      #  配置监控统计拦截的filters,去掉后监控界面sql无法统计.属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有: 监控统计用的filter:stat、 日志用的filter:log4j 、防御sql注入的filter:wall、
      filters: stat,wall,log4j2
      filter:                  # filter详细配置见: https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_StatFilter
        stat:
          log-slow-sql: true   # 开启log慢Sql
          slow-sql-millis: 1   # slowSqlMillis缺省值为3秒
          merge-sql: true      # 开启SQL合并  select * from t where id = ?
      # 也可以通过connectionProperties 属性来打开Sql合并功能和慢SQL记录
      #connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
      max-active: 20     # 最大活跃数(最大连接池数量)
      initialSize: 2     # 初始化建立物理连接的的数量。初始化发生在显示调用init方法,或者第一次getConnection时
      maxWait: 60000     # 获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。
      minIdle: 2         # 最小连接池数量

还需要自定义配置相关Bean:

@Configuration
public class DruidMonitorConfiguration {

    /**
     * 注册ServletRegistrationBean
     */
    @Bean
    public ServletRegistrationBean registrationBean() {
        ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        /** 初始化参数配置,initParams **/
        // 白名单
        bean.addInitParameter("allow", "127.0.0.1");// 多个ip逗号隔开
        // IP黑名单 (存在共同时,deny优先于allow) : 如果满足deny的话提示:Sorry, you are not
        // permitted to view this page.
        // bean.addInitParameter("deny", "192.168.1.73");
        // 登录查看信息的账号密码.
        // bean.addInitParameter("loginUsername", "root");
        // bean.addInitParameter("loginPassword", "root");
        // bean.addInitParameter("filters", "stat,wall,log4j");
        // 是否能够重置数据.
        bean.addInitParameter("resetEnable", "false");
        return bean;
    }

    /**
     * 注册一个filterRegistrationBean
     */
    @Bean
    public FilterRegistrationBean druidStatFilter2(){
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
        //添加过滤规则.
        filterRegistrationBean.addUrlPatterns("/*");
        //添加不需要忽略的格式信息.
        filterRegistrationBean.addInitParameter("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid2/*," +
                "/swagger-resources/*,/loginTest/*,/api/*,/webjars/*./webSocketServer/*,/webSocketTest/*,*.html,*.json");
        return filterRegistrationBean;
    }

    @Bean
    public DruidStatInterceptor druidStatInterceptor() {
        DruidStatInterceptor dsInterceptor = new DruidStatInterceptor();
        return dsInterceptor;
    }

    @Bean
    @Scope("prototype")
    public JdkRegexpMethodPointcut druidStatPointcut() {
        JdkRegexpMethodPointcut pointcut = new JdkRegexpMethodPointcut();
        pointcut.setPatterns(
                "fun.lzyz.porject.*"
        );
        return pointcut;
    }

    @Bean
    public DefaultPointcutAdvisor druidStatAdvisor(DruidStatInterceptor druidStatInterceptor, JdkRegexpMethodPointcut druidStatPointcut) {
        DefaultPointcutAdvisor defaultPointAdvisor = new DefaultPointcutAdvisor();
        defaultPointAdvisor.setPointcut(druidStatPointcut);
        defaultPointAdvisor.setAdvice(druidStatInterceptor);
        return defaultPointAdvisor;
    }
    
}

配置logback-spring.xml,记录日志:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration scan="true" monitorInterval="30">
    <!-- 等级 TRACE, DEBUG, INFO, WARN, ERROR -->
    <contextName>logback</contextName>

    <!-- 用来定义变量值的标签,有两个属性,name和value;
          · name  变量的名称
          · value 变量定义的值。通过定义的值会被插入到logger上下文中。
         定义变量后,可以使“${}”来使用变量。 -->
    <property name="logDir" value="logs"/>
    <property name="appName" value="porject"/>
    <property name="logLevel" value="INFO"/>
    
    <!--
         appender是一个日志打印的组件,这里组件里面定义了打印过滤的条件,打印输出方式,滚动策略,编码方式,打印格式等等。
         但是它仅仅是一个打印组件,我们如果不使用一个logger或者root的appender-ref指定某个具体的appender时,它就没有什么意义。
     -->
 <!--
         appender是一个日志打印的组件,这里组件里面定义了打印过滤的条件,打印输出方式,滚动策略,编码方式,打印格式等等。
         但是它仅仅是一个打印组件,我们如果不使用一个logger或者root的appender-ref指定某个具体的appender时,它就没有什么意义。
     -->
    <!-- 输出到控制台ConsoleLog  一般生产环境都是后台启动,这个没太大作用  -->
    <appender name="ConsoleLog" class="ch.qos.logback.core.ConsoleAppender">
        <!--展示格式 layout-->
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>
                <pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger{50} [line%L]: %msg%n</pattern>
            </pattern>
        </layout>
    </appender>

    <!-- 只保存错误日志 -->
    <appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--如果只是想要 Error 级别的日志,那么需要过滤一下,默认是 info 级别的,ThresholdFilter-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>Error</level>
        </filter>
        <!--日志名称,如果没有File 属性,那么只会使用FileNamePattern的文件路径规则
            如果同时有<File>和<FileNamePattern>,那么当天日志是<File>,明天会自动把今天
            的日志改名为今天的日期。即,<File> 的日志都是当天的。
        -->
        <File>${logDir}/error.${appName}.log</File>
        <!--滚动策略,按照时间滚动 TimeBasedRollingPolicy-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--文件路径,定义了日志的切分方式——把每一天的日志归档到一个文件中,以防止日志填满整个磁盘空间-->
            <FileNamePattern>${logDir}/erro/erroInfo.%d{yyyy-MM-dd}.log</FileNamePattern>
            <!--只保留最近60天的日志-->
            <maxHistory>60</maxHistory>
            <!--用来指定日志文件的上限大小,那么到了这个值,就会删除旧的日志-->
            <totalSizeCap>1GB</totalSizeCap>
        </rollingPolicy>
        <!--日志输出编码格式化-->
        <encoder>
            <charset>UTF-8</charset>
            <pattern>%d [%thread] %-5level %logger{36} %line - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- Druid日志 -->
    <appender name="DruidFILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${logDir}/log_druid.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">         
            <fileNamePattern>${logDir}/druid/log-druid-%d{yyyy-MM-dd}.%i.log</fileNamePattern>          
                <maxFileSize>2MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <MaxHistory>60</MaxHistory>
        </rollingPolicy>
        <append>true</append>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern>
            <charset>utf-8</charset>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>


    <logger name="com.alibaba.druid.filter.stat.StatFilter" level="ERROR">
        <appender-ref ref="DruidFILE" />
    </logger>

    <root level="INFO">
        <!-- 添加定义好的appender  -->
        <appender-ref ref="ConsoleLog"/>
        <appender-ref ref="fileErrorLog"/>
    </root>

</Configuration>

配置好后,访问:

http://[ip]:[port]/druid/index,使用配置的用户名密码登录 。

更多可参考: https://my.oschina.net/zhang2xiang/blog/3108186/print

Comments

No comments yet. Why don’t you start the discussion?

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注