ELK:對於docker使用logstash收集nginx日誌到elasticsearch的步驟小結

基於CentOs7

“ELK”是三個開源項目的首字母縮寫,這三個項目分別是:Elasticsearch、Logstash 和 Kibana。Elasticsearch 是一個搜索和分析引擎。Logstash 是服務器端數據處理管道,能夠同時從多個來源採集數據,轉換數據,然後將數據發送到諸如 Elasticsearch 等“存儲庫”中。Kibana 則可以讓用戶在 Elasticsearch 中使用圖形和圖表對數據進行可視化。

Docker 是一個開源的應用容器引擎,讓開發者可以打包他們的應用以及依賴包到一個可移植的容器中,然後發佈到任何流行的 Linux 機器上,也可以實現虛擬化。

 

 

一、Centos安裝docker(https://docs.docker.com/install/linux/docker-ce/centos/)

移除舊的版本:

sudo yum remove docker \

                  docker-client \

                  docker-client-latest \

                  docker-common \

                  docker-latest \

                  docker-latest-logrotate \

                  docker-logrotate \

                  docker-selinux \

                  docker-engine-selinux \

                  docker-engine

安裝一些必要的系統工具:

sudo yum install -y yum-utils device-mapper-persistent-data lvm2

添加軟件源信息:

sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

更新 yum 緩存:

sudo yum makecache fast

安裝 Docker-ce:

sudo yum -y install docker-ce

啓動 Docker 後臺服務:

sudo systemctl start docker

測試運行 hello-world

docker run hello-world

二.​​​​​​  配置與驗證 (elasticsearch運行需要至少2G內存)

修改配置文件      vim /etc/sysctl.conf

      tips:如果報錯:vim: command not found    參照: https://www.jianshu.com/p/93fe144f5739

rpm -qa |grep vim

vim-minimal-7.0.109-6.el5

vim-common-7.0.109-7.2.el5

vim-enhanced-7.0.109-7.2.el5

#如果上面三條少了其中的某一條,就直接安裝所有包

yum -y install vim*

添加或者修改      vm.max_map_count = 262144

使生效                 sysctl -p

服務安裝與運行

安裝ELK有很多種方式,比如源碼、rpm包,或docker;不過docker又分爲了單個安裝與ELK打包安裝,我們通過docker打包安裝,因爲這樣的方式相比來說最爲簡單,因爲只需要下載鏡像,然後運行起來就可以了

2.  鏡像下載獲取獲取

設置好加速地址之後,就可以開始拉取ELK鏡像,參考命令如下:

docker pull sebp/elk

下載鏡像之後可以使用docker的命令來驗證是否成功,參考命令如下:

docker images

執行後docker返回結果如下

REPOSITORY       TAG       IMAGE ID         CREATED        SIZE
sebp/elk          latest   99e6d3f782ad       2 months ago     2.06GB
hello-world       latest   fce289e99eb9       11 months ago     1.84kB


#在結果當中可以看出,ELK鏡像已經下載下來,佔用了將近2GB空間

3.  容器運行

運行此容器的時候,需要將宿主機的端口轉發到該容器,其中ES端口爲9200,kibana端口爲5601,logbate端口爲5044;

由於 docker 鏡像是隻讀的,而容器又是隨時創建刪除,所以建議將配置文件和數據存放在宿主機,便於後期維護,因此還需要將宿主機目錄掛載到容器當中。

先在宿主機創建掛載目錄

cd /opt
mkdir elk-data
cd elk-data
mkdir conf
mkdir elasticsearch-data
mkdir logs

# 編輯nginx配置文件
vim /usr/local/nginx/conf/nginx.conf

1) 配置 nginx 

下面是 nginx.conf 的配置內容:

#user  root;
worker_processes  1;

