服務(wù)搭建準(zhǔn)備工作:
1. 在linux下創(chuàng)建一個(gè)目錄,一般默認(rèn)創(chuàng)建在/home/**/** 路徑下
例如: mkdir -p? /home/gdca/elk
2. 創(chuàng)建一個(gè)新的用戶,es默認(rèn)不允許使用root用戶啟動(dòng)
創(chuàng)建用戶:linux: useradd elk
設(shè)置用戶密碼:passwd elk

給用戶分配目錄權(quán)限: chown elk:elk -R /home/gdca/elk

一、開始正式搭建elasticsearch服務(wù)
首先下載ES,這里我們采用的版本是7.6.0。我們進(jìn)入到/home/gdca/elk目錄下,下載elasticsearch7.6.0
curl -L -O https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.6.0-linux-x86_64.tar.gz

然后解壓文件: tar -zxvf elasticsearch-7.6.0-linux-x86_64.tar.gz, 解壓成功以后進(jìn)入到elasticsearch-7.6.0目錄中。

修改ES配置文件參數(shù):
es的所有配置文件都在${ES_HOME}/config這個(gè)目錄下,首先我們設(shè)置一下jvm參數(shù),打開jvm.options文件
vim jvm.options
################################################################
## IMPORTANT: JVM heap size
################################################################
##
## You should always set the min and max JVM heap
## size to the same value. For example, to set
## the heap to 4 GB, set:
##
## -Xms4g
## -Xmx4g
##
## See https://www.elastic.co/guide/en/elasticsearch/reference/current/heap-size.html
## for more information
##
################################################################
# Xms represents the initial size of total heap space
# Xmx represents the maximum size of total heap space
-Xms256m
-Xmx256m
我們改一下堆內(nèi)存的大小,我這里這里統(tǒng)一調(diào)整為256m內(nèi)存,大家可以根據(jù)自己機(jī)器的內(nèi)存情況進(jìn)行調(diào)整。
然后,打開elasticsearch.yml文件,配置一下這里邊的參數(shù)。
# ======================== Elasticsearch Configuration =========================
#
# NOTE: Elasticsearch comes with reasonable defaults for most settings.
#? ? ? Before you set out to tweak and tune the configuration, make sure you
#? ? ? understand what are you trying to accomplish and the consequences.
#
# The primary way of configuring a node is via this file. This template lists
# the most important settings you may want to configure for a production cluster.
#
# Please consult the documentation for further information on configuration options:
# https://www.elastic.co/guide/en/elasticsearch/reference/index.html
#
# ---------------------------------- Cluster -----------------------------------
#
# Use a descriptive name for your cluster:
#
cluster.name: cluster-a
#
# ------------------------------------ Node ------------------------------------
#
# Use a descriptive name for the node:
#
node.name: node-130
#
# Add custom attributes to the node:
#
#node.attr.rack: r1
#
# ----------------------------------- Paths ------------------------------------
#
我們先配置一下集群的名字,也就是cluster.name,在這里,我們叫做cluster-a。在另外兩臺機(jī)器上,集群的名字也要叫做cluster-a,這樣才能夠組成一個(gè)集群。在ES中,集群名字相同的節(jié)點(diǎn),會組成ES集群。
然后,我們再修改node.name節(jié)點(diǎn)名稱,這個(gè)名稱是每一個(gè)節(jié)點(diǎn)的,所以,每個(gè)節(jié)點(diǎn)的名稱都不能相同。這里我們以ip命名,130這臺機(jī)器,節(jié)點(diǎn)名稱就叫node-130,另外兩臺叫做node-131和node-132。
我們再接著看后面的配置,
# ----------------------------------- Paths ------------------------------------
#
# Path to directory where to store the data (separate multiple locations by comma):
#
#path.data: /path/to/data
#
# Path to log files:
#
#path.logs: /path/to/logs
#
# ----------------------------------- Memory -----------------------------------
#
# Lock the memory on startup:
#
#bootstrap.memory_lock: true
#
# Make sure that the heap size is set to about half the memory available
# on the system and that the owner of the process is allowed to use this
# limit.
#
# Elasticsearch performs poorly when the system is swapping the memory.
#
# ---------------------------------- Network -----------------------------------
#
# Set the bind address to a specific IP (IPv4 or IPv6):
#
network.host: 192.168.73.130
#
# Set a custom port for HTTP:
#
#http.port: 9200
路徑和內(nèi)存,咱們使用默認(rèn)的就好,咱們重點(diǎn)看一下網(wǎng)絡(luò)。我們需要指定一下ES綁定的地址,如果不設(shè)置,那么默認(rèn)綁定的就是localhost,也就是127.0.0.1,這樣就只有本機(jī)能夠訪問了,其他機(jī)器是訪問不了的。所以這里我們要綁定每臺機(jī)器的地址,分別是192.168.73.130,192.168.73.131,192.168.73.132。
接下來,我們看一下集群的相關(guān)配置,
# --------------------------------- Discovery ----------------------------------
#
# 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.73.130", "192.168.73.131","192.168.73.132"]
#
# Bootstrap the cluster using an initial set of master-eligible nodes:
#
cluster.initial_master_nodes: ["node-130", "node-131", "node-132"]
#
# For more information, consult the discovery and cluster formation module documentation.
#
也就是Discovery這一段的配置,我們先設(shè)置一下集群中節(jié)點(diǎn)的地址,也就是discovery.seed_hosts這一段,我們把3臺機(jī)器的ip寫在這里。然后再把3臺機(jī)器的節(jié)點(diǎn)名稱寫在cluster.initial_master_nodes,好了,集群的配置到這里就告一段落了。
系統(tǒng)配置(重點(diǎn):如果不做系統(tǒng)配置es啟動(dòng)會出錯(cuò),后臺運(yùn)行模式會無法啟動(dòng))
修改limits.conf文件,我們切換到root用戶,打開limits.conf文件,添加內(nèi)容如下圖

