1. ELK日志分析簡介
1.1 ELK日志分析概述
ELK可運行於分布式系統之上,通過搜集、過濾、傳輸、儲存,對海量系統和組件日志進行集中管理和准實時搜索、分析,使用搜索、監控、事件消息和報表等簡單易用的功能,幫助運維人員進行線上業務的准實時監控、業務異常時及時定位原因、排除故障、程序研發時跟蹤分析Bug、業務趨勢分析、深度挖掘日志的大數據價值。ELK主要可解決的問題如下:1.日志查詢,問題排查,上線檢查.2.服務器監控,應用監控,錯誤報警,Bug管理. 3.性能分析,安全漏洞分析。綜上,ELK是一套方便、易用的日志分析開源解決方案。
1.2 ELK主要組件介紹
生產環境中,ELK通常由以下4個組件構成:
1.2.1 ElasticSearch組件
ElasticSearch是一個基於Lucene的開源分布式搜索服務器。它的特點有:分布式,零配置,自動發現,索引自動分片,索引副本機制,restful風格接口,多數據源,自動搜索負載等。它提供了一個分布式多用戶能力的全文搜索引擎,基於RESTful web接口。Elasticsearch是用Java開發的,並作為Apache許可條款下的開放源碼發布,是第二流行的企業搜索引擎。設計用於雲計算中,能夠達到實時搜索,穩定,可靠,快速,安裝使用方便。
1.2.2 Logstash組件
Logstash是一個完全開源的工具,它可以對你的日志進行收集、過濾、分析,支持大量的數據獲取方法,並將其存儲供以后使用(如搜索)。一般工作方式為c/s架構,client端安裝在需要收集日志的主機上,server端負責將收到的各節點日志進行過濾、修改等操作在一並發往elasticsearch上去。Logstash事件處理有三個階段:inputs → filters → outputs。是一個接收,處理,轉發日志的工具,如下圖所示:
1.2.3 Kibana組件
Kibana是一個基於瀏覽器頁面的Elasticsearch前端展示工具,也是一個開源和免費的工具,Kibana可以為 Logstash 和 ElasticSearch 提供的日志分析友好的 Web 界面,可以幫助您匯總、分析和搜索重要數據日志。
1.2.4 Filebeat組件
Filebeat是一個日志文件托運工具,在你的服務器上安裝客戶端后,filebeat會監控日志目錄或者指定的日志文件,追蹤讀取這些文件,並且轉發這些信息到賦予他的輸出位置(常見如elasticsearch、kafka或logstarsh)中存放。Filebeat等同於一個輕量級的logstash,當你需要收集信息的機器配置或日志資源數量不是特別多時,最佳實踐是使用filebeat來代替logstash收集日志,filebeat十分小巧且穩定。下圖是filebeat的工作流程:當你開啟filebeat程序的時候,它會啟動一個或多個探測器(prospectors)去檢測你指定的日志目錄或文件,對於探測器找出的每一個日志文件,filebeat啟動收割進程(harvester),每一個收割進程讀取一個日志文件的新內容,並發送這些新的日志數據到處理程序(spooler),處理程序會集合這些事件,最后filebeat會發送集合的數據到你指定的地點。
2. Docker-elk搭建實驗環境
2.1 sebp/elk鏡像的獲取
外網環境下,執行命令:docker pull sebp/elk
將鏡像pull到本地來。
2.2 制作上報日志到ELK的filebeat鏡像
(1) 本地Window在官網下載filebeat,然后通過SecureCRT導入tar.gz壓縮包文件並在linux中解壓。
(2) 安裝JDK 鏡像
與elk鏡像同理,將JDK的官方鏡像pull到本地,作為基礎鏡像就好:java:8u111-jdk .
(3) 開放filebeat訪問ELK的權限
在我們使用的elk鏡像源碼的git倉庫中(地址是https://github.com/spujadas/elk-docker
),下載該鏡像的logstash-beats.crt文件來給filebeat提供授權,制作鏡像時要放在指定目錄下。
(4) 修改配置文件filebeat.yml
首先配置抓取WEB日志的目錄:
- type: log
# Change to true to enable this prospector configuration.
enabled: true
# Paths that should be crawled and fetched. Glob based paths.
paths:
- /applog/*.log
接下來為filebeat提供ELK授權:
#output.logstash:
# The Logstash hosts
hosts: ["localhost:5044"]
# Optional SSL. By default is off.
# List of root certificates for HTTPS server verifications
ssl.certificate_authorities: ["/home/hik/docker/logstash-beats.crt"]
(5) 制作filebeat和web服務的啟動腳本
編寫啟動filebeat和web應用的腳本filebeat-springboot-entrypoint.sh,在docker容器啟動的時候執行,這樣就能讓fliebeat和web應用在容器啟動后也自動啟動了:
echo "start filebeat now ..."
nohup /opt/filebeat-6.2.2-linux-x86_64/filebeat -e -c /opt/filebeat-6.2.2-linux-x86_64/filebeat.yml >/dev/null 2>&1 &
echo "start springboot jar now ..."
java -jar $1
(6) 通過Dockerfile完成filebeat鏡像構建
Dockerfile腳本的內容如下:
#基礎鏡像
FROM java:8u111-jdk
#定義日志文件存放目錄,這個要和web應用的日志配置一致
ENV APP_LOG_PATH /applog
#定義證書文件目錄,這個要和filebeat.yml的配置一致
ENV FILE_BEAT_CRT_PATH /etc/pki/tls/certs
#定義filebeat文件夾名稱
ENV FILE_BEAT_PACKAGE_NAME filebeat-6.2.2-linux-x86_64
#定義證書文件名稱
ENV FILE_BEAT_CRT_NAME logstash-beats.crt
#定義啟動文件名稱
ENV ENTRYPOINT_FILE_NAME filebeat-springboot-entrypoint.sh
#定義時區參數
ENV TZ=Asia/Shanghai
#設置時區
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
#使之生效
RUN . /etc/profile
#創建日志目錄文件夾
RUN mkdir $APP_LOG_PATH
#存放證書的文件夾
RUN mkdir -p $FILE_BEAT_CRT_PATH
#從當前目錄將證書文件復制到鏡像中
COPY ./$FILE_BEAT_CRT_NAME $FILE_BEAT_CRT_PATH/
#從當前目錄將filebeat文件復制到鏡像中
COPY ./$FILE_BEAT_PACKAGE_NAME /opt/$FILE_BEAT_PACKAGE_NAME
#復制啟動文件
COPY ./$ENTRYPOINT_FILE_NAME /$ENTRYPOINT_FILE_NAME
#賦寫權限
RUN chmod a+x /$ENTRYPOINT_FILE_NAME
如上所述,前面我們准備的材料在腳本都統統用上了;將filebeat-6.2.2-linux-x86_64 文件夾、Dockerfile文件、filebeat-springboot-entrypoint.sh文件、logstash-beats.crt放在同一目錄下,執行以下命令即可將鏡像構建成功:
docker build -t springboot-app-filebeat:0.0.3 .
注意:最后有一個空格和一個點,這代表當前路徑,不加的話會構建失敗。
2.3 通過2.2制作web工程鏡像
(1) 用maven創建一個springboot的web工程,在工程的目錄src/main/resources下增加一個logback.xml文件,用於配置日志有關的參數。日志文件的目錄設置在/applog/,和filebeat.yml中搜集日志的目錄保持一致(完成)
<!-- 文件日志:輸出全部日志到文件 -->
<appender name="FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>/applog/output.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>7</maxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${ENCODER_PATTERN}</pattern>
</encoder>
</appender>
(2) 在web工程的pom.xml中,新增一個插件docker-maven-plugin,用於將當前工程構建成的jar做成docker鏡像文件,基礎鏡像使用2.2中構建好的filebeat鏡像。
<!--新增的docker maven插件-->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.12</version>
<!--docker鏡像相關的配置信息-->
<configuration>
<!--鏡像名,這里用工程名-->
<imageName>bolingcavalry/${project.artifactId}</imageName>
<!--TAG,這里用工程版本號-->
<imageTags>
<imageTag>${project.version}</imageTag>
</imageTags>
<!--鏡像的FROM,使用springboot-app-filebeat:0.0.3-->
<baseImage>springboot-app-filebeat:0.0.3</baseImage>
<!--該鏡像的容器啟動后,直接運行spring boot工程-->
<entryPoint>["sh","/filebeat-springboot-entrypoint.sh","/${project.build.finalName}.jar"]</entryPoint>
<!--構建鏡像的配置信息-->
<dockerHost>http://10.66.35.173:2375</dockerHost>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
(3) 新增HelloController.java用於響應web請求,並且每次收到請求時都會打印一行日志到指定文件中。
@RequestMapping(value="/hello/{username}",method= RequestMethod.GET)
public String hello(@PathVariable String username) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String time = sdf.format(new Date());
logger.info("execute hello from {} - {}", username, time);
return "hello " + username + ", " + time;
}
(4) 在pom.xml文件所在目錄執行以下命令,即可編譯構建當前工程,並制作成docker鏡像:shell mvn clean package -U -DskipTests docker:build
2.4 連接2.1和2.3實現ELK管理WEB服務
通過docker-compose.yml來啟動ELK和最終鏡像。完成兩者的連接,使web工程在ELK容器中運行。
vi docker-compose.yml
version: '2'
services:
elk:
image: elk:6.4.2
ports:
- "5601:5601"
- "9200:9200"
restart: always
webapp:
image: elkdemo:1.0
depends_on:
- elk
links:
- elk:elkhost
ports:
- "18080:8080"
restart: always
啟動:shell sudo docker-compose up -d
注意:1.ELK server容器的5601端口映射為當前電腦的5601端口,用於訪問kibana;2.web應用鏡像使用link參數綁定ELK server容器,3使用webapp作為域名的地方都會被解析為ELK server容器的IP地址;3.web容器的8080映射為當前電腦的18080端口,訪問當前電腦的18080端口即可訪問web服務。
至此,整個ELK環境所需的鏡像和腳本都已做好,web服務和ELK服務也都成功運行起來了,實驗環境搭建完畢。
3. Logstash與filter插件應用
3.1 Logstash常用filter插件
Filter是Logstash功能強大的主要原因,它可以對Logstash Event進行豐富的處理,比如說解析數據、刪除字段、類型轉換等等,常見的有如下幾個:
(1)date: 日志解析,從字段解析日期以用作事件的Logstash時間戳。
(2)grok:正則匹配解析。將非結構化事件數據分析到字段中。 這個工具非常適用於系統日志,Apache和其他網絡服務器日志,MySQL日志,以及通常為人類而不是計算機消耗的任何日志格式。
(3)dissect:分割符解析。基於分隔符原理解析數據,解決grok解析時消耗過多cpu資源的問題,使用分隔符將非結構化事件數據提取到字段中。解剖過濾器不使用正則表達式,速度非常快。 但是,如果數據的結構因行而異,grok過濾器更合適。dissect的應用有一定的局限性:主要適用於每行格式相似且分隔符明確簡單的場景 。
(4)mutate:對字段做處理,比如重命名、刪除、替換等。
(5)json:按照json解析字段內容到指定字段中。
(6)geoip:增加地理位置數據。根據ip地址提供對應的地域信息,比如經緯度、城市名等,方便進行地理數據分析。
3.2 Logstash日志過濾實踐
(1) 修改filebeat.yml文件,將filebeat的輸出從elasticsearch改為logstash:
#-------------------------- Elasticsearch output ------------------------------
output.elasticsearch:
# Array of hosts to connect to.
# hosts: ["localhost:9200"] #注釋掉這句,filebeat不再輸出到elasticsearch,改為向logstash輸出
# Optional protocol and basic auth credentials.
#protocol: "https"
#username: "elastic"
#password: "changeme"
#----------------------------- Logstash output --------------------------------
#output.logstash:
# The Logstash hosts
hosts: ["localhost:5044"]
# Optional SSL. By default is off.
# List of root certificates for HTTPS server verifications
ssl.certificate_authorities: ["/home/hik/docker/logstash-beats.crt"]
(2) 查看正在運行中的容器,找到ELK容器elk:6.4.2
hik@root:~/docker/filebeat-6.2.2-linux-x86_64$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c02f0f0f6047 elkdemo:1.0 "sh /filebeat-spring…" 8 weeks ago Up About an hour 0.0.0.0:18080->8080/tcp docker_webapp_1
308de13c21e0 elk:6.4.2 "/usr/local/bin/star…" 8 weeks ago Up About an hour 0.0.0.0:5601->5601/tcp, 5044/tcp, 9300/tcp, 0.0.0.0:9200->9200/tcp docker_elk_1
(3) 進入ELK容器: sudo docker exec –it
hik@root:~/docker/filebeat-6.2.2-linux-x86_64$ sudo docker exec -it 308de13c21e0 /bin/bash
root@308de13c21e0:/# ls
bd_build bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
(4) 修改/opt/logstash/config路徑下的logstash-sample.conf,增加JSON過濾插件
#本操作使用json插件,處理結果刪除掉message字段。
input {
beats {
port => 5044
}
}
filter {
json {
source => "message"
remove_field => ["message"]
}
}
output {
elasticsearch {
hosts => ["http://localhost:9200"]
index => "%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}"
#user => "elastic"
#password => "changeme"
}
}
(5) 通過配置文件來啟動logstash,若出現端口占用需要先殺掉此前占用5044端口的進程:
bin/logstash -f logstash-sample.conf
(6) 處理結果為
{
"_index": "filebeat-2019.05.22",
"_type": "doc",
"_id": "CnCs3WoBtWWwz0jz3Y4z",
"_version": 1,
"_score": null,
"_source": {
"beat": {
"name": "be58d50b9f23",
"hostname": "be58d50b9f23",
"version": "6.2.2"
},
"tags": [
"beats_input_codec_plain_applied"
],
"@version": "1",
"source": "/applog/output.2019-05-22.log",
"@timestamp": "2019-05-22T03:53:09.901Z",
"offset": 2722,
"prospector": {
"type": "log"
},
"host": "be58d50b9f23"
},
"fields": {
"@timestamp": [
"2019-05-22T03:53:09.901Z"
]
},
"sort": [
1558497189901
]
}
4. 小結
本文首先簡單介紹了ELK日志分析的總體框架和重要組件,接下來通過docker-elk完成了日志分析平台的實驗環境搭建,最后對logstash和它的filter插件做了簡單介紹和實驗驗證。后續會繼續研究ELK的配置優化和插件運用,為后續ELK集成的WEB打好基礎。