#pid        logs/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    # 對日誌格式化成json
    log_format json '{"@timestamp":"$time_iso8601",'
                    '"@version":1,'
                    '"host":"$server_addr",'
                    '"client":"$remote_addr",'
                    '"size":$body_bytes_sent,'
                    '"responsetime":$request_time,'
                    '"domain":"$host",'
                    '"url":"$uri",'
                    '"status":"$status"}';

    # 用於記錄誰在什麼時候做了什麼
    access_log /opt/elk-data/logs/access.log  json;

    server {
        listen       0.0.0.0:80;
        server_name  localhost;

        #charset koi8-r;
        #access_log  logs/host.access.log  main;

        location / {
            modsecurity on;
            modsecurity_rules_file  /usr/local/nginx/conf/modsecurity_includes.conf;
            root   html;
            index  index.html index.htm;
            # proxy_pass http://127.0.0.1:8000
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

測試 nginx  文件配置的正確性

/usr/local/nginx/sbin/nginx -t 

出現下面這兩行代碼說明正確
Password:
nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok
nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful

tips:    可以使用  ps aux|grep nginx   命令來查看nginx配置路徑

 

2) logstash配置

logstash配置主要有三個地方要處理,首先是輸入源在什麼位置,然後是對數據進行過濾或者格式化,最後是需要將數據輸出到什麼地方;在下方的配置只做了其中兩項,編輯配置文件命令參考如下:

修改宿主機剛纔掛載的目錄,在目錄下創建conf目錄,建立test.conf文件

 vim /opt/elk-data/conf/test.conf

下面是 test.conf 的配置內容:

input {
    file {
        path => "/opt/logs/access.log"  # 填寫容器內部log文件路徑
        codec => "json"
    }
}
output {
    elasticsearch { 
        hosts => ["127.0.0.1:9200"] 
    }
    stdout { 
        codec => rubydebug 
    }
}

3) 進入容器,啓動logstash

前面已經將日誌格式與logstash配置好,現在需要啓動logstash開始收集日誌,logstash掛載到容器內,需要先啓動容器

docker run -p 5601:5601 -p 9200:9200 -p 5044:5044 -v /opt/elk-data/conf:/opt/conf  -v /opt/elk-data/logs:/opt/logs  -v /opt/elk-data/elasticsearch-data:/var/lib/elasticsearch  -it -d --name elk sebp/elk
# 開啓三個端口傳遞信息,掛載主機的三個路徑下的所有文件,給容器重命名爲elk,鏡像爲sebp/elk

啓動logstash之前需要先進入容器裏面,進入容器參考命令如下:

docker exec -it elk /bin/bash