調(diào)整mmapfs的數(shù)值
由于ES是使用mmapfs存儲索引,但是系統(tǒng)的默認(rèn)值太低了,我們調(diào)高一點(diǎn)。
sysctl -w vm.max_map_count=262144
接下來就可以啟動(dòng)es了
./bin/elasticsearch, 如果需要后臺啟動(dòng)運(yùn)行:./bin/elasticsearch -d
好,到這里我們所有的配置就完成了,現(xiàn)在依次啟動(dòng)3個(gè)節(jié)點(diǎn)的ES。啟動(dòng)完成后,我們在瀏覽器中檢查以下集群的狀態(tài):?http://192.168.73.130:9200/_cluster/health,
{"cluster_name":"cluster-a","status":"green","timed_out":false,"number_of_nodes":3,"number_of_data_nodes":3,"active_primary_shards":0,"active_shards":0,"relocating_shards":0,"initializing_shards":0,"unassigned_shards":0,"delayed_unassigned_shards":0,"number_of_pending_tasks":0,"number_of_in_flight_fetch":0,"task_max_waiting_in_queue_millis":0,"active_shards_percent_as_number":100.0}
二、搭建Logstash服務(wù)
注意ELK服務(wù)搭建時(shí)候要選擇同一個(gè)版本,不然容易出現(xiàn)各種莫名其妙的問題

