利用ELK構建一個小型的日誌收集平臺

利用ELK構建一個小型日誌收集平臺java

伴隨着應用以及集羣的擴展,查看日誌的方式老是不方便,咱們但願能夠有一個便於咱們查詢及提醒功能的平臺;那麼首先須要剖析有幾步呢?mysql

格式定義 --> 日誌收集 --> 運輸 --> 存入 --> 查詢linux

根據上面這幾步,咱們簡單來設計一個收集平臺,以下圖:nginx

這裏咱們使用了Elastic Stack家族的Filebeat用做客戶端收集,Kibana做爲數據展現,Elasticsearch(後面簡稱ES)來存儲日誌,Logstash做爲一箇中轉站幫助咱們運輸日誌;同時咱們還們還加入日誌隊列(這裏使用Redis來擔任)。redis

Filebeat以及Logstash自身帶有隊列功能,可是這裏放置Redis能夠作到解耦的功能,固然你也能夠選擇使用kafka這樣的;至於Redis這邊能夠採用LB的模式來預防單點問題;sql

LogAlert是咱們開發的專用於日誌報警的工具,具體內容咱們後面介紹。shell

總體軟件環境說明:Filebeat、Kibana、Logstash、es均採用官方6.5.4的版本,請注意版本。json

一、肯定採集項目

咱們簡單梳理下采集項目以下:api

  • 系統日誌 (Elastic Stack 有現成的模板)
    • Message
    • 審計日誌
    • 安全日誌
  • 開源組件 (絕大多數 Elastic Stack 有現成的模板)
    • Nginx: 負載均衡,Web服務器;主要收集HTTP訪問狀況;
    • Redis: 緩存組件;
    • MySQL: 主要收集慢查詢日誌和常規日誌;
    • .... 等等
  • Java應用 (好比自研發應用)
    • 常規日誌
    • 業務日誌

很是重要,必定要提早溝通規範日誌格式,否則後期在進行改動推進很是的難,最後日誌誰用就讓誰定義格式;同時也要安利一波日誌平臺的好處,要否則怎麼忽悠別人用呢,哈哈。緩存

二、環境準備說明

這裏呢,我將演示系統日誌、Nginx日誌、Redis日誌、以及一個Java應用;採用系統爲CentOS 7系統,若是未說明版本則不會影響咱們的使用。

這裏相關組件如Nginx、Redis咱們採用最簡單的Yum安裝,別的需求能夠本身定義。

三、採集節點日誌(System,Nginx,Redis)

採集日誌咱們經過filebeat來搞,Filebeat比Logstash的一大優勢是輕量級別,節省資源尤爲是在雲上咱們不少狀況下都是2核4G或者4核8G這樣的機器,因此Filebeat做爲客戶端日誌採集好處,balabala..... 我就不囉嗦了。(安裝包請自行官網下載)

安裝:

rpm -ivh filebeat-6.5.4-x86_64.rpm

打開Module的支持:

Module是Filebeat預配置的日誌收集,其原理也很是的簡單,經過Input進行收集,而後經過es pipeline進行解析日誌。

filebeat modules enable auditd nginx redis system

調整配置配置文件:

