vue+springboot練手demo(六)——Swagger、Druid監(jiān)控和日志

目錄

vue+springboot練手demo(一)——環(huán)境搭建
vue+springboot練手demo(二)——查詢功能的實(shí)現(xiàn)
vue+springboot練手demo(三)——?jiǎng)h除功能的實(shí)現(xiàn)
vue+springboot練手demo(四)——新增和修改功能的實(shí)現(xiàn)
vue+springboot練手demo(五)——校驗(yàn)功能
vue+springboot練手demo(六)——Swagger、Druid監(jiān)控和日志

本章內(nèi)容可以放在搭建環(huán)境那一章,放在這里只是為了效果更明顯。

Swagger

Swagger為當(dāng)下比較火的restful接口文檔,為了與時(shí)俱進(jìn)我們也來在這個(gè)小demo中使用swagger
導(dǎo)入依賴

        <!--引入swagger2-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.7.0</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.7.0</version>
        </dependency>

編寫配置類

@Configuration
@EnableSwagger2
public class swagger2 {
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.feng.employees.controller"))
                .paths(PathSelectors.any())
                .build();
    }
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                //頁面標(biāo)題
                .title("職工信息管理系統(tǒng)")
                //條款地址
                .termsOfServiceUrl("http://feng.io/")
                .contact("feng")
                .version("1.0")
                //描述
                .description("API 描述")
                .build();
    }
}

至此Swagger變集成成功了。重新啟動項(xiàng)目,訪問:http://localhost:8080/swagger-ui.html即可查看接口文檔。

7-1 swagger.png

監(jiān)控

這里使用了兩種監(jiān)控一種為數(shù)據(jù)源監(jiān)控采用的是Druid數(shù)據(jù)源監(jiān)控方法;另一種為SpringBoot自身的監(jiān)控。

Druid監(jiān)控

由于在yml已經(jīng)編寫了相關(guān)的Druid的配置。


7-2 druid yml配置.png

因此我們可以直接編寫配置類來監(jiān)控SQL的執(zhí)行狀態(tài)。

#創(chuàng)建一個(gè)DruidConfig類
@Configuration
public class DruidConfig {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Value("${spring.datasource.url}")
    private String dbUrl;

    @Value("${spring.datasource.username}")
    private String username;

    @Value("${spring.datasource.password}")
    private String password;

    @Value("${spring.datasource.driver-class-name}")
    private String driverClassName;

    @Value("${spring.datasource.initialSize}")
    private int initialSize;

    @Value("${spring.datasource.minIdle}")
    private int minIdle;

    @Value("${spring.datasource.maxActive}")
    private int maxActive;

    @Value("${spring.datasource.maxWait}")
    private int maxWait;

    @Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
    private int timeBetweenEvictionRunsMillis;

    @Value("${spring.datasource.minEvictableIdleTimeMillis}")
    private int minEvictableIdleTimeMillis;

    @Value("${spring.datasource.validationQuery}")
    private String validationQuery;

    @Value("${spring.datasource.testWhileIdle}")
    private boolean testWhileIdle;

    @Value("${spring.datasource.testOnBorrow}")
    private boolean testOnBorrow;

    @Value("${spring.datasource.testOnReturn}")
    private boolean testOnReturn;

    @Value("${spring.datasource.poolPreparedStatements}")
    private boolean poolPreparedStatements;

    @Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")
    private int maxPoolPreparedStatementPerConnectionSize;

    @Value("${spring.datasource.filters}")
    private String filters;

    @Value("{spring.datasource.connectionProperties}")
    private String connectionProperties;

    //注冊 Servlet 組件
    @Bean
    public ServletRegistrationBean statViewServlet(){
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        /*servletRegistrationBean.addInitParameter("allow", "192.168.10.3"); //白名單IP*/
        servletRegistrationBean.addInitParameter("loginUsername", "feng");
        servletRegistrationBean.addInitParameter("loginPassword", "feng");
        return servletRegistrationBean;
    }

    @Bean
    public FilterRegistrationBean statFilter(){
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
        //驗(yàn)證所有請求
        filterRegistrationBean.addUrlPatterns("/*");
        //對 *.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/* 不進(jìn)行驗(yàn)證
        filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        return filterRegistrationBean;
    }

