做爲運維工程師,咱們天天須要對服務器進行故障排除,那麼最早能幫助咱們定位問題的就是查看服務器日誌,經過日誌能夠快速的定位問題。javascript
目前咱們說的日誌主要包括系統日誌、應用程序日誌和安全日誌。系統運維和開發人員能夠經過日誌瞭解服務器軟硬件信息、檢查配置過程當中的錯誤及錯誤發生的緣由。常常須要分析日誌能夠了解服務器的負荷,性能安全性,從而及時採起措施糾正錯誤。並且日誌被分散的儲存不一樣的設備上。css
若是你管理數上百臺服務器,咱們登陸到每臺機器的傳統方法查閱日誌。這樣是否是感受很繁瑣和效率低下。當務之急咱們使用集中化的日誌管理,例如:開源的syslog,將全部服務器上的日誌收集彙總。html
集中化管理日誌後,日誌的統計和檢索又成爲一件比較麻煩的事情,通常咱們使用find、grep、awk和wc等Linux命令能實現檢索和統計,可是對於要求更高的查詢、排序和統計等要求和龐大的機器數量依然使用這樣的方法不免有點力不從心。前端
今天給你們分享的開源實時日誌分析ELK平臺可以完美的解決咱們上述的問題,ELK由ElasticSearch、Logstash和Kiabana三個開源工具組成。java
ELK=elasticsearch+Logstash+kibana node
1) Elasticsearch是個開源分佈式搜索引擎,它的特色有:分佈式,零配置,自動發現,索引自動分片,索引副本機制,restful風格接口,多數據源,自動搜索負載等,ELK官網:https://www.elastic.co/mysql
2) Logstash 主要是用來日誌的蒐集、分析、過濾日誌的工具,支持大量的數據獲取方式。工做方式爲C/S架構,Client端安裝在須要收集日誌的主機上,Server端負責將收到的各節點日誌進行過濾、修改等操做在一併發往Elasticsearch服務器。linux
3) Kibana 也是一個開源和免費的工具,它Kibana能夠爲 Logstash 和 ElasticSearch 提供的日誌分析友好的 Web 界面,能夠幫助您彙總、分析和搜索重要數據日誌;nginx
4) FileBeat是一個輕量級日誌採集器,Filebeat屬於Beats家族的6個成員之一,早期的ELK架構中使用Logstash收集、解析日誌而且過濾日誌,可是Logstash對CPU、內存、IO等資源消耗比較高,相比Logstash,Beats所佔系統的CPU和內存幾乎能夠忽略不計;es6
5) Logstash和Elasticsearch是用Java語言編寫,而Kibana使用node.js框架,在配置ELK環境要保證系統有JAVA JDK開發庫;
6) Redis 負責消息隊列機制,存儲數據,即便遠端Logstash server因故障中止運行,數據將會先被存儲下來,從而避免數據丟失。
今天帶你們一塊兒來學習EKL企業分佈式實時日誌平臺的構建.
若是使用Filebeat,Logstash從FileBeat獲取日誌文件。Filebeat做爲Logstash的輸入input將獲取到的日誌進行處理,將處理好的日誌文件輸出到Elasticsearch進行處理,
1) ELK工做流程
經過logstash收集客戶端APP的日誌數據,將全部的日誌過濾出來,存入Elasticsearch 搜索引擎裏,而後經過Kibana GUI在WEB前端展現給用戶,用戶須要能夠進行查看指定的日誌內容。
下圖爲EKL企業分佈式實時日誌平臺結構圖,若是沒有使用Filebeat,Logstash收集日誌,進行過濾處理,而且將數據發往elasticsearch,結構圖以下:
同時也能夠加入redis通訊隊列:
圖一:
圖二:
2) 加入Redis隊列後工做流程
Logstash包含Index和Agent(shipper) ,Agent負責客戶端監控和過濾日誌,而Index負責收集日誌並將日誌交給ElasticSearch,ElasticSearch將日誌存儲本地,創建索引、提供搜索,kibana能夠從ES集羣中獲取想要的日誌信息。
安裝ELK以前,須要先安裝JDK (Java Development Kit) 是 Java 語言的軟件開發工具包(SDK)),這裏選擇jdk-8u102-linux-x64.rpm ,bin文件安裝跟sh文件方法同樣,rpm -ivh jdk-8u102-linux-x64.rpm ,回車便可,默認安裝到/usr/java/jdk1.8.0_102目錄下。
配置java環境變量,參考博客篇:http://www.javashuo.com/article/p-rtvzuadn-eq.html
修改操做系統的內核優化,參考博客篇:https://www.cnblogs.com/zhangan/p/10956138.html#x3
註釋:java環境與操做系統的內核優化必須作,否則啓動程序會報錯。
另外修改操做系統的內核配置文件sysctl.conf(2臺),sysctl - p 生效
[root@es-master local]# vim /etc/sysctl.conf #在配置文件最後面添加以下內容 vm.max_map_count=262144 vm.swappiness=0
解釋:max_map_count文件包含限制一個進程能夠擁有的VMA(虛擬內存區域)的數量。虛擬內存區域是一個連續的虛擬地址空間區域。在進程的生命週期中,每當程序嘗試在內存中映射文件,連接到共享內存段,或者分配堆空間的時候,這些區域將被建立。當進程達到了VMA上線但又只能釋放少許的內存給其餘的內核進程使用時,操做系統會拋出內存不足的錯誤。
swappiness,Linux內核參數,控制換出運行時內存的相對權重。swappiness參數值可設置範圍在0到100之間。 低參數值會讓內核儘可能少用交換,更高參數值會使內核更多的去使用交換空間。默認值爲60,對於大多數操做系統,設置爲100可能會影響總體性能,而設置爲更低值(甚至爲0)則可能減小響應延遲。
vm.swappiness=1;進行最少許的交換,而不由用交換。若是設置爲 0 的話,則等同於禁用 swap
特別提醒:
Elasticsearch-7版本最低支持jdk版本爲JDK1.11
Elasticsearch-7.3該版本內置了JDK,而內置的JDK是當前推薦的JDK版本。固然若是你本地配置了JAVA_HOME那麼ES就是優先使用配置的JDK啓動ES。(言外之意,你不安裝JDK同樣能夠啓動,我試了能夠的。)
ES推薦使用LTS版本的JDK(這裏只是推薦,JDK8就不支持),若是你使用了一些不支持的JDK版本,ES會拒絕啓動。
因爲咱們平常的代碼開發都是使用的JDK1.8,並且可能JAVA_HOME配置成JDK1.8,那麼解決方法咱們只需更改Elasticsearch的啓動文件,使它指向Elasticsearch-7.3該版本內置了JDK,或者也能夠參照jdk安裝文檔升級jdk高版本
修改啓動配置文件
[root@localhost bin]# pwd
/data/elasticsearch/bin
[root@localhost bin]# vi elasticsearch
#配置es自帶的jdk路徑 export JAVA_HOME=/usr/local/elasticsearch-node1/jdk export PATH=$JAVA_HOME/bin:$PATH #添加jdk判斷 if [ -x "$JAVA_HOME/bin/java" ]; then JAVA="/usr/local/elasticsearch-node1/jdk/bin/java" else JAVA=`which java` fi
分別下載ELK軟件包:
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.3.1-linux-x86_64.tar.gz wget https://artifacts.elastic.co/downloads/logstash/logstash-7.3.1.tar.gz Wget https://artifacts.elastic.co/downloads/kibana/kibana-7.3.1-linux-x86_64.tar.gz wget http://117.128.6.27/cache/download.redis.io/releases/redis-4.0.14.tar.gz?ich_args2=522-03101307057974_3dd269048c70bdf875dc9acff1b71955_10001002_9c89622bd3c4f7d69f33518939a83798_c8a912a80ccc397fec935bfecdb1cca8 wget https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.3.1-linux-x86_64.tar.gz
|
1) ELK安裝信息
192.168.111.128 Elasticsearch 192.168.111.129 Kibana 192.168.111.130 Logstash + redis |
2) 192.168.111.128上安裝elasticsearch-node1
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.3.1-linux-x86_64.tar.gz tar xf elasticsearch-7.3.1.tar.gz -C /usr/local/ cd /usr/local/ mv elasticsearch-7.3.1 elasticsearch-node1 |
3) 配置
注意:因爲elasticsearch啓動的時候不能直接用root用戶啓動,因此須要建立普通用戶
useradd elk chown -R elk:elk /usr/local/elasticsearch-node1 |
分別建立兩個elasticsearch節點的數據目錄和日誌目錄
mkdir -pv /usr/local/elasticsearch-node1/{data,logs} chown -R elk:elk /usr/local/elasticsearch-node1 |
修改elasticsearch節點的配置文件jvm.options
cd /usr/local/elasticsearch-node1/config/ vi jvm.options |
修改以下兩個選項:
注意:
1. 最大值和最小值設置爲同樣的值,不然在系統使用的時候會因jvm值變化而致使服務暫停
2. 過多的內存,會致使用於緩存的內存越多,最終致使回收內存的時間也加長
3. 設置的內存不要超過物理內存的50%,以保證有足夠的內存留給操做系統
4. 不要將內存設置超過32GB
修改elasticsearch節點的配置文件elasticsearch.yml
[root@es-master local]# vim elasticsearch-node1/config/elasticsearch.yml #修改如下項 #表示集羣標識,同一個集羣中的多個節點使用相同的標識 cluster.name: elasticsearch #節點名稱 node.name: "elasticsearch-node1" #數據存儲目錄 path.data: /usr/local/elasticsearch-node1/data #日誌目錄 path.logs: /usr/local/elasticsearch-node1/logs #節點所綁定的IP地址,而且該節點會被通知到集羣中的其餘節點 network.host: 192.168.11.128 #綁定監聽的網絡接口,監聽傳入的請求,能夠設置爲IP地址或者主機名 network.bind_host: 192.168.111.128 #發佈地址,用於通知集羣中的其餘節點,和其餘節點通信,不設置的話默承認以自動設置。必須是一個存在的IP地址 network.publish_host: 192.168.111.128 #es7.x 以後新增的配置,初始化一個新的集羣時須要此配置來選舉master cluster.initial_master_nodes: ["192.168.111.128:9300"] #集羣通訊端口 transport.tcp.port: 9300 #對外提供服務的http端口,默認爲9200 http.port: 9200 #集羣中主節點的初始列表,當主節點啓動時會使用這個列表進行非主節點的監測 discovery.zen.ping.unicast.hosts: ["192.168.111.128:9300","192.168.111.128:9301"] #下面這個參數控制的是,一個節點須要看到的具備master節點資格的最小數量,而後才能在集羣中作操做。官方推薦值是(N/2)+1; #其中N是具備master資格的節點的數量(咱們的狀況是2,所以這個參數設置爲1) #可是:但對於只有2個節點的狀況,設置爲2就有些問題了,一個節點DOWN掉後,確定連不上2臺服務器了,這點須要注意 discovery.zen.minimum_master_nodes: 1 #集羣ping過程的超時 discovery.zen.ping_timeout: 120s #客戶端鏈接超時 client.transport.ping_timeout: 60s #cache緩存大小,10%(默認),可設置成百分比,也可設置成具體值,如256mb。 indices.queries.cache.size: 20% #索引期間的內存緩存,有利於索引吞吐量的增長。 indices.memory.index_buffer_size: 30% #開啓了內存地址鎖定,爲了不內存交換提升性能。可是Centos6不支持SecComp功能,啓動會報錯,因此須要將其設置爲false bootstrap.memory_lock: true bootstrap.system_call_filter: false #設置該節點是否具備成爲主節點的資格以及是否存儲數據。 node.master: true node.data: true #ElasticSearch 更改search線程池,search 線程設置太小致使程序崩潰 thread_pool.search.queue_size: 1000 #queue_size容許控制沒有線程執行它們的掛起請求隊列的初始大小。 thread_pool.search.size: 200 #size參數控制線程數,默認爲核心數乘以5。 thread_pool.search.min_queue_size: 10 #min_queue_size設置控制queue_size能夠調整到的最小量。 thread_pool.search.max_queue_size: 1000 #max_queue_size設置控制queue_size能夠調整到的最大量。 thread_pool.search.auto_queue_frame_size: 2000 #auto_queue_frame_size設置控制在調整隊列以前進行測量的操做數。它應該足夠大,以便單個操做不會過分偏向計算。 thread_pool.search.target_response_time: 6s #target_response_time是時間值設置,指示線程池隊列中任務的目標平均響應時間。若是任務一般超過此時間,則將調低線程池隊列以拒絕任務。
4) 192.168.111.128上安裝elasticsearch-node2
cd /usr/local/ cp -r elasticsearch-node1 elasticsearch-node2 |
修改vim /usr/local/elasticsearch-node2/config/elasticsearch.yml文件
[root@es-master local]# vim elasticsearch-node1/config/elasticsearch.yml #修改如下項 cluster.name: elasticsearch node.name: "elasticsearch-node2" path.data: /usr/local/elasticsearch-node2/data path.logs: /usr/local/elasticsearch-node2/logs network.host: 192.168.11.128 network.bind_host: 192.168.11.128 network.publish_host: 192.168.11.128 cluster.initial_master_nodes: ["192.168.11.128:9300"] transport.tcp.port: 9301 http.port: 9201 discovery.zen.ping.unicast.hosts: ["192.168.111.128:9300","192.168.111.128:9301"] discovery.zen.minimum_master_nodes: 1 discovery.zen.ping_timeout: 120s client.transport.ping_timeout: 60s indices.queries.cache.size: 20% indices.memory.index_buffer_size: 30% bootstrap.memory_lock: true bootstrap.system_call_filter: false node.master: true node.data: true thread_pool.search.queue_size: 1000 thread_pool.search.size: 200 thread_pool.search.min_queue_size: 10 thread_pool.search.max_queue_size: 1000 thread_pool.search.auto_queue_frame_size: 2000 thread_pool.search.target_response_time: 6s
5) 啓動
首先切換爲elk用戶
su - elk /usr/local/elasticsearch-node1/bin/elasticsearch -d /usr/local/elasticsearch-node2/bin/elasticsearch -d |
啓動後以下圖:
使用curl測試節點是否能夠正常訪問,
curl 192.168.111.128:9200
curl 192.168.111.128:9201
查看狀態
curl "http://127.0.0.1:9200/_status?pretty=true"
查看集羣健康
curl "http://127.0.0.1:9200/_cat/health?v"
至此ES配置完畢,
下載解壓安裝:
wget https://artifacts.elastic.co/downloads/kibana/kibana-7.3.1-linux-x86_64.tar.gz tar xf kibana-7.3.1-linux-x86_64.tar.gz -C /usr/local |
修改kibana的配置文件kibana.yml
[root@localhost local]# cd kibana/config #設置請求時長 |
啓動kibana
[root@localhost config]# cd /usr/local//bin |
若是啓動正常,在瀏覽器端訪問http://192.168.111.129:5601,便可看到圖形化操做工具
vi kibana.yml i18n.locale: "zh-CN" |
時區修改步驟:
進入kibana界面-》管理-》高級設置-》設置日期格式的時區
默認:Browser
可修改成:Asia/Shanghai
重啓便可!
1、wget https://artifacts.elastic.co/downloads/logstash/logstash-7.3.1.tar.gz
解壓logstash:
tar xzf logstash-7.3.1.tar.gz mv logstash-7.3.1 /usr/local/logstash/ |
二、logstash的優化pipelines.yml丶logstash.yml配置
能夠優化的參數,可根據本身的硬件進行優化配置:
①pipeline線程數,官方建議是等於CPU內核數
②實際output時的線程數
③每次發送的事件數
④發送延時(單位是毫秒)
總結:
Logstash中的jvm.options配置文件:
Logstash是一個基於Java開發的程序,須要運行在JVM中,能夠經過配置jvm.options來針對JVM進行設定。好比內存的最大最小、垃圾清理機制等等。JVM的內存分配不能太大不能過小,太大會拖慢操做系統。過小致使沒法啓動。默認以下:
wget http://117.128.6.27/cache/download.redis.io/releases/redis-4.0.14.tar.gz?ich_args2=522-03101307057974_3dd269048c70bdf875dc9acff1b71955_10001002_9c89622bd3c4f7d69f33518939a83798_c8a912a80ccc397fec935bfecdb1cca8 tar zxf redis-4.0.14.tar.gz -C /usr/local cd redis-3.0.5 make make install |
將/usr/local/redis/bin/目錄加入至環境變量配置文件/etc/profile末尾,而後Shell終端執行source /etc/profile讓環境變量生效。
export PATH=/usr/local/redis/bin:$PATH |
配置:
vim redis.conf #修改如下內容,不是必須的 bind 127.0.0.1 192.168.111.130 #兩臺主機分別改成本身的IP logfile "/usr/local/src/redis-3.0.3/redis.log" daemonize yes #啓用守護模式 #requirepass "admin.123" #設置redis登陸密碼 這個看本身需求能夠不要 |
Redis作ELK緩衝隊列的優化:
啓動及中止Redis服務命令:
/usr/local/redis/bin/redis-server /usr/local/redis/redis.conf /usr/local/redis/bin/redis-cli -p 6379 shutdown |
查看redis內存使用狀況:redis-cli -r 100 -i 1 info Memory |grep "used_memory_human"
wget https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.3.1-linux-x86_64.tar.gz tar -zxvf filebeat-7.3.1-linux-x86_64.tar.gz -C /usr/local/ mv filebeat-7.3.1-linux-x86_64 filebeat |
啓動方式以下:
./filebeat -e -c ../filebeat.yml
-c:配置文件位置
-path.logs:日誌位置
-path.data:數據位置
-path.home:家位置
-e:關閉日誌輸出
-d 選擇器:啓用對指定選擇器的調試。 對於選擇器,能夠指定逗號分隔的組件列表,也可使用-d「*」爲全部組件啓用調試.例如,-d「publish」顯示全部「publish」相關的消息。
後臺啓動filebeat
nohup ./filebeat -e -c ../filebeat.yml >/dev/null 2>&1 & 將全部標準輸出及標準錯誤輸出到/dev/null空設備,即沒有任何輸出
nohup ./filebeat -e -c ./filebeat.yml > filebeat.log &
目錄/usr/local/filebeat/config/filebeat.yml:
1) filebeat客戶端日誌採集-存入Redis緩存數據庫;
filebeat.yml文件內容:
filebeat.inputs:- type: log - type: log enabled: true paths: - /var/log/mysqld.log encoding: utf-8 tail_files: true exclude_lines: ["invoke:method=execute","profile"] fields: log_topic: mysql close_older: 24h scan_frequency: 3s harvester_buffer_size: 32768 max_bytes: 10485760 idle_timeout: 5s multiline.pattern: '^\d{4}-\d{1,2}-\d{1,2}\s\d{1,2}:\d{1,2}:\d{1,2}' multiline.negate: true multiline.match: after processors: - drop_fields: #刪除字段,再也不kibana裏面展現,默認狀況kibana裏面會自動展現這些beat字段 fields: ["type","prospector","source","input","beat","version","@version","offset"] output.redis: hosts: ["192.168.111.130:6379"] key: "filebeat" db: 0 datatype: list loadbalance: true
主要配置項說明:
enabled:true 表明開啓這個配置節
paths: 監控指定目錄下的文件,支持模糊搜索
tail_files: true :第一次讀取的是最新內容,不須要整個文件讀取 (可選)
exclude_lines: 指定正則表達式,用來指定不要匹配的行,在輸入中排除符合正則表達式列表的那些行,能夠有幾個。(可選)
close_older: 若是一個文件在某個時間段內沒有發生過更新則關閉監控的文件handle。默認1h,change只會在下一次scan纔會被發現(可選)
scan_frequency: Filebeat以多快的頻率去prospector指定的目錄下面檢測文件更新好比是否有新增文件若是設置爲0s則Filebeat會盡量快地感知更新佔用的CPU會變高。默認是10s。
harvester_buffer_size: 每一個harvester監控文件時使用的buffer的大小。(可選)
max_bytes: 日誌文件中增長一行算一個日誌事件max_bytes限制在一第二天志事件中最多上傳的字節數多出的字節會被丟棄。The default is 10MB.(可選)
idle_timeout: 後臺刷新超時時間,超過定義時間後強制發送,無論spool_size後臺事件計數閾值是否達到,默認5秒。
fields: 增長fields額外字段,附加的可選字段,以向output添加額外的信息。output裏面可使用這個變量
multiline: 多行日誌監控,下面配置的意思是:不以[開頭的行都合併到上一行的末尾(正則寫的很差,忽略忽略)
pattern:正則表達式
negate:true 或 & false;默認是false,匹配pattern的行合併到上一行;true,不匹配pattern的行合併到上一行
match:after 或 before,合併到上一行的末尾或開頭
drop_fields: #刪除字段,再也不kibana裏面展現,默認狀況kibana裏面會自動展現這些beat字段
output.redis: 配置host指定redis地址
loadbalance: true 每一條message都隨機負載均衡到redis
而後啓動Agent:
nohup ./filebeat -e -c ../config/filebeat.yml > filebeat.log &
2) Redis數據-存入ES;
index.conf文件內容:
input { redis { host => "192.168.111.130" #redis地址 port => "6379" #redis端口號 data_type => "list" #logstash redis插件工做方式 key => "filebeat" #監聽的鍵值 #add_field => { "[@metadata][myid]" => "mysql-111.111" } #增長一個字段,用於標識和判斷,與下方output輸出相對應 ,es6.0版本以上就不支持type類型了 db => 0 #redis數據庫的編號,通常是16個,默認登陸後是0,能夠經過命令選擇。若是應用系統選擇使用了不一樣的數據庫,經過配置這個參數從指定的數據庫中讀取信息。 threads => 10 #啓用線程數量,啓用線程數越多效率也快 batch_count => 1 #返回的事件數量,此屬性僅在list模式下起做用。 codec => "json" #輸出josn格式 } } output { stdout { codec => json_lines #輸出json格式 } if [fields][log_type] == "mysql" { # 當有多個輸入源的時候,可根據不一樣的標識,指定不一樣的輸出地址 elasticsearch { hosts => ["192.168.111.128:9200"] #若是是集羣須要把其他節點加進來 index => "logstash_%{[fields][log_type]}-%{+YYYY.MM.dd.HH}" ## 輸出es的日誌索引格式。 } } } |
注意:YYYY.MM.dd.HH 是以小時爲單位切割索引文件
而後啓動logstash:
../bin/logstash -f index.conf
查看啓動進程:
注意:全部指定新建索引名稱必須是小寫,不然會報錯 "Could not index event to Elasticsearch"
目錄/usr/local/filebeat/config/filebeat.yml:
3) filebeat客戶端日誌採集-存入Redis緩存數據庫;
filebeat.yml文件內容:
filebeat.inputs: - type: log enabled: true paths: - /usr/local/nginx/logs/access.log tail_files: true exclude_lines: ["invoke:method=execute","profile"] fields: log_topic: nginx_access close_older: 24h scan_frequency: 3s idle_timeout: 5s - type: log enabled: true paths: - /usr/local/nginx/logs/error.log tail_files: true exclude_lines: ["invoke:method=execute","profile"] fields: log_topic: nginx_error close_older: 24h scan_frequency: 3s idle_timeout: 5s processors: - drop_fields: #刪除字段,再也不kibana裏面展現,默認狀況kibana裏面會自動展現這些beat字段 fields: ["type","prospector","source","input","beat","version","@version","offset"] output.redis: hosts: ["192.168.111.130:6379"] key: "filebeat" db: 0 datatype: list loadbalance: true
而後啓動Agent:
../bin/logstash -f agent.conf
4) Redis數據-存入ES;
index.conf文件內容:
input { stdout {
|
而後啓動index:
../bin/logstash -f index.conf
查看啓動進程:
瀏覽器訪問kibana-WEB:
http://192.168.111.129:5601
如上配置能夠正常收集單臺服務器的日誌,如何批量收集其餘服務器的日誌信息呢,方法步驟是什麼呢?
能夠基於SHELL腳本將配置完畢的logstash文件夾同步至其餘服務器,或者經過ansible、saltstack服務器都可。
例如收集Nginx日誌,index.conf和agent.conf內容保持不變便可:
第一種密碼訪問方式:x-pack密鑰
從 6.8.0 和 7.1.0 版本開始, Elastic Stack安全功能免費提供。用戶如今可以對網絡流量進行加密、建立和管理用戶、定義可以保護索引和集羣級別訪問權限的角色,而且使用 Spaces 爲 Kibana 提供全面保護。
配置 TLS 和身份驗證
咱們要作的第一件事是生成證書,經過這些證書便能容許節點安全地通訊。您可使用企業 CA 來完成這一步驟,可是在此演示中,咱們將會使用一個名爲 elasticsearch-certutil 的命令,經過這一命令,您無需擔憂證書一般帶來的任何困擾,便能完成這一步。
第 1步:在 Elasticsearch 主節點上配置 TLS
使用 cd 命令更改至 master 目錄,而後運行下列命令:
bin/elasticsearch-certutil cert -out config/elastic-certificates.p12 -pass ""
接下來,打開文件 config/elasticsearch.yaml。將下列代碼行粘貼到文件末尾,每一個節點都要加。
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.keystore.path: elastic-certificates.p12
xpack.security.transport.ssl.truststore.path: elastic-certificates.p12
保存文件,如今咱們即可以啓動主節點了
第 2 步:Elasticsearch 集羣密碼
一旦主節點開始運行,即可覺得集羣設置密碼了。運行命令 bin/elasticsearch-setup-passwords auto。這將會爲不一樣的內部堆棧用戶生成隨機密碼。或者,您也能夠跳過 auto 參數,改成經過 interactive 參數手動定義密碼。請記錄這些密碼,咱們很快就會再次用到這些密碼。
注意點:在主節點生成p12文件、配置重啓,生成密碼完成前,千萬不能操做其餘節點。
第 3 步:在 Elasticsearch 節點上配置 TLS
在第1步運行bin/elasticsearch-certutil cert -out config/elastic-certificates.p12 -pass ""
該命令的時候 將會在config下生成elastic-certificates.p12文件,將此文件cp -a到其餘兩個節點的config目錄,而後重啓節點。
咱們將看到其加入集羣。並且,若是看一下主節點的終端窗口,咱們會看到有一條消息顯示已有一個節點加入集羣。如今,咱們的兩節點集羣便開始運行了。
注意點:必定要注意p12文件的權限屬主
第 4 步:在 Kibana 中實現安全性
要作的最後一件事是爲 Kibana 配置用戶密碼。咱們能夠從以前 setup-passwords 命令的輸出內容中找到密碼。打開 config/kibana.yml 文件。找到相似下面的代碼行
#elasticsearch.username: "user"
#elasticsearch.password: "pass"
對 username 和 password 字段取消註釋,方法是刪除代碼行起始部分的 # 符號。將 "user" 更改成 "kibana",而後將 "pass" 更改成 setup-passwords 命令告訴咱們的任何 Kibana 密碼。保存文件,而後咱們即可經過運行 bin/kibana啓動 Kibana 了。
登陸後能夠在此頁面建立用戶及控制用戶權限,還能夠對超級用戶進行密碼修改
而後相應的logstash收集過濾日誌也須要配置用戶密碼,否則輸出日誌到elasticsearch失敗,寫法以下:
output { stdout { codec => json_lines } if [fields][log_topic] == "dispatcher-connector_zone2" { elasticsearch { hosts => ["192.168.115.98:9200","192.168.115.87:9200","192.168.115.126:9200"] user => "elastic" password => "Ericss0n" index => "logstash_%{[fields][log_topic]}-%{+YYYY.MM.dd}" } } }
第二種方式:Apache的密碼認證進行安全配置。經過訪問Nginx轉發kibana服務器地址。
當咱們安裝完ES、Kibana啓動進程,能夠直接在瀏覽器訪問,這樣不利於數據安全,接下來咱們利用Apache的密碼認證進行安全配置。經過訪問Nginx轉發只ES和kibana服務器。
Kibana服務器安裝Nginx:
yum install openssl openssl-devel pcre-devel pcre zlib zlib-devel –y wget -c http://nginx.org/download/nginx-1.8.1.tar.gz tar -xzf nginx-1.8.1.tar.gz cd nginx-1.8.1 useradd www ;./configure --user=www --group=www --prefix=/usr/local/nginx --with-pcre --with-pcre-jit --with-http_sub_module --with-http_stub_status_module --with-http_ssl_module --with-http_flv_module --with-http_realip_module --with-http_spdy_module --with-http_gunzip_module --with-http_gzip_static_module make make install #自此Nginx安裝完畢 /usr/local/nginx/sbin/nginx -t 檢查nginx配置文件是否正確,返回OK即正確。 |
修改Nginx.conf配置文件代碼以下:
#user www www; worker_processes 2; worker_cpu_affinity 00000001 00000010; error_log /opt/ericsson/nginx/logs/error.log crit; pid /opt/ericsson/nginx/nginx.pid; worker_rlimit_nofile 102400; events { use epoll; worker_connections 102400; multi_accept on; } http { include mime.types; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$request_time"'; default_type application/octet-stream; access_log logs/access.log main ; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 60; gzip on; gzip_min_length 1k; gzip_buffers 4 16k; gzip_http_version 1.1; gzip_comp_level 4; gzip_types text/plain application/x-javascript text/css application/xml; gzip_vary on; client_max_body_size 10m; client_body_buffer_size 128k; proxy_connect_timeout 90; proxy_send_timeout 90; proxy_read_timeout 90; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; large_client_header_buffers 4 4k; client_header_buffer_size 4k; open_file_cache max=102400 inactive=20s; open_file_cache_valid 30s; open_file_cache_min_uses 1; upstream kibana_web1 { server 172.31.15.228:5601 weight=1 max_fails=2 fail_timeout=30s; }
server { listen 8080; server_name 172.31.15.202; location / { auth_basic "ELK Kibana Monitor Center"; auth_basic_user_file /opt/ericsson/nginx/html/.htpasswd; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://kibana_web1; } } } |
修改kibana配置文件監聽IP爲127.0.0.1:
重啓kibana和Nginx服務,經過Nginx 80端口訪問以下:
添加Nginx權限認證:
Nginx.conf配置文件location /中加入以下代碼:
auth_basic "ELK Kibana Monitor Center"; auth_basic_user_file /usr/local/nginx/html/.htpasswd; |
經過Apache加密工具htpasswd生成用戶名和密碼:
須要安裝:yum -y install httpd-tools
htpasswd -c /usr/local/nginx/html/.htpasswd admin
重啓Nginx web服務,訪問以下:
用戶名和密碼正確,便可登陸成功,
1,普通正則表達式以下:
. 任意一個字符 * 前面一個字符出現0次或者屢次 [abc] 中括號內任意一個字符 [^abc] 非中括號內的字符 [0-9] 表示一個數字 [a-z] 小寫字母 [A-Z] 大寫字母 [a-zA-Z] 全部字母 [a-zA-Z0-9] 全部字母+數字 [^0-9] 非數字 ^xx 以xx開頭 xx$ 以xx結尾 \d 任何一個數字 \s 任何一個空白字符 |
2,擴展正則表達式,在普通正則符號再進行了擴展
擴展正則表達式,在普通正則符號再進行了擴展 ? 前面字符出現0或者1次 + 前面字符出現1或者屢次 {n} 前面字符匹配n次 {a,b} 前面字符匹配a到b次 {,b} 前面字符匹配0次到b次 {a,} 前面字符匹配a或a+次 (string1|string2) string1或string2 |
簡單提取IP
114.114.114.114 255.277.277.277
1-3個數字.1-3個數字.1-3個數字.1-3個數字
[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}
1.13 logstash之multiline插件,匹配多行日誌
在外理日誌時,除了訪問日誌外,還要處理運行時日誌,該日誌大都用程序寫的,一個異常的日誌是多行的,咱們目的是要把有這樣的日誌合併成一條
安裝插件命令是 # logstash-plugin install logstash-filter-multiline
# logstash-plugin install logstash-filter-multiline
Validating logstash-filter-multiline
Installing logstash-filter-multiline
Installation successfu |
在logstash filter中使用multiline插件(不推薦):
不推薦的緣由:
在filter中,加入如下代碼:
filter {
multiline { }
}
在logstash input中使用multiline插件(沒有filebeat時推薦):
multiline字段屬性:
對於multiline插件來講,有三個設置比較重要:negate , pattern 和 what
codec =>multiline { charset=>... #可選 字符編碼(UTF-8) max_bytes=>... #可選 bytes類型 設置最大的字節數 max_lines=>... #可選 number類型 設置最大的行數,默認是500行 pattern=>... #必選 string類型 設置匹配的正則表達式 patterns_dir=>... #可選 array類型 能夠設置多個正則表達式 negate=>... #必選 boolean類型 默認false不顯示,可設置ture what=>... #必選 向前previous , 向後 next auto_flush_interval => 30 # 若是在規定時候內沒有新的日誌事件就不等待後面的日誌事件 }
下面看看這兩個例子:
1.一個java的報錯:
input能夠設置以下:
input { file { type => "TC" start_position => "end" path => "/opt/ericsson/csp/logs/TC.log" codec => multiline { pattern => "^\[" negate => true what => "previous" charset => "UTF-8" } } }
說明:區配以"["開頭的行,若是不是,那確定是屬於前一行的
2.好比一個java應用產生的異常日誌是這樣:
input能夠設置以下:
input { file { type => "tsc-remote-status" start_position => "end" path => "/opt/qweq/logs/tsc-remote-status.log" codec => multiline { pattern => "^\d{4}-\d{1,2}-\d{1,2}\s\d{1,2}:\d{1,2}:\d{1,2}" negate => true what => "previous" charset => "UTF-8" } } }
說明:目的匹配以 「2017-11-15 14:32:03」 這種時間格式開頭的日誌,若是不是,那確定是屬於前一行的
1,條件判斷
使用條件來決定filter和output處理特定的事件。logstash條件相似於編程語言。條件支持if、else if、else語句,能夠嵌套。
比較操做有:
==
, !=
, <
, >
, <=
, >=
=~(匹配正則)
, !~(不匹配正則)
in(包含)
, not in(不包含)
布爾操做:
and(與)
, or(或)
, nand(非與)
, xor(非或)
一元運算符:
!(取反)
()
(複合表達式), !()
(對複合表達式結果取反)2,經常使用的過濾器爲:
mutate插件:使用最頻繁的操做,能夠對字段進行各類操做,好比重命名、刪除、替換、更新等,主要參數以下:
filter { mutate { convert => { "local_port" => "integer" "bytes" => "integer" "latency_ms" => "integer" } rename => { "[host][name]" => "host" } remove_field => ["type","prospector","source","input","beat","version","@version","offset"] } }
drop插件:丟棄一部分events不進行處理,匹配篩選多餘日誌。
filter { #dispatcher if([message]=~ "DEBUG") or ([message]=~ "traceLogger") or ([message]=~ "^20.*\ WARN\ .*\ by\ regular\ expression.*"){ drop{} } #tsc if([message]=~ ".*\ The\ HTTP\ headers\ are.*") or ([message]=~ "with Queue depth: 0$") or ([message]=~ "%$") or ([message]=~ "execute...$"){ drop{} } #tc if([message]=~ "\[]$") or ([message]=~ "invoke:method=execute") { drop{} } #等等 }
date:時間處理
處理2條不一樣格式時間日誌示例以下:
2019-09-16 21:59:18.131 [TSC_MESSAGE] [INFO] [c.e.c.t.m.r.RemoteControllMessageResourceImpl] [csp] [Add message] [LB37722Z5KH038111] [OPERATION_SUCCESS] []
192.168.112.24 - - [16/Sep/2019:21:58:16 +0800] "GET /services/serviceconnection/ HTTP/1.1" 200 1836
date使用:
filter { grok { match => {"message" => "%{TIMESTAMP_ISO8601:access_time}"} match => {"message" => "%{IP:ip}\s*%{DATA:a}\s*\[%{HTTPDATE:access_time}\]"} } date { # 這個纔是真正的access發生時間,識別爲記錄的@timestamp timezone => "Asia/Shanghai" match => [ "access_time","ISO8601","dd/MMM/yyyy:HH:mm:ss Z"] } }
注:match => [ "access_time", "ISO8601"] } 注意:時區偏移量只須要用一個字母 Z 便可。
ISO8601 - 應解析任何有效的ISO8601時間戳 如:2019-09-16 21:59:18.131
dd/MMM/yyyy:HH:mm:ss Z - 應解析爲16/Sep/2019:21:58:16 +0800的時間格式
date介紹:
就是將匹配日誌中時間的key替換爲@timestamp的時間,由於@timestamp的時間是日誌送到logstash的時間,並非日誌中真正的時間。
Grok插件:
詳細語法參照博客篇: http://www.javashuo.com/article/p-hjufbcdv-ew.html
語法解釋:
%{HOSTNAME},匹配請求的主機名
%{TIMESTAMP_ISO8601:time},表明時間戳
%{LOGLEVEL},表明日誌級別
%{URIPATHPARAM},表明請求路徑
%{DATA},表明任意數據
%{INT},表明字符串整數數字大小
%{NUMBER}, 能夠匹配整數或者小數
%{IP}, 匹配ip
%{WORD}, 匹配請求的方式
%{GREEDYDATA},匹配全部剩餘的數據
(?([\S+]*)),自定義正則
\s*或者\s+,表明多個空格
\S+或者\S*,表明多個字符
大括號裏面:xxx,至關於起別名
(?<class_info>([\S+]*)), 自定義正則匹配多個字符
舉例1,在日誌文件中原生日誌時間是這樣子的:2019-03-19 13:08:07.782
重點是後面的」.782「,後面附加以毫秒爲單位的。
那麼grok插件中能夠這樣子定義匹配的規則:
grok { match => {"message" => "%{TIMESTAMP_ISO8601:access_time}"} }
舉例2,操做以下:
[2019-08-22 12:25:51.441] [TSC_IHU] [ERROR] [c.e.c.t.i.t.s.IhuTsaUplinkServiceImpl] Activation/Bind uplink, query UserSession by Token failure!
grok { match => {"message" => "\[%{TIMESTAMP_ISO8601:time}\]\s*%{DATA:name}\s*\[%{LOGLEVEL:level}\]\s*%{GREEDYDATA:data}"} }
舉例3,操做以下:
2019-09-12 14:16:36.320+08:00 INFO 930856f7-c78f-4f12-a0f1-83a2610b2dfc DispatcherConnector ip-192-168-114-244 [Mqtt-Device-1883-worker-18-1] com.ericsson.sep.dispatcher.api.transformer.v1.MessageTransformer {"TraceID":"930856f7-c78f-4f12-a0f1-83a2610b2dfc","clientId":"5120916600003466K4GA1059","username":"LB37622Z3KX609880"}
grok { match => {"message" => "%{TIMESTAMP_ISO8601:access_time}\s*%{LOGLEVEL:level}\s*%{UUID:uuid}\s*%{WORD:word}\s*%{HOSTNAME:hostname}\s*\[%{DATA:work}\]\s*(?<api>([\S+]*))\s*(?<TraceID>([\S+]*))\s*%{GREEDYDATA:message_data}"} }
舉例4,操做以下:
192.168.125.138 - - [12/Sep/2019:14:10:58 +0800] "GET /backend/services/ticketRemind/query?cid=&msgType=1&pageSize=100&pageIndex=1&langCode=zh HTTP/1.1" 200 91
grok { match => {"message" => "%{IP:ip}\s*%{DATA:a}\s*\[%{HTTPDATE:access_time}\]\s*%{DATA:b}%{WORD:method}\s*%{URIPATH:url}%{URIPARAM:param}\s*%{URIPROTO:uri}%{DATA:c}%{NUMBER:treaty}%{DATA:d}\s*%{NUMBER:status}\s*%{NUMBER:latency_millis}"} }
舉例5,操做以下:
[08/Nov/2019:11:40:24 +0800] tc-com.g-netlink.net - - 192.168.122.58 192.168.122.58 192.168.125.135 80 GET 200 /geelyTCAccess/tcservices/capability/L6T7944Z0JN427155 ?pageIndex=1&pageSize=2000&vehicleType=0 21067 17
grok { match => { "message"=> "\[%{HTTPDATE:access_time}\] %{DATA:hostname} %{DATA:username} %{DATA:fwd_for} %{DATA:remote_hostname} %{IP:remote_ip} %{IP:local_ip} %{NUMBER:local_port} %{DATA:method} %{DATA:status} %{DATA:uri} %{DATA:query} %{NUMBER:bytes} %{NUMBER:latency_ms}"} }
grok同時處理多種日誌不一樣行的寫法:
filter { if [fields][log_topic] == "dispatcher-connector" { grok { match => {"message" => "%{TIMESTAMP_ISO8601:time}\s*%{LOGLEVEL:level}\s*%{UUID:uuid}\s*%{WORD:word}\s*%{HOSTNAME:hostname}\s*\[%{DATA:work}\]\s*(?<api>([\S+]*))\s*(?<TraceID>([\S+]*))\s*%{GREEDYDATA:message_data}"} match => {"message" => "%{TIMESTAMP_ISO8601:time}\s*%{LOGLEVEL:level}\s*%{WORD:word}\s*%{HOSTNAME:hostname}\s*(?<TraceID>([\S+]*))\s*(?<api>([\S+]*))\s*(?<brackets>([\S+]*))\s*%{GREEDYDATA:message_data}"} remove_field =>["message","time","level","uuid","word","hostname","brackets","work","api","TraceID"] } } }
1,ES數據按期刪除
#/bin/bash #es-index-clear #只保留15天內的日誌索引 LAST_DATA=`date -d "-7 days" "+%Y.%m.%d"` #刪除上個月份全部的索引(根據本身的索引格式編寫) curl -XDELETE 'http://ip:port/*-'${LAST_DATA}''
crontab -e添加定時任務:天天的凌晨清除索引。
0 1 * * * /search/odin/elasticsearch/scripts/es-index-clear.sh
2,ES按期清理cache
爲避免fields data佔用大量的jvm內存,能夠經過按期清理的方式來釋放緩存的數據。釋放的內容包括field data, filter cache, query cache
curl -XPOST "ip:port/_cache/clear"
curl -XPOST -uelastic:Ericss0n "ip:port/_cache/clear"
crontab -e添加定時任務:天天的凌晨清除緩存
3,ES索引寫入優化
調小索引副本數,經過增大refresh間隔週期,同時不設置副原本提升寫性能。
curl -XPUT 'ip:9200/_all/_settings' -H 'Content-Type: application/json' -d '{"index":{"refresh_interval":"120s","number_of_replicas":"0"},"translog.durability": "async","translog.flush_threshold_size":"1024mb","translog.sync_interval": "120s","merge.scheduler.max_thread_count":"1","merge.policy.floor_segment":"10mb"}'
curl -XPUT 'ip:9200/_all/_settings' -uelastic:Ericss0n -H 'Content-Type: application/json' -d '{"index":{"refresh_interval":"120s","number_of_replicas":"0"},"translog.durability": "async","translog.flush_threshold_size":"1024mb","translog.sync_interval": "120s","merge.scheduler.max_thread_count":"1","merge.policy.floor_segment":"10mb"}'
crontab -e添加定時任務:天天的凌晨執行
4,修改集羣分片數,默認只容許1000個分片,難免後期分片數不足丟失數據
curl -XPUT 'ip:9200/_cluster/settings' -uelastic:Ericss0n -H "Content-Type: application/json" -d '{"transient":{"cluster":{"max_shards_per_node":10000}}}'