基於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
1 服務安裝與運行
安裝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
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 }
}
3、客戶端啓動nginx,filebeat 收集日誌,服務端啓動logstash,發送並展示日誌信息
啓動nginx(之前修改過nginx,需要重啓後再啓動)
curl localhost:80
啓動成功後查看日誌文件中是否收集到日誌
[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"}
客戶端啓動 filebeat
./filebeat -e -c filebeat.yml -d "publish"
服務端啓動logstash
/opt/logstash/bin/logstash -f /opt/conf/logstash.conf --config.reload.automatic
查看kibana,確認ES是否收集到
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;
# }
#}
}
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
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 }
}
服務端logstash啓動:
/opt/logstash/bin/logstash -f /opt/conf/logstash.conf --config.reload.automatic
客戶端filebeat啓動:
./filebeat -e -c filebeat.yml -d "publish"
logstash收集並打印出日誌:
kibana顯示:
=======================================================================================================
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文件了。
=======================================================================================================
=======================================================================================================
=======================================================================================================