    @Bean
    @Primary //主數(shù)據(jù)源
    public DataSource dataSource(){
        DruidDataSource datasource = new DruidDataSource();
        datasource.setUrl(this.dbUrl);
        datasource.setUsername(username);
        datasource.setPassword(password);
        datasource.setDriverClassName(driverClassName);
        //configuration
        datasource.setInitialSize(initialSize);
        datasource.setMinIdle(minIdle);
        datasource.setMaxActive(maxActive);
        datasource.setMaxWait(maxWait);
        datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
        datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
        datasource.setValidationQuery(validationQuery);
        datasource.setTestWhileIdle(testWhileIdle);
        datasource.setTestOnBorrow(testOnBorrow);
        datasource.setTestOnReturn(testOnReturn);
        datasource.setPoolPreparedStatements(poolPreparedStatements);
        datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
        try {
            datasource.setFilters(filters);
        } catch (SQLException e) {
            logger.error("druid configuration Exception", e);
        }
        datasource.setConnectionProperties(connectionProperties);
        return datasource;
    }

}

Druid的配置已經(jīng)完成。重啟項(xiàng)目,訪問http://localhost:8080/druid/login.html即可來到Druid的登陸頁面。

7-3 登錄Druid頁面.png

通過Servlet 組件中指定的用戶名和密碼登錄網(wǎng)頁。
7-4 Druid主頁.png

當(dāng)執(zhí)行了一系列的增刪改查后,我們查看主頁中的SQL監(jiān)控。
7-5 SQL監(jiān)控.png

發(fā)現(xiàn)有對應(yīng)的SQL語句信息。這就是Druid為我們提供的SQL監(jiān)控。

日志

日志配置十分簡單,只需要一個(gè)logback-spring.xml配置文件即可。

<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志級別從低到高分為TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果設(shè)置為WARN,則低于WARN的信息都不會輸出 -->
<!-- scan:當(dāng)此屬性設(shè)置為true時(shí),配置文檔如果發(fā)生改變,將會被重新加載,默認(rèn)值為true -->
<!-- scanPeriod:設(shè)置監(jiān)測配置文檔是否有修改的時(shí)間間隔,如果沒有給出時(shí)間單位,默認(rèn)單位是毫秒。
                 當(dāng)scan為true時(shí),此屬性生效。默認(rèn)的時(shí)間間隔為1分鐘。 -->
