1. 前言
針對nginx的訪問日志需要進行一個近實時的監(jiān)控,以便統(tǒng)計用戶的訪問情況政基,包括用戶的請求IP示辈,請求數(shù)據(jù)等。因為服務(wù)器是和負載均衡用的是阿里云的掌桩,阿里云本身也有提供針對負載均衡的日志統(tǒng)計功能边锁,但是作為一個通用日志其是有嚴重缺陷的:
- 無法收集用戶自定義的請求頭(我們的實際情況是通過一個自定義的請求頭來做用戶的身份識別,請求頭有用戶的唯一識別信息)
- 無法獲取到用戶的請求數(shù)據(jù)($request_body) (很多時候波岛,當(dāng)出現(xiàn)異常訪問的時候茅坛,是需要通過查詢用戶的訪問數(shù)據(jù)的,特別像搜索這種業(yè)務(wù)模塊時)
由于存在上面比較嚴重的缺點则拷,基本上阿里云的日志對我來說就有點雞肋(食之無味贡蓖,棄之可惜,你不得不同意他除了上面兩點缺點外煌茬,日志的其他方面都是做得不錯的)斥铺。因此我決定自己動手搭建符合自己業(yè)務(wù)的ELK日志服務(wù)。
之前我是有搭建過ELK的經(jīng)驗的坛善,但是沒在生產(chǎn)環(huán)境試過晾蜘,起初在搭建的時候我考慮到可能會有以下幾個問題:
- Elasticsearch對內(nèi)存的占用情況
- 收集nginx訪問日志邻眷,相當(dāng)于需要打開nginx的access日志開關(guān),硬盤的讀寫情況剔交,硬盤的占用耗溜,會不會影響到用戶。
- 日志收集對應(yīng)用服務(wù)器的影響
我現(xiàn)在還是在一兩臺服務(wù)器開啟了日志收集省容,做一個灰度測試抖拴。
2. Elasticsearch搭建
2.1 Elasticsearch下載安裝
Elasticsearch的安裝比較簡單,直接下載解壓縮即可
### 下載
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.4.2-linux-x86_64.tar.gz
### 解壓縮:
tar -zxvf elasticsearch-7.4.2-linux-x86_64.tar.gz
2.2 Elasticsearch配置
1. 修改cluster-name和node-name
cluster.name: my-application
node.name: node-1
node.master: true
node.data: true
2. 修改網(wǎng)絡(luò)相關(guān)
network.host: 0.0.0.0 ## 0.0.0.0允許所有的ip腥椒,這里我是為了方便阿宅,后面可以根據(jù)實際情況填寫
http.port: 9200 ## default
transport.tcp.port: 9300 ## defalut
3. 修改head插件的跨域問題
# 以下的兩個配置是為了解決跨域問題,在head插件訪問es的時候報跨域了
http.cors.enabled: true
http.cors.allow-origin: "*"
4. 發(fā)現(xiàn)配置
# Pass an initial list of hosts to perform discovery when this node is started:
# The default list of hosts is ["127.0.0.1", "[::1]"]
discovery.seed_hosts: ["192.168.1.57"] ## 可被發(fā)現(xiàn)的節(jié)點IP集合
cluster.initial_master_nodes: ["node-1", "node-2"]
5. 解決es啟動時的報錯問題笼蛛,.ElasticSearch集群啟動錯誤,錯誤的原因是:因為Centos6不支持SecComp,而ES默認bootstrap.system_call_filter為true進行檢測,所以導(dǎo)致檢測失敗
bootstrap.memory_lock: false
bootstrap.system_call_filter: false
2.3 問題
1. 外網(wǎng)訪問不了9200的Elasticsearch?
- 配置防火墻端口
- 修改elasticsearch.yml洒放,主要是要修改host(我改成0.0.0.0,方便調(diào)試,后期穩(wěn)定之后會再修改)
2. 啟動報錯
- vm.max_map_count過小滨砍,java虛擬機的virtual memory過小
在/etc/sysctl.conf最后加入一行vm.max_map_count=262144數(shù)量根據(jù)實際情況定
在這里插入圖片描述
- max user threads過型(root和dves兩個用戶的max user threads不一樣)
針對這個問題,可以通過
ulimit -a
查看目前可支持的max user threads
在這里插入圖片描述
修改 max user process
Linux系統(tǒng)為每一個用戶都設(shè)置了一個最大進程數(shù)惋戏,這個特性可以讓我們控制服務(wù)器上現(xiàn)有用戶可以創(chuàng)建的進程數(shù)量
- 修改方式1:
修改
/etc/security/limits.conf
文件,添加以下配置
## 針對所有用戶的可開啟最大線程數(shù)為4096
* soft nproc 4096
* hard nproc 4096
- 修改方式2:
修改
/etc/security/limits.d/90-nproc.conf
文件领追,添加以下配置(先把其他默認的給注釋掉):
* soft nproc 4096 ## 非root用戶配置為4096,這個對es來說夠用了
root soft nproc unlimited ## root用戶配置最大 128354
針對這兩種修改方式解釋下响逢,我是在
/etc/security/limits.d/90-nproc.conf
這個文件下修改的绒窑。對于max user process
的配置,Linux系統(tǒng)默認先讀取/etc/security/limits.conf
中的信息舔亭,如果/etc/security/limits.d/
目錄下還有配置文件的話些膨,也會依次遍歷讀取,最終/etc/security/limits.d/
的配置會覆蓋/etc/security/limits.conf
的相同配置信息
3. FileBeat搭建
3.1 Filebeat下載安裝
curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.4.2-x86_64.rpm
rpm -vi filebeat-7.4.2-x86_64.rpm
安裝完成钦铺,
filebeat
命令已配置到service服務(wù)中订雾,配置文件在/etc/filebeat
,日志文件在/var/log/filebeat/filebeat
,注意,每次重啟filebeat的時候矛洞,該日志文件都會重新生成洼哎,這個時候若如果你是通過tail
命令來觀察的,需要結(jié)束當(dāng)前的tail
命令再重復(fù)執(zhí)行一次tail
命令tail -900f filebeat
3.2 Filebeat收集nginx訪問日志
3.2.1 nginx的訪問日志格式及配置
nginx訪問日志是如何配置的缚甩,我這里不細說谱净,我只是說下我是如何配置的窑邦,如果對nginx的訪問日志配置不熟悉的擅威,可以查看這個:ngx_http_log_module
1. 日志格式
因為我們最終要通過Kibana進行展示的,我們需要對訪問日志的每個字段都進行解析冈钦,所以我們就需要確定nginx的日志是json格式的
## 這個是寫在http模塊的
log_format json_main '{"@times" : "$time_iso8601",' ## 該time作為Kibana的date類型郊丛,在創(chuàng)建Kibana的index_pattern時作為時間篩選的key
'"userAgent" : "$http_user_agent",'
'"remoteAddr" : "$remote_addr", '
'"realIp" : "$http_x_forwarded_for", '
'"requestUri" : "$request", '
'"status" : "$status", '
'"referer" : "$http_referer", '
'"requestTime" : "$request_time", '
'"requestBody" : "$request_body", ' ## 請求數(shù)據(jù)
'"domoCustom" : "$http_domo_custom"}'; ## 自定義請求頭
2. 打開請求日志
對map模塊有興趣的可以查看這里:ngx_http_map_module
## 這個在server模塊
access_log /opt/nginx/logs/requestLog.log json_main if=$myUri;
## /opt/nginx/logs/requestLog.log:這個是日志收集的地方,若該日志不存在,在reload或重啟nginx的是厉熟,會自動創(chuàng)建
## json_main:`log_format`定義的日志格式名
## if=$myUri:一個判斷导盅,如果`$myUri`為0或者空字符串,則該日志不收集揍瑟。這個的作用可以過濾掉一些我們不想收集的日志信息白翻,我是根據(jù)請求頭來設(shè)置的。
## 這個寫在http模塊绢片,使用map這個內(nèi)置模塊滤馍,可以通過判斷`$request`這個
## 內(nèi)置變量是否符合下面的判斷,然后把0或1賦值給`$myUri`.
## 這里我的用法就是底循,如果是OPTIONS請求為0不記錄日志信息巢株,
## 如果是`/api/qiqyu`這個第三方的請求也為0不記錄日志信息
## 其他的`/api/`正則的則為1記錄日志信息
## 非上面集中情況的一律為0不記錄相應(yīng)的日志信息
map $request $myUri {
~OPTIONS 0;
~/api/qiyu/ 0;
~/api/ 1;
default 0;
}
reload
nginx之后就能在/opt/nginx/logs/requestLog.log
這個文件夾下看到相應(yīng)的日志了
在這里插入圖片描述
3.3 Filebeat配置
3.3.1 基本配置文件配置
vim /etc/filebeat/filebeat.yml
1. Filebeat inputs
- type: log
# Change to true to enable this input configuration.
enabled: true ## 打開開關(guān)
exclude_lines: ['^DBG'] ## 忽略的行
# Paths that should be crawled and fetched. Glob based paths.
paths:
#- /var/log/*.log
- /opt/nginx/logs/requestLog.log ## 配置從哪里按行讀取日志
#- c:\programdata\elasticsearch\logs\*
## 如果要讓filebeat輸入json格式的數(shù)據(jù),除了nginx的日志本身是json格式
## 的外熙涤,還必須在filebeat中配置一下設(shè)置
json.keys_under_root: true
json.overwrite_keys: true
json.add_error_key: true
json.message_key: message ## 如果message在啟動的時候報錯阁苞,可以改成"json"(帶雙引號)
2. Elasticsearch template setting
setup.ilm.enabled: false ## 這個必須要配置成false,否則自定義index就不會生效
setup.template.enabled: false ## 關(guān)掉filebeat默認的es模板
setup.template.overwrite: true ## 表示我們自定義的模板和index會覆蓋默認的
setup.template.fields: "/etc/filebeat/self/fields.yml" ## 自定義的fields.yml祠挫,這個文件不熟悉的話就別瞎折騰了那槽,我直接從原來的copy了一份而已
setup.template.name: "nginx-access-log" ## 模板名,這個和后面要創(chuàng)建的es模板名保持一致
setup.template.pattern: "nginx-access-log-*" ## 模板對應(yīng)的pattern等舔,也是對應(yīng)的index倦炒,這些都是有規(guī)律的。因為你模板名是`nginx-access-log`,則你接下來的自定義索引名就最好是`nginx-access-log-%{[agent.version]}-%{+yyyy.MM.dd}`,pattern的正則就是`nginx-access-log-*`
3. Dashboards(這個配置可不配软瞎,主要是看你的filebeat是否安裝了默認看板逢唤,這個安裝后會生效的前提是:你必須使用filebeat的默認模板,默認索引涤浇,一旦你執(zhí)行了上面第二步鳖藕,這里的配置就不會生效)
setup.dashboards.enabled: true
setup.dashboards.index: "nginx-access-log-*"
4. Kibana
setup.kibana:
host: "192.168.1.57:5601"
# Kibana Host
# Scheme and port can be left out and will be set to the default (http and 5601)
# In case you specify and additional path, the scheme is required: http://localhost:5601/path
# IPv6 addresses should always be defined as: https://[2001:db8::1]:5601
#host: "localhost:5601"
5. Outputs(Elasticsearch)
#-------------------------- Elasticsearch output ------------------------------
output.elasticsearch:
# Array of hosts to connect to.
hosts: ["192.168.1.57:9200"]
## 這里的index的前綴要和上面第二步配置的模板名保持一致,而且只锭,index的名字中不能包含大寫字母箍土,這是我的教訓(xùn)來著
index: "nginx-access-log-%{[agent.version]}-%{+yyyy.MM.dd}"
# Optional protocol and basic auth credentials.
#protocol: "https"
#username: "elastic"
#password: "changeme"
3.3.2 啟用nginx模塊
其實對于filebeat中,它提供了多個模塊说榆,比如nginx渔隶,mysql等,這些能夠讓我們快速地上手filebeat纵顾。但是我一直搞不懂這些模塊的用途是什么伍茄,明明我可以在
filebeat.yml
中配置的。nginx的模塊格式如下:
我雖然安裝了該模塊施逾,但是該模塊我是關(guān)掉的敷矫,一方面是我對該模塊的理解不夠例获,我不啟用該模塊也能正常收集日志,另一方面曹仗,開啟該模塊的時候榨汤,在收集日志的時候會不定時地報錯
Provided Grok expressions do not match field value:
# Module: nginx
# Docs: https://www.elastic.co/guide/en/beats/filebeat/7.4/filebeat-module-nginx.html
- module: nginx
# Access logs
access:
enabled: false
var.paths: ["/opt/nginx/logs/requestLog.log"]
# Set custom paths for the log files. If left empty,
# Filebeat will choose the paths depending on your OS.
#var.paths:
# Error logs
error:
enabled: false
# Set custom paths for the log files. If left empty,
# Filebeat will choose the paths depending on your OS.
#var.paths:
安裝過程
在配置好
filebeat.ymt
后執(zhí)行如下命令:
filebeat modules enable nginx
3.3.3 啟動filebeat模塊
filebeat setup
service filebeat start
4. Kibana搭建
4.1 Kibana下載安裝
注意:如果es是7版本,那么kibana的版本也要是7怎茫,兩者之間的大版本要互相對應(yīng)
wget https://artifacts.elastic.co/downloads/kibana/kibana-7.4.2-linux-x86_64.tar.gz
## 解壓縮后即可使用
tar -zxvf kibana-7.4.2-linux-x86_64.tar.gz
4.2 Kibana配置
vim kibana.yml
## 端口號收壕,默認5601
#server.port: 5601
## 指定kibana指定的IP
server.host: "192.168.1.57"
## 因為我的kibana和Elasticsearch是在同一臺機器上的,所以我不需要去配置es的IP和端口等信息轨蛤,kibana會自動在本機尋找
#elasticsearch.hosts: ["http://localhost:9200"]
4.2.1 自定義Elasticsearch的template
這個
template_name
和index_patterns
要和前面我們在Elasticsearch中配置的一致啼器。除了template_name
和index_patterns
要修改外,還有一個要修改的地方就是mapping
俱萍,這個因人而異端壳,我覺得默認的mapping輸出太多我不需要用到的東西,所以才去簡化的枪蘑,其余的都保持默認损谦。新建好template
后重啟filebeat即可。重啟filebeat之前建議把nginx的訪問日志也清空掉岳颇,免得有臟數(shù)據(jù)影響
mapping信息:
{
"_meta": {
"beat": "filebeat",
"version": "7.4.2"
},
"dynamic_templates": [
{
"labels": {
"path_match": "labels.*",
"mapping": {
"type": "keyword"
},
"match_mapping_type": "string"
}
},
{
"container.labels": {
"path_match": "container.labels.*",
"mapping": {
"type": "keyword"
},
"match_mapping_type": "string"
}
},
{
"dns.answers": {
"path_match": "dns.answers.*",
"mapping": {
"type": "keyword"
},
"match_mapping_type": "string"
}
},
{
"fields": {
"path_match": "fields.*",
"mapping": {
"type": "keyword"
},
"match_mapping_type": "string"
}
},
{
"docker.container.labels": {
"path_match": "docker.container.labels.*",
"mapping": {
"type": "keyword"
},
"match_mapping_type": "string"
}
},
{
"kubernetes.labels.*": {
"path_match": "kubernetes.labels.*",
"mapping": {
"type": "keyword"
},
"match_mapping_type": "*"
}
},
{
"kubernetes.annotations.*": {
"path_match": "kubernetes.annotations.*",
"mapping": {
"type": "keyword"
},
"match_mapping_type": "*"
}
},
{
"docker.attrs": {
"path_match": "docker.attrs.*",
"mapping": {
"type": "keyword"
},
"match_mapping_type": "string"
}
},
{
"cef.extensions": {
"path_match": "cef.extensions.*",
"mapping": {
"type": "keyword"
},
"match_mapping_type": "string"
}
},
{
"kibana.log.meta": {
"path_match": "kibana.log.meta.*",
"mapping": {
"type": "keyword"
},
"match_mapping_type": "string"
}
},
{
"strings_as_keyword": {
"mapping": {
"ignore_above": 1024,
"type": "keyword"
},
"match_mapping_type": "string"
}
}
],
## 這里是指是否要指定一個key作為date類型來進行時間篩選照捡,如果不為true,
## 后面你就無法根據(jù)@times進行時間篩選
"date_detection": true
}
4.2.2 devtool工具查詢
在未建立kibana的
index_pattern
之前话侧,我們是無法在discover
發(fā)現(xiàn)面板上去查看自己的數(shù)據(jù)的栗精,這個時候我們并不著急去創(chuàng)建index_pattern
,我們要先驗證一下日式數(shù)據(jù)是否已成功收集瞻鹏。打開kibana的dev tool
1. 查看目前es中的索引悲立,確認我們的自定義索引是否已生成
get _cat/indices?v
這個索引出現(xiàn)了表明索引已自動生成了
在這里插入圖片描述
2. 查看該索引目前的數(shù)據(jù),是否符合我們預(yù)期
GET /nginx-access-log-7.4.2-2019.11.18/_search
數(shù)據(jù)結(jié)果是json格式的新博,而且我們需要的數(shù)據(jù)都有薪夕,符合我們的預(yù)期。
在這里插入圖片描述
4.2.3 自定義index_pattern
在上面的步驟確認好之后赫悄,就可以創(chuàng)建kibana的
index_pattern
4.2.3 Discover功能
選擇剛我們創(chuàng)建的
index_pattern
就可以看到和我們index_pattern格式相對應(yīng)的數(shù)據(jù)了
在這里插入圖片描述
4.2.4 Visualize功能
新建一個可視化的圖表原献,它里面幫我們內(nèi)嵌了多個圖表,但數(shù)據(jù)源都不是我們自定義的數(shù)據(jù)埂淮,可以參考姑隅,但是沒多大意義,我們可以自己創(chuàng)建倔撞。
在這里插入圖片描述
4.2.5 Dashboard功能
多個 Visualize放在一起就是一個面板讲仰,這里不多贅述,沒什么技術(shù)含量
5. 參考鏈接
開始使用Filebeat
快速開始Elasticsearch
Es的官網(wǎng)教學(xué)
自定義index template
Filebeat自定義index的一個坑
Filebeat模塊與配置
Linux修改max user threads
ElkStack運維手冊
Es中文手冊
nginx中文地址
6. 總結(jié)
搭建這個簡單的ELK還是花費了我一些時間的误窖,一方面主要是我太久沒接觸ES叮盘,另一方面我對filebeat和kibana一直都是一知半解的狀態(tài)。在搭建的過程中霹俺,沒有像我上面寫得那么順利柔吼,一路磕磕碰碰,遇到很多問題丙唧,最后通過查詢大量資料加上自己的理解才終于搞定愈魏。大家如果在搭建的時候有不明白的可以直接聯(lián)系
756795605@qq.com
這個郵箱