這是elk的第二篇文章php
elk支持多種輸入輸出方法 ,本文章主要描述經過redis作隊列中間件 ,緩解elk平臺的壓力
數據不可控時 ,例如日誌不是文件 , 而是由TCP直接推送到elk的 ,filebeats就沒法使用了固然redis是能夠和beats一塊兒使用的, 例如beats讀取文件解析後輸出到redis ,再由elk正常流程處理, 具體的這裏不作討論linux
在經過logstash以前走redis , 分散壓力不至於logstash負載過高 ,處理緩慢甚至宕機
請看第一篇文章 : 編譯安裝日誌分析平臺 elk + filebeat
Redis是一個支持多種數據結構的開源(BSD許可)內存型數據庫 , 除此以外它甚至能夠被用做持久化數據庫,緩存器和消息隊列 查看更多
極其簡單 ,使用yum或下載源碼make便可 , 再也不贅述nginx
yum -y install redis
cd /opt wget http://download.redis.io/releases/redis-4.0.11.tar.gz || curl -O http://download.redis.io/releases/redis-4.0.11.tar.gz tar xzvf redis-4.0.11.tar.gz && \ cd redis-4.0.11 && \ yum -y install gcc && \ make
能夠不配置 ,可是筆者須要從外部連接redis ,因此把監聽地址修改成局域網IP
你們按需執行便可git
配置文件位置:
yum : /etc/redis.conf
源碼 : /opt/redis-4.0.11/redis.conf
github
# 修改監聽地址 sed -i 's/^bind 127.0.0.1/bind 192.168.1.147/' /opt/redis-4.0.11/redis.conf # 修改監聽端口 sed -i 's/^port 6379/port 6379/' /opt/redis-4.0.11/redis.conf
這裏也分兩種
yum安裝啓動方法redis
systemctl redis start
源碼安裝啓動方法數據庫
/opt/redis-4.0.11/src/redis-server /opt/redis-4.0.11/redis.conf &
和第一篇中爲elk加入beats同樣 , 只須要編輯logstash的配置文件就能夠了json
爲了不你已經手動修改了配置文件 , 咱們再也不使用sed爲改成手動修改配置文件
使用你喜好的編輯器打開 /opt/logstash-6.3.2/config/logstash-io.conf api
在input代碼塊中增長以下內容並保存緩存
redis { key => "redis_log" data_type => "list" type => "redis" host => "192.168.1.147" port => "6379" threads => 12 # 若是存進redis的數據是json才須要這一行 codec => "json" }
在input代碼塊的同級增長以下內容並保存
這裏是處理nginx日誌的過濾器 , 稍候會講裏面的grok語法
filter { if [type] == "redis" { grok { match => { "message" => "%{IPORHOST:remote_ip} - - \[%{HTTPDATE:datetime}\] \"(:?%{WORD:request_method} %{NOTSPACE:uri}) (:?HTTP/%{NUMBER:http_version})\" (:?%{NUMBER:http_code}) (:?%{NUMBER:contents_length}) \"(:?%{NOTSPACE:domail})\" \"(:?%{DATA:ua}) \((:?%{DATA:os})%{NUMBER:os_version}\) %{DATA}\) %{DATA:browser}/%{DATA:browser_version} (:?%{DATA:safari_version})\"" } } geoip { source => "client_ip" } date { match => [ "timestamp" , "dd/MMM/YYYY:HH:mm:ss Z" ] } } }
修改output代碼爲以下這樣
這爲了按類型劃分索引
output { if [type] == "redis" { elasticsearch { hosts => ["192.168.1.147:9200"] manage_template => false index => "redis-%{+YYYY.MM.dd}" } } else if [type] == "beats" { elasticsearch { hosts => ["192.168.1.147:9200"] manage_template => false index => "beats-%{+YYYY.MM.dd}" } } else { elasticsearch { hosts => ["192.168.1.147:9200"] manage_template => false index => "unkown-%{+YYYY.MM.dd}" } } }
最終配置文件大概會是這個樣子
input { beats { port => 5044 type => "beats" } redis { key => "redis_log" data_type => "list" type => "redis" host => "192.168.1.147" port => "6379" threads => 12 codec => "json" } } filter { if [type] == "redis" { grok { match => { "message" => "%{IPORHOST:remote_ip} - - \[%{HTTPDATE:datetime}\] \"(:?%{WORD:request_method} %{NOTSPACE:uri}) (:?HTTP/%{NUMBER:http_version})\" (:?%{NUMBER:http_code}) (:?%{NUMBER:contents_length}) \"(:?%{NOTSPACE:domail})\" \"(:?%{DATA:ua}) \((:?%{DATA:os})%{NUMBER:os_version}\) %{DATA}\) %{DATA:browser}/%{DATA:browser_version} (:?%{DATA:safari_version})\"" } } geoip { source => "client_ip" } date { match => [ "timestamp" , "dd/MMM/YYYY:HH:mm:ss Z" ] } } } output { if [type] == "redis" { elasticsearch { hosts => ["192.168.1.147:9200"] manage_template => false index => "redis-%{+YYYY.MM.dd}" } } else if [type] == "beats" { elasticsearch { hosts => ["192.168.1.147:9200"] manage_template => false index => "beats-%{+YYYY.MM.dd}" } } else { elasticsearch { hosts => ["192.168.1.147:9200"] manage_template => false index => "unkown-%{+YYYY.MM.dd}" } } }
而後和第一篇同樣 , 使用screen啓動elk
screen -S elk /opt/elasticsearch-6.3.2/bin/elasticsearch & \ /opt/logstash-6.3.2/bin/logstash -f /opt/logstash-6.3.2/config/logstash-io.conf & \ /opt/kibana-6.3.2-linux-x86_64/bin/kibana & # 本次不切換回去了 # Ctrl A + c
若是配置沒有問題的話, 最後會輸出12行 [logstash.inputs.redis ] Registering Redis...
這樣的句子
會輸出12行由於咱們在input部分指定了threads爲12
而後咱們再看一看熟悉的kibana , 而且作一些事情
若是啓動完成可是看不到kibana ,就回到root關閉防火牆
systemctl stop firewalld
任何語言的redis客戶端均可以向redis推送數據
測試邏輯
連接到redis後, 向redis_log這個list結構循環推送下面的日誌內容
127.0.0.1 - - [21/Aug/2018:06:00:32 +0800] "GET /api/index/game-type HTTP/1.0" 200 269 "http://yooooooooo.com/" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36"
以php的predis客戶端爲例向redis推送數據
predis下載地址
<?php use Predis\Client; require __DIR__ . '/src/Autoloader.php'; Predis\Autoloader::register(); // 使用predis來連接redis $client = new Client('tcp://192.168.1.147:6379'); // 開始一個死循環 while (true) { // 每次向redis的redis_log這個list推送10000條數據 foreach (range(0 ,10000) as $value) { $client->lpush('redis_log' ,'127.0.0.1 - - [21/Aug/2018:06:00:32 +0800] "GET /api/index/game-type HTTP/1.0" 200 269 "http://yooooooooo.com/" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36"'); echo "$value \n"; } // 推送完成休息一秒 sleep(1); }
運行這個php例子
php ./pushToRedis.php
假設連接沒有問題 , 你會在elk那個終端裏看到輸出 , 我這裏由於配置了json卻輸入的字符串 , 纔會輸出的全是錯誤
來到 management 部分
一路下一步 ,建立完成
回到首頁(必定到確保左上角是redis... 若是不是就點名字旁邊的按鈕來切換到redis) ,而後打開自動刷新 , 數據就會源源不斷的渲染到頁面上了
而且咱們發現 , 左側是篩選條件和右側的數據都多了不少字段 , 這就是修改配置文件時 ,加入的filter段的功勞