刪除02-beats-input.conf 關於ssl的三行設置,否則客戶端需要另外配置證書相關配置項(每次重新創建容器都需要刪除這三行設置

vim /etc/logstash/conf.d/02-beats-input.con

需要關閉自動開啓的 logstash,檢查logstash,elasticsearch狀態,保持elasticsearch開啓,logstash關閉

service logstash stop

進入容器之後,需要啓動logstash來收集數據,啓動的時候需要帶兩個參數進去,第一個是logstash的數據暫存位置,第二個是使用的配置文件,因此構造的命令如下所示:

 /opt/logstash/bin/logstash -f /opt/conf/test.conf --config.reload.automatic 
                                                 #(如果配置文件有改動會自動加載)

複製會話,另起一個窗口請求nginx:

curl localhost:80

三、繪圖配置與展示

當數據導入之後,纔可以使用kibana的圖形化來查看數據了,所以首先確認一下ES中是否有數據,確認有數據後就可以進行繪圖配置,配置完成之後就可以進行篩選日誌等操作了。

1.ES數據檢查

當數據添加到ES服務器當中後,可以通過ES服務提供的URL來查看其中的數據,URL地址如下所示:

http://localhost:9200/_search?pretty

就會看到剛剛產生的日誌內容,當看到total數量變大,並在下面的數據項中看到了nginx日誌信息時,則代表導入數據成功了。

2.kibana索引配置

通過瀏覽器訪問kibana,URL地址如下

http://127.0.0.1:5601/app/kibana#/management/kibana/index?_g=()

點擊左側導航欄的Discover鏈接,便可進入創建索引模式界面,可以選擇索引查看相對應索引的數據

點擊左側導航欄的Management鏈接,點擊頁面Index Pattern鏈接,點擊右上方Create index pattern,方框裏面輸入你創建的索引名字,點擊Next step便創建kibana的索引完成,此時再次點擊左側導航欄的Discover鏈接,便可以看到剛纔創建索引的一些視圖,數據。

在圖中有一個input輸入框,可以在裏面填寫篩選所需要的關鍵詞;如果沒有篩選出結果,也可檢查左側的時間篩選項是否設置正確,默認顯示最近十五分鐘產生的數據 。

此處有對應的數據,說明收集成功。

四.filebeat客戶端配置

filebeat 是用來轉發和集中日誌數據的輕量級服務。能監視指定的日誌文件和位置。收集日誌文件,並將它們轉發到logstash或elasticsearch。

另裝一個虛擬機作爲客戶端,上面的docker,logstash作爲服務器。

部署流程:

1、192.168.194.5(客戶端配置)

filebeat文件配置:filebeat.yml

filebeat.inputs:
- type: log
  enabled: true
  paths:
      - /usr/local/nginx/logs/access.log  # 指定需要收集的日誌文件的路徑
  fields:
      indexname: nginx-access

fields:
  host_ip: 192.168.194.5    #發送本機出口ip,便於服務器端方便篩選

output.logstash:
   hosts: ["192.168.194.6:5044"]   #指定日誌服務器的ip:port

 nginx文件配置(部分配置:json格式化,log存儲路徑):nginx.conf

    log_format json '{"@timestamp":"$time_iso8601",'
                    '"@version":1,'
                    '"host":"$server_addr",'
                    '"client":"$remote_addr",'
                    '"size":$body_bytes_sent,'
                    '"responsetime":$request_time,'
                    '"domain":"$host",'
                    '"url":"$uri",'
                    '"status":"$status"}';

    access_log /usr/local/nginx/logs/access.log  json;

nginx改了配置需要重啓下:

 
/usr/local/nginx/sbin/nginx -s reload
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

2、192.168.194.6(服務器端配置)

 logstash文件配置:

input {
  beats {
    port => 5044         # 設置專用端口用於接收各個來源的日誌
  }
}
output {
    elasticsearch {
        index => "log_%{+YYYY.MM.dd}"
        hosts => ["127.0.0.1:9200"]     # 發送到本機的elasticsearch上
    }
    stdout { codec => rubydebug }
}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

3、客戶端啓動nginx,filebeat 收集日誌,服務端啓動logstash,發送並展示日誌信息

啓動nginx(之前修改過nginx,需要重啓後再啓動)

curl localhost:80
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

啓動成功後查看日誌文件中是否收集到日誌

[root@localhost filebeat-7.4.0-linux-x86_64]# cat /usr/local/nginx/logs/access.log
{"@timestamp":"2019-12-26T09:22:51+08:00","@version":1,"host":"127.0.0.1","client":"127.0.0.1","size":612,"responsetime":0.000,"domain":"localhost","url":"/index.html","status":"200"}

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

客戶端啓動 filebeat

./filebeat -e -c filebeat.yml -d "publish"
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

服務端啓動logstash

/opt/logstash/bin/logstash -f /opt/conf/logstash.conf --config.reload.automatic
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

查看kibana,確認ES是否收集到

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

4、filebeat 日誌分類,logstash過濾

nginx.conf配置

user  nobody;
worker_processes  1;

error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    log_format json '{"@timestamp":"$time_iso8601",'
                    '"@version":1,'
                    '"host":"$server_addr",'
                    '"client":"$remote_addr",'
                    '"size":$body_bytes_sent,'
                    '"responsetime":$request_time,'
                    '"domain":"$host",'
                    '"url":"$uri",'
                    '"status":"$status"}';

    access_log /usr/local/nginx/logs/access.log  json;
    error_log  /usr/local/nginx/logs/error.log;

    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

filebeat.yml配置:

filebeat.inputs:
- type: log
  enabled: true
  paths:
      - /usr/local/nginx/logs/access.log  # 指定需要收集的日誌文件的路徑
  fields:
      indexname: nginx-access

- type: log
  enabled: true
  paths:
      - /usr/local/nginx/logs/error.log  # 指定需要收集的日誌文件的路徑
  fields:
      indexname: nginx-error

- type: log
  enabled: true
  paths:
      - /var/log/jsac.agentjsac.info.log  # 指定需要收集的日誌文件的路徑
  fields:
      indexname: jsac-agentjsac-info

- type: log
  enabled: true
  paths:
      - /var/log/jsac.agentjsac.error.log  # 指定需要收集的日誌文件的路徑
  fields:
      indexname: jsac-agentjsac-error

- type: log
  enabled: true
  paths:
      - /var/log/jsac.agentjsac.debug.log  # 指定需要收集的日誌文件的路徑
  fields:
      indexname: jsac-agentjsac-debug

- type: log
  enabled: true
  paths:
      - /var/log/jsac.agentjsac.warn.log  # 指定需要收集的日誌文件的路徑
  fields:
      indexname: jsac-agentjsac-warn

- type: log
  enabled: true
  paths:
      - /var/log/jsac.driver-install.log  # 指定需要收集的日誌文件的路徑
  fields:
      indexname: jsac-driver-install

- type: log
  enabled: true
  paths:
      - /var/log/jsac.tsthostapi.debug.log  # 指定需要收集的日誌文件的路徑
  fields:
      indexname: jsac-tsthostapi.debug

- type: log
  enabled: true
  paths:
      - /var/log/jsac.tsthostapi.error.log  # 指定需要收集的日誌文件的路徑
  fields:
      indexname: jsac-tsthostapi.error

- type: log
  enabled: true
  paths:
      - /var/log/jsac.update.info.log  # 指定需要收集的日誌文件的路徑
  fields:
      indexname: jsac-update.info

fields:
  host_ip: 192.168.194.5    #發送本機出口ip,便於服務器端方便篩選

output.logstash:
   hosts: ["192.168.194.6:5044"]   #指定日誌服務器的ip:port
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

logstash.conf配置:

input {
  beats {
    port => 5044
  }
}

filter {
  mutate {
    rename => { "[host][name]" => "host" }
  }
  if [fields][indexname] == "nginx-error" {
      grok {
          match => {
                "message" => "%{DATESTAMP:datetime}\s+\[%{LOGLEVEL:loglevel}\]\s+%{GREEDYDATA:error_reason}"
          }
      }
  }
  else if [fields][indexname] == "nginx-access" {
      grok {
           match => { "message" => "%{NGINXACCESS}" }
      }
  }
  else if "agentjsac" in [fields][indexname]  {
      grok {
          match => { "message" => "%{DATESTAMP:datetime} %{LOGLEVEL:loglevel} %{GREEDYDATA:reason}" }
      }
  }
  else if "tsthostapi" in [fields][indexname]  {
      grok {
          match => { "message" => "%{GREEDYDATA:description}" }
      }
  }
  date {
      match =>  [ "timestamp", "YY/MM/dd HH:mm:ss","YYYY-MM-dd HH:mm:ss", "dd/MMM/YYYY:HH:mm:ss Z" ]
  }
  mutate {
      remove_field => ["host", "tags", "@version", "type"]
  }
}

output {
    elasticsearch {
        action => "index"
        index => "log_%{+YYYY.MM.dd}"
        hosts => ["127.0.0.1:9200"]
    }
    stdout { codec => rubydebug }
}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

服務端logstash啓動:

/opt/logstash/bin/logstash -f /opt/conf/logstash.conf --config.reload.automatic
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

客戶端filebeat啓動:

./filebeat -e -c filebeat.yml -d "publish"
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

logstash收集並打印出日誌:

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

kibana顯示:

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

 

 

 

 

 

 

 

 

 

 

 

 

=======================================================================================================

nginx的error.log日誌常見的幾個錯誤解決方法

參照:https://blog.51cto.com/chenx1242/1769724

error.log:

[emerg] 20952#0: unexpected "}" in /usr/local/nginx/conf/nginx.conf:87
# 這句話就說明在nginx.conf的87行裏有一個 } 是錯誤的,檢查一下}是不是多餘了,或者;少了,這個錯誤的級別是emergency;


[emerg] 21023#0: "root" directive is duplicate in /usr/local/nginx/conf/nginx.conf:86
# 這句話就是說明在nginx.conf的第86行裏root設定重複了,級別同樣是emergency。以上兩個都是書寫的問題,很好糾正;


[notice] 21045#0: signal process started
# 這個意思是nginx已經在運行的狀態下,被執行啓動,這個不算致命錯誤;

 

nginx: [alert] could not open error log file: open()"/usr/local/nginx/logs/error.log" failed (13:Permissiondenied)
# 這個是說當前用戶沒有權限寫入error.log的日誌,解決方法要來權限就行了;

 

nginx: [error] open() "/usr/local/nginx/logs/nginx.pid" failed (2: No such file or directory)
# nginx提示無法找到nginx.pid這個文件了
#使用#/usr/local/nginx/sbin/nginx -c  /usr/local/nginx/conf/nginx.conf,重新啓動一下,就自動生成pid文件了。

=======================================================================================================

 

 

=======================================================================================================

 

=======================================================================================================

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章