同樣進(jìn)入config配置文件,配置一下jvm啟動(dòng)參數(shù),這邊配置也用256m的啟動(dòng)內(nèi)存,實(shí)際需要根據(jù)具體環(huán)境擴(kuò)展: vim ./config/jvm.option
同樣修改一下基礎(chǔ)配置文件: vim ./config/logstash.yml, 主要改動(dòng)http_ip 從127.0.0.1 修改為 0.0.0.0 支持ip地址訪問,端口號http_port:9600 使用默認(rèn)參數(shù),這邊根據(jù)實(shí)際業(yè)務(wù)需要做調(diào)整,這里我采用基本默認(rèn)的推薦參數(shù)。
推薦logstash 啟動(dòng)方式為 ./bin/logstash.sh -f? 配置文件路徑 & ,注意這里一定要配置conf文件,為了方便后臺啟動(dòng),要配置訪問路徑和es路徑,不能直接配置stdin{}, 這樣后臺啟動(dòng)會等待命令行輸入測試內(nèi)容,而卡在命令行執(zhí)行導(dǎo)致系統(tǒng)無法正常打開端口啟動(dòng)?。?!重點(diǎn),我這里被坑了2個(gè)多小時(shí)
Logstash配置基礎(chǔ):
input plugin?讓logstash可以讀取特定的事件源
示范:
input{
? ? file{
? ? ? ? path => "/var/log/nginx/access.log"
? ? ? ? start_position => "beginning"
? ? ? ? type => "nginx_access_log"
? ? }
}
說明:
file?從文件讀取數(shù)據(jù)
file{
? ? path => ['/var/log/nginx/access.log']? #要輸入的文件路徑
? ? type => 'nginx_access_log'
? ? start_position => "beginning"
}
# path? 可以用/var/log/*.log,/var/log/**/*.log,如果是/var/log則是/var/log/*.log
# type 通用選項(xiàng). 用于激活過濾器
# start_position 選擇logstash開始讀取文件的位置,begining或者end。一般來說默認(rèn)begining
還有一些常用的例如:discover_interval,exclude,sincedb_path,sincedb_write_interval等可以參考官網(wǎng),這部分暫時(shí)沒看懂等待后續(xù)補(bǔ)充。
syslog ?通過網(wǎng)絡(luò)將系統(tǒng)日志消息讀取為事件
syslog{
? ? port =>"514"
? ? type => "syslog"
}
# port 指定監(jiān)聽端口(同時(shí)建立TCP/UDP的514端口的監(jiān)聽)
#從syslogs讀取需要實(shí)現(xiàn)配置rsyslog:
# cat /etc/rsyslog.conf? 加入一行
*.* @172.17.128.200:514 ? #指定日志輸入到這個(gè)端口,然后logstash監(jiān)聽這個(gè)端口,如果有新日志輸入則讀取
# service rsyslog restart? #重啟日志服務(wù)
beats ??從Elastic beats接收事件
beats {
? ? port => 5044? #要監(jiān)聽的端口
}
# 還有host等選項(xiàng)
# 從beat讀取需要先配置beat端,從beat輸出到logstash。
# vim /etc/filebeat/filebeat.yml
..........
output.logstash:
hosts: ["localhost:5044"]
kafka ?將 kafka topic 中的數(shù)據(jù)讀取為事件
kafka{
? ? bootstrap_servers=> "kafka01:9092,kafka02:9092,kafka03:9092"
? ? topics => ["access_log"]
? ? group_id => "logstash-file"
? ? codec => "json"
}
kafka{
? ? bootstrap_servers=> "kafka01:9092,kafka02:9092,kafka03:9092"
? ? topics => ["weixin_log","user_log"]?
? ? codec => "json"
}
# bootstrap_servers 用于建立群集初始連接的Kafka實(shí)例的URL列表。
# topics? 要訂閱的主題列表,kafka topics
# group_id 消費(fèi)者所屬組的標(biāo)識符,默認(rèn)為logstash。kafka中一個(gè)主題的消息將通過相同的方式分發(fā)到Logstash的group_id# codec 通用選項(xiàng),用于輸入數(shù)據(jù)的編解碼器。
以上是常用的一些input插件,還有很多的input插件類型,可以參考官方文檔來配置。
filter plugin 過濾器插件,對事件執(zhí)行中間處理。
? ??grok ?解析文本并構(gòu)造 。把非結(jié)構(gòu)化日志數(shù)據(jù)通過正則解析成結(jié)構(gòu)化和可查詢化
grok {
? ? ? ? ? ? match => {"message"=>"^%{IPORHOST:clientip} %{USER:ident} %{USER:auth} \[%{HTTPDATE:timestamp}\] "%{WORD:verb} %{DATA:request} HTTP/%{NUMBER:httpversion}" %{NUMBER:response:int} (?:-|%{NUMBER:bytes:int}) %{QS:referrer} %{QS:agent}$"}
? ? ? ? }
匹配nginx日志
# 203.202.254.16 - - [22/Jun/2018:16:12:54 +0800] "GET / HTTP/1.1" 200 3700 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/601.7.7 (KHTML, like Gecko) Version/9.1.2 Safari/601.7.7"
#220.181.18.96 - - [13/Jun/2015:21:14:28 +0000] "GET /blog/geekery/xvfb-firefox.html HTTP/1.1" 200 10975 "-" "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)"
注意這里grok 可以有多個(gè)match匹配規(guī)則,如果前面的匹配失敗可以使用后面的繼續(xù)匹配。例如
grok {
? ? ? ? ? ? match => ["message", "%{IP:clientip} - %{USER:user} \[%{HTTPDATE:raw_datetime}\] \"(?:%{WORD:verb} %{URIPATHPARAM:request} HTTP/%{NUMBER:httpversion})\" (?:\"%{DATA:body}\" )?(?:\"%{DATA:cookie}\" )?%{NUMBER:response} (?:%{NUMBER:bytes:int}|-) \"%{DATA:referrer}\" \"%{DATA:agent}\" (?:(%{IP:proxy},? ?)*|-|unknown) (?:%{DATA:upstream_addr} |)%{NUMBER:request_time:float} (?:%{NUMBER:upstream_time:float}|-)"]
? ? ? ? ? ? match => ["message", "%{IP:clientip} - %{USER:user} \[%{HTTPDATE:raw_datetime}\] \"(?:%{WORD:verb} %{URI:request} HTTP/%{NUMBER:httpversion})\" (?:\"%{DATA:body}\" )?(?:\"%{DATA:cookie}\" )?%{NUMBER:response} (?:%{NUMBER:bytes:int}|-) \"%{DATA:referrer}\" \"%{DATA:agent}\" (?:(%{IP:proxy},? ?)*|-|unknown) (?:%{DATA:upstream_addr} |)%{NUMBER:request_time:float} (?:%{NUMBER:upstream_time:float}|-)"]? ? ?
? ? ? ? }
? ? ? grok 語法:%{SYNTAX:SEMANTIC} ? 即 %{正則:自定義字段名}
官方提供了很多正則的grok pattern可以直接使用? :https://github.com/logstash-plugins/logstash-patterns-core/blob/master/patterns
? ? ? ? ? ? ? ? ? ? ?grok debug工具: http://grokdebug.herokuapp.com
正則表達(dá)式調(diào)試工具: https://www.debuggex.com/
需要用到較多的正則知識,參考文檔有:https://www.jb51.net/tools/zhengze.html
自定義模式:(?<字段名>the pattern)
?? 例如: 匹配 2018/06/27 14:00:54 ?
? ? ? ? ? ? ? ? (?<datetime>\d\d\d\d\/\d\d\/\d\d \d\d:\d\d:\d\d)
? ? ? ? ? 得到結(jié)果:??"datetime": "2018/06/27 14:00:54"
output plugin? 輸出插件,將事件發(fā)送到特定目標(biāo)。
stdout? 標(biāo)準(zhǔn)輸出。將事件輸出到屏幕上
output{
? ? stdout{
? ? ? ? codec => "rubydebug"
? ? }
}
file? ?將事件寫入文件
? ? file {
? ? ? path => "/data/logstash/%{host}/{application}
? ? ? codec => line { format => "%{message}"} }
? ? }
kafka? 將事件發(fā)送到kafka
? ? kafka{
? ? ? ? bootstrap_servers => "localhost:9092"
? ? ? ? topic_id => "test_topic"? #必需的設(shè)置。生成消息的主題
? ? }
elasticseach? 在es中存儲日志
? ? elasticsearch {
? ? ? ? hosts => "localhost:9200"
? ? ? ? index => "nginx-access-log-%{+YYYY.MM.dd}"?
? ? }
#index 事件寫入的索引??梢园凑杖罩緛韯?chuàng)建索引,以便于刪舊數(shù)據(jù)和按時(shí)間來搜索日志