ELK 日志采集 實戰教程


 概要

        帶着問題去看教程:

  • 不是用logstash來監聽我們的日志,我們可以使用logback配置來使用TCP appender通過TCP協議將日志發送到遠程Logstash實例。

  • 我們可以使用Logstash指向多個日志文件。

  • 我們可以在logstash配置文件中使用更復雜的過濾器,以根據需要執行更多操作。

  • 我們可以使用遠程ELK集群指向我們的日志文件,或者將日志推入,這在將所有應用程序部署到雲中時基本上是必需的。

  • 在logstash中創建不同的索引模式。

        通過使用微服務,我們已經能夠克服許多遺留問題,並且它允許我們創建穩定的分布式應用程序,並對代碼,團隊規模,維護,發布周期,雲計算等進行所需的控制。但它也引入了一些挑戰。其他領域,例如分布式日志管理和查看在許多服務中分布的完整事務的日志和一般的分布式調試的能力。

        實際上,挑戰在於微服務是相互隔離的,它們不共享公共數據庫和日志文件。隨着微服務數量的增加以及我們使用自動化持續集成工具實現雲部署,當我們遇到任何問題時,非常有必要對組件進行一些調試。

        感謝開源運動。我們已經擁有了一系列工具,如果一起使用可以發揮魔力。一組如此受歡迎的工具是Elastic Search,Logstash和Kibana - 一起稱為ELK Stack 。它們用於實時搜索,分析和可視化日志數據。        

ELK Stack

  1. Elasticsearch是一個基於JSON的分布式搜索和分析引擎,專為水平可擴展性,最高可靠性和易管理性而設計。

  2. Logstash是一個動態數據收集管道,具有可擴展的插件生態系統和強大的Elasticsearch協同作用。

  3. Kibana通過UI 提供數據可視化

ELK Stack架構

Logstash根據我們設置的過濾條件處理應用程序日志文件,並將這些日志發送到Elasticsearch。通過Kibana,我們可以在需要時查看和分析這些日志。

ELK配置

所有這三個工具都基於JVM,在開始安裝之前,請驗證JDK是否已正確配置。檢查標准JDK 1.8安裝,JAVA_HOME並且PATH已經完成設置。

Elasticsearch

  • 從此下載頁面下載最新版本的Elasticsearch 並將其解壓縮到任何文件夾中。

  • bin\elasticsearch.bat從命令提示符運行。

  • 默認情況下,它將從http:// localhost:9200

Kibana

  • 從下載頁面下載最新的發行版並解壓縮到任何文件夾中。

  • config/kibana.yml在編輯器中打開並設置elasticsearch.url為指向您的Elasticsearch實例。在我們的例子中,我們將使用本地實例取消注釋elasticsearch.url: "http://localhost:9200"

  • bin\kibana.bat從命令提示符運行。

  • 成功啟動后,Kibana將啟動默認端口5601,Kibana UI將在http:// localhost:5601上提供

Logstash

  • 從下載頁面下載最新的發行版並解壓縮到任何文件夾中。

  • logstash.conf根據配置說明創建一個文件。在實際演示時間內,我們將再次進行精確配置。

    現在運行bin/logstash -f logstash.conf以啟動logstash

ELK堆棧未啟動並正在運行。現在我們需要創建一些微服務並指向API日志路徑的logstash。

創建微服務

創建Spring Boot項目

讓我們使用spring boot創建一個應用程序,以縮短開發時間。請按照這些步驟啟動此服務。

添加REST端點

添加一個RestController類會暴露一些端點一樣/elk/elkdemo/exception。實際上我們只會測試幾個日志語句,因此可以根據您的選擇隨意添加/修改日志。

package  com.example.howtodoinjava.elkexamplespringboot;
 
import  java.io.PrintWriter;
import  java.io.StringWriter;
import  java.util.Date;
 
import  org.apache.log4j.Level;
import  org.apache.log4j.Logger;
import  org.springframework.beans.factory.annotation.Autowired;
import  org.springframework.boot.SpringApplication;
import  org.springframework.boot.autoconfigure.SpringBootApplication;
import  org.springframework.context.annotation.Bean;
import  org.springframework.core.ParameterizedTypeReference;
import  org.springframework.http.HttpMethod;
import  org.springframework.web.bind.annotation.RequestMapping;
import  org.springframework.web.bind.annotation.RestController;
import  org.springframework.web.client.RestTemplate;
 
@SpringBootApplication
public  class  ElkExampleSpringBootApplication {
 
     public  static  void  main(String[] args) {
         SpringApplication.run(ElkExampleSpringBootApplication. class , args);
     }
}
 
@RestController
class  ELKController {
     private  static  final  Logger LOG = Logger.getLogger(ELKController. class .getName());
 
     @Autowired
     RestTemplate restTemplete;
 
     @Bean
     RestTemplate restTemplate() {
         return  new  RestTemplate();
     }
 
