使用ELK管理SpringBoot日志

使用ELK管理SpringBoot日志

當(dāng)我們開發(fā)一個新項目的時候,一個經(jīng)常遇到的問題是日志的管理。ELK棧(Elastic,Logstash,Kibana)是一個功能強大且免費的日志管理解決方案。在本文中,將為您展示如何安裝、如何設(shè)置ELK,如何使用它來管理SpringBoot應(yīng)用程序中的默認(rèn)格式的日志。

  在本文中,我們設(shè)置了一個演示SpringBoot應(yīng)用程序,并且啟用了日志管理,同時使用Logstash配置把日志條目送到了Elasticsearch。

  應(yīng)用程序會把日志存在一個文件中。Logstash將讀取并解析日志文件并將日志條目發(fā)送給Elasticsearch實例。最后,我們將使用Kibana4(ElasticsearchWeb前端)來搜索和分析日志。

  步驟一安裝Elasticsearch

  下載Elasticsearch,下載地址:https://www.elastic.co/downloads/elasticsearch  解壓縮到一個路徑(解壓縮)

  運行Elasticsearch(bin/elasticsearch或bin/elasticsearch.bat在Windows上)  檢查它是在使用curl-XGEThttp://localhost:9200運行  下面是如何操作(下面步驟是為OSX編寫的,但其它操作系統(tǒng)大致相同)

  wgethttps://download.elastic.co/elasticsearch/elasticsearch/elasticsearch-1.7.1.zip  unzipelasticsearch-1.7.1.zip  cdelasticsearch-1.7.1  bin/elasticsearch

現(xiàn)在,Elasticsearch應(yīng)該已經(jīng)在運行中了。您可以使用curl命令來驗證。在單獨的終端窗口中執(zhí)行Elasticsearch狀態(tài)頁面的GET請求:  curl-XGEThttp://localhost:9200  如果一切正常,你應(yīng)該得到以下結(jié)果:

{  "status":200,  "name":"Tartarus",  "cluster_name":"elasticsearch",  "version":{  "number":"1.7.1",  "build_hash":"b88f43fc40b0bcd7f173a1f9ee2e97816de80b19",  "build_timestamp":"2015-07-29T09:54:16Z",  "build_snapshot":false,  "lucene_version":"4.10.4"  },  "tagline":"YouKnow,forSearch"  }

步驟二安裝InstallKibana04

下載Kibana,下載地址:https://www.elastic.co/downloads/kibana(請注意你的系統(tǒng)屬性,下載與你系統(tǒng)相匹配的版本,鏈接給出的是OSX系統(tǒng)的)

解壓縮文件  運行Kivana(bin/kibana)

通過把瀏覽器指向Kibana's來檢查它是否在運行

下面是具體的做法:

wgethttps://download.elastic.co/kibana/kibana/kibana-4.1.1-darwin-x64.tar.gz  tarxvzfkibana-4.1.1-darwin-x64.tar.gz  cdkibana-4.1.1-darwin-x64  bin/kibana

將你的瀏覽器指向http://localhost:5601(如果頁面顯示正常,說明我做的很好,我們將在稍后配置它)。

步驟三安裝Logstash

下載Logstash,下載地址:https://www.elastic.co/downloads/logstash

提取文件(解壓縮)  wgethttps://download.elastic.co/logstash/logstash/logstash-1.5.3.zip  unziplogstash-1.5.3.zip

步驟四配置SpringBoot的日志文件

為了讓Logstash傳遞文件到Elasticsearch,我們必須先配置SpringBoot來把日志條目存儲到一個文件中。我們將建立以下傳遞路徑:SpringBootApp——日志文件——Logstash——Elasticsearch。這里還有其它的方法可以完成同樣的事情,比如配置logback來使用TCP附加器把日志發(fā)送到一個遠(yuǎn)程的Logstash,以及其它的有些配置。但我更喜歡文件方法,因為這樣更簡單、很自然(你可以很容易的把它添加到已存在的系統(tǒng)中),并且當(dāng)Logstash停止工作或者Elasticearch宕機的時候,不會丟失或者破壞任何文件。

不管如何,讓我們來配置SpringBoot的日志文件。最簡單的方法是在application.properties中配置日志文件。添加下面一行就足夠了:

logging.file=application.log  現(xiàn)在,SpringBoot將會在application.log中記錄ERROR,WARN和INFO級別的信息,并且當(dāng)信息量達(dá)到10M的時候更迭。

步驟五配置Logstash

