elk 第二篇 , 爲elk加入redis, 替換下beats

爲elk加入redis, 替換下beats

這是elk的第二篇文章php

elk支持多種輸入輸出方法 ,本文章主要描述經過redis作隊列中間件 ,緩解elk平臺的壓力

使用場景

數據不可控時 ,例如日誌不是文件 , 而是由TCP直接推送到elk的 ,filebeats就沒法使用了

固然redis是能夠和beats一塊兒使用的, 例如beats讀取文件解析後輸出到redis ,再由elk正常流程處理, 具體的這裏不作討論linux

優點

在經過logstash以前走redis , 分散壓力不至於logstash負載過高 ,處理緩慢甚至宕機

流程圖

elk

請看第一篇文章 : 編譯安裝日誌分析平臺 elk + filebeat

redis

什麼是redis

Redis是一個支持多種數據結構的開源(BSD許可)內存型數據庫 , 除此以外它甚至能夠被用做持久化數據庫,緩存器和消息隊列 查看更多

如何安裝redis

極其簡單 ,使用yum或下載源碼make便可 , 再也不贅述nginx

  • yum安裝
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

能夠不配置 ,可是筆者須要從外部連接redis ,因此把監聽地址修改成局域網IP
你們按需執行便可git

配置文件位置:
yum : /etc/redis.conf
源碼 : /opt/redis-4.0.11/redis.confgithub

# 修改監聽地址
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

啓動redis

這裏也分兩種
yum安裝啓動方法redis

systemctl redis start

源碼安裝啓動方法數據庫

/opt/redis-4.0.11/src/redis-server /opt/redis-4.0.11/redis.conf &

啓動完成就像這樣 , 而後回車便可

配置elk

和第一篇中爲elk加入beats同樣 , 只須要編輯logstash的配置文件就能夠了json

修改logstash的輸入輸出配置

爲了不你已經手動修改了配置文件 , 咱們再也不使用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

測試elk + redis

任何語言的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卻輸入的字符串 , 纔會輸出的全是錯誤

在kibana創建redis索引

來到 management 部分

一路下一步 ,建立完成

回到首頁(必定到確保左上角是redis... 若是不是就點名字旁邊的按鈕來切換到redis) ,而後打開自動刷新 , 數據就會源源不斷的渲染到頁面上了

而且咱們發現 , 左側是篩選條件和右側的數據都多了不少字段 , 這就是修改配置文件時 ,加入的filter段的功勞

大功告成

相關文章
相關標籤/搜索