Spring Cloud構建微服務架構:分佈式服務跟蹤(整合logstash)【Dalston版】

經過以前的入門示例,咱們已經爲trace-1trace-2引入了Spring Cloud Sleuth的基礎模塊spring-cloud-starter-sleuth,實現了爲各微服務的日誌信息中添加跟蹤信息的功能。可是,因爲日誌文件都離散的存儲在各個服務實例的文件系統之上,僅僅經過查看日誌文件來分析咱們的請求鏈路依然是一件至關麻煩的差事,因此咱們還須要一些工具來幫助咱們集中的收集、存儲和搜索這些跟蹤信息。引入基於日誌的分析系統是一個不錯的選擇,好比:ELK平臺,它能夠輕鬆的幫助咱們來收集和存儲這些跟蹤日誌,同時在須要的時候咱們也能夠根據Trace ID來輕鬆地搜索出對應請求鏈路相關的明細日誌。git

ELK平臺主要有由ElasticSearch、Logstash和Kiabana三個開源免費工具組成:github

  • Elasticsearch是個開源分佈式搜索引擎,它的特色有:分佈式,零配置,自動發現,索引自動分片,索引副本機制,restful風格接口,多數據源,自動搜索負載等。
  • Logstash是一個徹底開源的工具,他能夠對你的日誌進行收集、過濾,並將其存儲供之後使用。
  • Kibana 也是一個開源和免費的工具,它Kibana能夠爲 Logstash 和 ElasticSearch 提供的日誌分析友好的 Web 界面,能夠幫助您彙總、分析和搜索重要數據日誌。

Spring Cloud Sleuth在與ELK平臺整合使用時,實際上咱們只要實現與負責日誌收集的Logstash完成數據對接便可,因此咱們須要爲Logstash準備json格式的日誌輸出。因爲Spring Boot應用默認使用了logback來記錄日誌,而Logstash自身也有對logback日誌工具的支持工具,因此咱們能夠直接經過在logback的配置中增長對logstash的appender,就能很是方便的將日誌轉換成以json的格式存儲和輸出了。spring

下面咱們來詳細介紹一下在快速入門示例的基礎上,如何實現面向Logstash的日誌輸出配置:json

  • pom.xml依賴中引入logstash-logback-encoder依賴,具體以下:
<dependency>
  <groupId>net.logstash.logback</groupId>
  <artifactId>logstash-logback-encoder</artifactId>
  <version>4.6</version>
</dependency>
  • 在工程/resource目錄下建立bootstrap.properties配置文件,將spring.application.name=trace-1配置移動到該文件中去。因爲logback-spring.xml的加載在application.properties以前,因此以前的配置logback-spring.xml沒法獲取到spring.application.name屬性,所以這裏將該屬性移動到最早加載的bootstrap.properties配置文件中。
  • 在工程/resource目錄下建立logback配置文件logback-spring.xml,具體內容以下:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
      
    <springProperty scope="context" name="springAppName" source="spring.application.name"/>
    <!-- 日誌在工程中的輸出位置 -->
    <property name="LOG_FILE" value="${BUILD_FOLDER:-build}/${springAppName}"/>
    <!-- 控制檯的日誌輸出樣式 -->
    <property name="CONSOLE_LOG_PATTERN"
              value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr([${springAppName:-},%X{X-B3-TraceId:-},%X{X-B3-SpanId:-},%X{X-Span-Export:-}]){yellow} %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>

    <!-- 控制檯Appender -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">           
            <level>INFO</level>
        </filter>
         <encoder>
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>utf8</charset>
       </encoder>
    </appender>

    <!-- 爲logstash輸出的json格式的Appender -->
    <appender name="logstash" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_FILE}.json</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_FILE}.json.%d{yyyy-MM-dd}.gz</fileNamePattern>
            <maxHistory>7</maxHistory>
        </rollingPolicy>
        <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
            <providers>
                <timestamp>
                    <timeZone>UTC</timeZone>
                </timestamp>
                <pattern>
                    <pattern>
                        {
                          "severity": "%level",
                          "service": "${springAppName:-}",
                          "trace": "%X{X-B3-TraceId:-}",
                          "span": "%X{X-B3-SpanId:-}",
                          "exportable": "%X{X-Span-Export:-}",
                          "pid": "${PID:-}",
                          "thread": "%thread",
                          "class": "%logger{40}",
                          "rest": "%message"
                        }
                    </pattern>
                </pattern>
            </providers>
        </encoder>
    </appender>
      
    <root level="INFO">
        <appender-ref ref="console"/>
        <appender-ref ref="logstash"/>
    </root>
</configuration>

對logstash支持主要經過名爲logstash的appender實現,內容並不複雜,主要是對日誌信息的格式化處理,上面爲了方便調試查看咱們先將json日誌輸出到文件中。bootstrap

完成上面的改造以後,咱們再將快速入門的示例運行起來,併發起對trace-1的接口訪問。此時咱們能夠在trace-1trace-2的工程目錄下發現有一個build目錄,下面分別建立了以各自應用名稱命名的json文件,該文件就是在logback-spring.xml中配置的名爲logstash的appender輸出的日誌文件,其中記錄了相似下面格式的json日誌:bash

{"@timestamp":"2016-12-04T06:57:58.970+00:00","severity":"INFO","service":"trace-1","trace":"589ee5f7b860132f","span":"a9e891273affb7fc","exportable":"false","pid":"19756","thread":"http-nio-9101-exec-1","class":"c.d.TraceApplication$$EnhancerBySpringCGLIB$$a9604da6","rest":"===<call trace-1>==="}
{"@timestamp":"2016-12-04T06:57:59.061+00:00","severity":"INFO","service":"trace-1","trace":"589ee5f7b860132f","span":"2df8511ddf3d79a2","exportable":"false","pid":"19756","thread":"http-nio-9101-exec-1","class":"o.s.c.a.AnnotationConfigApplicationContext","rest":"Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@64951f38: startup date [Sun Dec 04 14:57:59 CST 2016]; parent: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@4b8c8f15"}

咱們除了能夠經過上面的方式生成json文件以外,也可使用LogstashTcpSocketAppender將日誌內容直接經過Tcp Socket輸出到logstash服務端,好比:restful

<appender name="logstash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
  <destination>127.0.0.1:9250</destination>
  ...
</appender>
原文地址: http://blog.didispace.com/spr...

完整示例:

讀者能夠根據喜愛選擇下面的兩個倉庫中查看trace-1trace-2兩個項目:併發

若是您對這些感興趣,歡迎star、follow、收藏、轉發給予支持!app

本文內容部分節選自個人《Spring Cloud微服務實戰》,但對依賴的Spring Boot和Spring Cloud版本作了升級。分佈式

相關文章
相關標籤/搜索