     @RequestMapping (value =  "/elkdemo" )
     public  String helloWorld() {
         String response =  "Hello user ! "  new  Date();
         LOG.log(Level.INFO,  "/elkdemo - > "  + response);
 
         return  response;
     }
 
     @RequestMapping (value =  "/elk" )
     public  String helloWorld1() {
 
         String response = restTemplete.exchange( "http://localhost:8080/elkdemo" , HttpMethod.GET,  null new ParameterizedTypeReference() {
         }).getBody();
         LOG.log(Level.INFO,  "/elk - > "  + response);
 
         try  {
             String exceptionrsp = restTemplete.exchange( "http://localhost:8080/exception" , HttpMethod.GET,  null , new  ParameterizedTypeReference() {
             }).getBody();
             LOG.log(Level.INFO,  "/elk trying to print exception - > "  + exceptionrsp);
             response = response +  " === "  + exceptionrsp;
         catch  (Exception e) {
             // exception should not reach here. Really bad practice :)
         }
 
         return  response;
     }
 
     @RequestMapping (value =  "/exception" )
     public  String exception() {
         String rsp =  "" ;
         try  {
             int  i =  1  0 ;
             // should get exception
         catch  (Exception e) {
             e.printStackTrace();
             LOG.error(e);
             
             StringWriter sw =  new  StringWriter();
             PrintWriter pw =  new  PrintWriter(sw);
             e.printStackTrace(pw);
             String sStackTrace = sw.toString();  // stack trace as a string
             LOG.error( "Exception As String :: - > " +sStackTrace);
             
             rsp = sStackTrace;
         }
 
         return  rsp;
     }
}

配置Spring引導記錄

application.propertiesresources文件夾下打開並添加以下配置條目。

logging.file=elk-example.log
spring.application.name = elk-example

驗證微服務生成的日志

通過瀏覽http:// localhost:8080 / elk,mvn clean install使用命令java -jar target\elk-example-spring-boot-0.0.1-SNAPSHOT.jar和測試來執行最終的maven構建並啟動應用程序。

不要害怕看到屏幕上的大堆棧跟蹤,因為有意識地看看ELK如何處理異常消息。

轉到應用程序根目錄並驗證是否elk-example.log已創建日志文件,並對端點執行幾次訪問,並驗證日志文件中是否添加了日志。

 

Logstash配置

我們需要創建一個logstash配置文件,以便它監聽日志文件並將日志消息推送到彈性搜索。以下是示例中使用的logstash 配置,請根據您的設置更改日志路徑。

input {
   file {
     type =>  "java"
     path =>  "F:/Study/eclipse_workspace_mars/elk-example-spring-boot/elk-example.log"
     codec => multiline {
       pattern =>  "^%{YEAR}-%{MONTHNUM}-%{MONTHDAY} %{TIME}.*"
       negate =>  "true"
       what =>  "previous"
     }
   }
}
 
filter {
   #If log line contains tab character followed by  'at'  then we will tag that entry as stacktrace
   if  [message] =~  "\tat"  {
     grok {
       match => [ "message" "^(\tat)" ]
       add_tag => [ "stacktrace" ]
     }
   }
 
  grok {
     match => [  "message" ,
                "(?<timestamp>%{YEAR}-%{MONTHNUM}-%{MONTHDAY} %{TIME})  %{LOGLEVEL:level} %{NUMBER:pid} --- \[(?<thread>[A-Za-z0-9-]+)\] [A-Za-z0-9.]*\.(?<class>[A-Za-z0-9#_]+)\s*:\s+(?<logmessage>.*)" ,
                "message" ,
                "(?<timestamp>%{YEAR}-%{MONTHNUM}-%{MONTHDAY} %{TIME})  %{LOGLEVEL:level} %{NUMBER:pid} --- .+? :\s+(?<logmessage>.*)"
              ]
   }
 
  
   date {
     match => [  "timestamp"  "yyyy-MM-dd HH:mm:ss.SSS"  ]
   }
}
 
output {
   
   stdout {
     codec => rubydebug
   }
 
   # Sending properly parsed log events to elasticsearch
   elasticsearch {
     hosts => [ "localhost:9200" ]
   }
}

 

Kibana配置

在查看Kibana中的日志之前,我們需要配置索引模式。我們可以配置logstash-*為默認配置。我們總是可以在logstash端更改此索引模式並在Kibana中進行配置。為簡單起見,我們將使用默認配置。

索引模式管理頁面如下所示。通過這種配置,我們將Kibana指向您選擇的Elasticsearch索引。Logstash使用名稱模式創建索引。logstash-YYYY.MM.DD我們可以在Kibana控制台http:// localhost:5601 / app / kibana中執行所有這些配置,然后轉到左側面板中的Management鏈接。

驗證ELK

現在,當所有組件都啟動並運行時,讓我們驗證整個生態系統。

轉到應用程序並測試端點幾次以便生成日志,然后轉到Kibana控制台,看看日志是否正確堆疊在Kibana中,還有許多額外的功能,比如我們可以過濾,查看內置的不同圖表等。

以下是Kibana中生成的日志的視圖。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM