使用Docker搭建ELK日志系統

使用Docker搭建ELK日志系統

之前用本地版本安裝了ELK之后,就沒有再去弄它了。年底沒那么忙,心里一直惦記,所以最近又開始折騰了。去elastic官網看一下,果然版本帝就是版本帝,一周一版本?,F在我用的版本是基于6.1.1版本的。

目標

  1. 收集Java日志文件,并且根據文件的不同將日志分類,比如:訂單日志,客戶日志等。
  2. 日志文件多行處理

總體架構圖

準備鏡像

6.0之后官方開始自己維護鏡像版本:https://www.docker.elastic.co/。找到需要的ELK鏡像地址,pull下來就好了。官方pull下來之后鏡像名太長了,所以我將鏡像全部重新打了tag,命令:docker tag docker.elastic.co/elasticsearch/elasticsearch:6.1.1 elasticsearch:latest
使用docker images查看:

安裝docker版本ElasticSearch

在elasticsearch的docker版本文檔中,官方提到了vm.max_map_count的值在生產環境最少要設置成262144。設置的方式有兩種

  1. 永久性的修改,在/etc/sysctl.conf文件中添加一行:
grep vm.max_map_count /etc/sysctl.conf # 查找當前的值。

vm.max_map_count=262144 # 修改或者新增

  1. 正在運行的機器:
sysctl -w vm.max_map_count=262144

之后我們執行命令,暴露容器的9200,9300端口,方便我們在其它集器上可以通過類似head插件去做es索引的操作等。執行命令為:

docker run -p 127.0.0.1:9200:9200 -p 9300:9300 --name elasticsearch -e "discovery.type=single-node" elasticsearch

如果實際使用中,可能需要設置集群等操作。因實際情況而定。如果你需要存儲歷史數據,那么就可能需要將data目錄保存到本地,使用-v,或者mount參數掛載本地一個目錄。

安裝docker版本kibana

kibana的作用主要是幫助我們將日志文件可視化。便于我們操作,統計等。它需要ES服務,所以我們將部署好的es和kibana關聯起來,主要用到的參數是--link:

docker run -d -p 5601:5601 --link elasticsearch -e ELASTICSEARCH_URL=http://elasticsearch:9200 kibana

使用link參數,會在kibana容器hosts文件中加入elasticsearch ip地址,這樣我們就直接通過定義的name來訪問es服務了。

安裝logstash和filebeat

前面的kibana和ES的安裝,如果我們在開發環境中并不需要太多的關注他們的詳細配置。但是logstash和filebeat我們需要注意下它的配置,因為這兩者是我們完成需求的重要點。

logstash我們只讓它進行日志處理,處理完之后將其輸出到elasticsearch。

filebeat是一個輕量級收集器,我們使用它來收集Java日志,將不同文件夾下的日志進行tag,處理多行日志行為(主要針對Java異常信息),之后發送給logstash。

日志的文件格式大概就是:DATE LOG-LEVEL LOG-MESSAGE,格式是在log4j.properties中定義的。你也可以自己定義輸出格式。

現在我們定義logstash.conf,主要在logstash中使用grok filter插件。

logstash.conf:

input {
  beats {
    host => "localhost"
    port => "5043"
  }
}
filter {
   if [fields][doc_type] == 'order' {
    grok {
            match => { "message" => "%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:level} %{JAVALOGMESSAGE:msg}" }
        }
   }

   if [fields][doc_type] == 'customer' { # 這里寫兩個一樣的grok,實際上可能出現多種不同的日志格式,這里做個提示而已,當然如果是相同的格式,這里可以不寫的
    grok {
            match => { "message" => "%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:level} %{JAVALOGMESSAGE:msg}" }
        }
   }
}

output {
  stdout { codec => rubydebug }
  elasticsearch {
        hosts => [ "localhost:9200" ]
        index => "%{[fields][doc_type]}-%{+YYYY.MM.dd}"
    }
}

在logstash.conf中,我們主要使用[fields][doc_type]來標明日志的類型,這個值實在filebeat中定義的。

現在我們假定需要收集兩個目錄下的日志文件:/home/user/elk/customer/*.log,/home/user/elk/order/*.log

customer.log:

2017-12-26 10:05:56,476 INFO ConfigClusterResolver:43 - Resolving eureka endpoints via configuration
2017-12-26 10:07:23,529 INFO WarehouseController:271 - findWarehouseList,json{"formJSON":{"userId":"885769620971720708"},"requestParameterMap":{},"requestAttrMap":{"name":"asdf","user":"8857696","ip":"183.63.112.1","source":"asdfa","customerId":"885768861337128965","IMEI":"863267033748196","sessionId":"xm1cile2bcmb15wtqmjno7tgz","sfUSCSsadDDD":"asdf/10069&ADR&1080&1920&OPPO R9s Plus&Android6.0.1","URI":"/warehouse-service/appWarehouse/findByCustomerId.apec","encryptType":"2","requestStartTime":3450671468321405}}
2017-12-26 10:07:23,650 INFO WarehouseServiceImpl:325 - warehouse list:8,warehouse str:[{"addressDetail":"nnnnnnnn","areaId":"210624","areaNa":""}]
2017-12-26 10:10:56,477 INFO ConfigClusterResolver:43 - Resolving eureka endpoints via configuration
2017-12-26 10:15:56,477 INFO ConfigClusterResolver:43 - Resolving eureka endpoints via configuration
2017-12-26 10:20:56,478 INFO ConfigClusterResolver:43 - Resolving eureka endpoints via configuration
2017-12-26 10:05:56,476 INFO ConfigClusterResolver:43 - Resolving eureka endpoints via configuration
2017-12-26 10:07:23,529 INFO WarehouseController:271 - findWarehouseList,json{"formJSON":{"userId":"885769620971720708"}}]
2017-12-26 10:10:56,477 INFO ConfigClusterResolver:43 - Resolving eureka endpoints via configuration
2017-12-26 10:15:56,477 INFO ConfigClusterResolver:43 - Resolving eureka endpoints via configuration
2017-12-26 10:20:56,478 INFO ConfigClusterResolver:43 - Resolving eureka endpoints via configuration

order.log:

2017-12-26 11:29:19,374 INFO WebLogAspect:53 -- 請求:18,SPEND TIME:0
2017-12-26 11:38:20,404 INFO NoticeServiceApplication:664 -- The following profiles are active: test
2017-12-26 11:41:07,754 INFO NoticeServiceApplication:664 -- The following profiles are active: test
2017-12-26 12:38:58,683 INFO RedisClusterConfig:107 -- //// --- 啟動單點Redis ---
2017-12-26 12:39:00,325 DEBUG ApplicationContextRegister:26 -- 
2017-12-26 12:39:06,961 INFO NoticeServiceApplication:57 -- Started NoticeServiceApplication in 17.667 seconds (JVM running for 18.377)
2017-12-26 11:27:56,577 INFO WebLogAspect:51 -- 請求:19,RESPONSE:"{\"data\":null,\"errorCode\":\"\",\"errorMsg\":\"\",\"repeatAct\":\"\",\"succeed\":true}"
2017-12-26 11:27:56,577 INFO WebLogAspect:53 -- 請求:19,SPEND TIME:1
2017-12-26 11:28:09,829 INFO WebLogAspect:42 -- 請求:20,URL:http://192.168.7.203:30004/sr/flushCache
2017-12-26 11:28:09,830 INFO WebLogAspect:43 -- 請求:20,HTTP_METHOD:POST
2017-12-26 11:28:09,830 INFO WebLogAspect:44 -- 請求:20,IP:192.168.7.98
2017-12-26 11:28:09,830 INFO WebLogAspect:45 -- 請求:20,CLASS_METHOD:com.notice.web.estrictController
2017-12-26 11:28:09,830 INFO WebLogAspect:46 -- 請求:20,METHOD:flushRestrict
2017-12-26 11:28:09,830 INFO WebLogAspect:47 -- 請求:20,ARGS:["{\n}"]
2017-12-26 11:28:09,830 DEBUG SystemRestrictController:231 -- 刷新權限限制鏈
2017-12-26 11:38:20,404 INFO NoticeServiceApplication:664 -- The following profiles are active: test
2017-12-26 11:41:07,754 INFO NoticeServiceApplication:664 -- The following profiles are active: test
2017-12-26 11:41:40,664 INFO NoticeServiceApplication:664 -- The following profiles are active: test
2017-12-26 11:43:38,224 INFO NoticeServiceApplication:664 -- The following profiles are active: test
2017-12-26 11:47:49,141 INFO NoticeServiceApplication:664 -- The following profiles are active: test
2017-12-26 11:51:02,525 INFO NoticeServiceApplication:664 -- The following profiles are active: test
2017-12-26 11:52:28,726 INFO NoticeServiceApplication:664 -- The following profiles are active: test
2017-12-26 11:53:55,301 INFO NoticeServiceApplication:664 -- The following profiles are active: test
2017-12-26 11:54:26,717 INFO NoticeServiceApplication:664 -- The following profiles are active: test
2017-12-26 11:58:48,834 INFO NoticeServiceApplication:664 -- The following profiles are active: test
2017-12-26 12:38:51,126 INFO NoticeServiceApplication:664 -- The following profiles are active: test
2017-12-26 12:38:58,683 INFO RedisClusterConfig:107 -- //// --- 啟動單點Redis ---
2017-12-26 12:39:00,325 DEBUG ApplicationContextRegister:26 -- ApplicationContextRegister.setApplicationContext:applicationContextorg.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@5f150435: startup date [Tue Dec 26 12:38:51 CST 2017]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@63c12fb0
2017-12-26 12:39:06,961 INFO NoticeServiceApplication:57 -- Started NoticeServiceApplication in 17.667 seconds (JVM running for 18.377)

日志的文件格式大概就是:DATE LOG-LEVEL LOG-MESSAGE,格式我們是在log4j.properties中定義的。你可以自己定義,自定義注意修改logstash.conf中的grok就好。

之后解決我們的filebeat要解決的問題:收集日志,處理多行日志,給日志打標簽。在filebeat.yml中,如下定義:

filebeat.yml

filebeat.prospectors:
- paths:
    - /home/user/elk/logs/order/*.log
  multiline:
      pattern: ^\d{4}
      negate: true
      match: after
  fields:
    doc_type: order
- paths:
    - /home/user/elk/logs/customer/*.log
  multiline:
      pattern: ^\d{4}
      negate: true
      match: after
  fields:
    doc_type: customer
output.logstash: # 輸出地址
  hosts: ["logstash:5043"]

  1. 收集日志:直接使用prospector定位并且處理日志文件。
  2. 多行日志: 根據日志格式,我們開頭都是yyyy,類似與純4個數字,所以我們使用multile插件,做配置就好。官方的文檔挺詳細的,主要就是實踐:filebeat multiline
  3. 打標簽:這個是最重要的,主要的目的是讓logstash知道filebeat發送給它的消息是那個類型,然后logstash發送到es的時候,我們可以建立相關索引。這里的fields是內置的,doc_type是自定義的。

之前的document_type 在5.5.0中就已經廢棄了。https://www.elastic.co/guide/en/beats/libbeat/6.1/release-notes-5.5.0.html#_deprecated_6

了解這些之后,我們啟動我們的logstash和filebeat。

啟動docker版本的logstash:

docker run --rm -it --name logstash --link elasticsearch -d -v ~/elk/yaml/logstash.conf:/usr/share/logstash/pipeline/logstash.conf logstash

啟動filebeat,將文件掛載到容器中,這里也可以有其它的處理方法,你可以根據自己的需求來。

docker run --name filebeat -d --link logstash -v ~/elk/yaml/filebeat.yml:/usr/share/filebeat/filebeat.yml -v ~/elk/logs/:/home/logs/ filebeat

最后記得在kibana里面建立索引(create index)的時候,默認使用的是logstash,而我們是自定義的doc_type,所以你需要輸入order,customer這樣就可以建立兩個索引了。

之后就可以在kibana的Discovery里面看到你配置的了

如果你直接用我的log,請將時間稍微改一下,2017-12-26改為當天實驗年月。

上面的命令我都自己實踐過,是可以用的,注意下-v參數掛載的幾個本地盤的地址。還有filebeat收集的地址。

配置文件地址倉庫:使用Docker搭建ELK日志系統

參考文章:
使用Docker搭建ELK日志系統
基于ELK+Filebeat搭建日志中心

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容