shell> cat /etc/filebeat/filebeat.yml
        filebeat.inputs:
        
        filebeat.config.modules:
          path: ${path.config}/modules.d/*.yml
          reload.enabled: false
        
        setup.template.settings:
          index.number_of_shards: 3
        
        setup.kibana:
          host: "localhost:5601"
        
        output.redis:
          hosts: ["localhost:6379"]
          password: "123456"
          key: "logs"
          db: 0
          timeout: 5
        
        processors:
          - add_host_metadata: ~

這裏的配置說明是,配置redis的地址,以及KibanaAPI的地址;redis的配置咱們須要簡單調整下,調整以下:

shell> cat /etc/filebeat/modules.d/redis.yml 
- module: redis
  # Main logs
  log:
    enabled: true

    # Set custom paths for the log files. If left empty,
    # Filebeat will choose the paths depending on your OS.
    var.paths: ["/var/log/redis/redis.log*"]

  # Slow logs, retrieved via the Redis API (SLOWLOG)
  slowlog:
    enabled: false

    # The Redis hosts to connect to.
    #var.hosts: ["localhost:6379"]

    # Optional, the password to use when connecting to Redis.
    #var.password:

能夠看到,咱們調整了Redis日誌的路徑,同時關閉了slowlog日誌功能,當前版本仍是測試,有興趣的小夥伴能夠研究一下,我這裏就暫不使用。

啓動服務:

shell> systemctl enable filebeat
shell> systemctl start filebeat

咱們檢查下Redis是否有日誌存在

127.0.0.1:6379> LLEN logs
(integer) 5559

Ok, 至此咱們經過Filebeat的Module快速收集了日誌,接下來咱們搞一個存儲和Kibana了。

四、ES+Kibana部署

常規安裝走一波:

首先咱們須要看裝JDK1.8的版本

shell> rpm -ivh jdk-8u191-linux-x64.rpm

安裝部署ES

shell> rpm -ivh elasticsearch-6.5.4.rpm 
shell> systemctl daemon-reload
shell> systemctl enable elasticsearch.service
shell> systemctl start elasticsearch.service

安裝插件ingest-user-agent, ingest-geoip

shell> /usr/share/elasticsearch/bin/elasticsearch-plugin install file:///usr/local/src/ingest-user-agent-6.5.4.zip 
shell> /usr/share/elasticsearch/bin/elasticsearch-plugin install file:///usr/local/src/ingest-geoip-6.5.4.zip 
shell> systemctl restart elasticsearch

安裝Kibana

shell> rpm -ivh kibana-6.5.4-x86_64.rpm 
shell> systemctl enable kibana
shell> systemctl start kibana

而後能夠Web查看一下,若是是其餘機器請調整監聽端口便可。

導入Filebeat模板與pipeline:

系統模板中,定義了很是多的字段屬性,同時pipeline中定義的解析日誌的規則;

導出默認的系統模板

shell> filebeat export template > filebeat.template.json
shell> sed -i 's@filebeat-6.5.4@sys-log@g' filebeat.template.json   # 修改匹配索引
shell> curl -H 'Content-Type: application/json' -XPUT 'http://localhost:9200/_template/sys-log' -d@filebeat.template.json

導入modules到ES的pipline(導入前咱們須要調整下,否則會有時區問題)

Nginx模塊:

​ 咱們修改配置模板文件:/usr/share/filebeat/module/nginx/error/ingest/pipeline.json

​ 原內容

"date": {
                      "field": "nginx.error.time",
                      "target_field": "@timestamp",
                      "formats": ["YYYY/MM/dd H:m:s"]
                    }

​ 修改後

"date": {
                      "field": "nginx.error.time",
                      "target_field": "@timestamp",
                      "formats": ["YYYY/MM/dd H:m:s"],
                      "timezone" : "Asia/Shanghai"
                   }

Redis模塊:

​ 咱們修改配置模板文件:/usr/share/filebeat/module/redis/log/ingest/pipeline.json

​ 原內容

"date": {
                        "field": "redis.log.timestamp",
                        "target_field": "@timestamp",
                        "formats": ["dd MMM H:m:s.SSS", "dd MMM H:m:s", "UNIX"],
                        "ignore_failure": true
                     }

​ 修改後

"date": {
                        "field": "redis.log.timestamp",
                        "target_field": "@timestamp",
                        "formats": ["dd MMM H:m:s.SSS", "dd MMM H:m:s", "UNIX"],
                        "ignore_failure": true,
                        "timezone" : "Asia/Shanghai"
                      }

系統模塊:

​ 咱們編輯配置文件:/usr/share/filebeat/module/system/syslog/manifest.yml 打開時區的支持(Auth文件一樣:/usr/share/filebeat/module/system/auth/manifest.yml)

​ 原內容

- name: convert_timezone
            default: false

​ 修改後

- name: convert_timezone
            default: true

審計模塊:

​ 咱們修改配置模板文件:/usr/share/filebeat/module/auditd/log/ingest/pipeline.json

​ 原內容

"date": {
                        "field": "auditd.log.epoch",
                        "target_field": "@timestamp",
                        "formats": [
                            "UNIX"
                        ],
                        "ignore_failure": true
                    }

​ 修改後

"date": {
                        "field": "auditd.log.epoch",
                        "target_field": "@timestamp",
                        "formats": [
                            "UNIX"
                        ],
                        "ignore_failure": true,
                        "timezone" : "Asia/Shanghai"
                    }

導入到ES系統之中:

shell> filebeat setup --modules nginx,redis,system,auditd --pipelines -e -E 'output.elasticsearch.hosts=["localhost:9200"]'

這裏能夠經過ES API進行查詢是否寫入

es api> GET /_ingest/pipeline/

這裏會提示多個Out衝突,怎麼辦呢? 吧原先的Output註釋掉便可,不用重啓服務。

五、經過Logstash打通日誌

安裝

shell> rpm -ivh logstash-6.5.4.rpm

配置一個pip

shell> cat /etc/logstash/conf.d/sys-log.conf
        input {
          redis {
            host => "127.0.0.1"
            password => '123456'
            port => "6379"
            db => "0"
            data_type => "list"
            key => "logs"
          }
        }
        filter {
        }
        output {
          if [fileset][module] in ["system", "nginx", "redis", "mysql", "auditd"] {
            if [fileset][module] == "nginx" and [fileset][name] == "access" {
              elasticsearch {
                hosts => localhost
                index => "sys-log-%{+YYYY.MM.dd}"
                pipeline => "filebeat-6.5.4-%{[fileset][module]}-%{[fileset][name]}-default"
              }
            } else {
              elasticsearch {
                hosts => localhost
                index => "sys-log-%{+YYYY.MM.dd}"
                pipeline => "filebeat-6.5.4-%{[fileset][module]}-%{[fileset][name]}-pipeline"
              }
            }
          }
        }

啓動測試

shell> systemctl enable logstash
shell> systemctl start logstash

能夠經過Redis隊列狀態 或者 ES當前日誌信息進行查詢。

六、自定義收集項

Grok表達式:

\[%{DATA:svc}\] %{TIMESTAMP_ISO8601:time} %{LOGLEVEL:log.level} %{POSINT:process.pid} --- \[ *%{DATA:process.thread}\] %{DATA:process.class} *: %{GREEDYDATA:msg}

配置系統日誌索引模板:主要內容字段根據Grok表達式寫入模板文件,模板文件根據系統模板修改而成。

將模板導入ES系統之中:

shell> curl -H 'Content-Type: application/json' -XPUT 'http://localhost:9200/_template/svc-log' -d@svc.template.json

配置Filebeat抓取服務日誌:(增長Input內容以下)

- type: log
          paths:
            - /application/apps/*/server.log
          multiline.pattern: '^\['
          multiline.negate: true
          multiline.match: after
          fields:
            svc_type: java

具體配置信息,請了解官方信息。

配置Logstash解析格式

input {
        ...
        }
        filter {
          if [fields][svc_type] == "java" {
            grok {
              match => { "message" => "\[%{DATA:svc}\] %{TIMESTAMP_ISO8601:time} +%{LOGLEVEL:log.level} %{POSINT:process.pid} --- \[ *%{DATA:process.thread}\] %{DATA:process.class} *: %{GREEDYDATA:msg}" }
                remove_field => "message"
              }
            date {
              match => [ "time", "ISO8601", "yyyy-MM-dd HH:mm:ss.SSS" ]
              remove_field => "time"
            }
            mutate {
              add_field => { "read_timestamp" => "%{@timestamp}" }
            }
          }
        }
        output {
          if [fields][svc_type] == "java" {
            elasticsearch {
              hosts => localhost
              index => "svc-log-%{+YYYY.MM.dd}"
            }
          }
        }

至此,咱們簡單的日誌架構就已經完成了。

相關文章
相關標籤/搜索