通過配置Logstash可以了解SpringBoot的日志文件格式。這部分比較棘手?! ∥覀冃枰獎?chuàng)建一個Logstash配置文件。典型的Logstash配置文件包含三個部分:input、filter、output。每個部分包含執(zhí)行相關(guān)部分處理的插件,例如:從文件中讀取日志時間的文件輸入插件,或者將日志時間發(fā)送到Elasticsearch的elasticseatch輸出插件。

input部分定義了Logstash從哪里讀取輸入數(shù)據(jù)——在我們的例子中它是一個文件,所以我們將使用一個file插件multilinecodec。這基本上意味著我們的輸入文件可能每個條目有多行。

  Input部分  下面是輸入部分的配置:

 input{  file{  type=>"java"  path=>"/path/to/application.log"  codec=>multiline{  pattern=>"^%{YEAR}-%{MONTHNUM}-%{MONTHDAY}%{TIME}.*"  negate=>"true"  what=>"previous"  }  }  }

  我們將會用到file插件?! ype被設(shè)置為java——這只是額外的元數(shù)據(jù),以備將來使用多種類型的日志文件?! ath是日志文件的絕對路徑。它必須是絕對的——Logstash對這點很嚴(yán)格。

我們使用multilinecodec意味著多個行可能對應(yīng)著一個日志事件?! 榱藱z測在邏輯上與前一行分組的行,我們使用檢測模式:  pattern=>"^%{YEAR}-%{MONTHNUM}-%{MONTHDAY}%{TIME}.*"→每個新的日志事件都需要以日期開始?! egate=>"true"→如果它不以日期開始......  what=>"previous"→...然后,它應(yīng)該與前一行分組?! ∥募斎氩寮?,就像配置的一樣,將會跟蹤日志文件(例如:只讀取文件末尾的新條目)。所以,測試的時候,為了讓Logstash讀取某些內(nèi)容,您需要生成新的日志條目。

  Filter部分  Filter部分包含對日志時間執(zhí)行中間處理的插件。在我們的例子中國,事件可以是根據(jù)上述規(guī)則分組的單個日志行貨多行日志事件。在Filter部分,我們會做幾件事情:

  如果一個日志事件包含堆棧跟蹤,我們會標(biāo)記它。這將有助于我們在后面尋找我們所期望的信息。解析出時間戳,日志等級,pid,線程,類名稱(記錄器實際)和日志信息。指定時間戳的區(qū)域和格式——Kibana將會用到它來進(jìn)行實踐的基本搜索。