<!-- debug:當(dāng)此屬性設(shè)置為true時(shí),將打印出logback內(nèi)部日志信息,實(shí)時(shí)查看logback運(yùn)行狀態(tài)。默認(rèn)值為false。 -->
<configuration  scan="true" scanPeriod="10 seconds">
    <contextName>logback</contextName>

    <!-- name的值是變量的名稱,value的值時(shí)變量定義的值。通過定義的值會被插入到logger上下文中。定義后,可以使“${}”來使用變量。 -->
    <property name="log.path" value="E://Log/Emps/" />

    <!--0. 日志格式和顏色渲染 -->
    <!-- 彩色日志依賴的渲染類 -->
    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
    <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
    <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
    <!-- 彩色日志格式 -->
    <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>

    <!--1. 輸出到控制臺-->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <!--此日志appender是為開發(fā)使用,只配置最底級別,控制臺輸出的日志級別是大于或等于此級別的日志信息-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>debug</level>
        </filter>
        <encoder>
            <Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
            <!-- 設(shè)置字符集 -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!--2. 輸出到文檔-->
    <!-- 2.1 level為 DEBUG 日志,時(shí)間滾動輸出  -->
    <appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在記錄的日志文檔的路徑及文檔名 -->
        <file>${log.path}/web_debug.log</file>
        <!--日志文檔輸出格式-->
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            <charset>UTF-8</charset> <!-- 設(shè)置字符集 -->
        </encoder>
        <!-- 日志記錄器的滾動策略,按日期,按大小記錄 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志歸檔 -->
            <fileNamePattern>${log.path}/web-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文檔保留天數(shù)-->
            <maxHistory>15</maxHistory>
        </rollingPolicy>
        <!-- 此日志文檔只記錄debug級別的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>debug</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 2.2 level為 INFO 日志,時(shí)間滾動輸出  -->
    <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在記錄的日志文檔的路徑及文檔名 -->
        <file>${log.path}/web_info.log</file>
        <!--日志文檔輸出格式-->
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <!-- 日志記錄器的滾動策略,按日期,按大小記錄 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 每天日志歸檔路徑以及格式 -->
            <fileNamePattern>${log.path}/web-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文檔保留天數(shù)-->
            <maxHistory>15</maxHistory>
        </rollingPolicy>
        <!-- 此日志文檔只記錄info級別的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>info</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 2.3 level為 WARN 日志,時(shí)間滾動輸出  -->
    <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在記錄的日志文檔的路徑及文檔名 -->
        <file>${log.path}/web_warn.log</file>
        <!--日志文檔輸出格式-->
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            <charset>UTF-8</charset> <!-- 此處設(shè)置字符集 -->
        </encoder>
        <!-- 日志記錄器的滾動策略,按日期,按大小記錄 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/web-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文檔保留天數(shù)-->
            <maxHistory>15</maxHistory>
        </rollingPolicy>
        <!-- 此日志文檔只記錄warn級別的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>warn</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 2.4 level為 ERROR 日志,時(shí)間滾動輸出  -->
    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在記錄的日志文檔的路徑及文檔名 -->
        <file>${log.path}/web_error.log</file>
        <!--日志文檔輸出格式-->
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            <charset>UTF-8</charset> <!-- 此處設(shè)置字符集 -->
        </encoder>
        <!-- 日志記錄器的滾動策略,按日期,按大小記錄 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/web-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文檔保留天數(shù)-->
            <maxHistory>15</maxHistory>
        </rollingPolicy>
        <!-- 此日志文檔只記錄ERROR級別的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!--
        <logger>用來設(shè)置某一個(gè)包或者具體的某一個(gè)類的日志打印級別、
        以及指定<appender>。<logger>僅有一個(gè)name屬性,
        一個(gè)可選的level和一個(gè)可選的addtivity屬性。
        name:用來指定受此logger約束的某一個(gè)包或者具體的某一個(gè)類。
        level:用來設(shè)置打印級別,大小寫無關(guān):TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
              還有一個(gè)特俗值INHERITED或者同義詞NULL,代表強(qiáng)制執(zhí)行上級的級別。
              如果未設(shè)置此屬性,那么當(dāng)前l(fā)ogger將會繼承上級的級別。
        addtivity:是否向上級logger傳遞打印信息。默認(rèn)是true。
        <logger name="org.springframework.web" level="info"/>
        <logger name="org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor" level="INFO"/>
    -->

    <!--
        使用mybatis的時(shí)候,sql語句是debug下才會打印,而這里我們只配置了info,所以想要查看sql語句的話,有以下兩種操作:
        第一種把<root level="info">改成<root level="DEBUG">這樣就會打印sql,不過這樣日志那邊會出現(xiàn)很多其他消息
        第二種就是單獨(dú)給dao下目錄配置debug模式,代碼如下,這樣配置sql語句會打印,其他還是正常info級別:
        【logging.level.org.mybatis=debug logging.level.dao=debug】
     -->

    <!--
        root節(jié)點(diǎn)是必選節(jié)點(diǎn),用來指定最基礎(chǔ)的日志輸出級別,只有一個(gè)level屬性
        level:用來設(shè)置打印級別,大小寫無關(guān):TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
        不能設(shè)置為INHERITED或者同義詞NULL。默認(rèn)是DEBUG
        可以包含零個(gè)或多個(gè)元素,標(biāo)識這個(gè)appender將會添加到這個(gè)logger。
    -->

    <!-- 4. 最終的策略 -->
    <!-- 4.1 開發(fā)環(huán)境:打印控制臺-->
    <springProfile name="dev">
        <logger name="com.feng.employees.dao" level="debug"/>
        <logger name="com.feng.employees.controller" level="info"/>
    </springProfile>

    <root level="info">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="DEBUG_FILE" />
        <appender-ref ref="INFO_FILE" />
        <appender-ref ref="WARN_FILE" />
        <appender-ref ref="ERROR_FILE" />
    </root>

    <!-- 4.2 生產(chǎn)環(huán)境:輸出到文檔
    <springProfile name="pro">
        <root level="info">
            <appender-ref ref="CONSOLE" />
            <appender-ref ref="DEBUG_FILE" />
            <appender-ref ref="INFO_FILE" />
            <appender-ref ref="ERROR_FILE" />
            <appender-ref ref="WARN_FILE" />
        </root>
    </springProfile> -->
</configuration>

controller層,通過logger.info添加日志信息。

    private final Logger logger = LoggerFactory.getLogger(getClass());
    /**
     * 獲取時(shí)間
     */
    public String GetDate(){
        Date date = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return dateFormat.format(date);
    }
    public Msg GetAllEmps(Integer currentpage, String name) {
        logger.info(GetDate()+":---------->查詢所有員工");
        ....
    }
    //剩下的省略

啟動項(xiàng)目,隨意執(zhí)行幾個(gè)查詢、修改操作,查看日志情況。


7-10 日志文件.png
7-11 日志信息.png

參考

Swagger:https://swagger.io/、http://www.itdecent.cn/p/349e130e40d5
Druid:https://github.com/alibaba/druidhttps://www.oschina.net/p/druid?hmsr=aladdin1e1

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容