上面提及的SpringBoot日志格式的過濾器部分看起來是這樣的:  filter{  #Ifloglinecontainstabcharacterfollowedby'at'thenwewilltagthatentryasstacktrace  if[message]=~"\tat"{  grok{  match=>["message","^(\tat)"]  add_tag=>["stacktrace"]  }  }  #GrokkingSpringBoot'sdefaultlogformat  grok{  match=>["message",  "(?%{YEAR}-%{MONTHNUM}-%{MONTHDAY}%{TIME})%{LOGLEVEL:level}%{NUMBER:pid}---\[(?[A-Za-z0-9-]+)\][A-Za-z0-9.]*\.(?[A-Za-z0-9#_]+)\s*:\s+(?.*)",  "message",  "(?%{YEAR}-%{MONTHNUM}-%{MONTHDAY}%{TIME})%{LOGLEVEL:level}%{NUMBER:pid}---.+?:\s+(?.*)"  ]  }  #Parsingouttimestampswhichareintimestampfieldthankstopreviousgroksection  date{  match=>["timestamp","yyyy-MM-ddHH:mm:ss.SSS"]  }  }

說明  if[message]=~"\tat"→如果消息包含后面跟著at的tab字符(這是ruby語法),那么......  ...使用grok插件來標(biāo)記堆棧蹤跡:  match=>["message","^(\tat)"]→當(dāng)message匹配行的開頭,后面跟著tab,之后跟著at,然后是...  add_tag=>["stacktrace"]→...用stacktrace標(biāo)簽標(biāo)記事件?! ∈褂胓rok插件進(jìn)行常規(guī)的SpringBoot日志消息解析:  第一種模式提取時間戳,級別,pid,線程,類名(實際上是記錄器名稱)和日志消息?! 〔恍业氖?,某些日志消息沒有類似于類名的記錄器名稱(例如,Tomcat日志),因此第二個模式將跳過記錄器/類字段并解析出時間戳,級別,pid,線程和日志消息。  使用date插件解析并設(shè)置事件日期:  match=>["timestamp","yyyy-MM-ddHH:mm:ss.SSS"]→timestamp字段(早先grokked)包含指定格式的時間戳

  Output部分  Output部分包含將事件數(shù)據(jù)發(fā)送到特定目標(biāo)的輸出插件。產(chǎn)出是事件管道的最后階段。我們將把日志事件發(fā)送到stdout(控制臺輸出,用于調(diào)試)和Elasticsearch。  與Filter分相比,Output部分非常簡單:

  filter{  #Ifloglinecontainstabcharacterfollowedby'at'thenwewilltagthatentryasstacktrace  if[message]=~"\tat"{  grok{  match=>["message","^(\tat)"]  add_tag=>["stacktrace"]  }  }  #GrokkingSpringBoot'sdefaultlogformat  grok{  match=>["message",  "(?%{YEAR}-%{MONTHNUM}-%{MONTHDAY}%{TIME})%{LOGLEVEL:level}%{NUMBER:pid}---\[(?[A-Za-z0-9-]+)\][A-Za-z0-9.]*\.(?[A-Za-z0-9#_]+)\s*:\s+(?.*)",  "message",  "(?%{YEAR}-%{MONTHNUM}-%{MONTHDAY}%{TIME})%{LOGLEVEL:level}%{NUMBER:pid}---.+?:\s+(?.*)"

  ]

  }

  #Parsingouttimestampswhichareintimestampfieldthankstopreviousgroksection

  date{

  match=>["timestamp","yyyy-MM-ddHH:mm:ss.SSS"]

  }

  }

  說明:

  我們正在使用多個輸出:stdout和elasticsearch。

  stdout{...}→stdout插件將日志事件打印到標(biāo)準(zhǔn)輸出(控制臺)。

  codec=>rubydebug→使用類似JSON格式的漂亮打印事件。

  elasticsearch{...}→elasticsearch插件將日志事件發(fā)送到Elasticsearch服務(wù)器。

  host=>"127.0.0.1"→Elasticsearch所在的主機名在我們的例子中是localhost。

  Update5/9/2016:在編寫此更新時,Logstash的elasticsearch輸出插件的最新版本使用hosts配置參數(shù),而不是host上面的示例中所示。新參數(shù)將一組主機(例如elasticsearchcluster)作為值。換句話說,如果您正在使用最新的Logstash版本,請按如下所示配置elasticsearch輸出插件:

  elasticsearch{

  hosts=>["127.0.0.1"]

  }

  把各個部分放在一起

  最后,三個部分——input,filter和output需要復(fù)制粘貼到一起并保存在Logstash.conf配置文件中。一旦配置文件就位,并且Elasticsearch運行,我們可以運行Logstash:

  elasticsearch{

  hosts=>["127.0.0.1"]

  }

  如果一切順利,Logstash正在傳遞日志時間到Elasticsearch。

  步驟六配置Kibana

  現(xiàn)在是我們再次訪問KibanawebUI的時候了,我們已經(jīng)在第二部中啟動了,它應(yīng)該在http://localhost:5601上運行。

  首先,您需要將Kibana指向您選擇的elasticsearch索引。Logstash創(chuàng)建索引的名稱模式是:logstash-YYYY.MM.DD。在Kibana設(shè)置——索引中配置索引。

  索引包含基于時間的事件(選擇此項)

  使用事件時間創(chuàng)建索引名稱(選擇此項)

  索引模式間隔:日

  索引名稱或模式:[logstash-]YYYY.MM.DD

  點擊“創(chuàng)建索引”

  現(xiàn)在,點擊“Discover”標(biāo)簽。在我看來,“Discover”選項卡在Kibana中的確命名不正確-它應(yīng)該被標(biāo)記為“Search”而不是“Discover”,因為它允許您執(zhí)行新的搜索并保存/管理它們。日志事件現(xiàn)在應(yīng)該顯示在主窗口中。如果不是,則再次檢查屏幕右上角的時間段過濾器。默認(rèn)表格默認(rèn)有2列:Time和_source。為了使列表更有用,我們可以配置顯示的列。從左側(cè)的選擇菜單中選擇級別,類別和日志消息。

  好的!您現(xiàn)在已準(zhǔn)備好使用ELK堆棧來控制日志,并開始自定義和調(diào)整日志管理配置。

  您可以從這里下載這篇文章時使用的示例應(yīng)用程序:https://github.com/knes1/todo。它已被配置為將日志寫入文件,并具有上述的Logstash配置(盡管需要調(diào)整絕對路徑logstash.conf)。

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

相關(guān)閱讀更多精彩內(nèi)容

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