通常咱們須要進行日誌分析場景:直接在日誌文件中 grep、awk 就能夠得到本身想要的信息。但在規模較大的場景中,此方法效率低下,面臨問題包括日誌量太大如何歸檔、文本搜索太慢怎麼辦、如何多維度查詢。須要集中化的日誌管理,全部服務器上的日誌收集彙總。常看法決思路是創建集中式日誌收集系統,將全部節點上的日誌統一收集,管理,訪問。java
通常大型系統是一個分佈式部署的架構,不一樣的服務模塊部署在不一樣的服務器上,問題出現時,大部分狀況須要根據問題暴露的關鍵信息,定位到具體的服務器和服務模塊,構建一套集中式日誌系統,能夠提升定位問題的效率。linux
一個完整的集中式日誌系統,須要包含如下幾個主要特色:
收集-可以採集多種來源的日誌數據
傳輸-可以穩定的把日誌數據傳輸到中央系統
存儲-如何存儲日誌數據
分析-能夠支持 UI 分析
警告-可以提供錯誤報告,監控機制nginxELK提供了一整套解決方案,而且都是開源軟件,之間互相配合使用,完美銜接,高效的知足了不少場合的應用。目前主流的一種日誌系統。正則表達式
Logstash : 開源的服務器端數據處理管道,可以同時從多個來源採集數據,轉換數據,而後將數據存儲到數據庫中。redis
Elasticsearch:搜索,分析和存儲數據,分佈式數據庫。數據庫
Kibana:數據可視化。apache
Beats:輕量型採集器的平臺,從邊緣機器向Logstash和Elasticsearch發送數據。vim
Filebeat:輕量型日誌採集器。安全
Input:輸入,輸出數據能夠是Stdin,File,TCP,Redis,Syslog等
Filter:過濾,將日誌格式化。有豐富的過濾插件:Grok正則捕獲,Date時間處理,Json編碼解碼,Mutate數據修改等
Output:輸出,輸出目標能夠是Stdout,File,TCP,Redis,ES等
主機名 | IP | 備註 |
---|---|---|
elkstack | 192.168.200.70 | 內存3G |
連接:https://pan.baidu.com/s/1PTUOKy5MNXYIhSUkkbb-DA
提取碼:fa6n
cat /etc/redhat-release
uname -r
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
ls
tar xf jdk-8u60-linux-x64.tar.gz -C /usr/local/
mv /usr/local/jdk1.8.0_60 /usr/local/jdk
vim /etc/profile
tail -3 /etc/profile
export JAVA_HOME=/usr/local/jdk/
export PATH=$PATH:$JAVA_HOME/bin
export CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:$CLASSPATH
source /etc/profile
java -version
kibana主要用來展示數據,它自己不存儲數據
https://artifacts.elastic.co/downloads/kibana/kibana-6.2.3-linux-x86_64.tar.gz
useradd -s /sbin/nologin -M elk
ls
tar xf kibana-6.2.3-linux-x86_64.tar.gz -C /usr/local/
mv /usr/local/kibana-6.2.3-linux-x86_64 /usr/local/kibana
cat -n /usr/local/kibana/config/kibana.yml | sed -n '2p;7p;21p;39p;40p'
2 #server.port: 5601
7 #server.host: "localhost"
21 #elasticsearch.url: "http://localhost:9200"
39 #elasticsearch.username: "user"
40 #elasticsearch.password: "pass"
vim /usr/local/kibana/config/kibana.yml
cat -n /usr/local/kibana/config/kibana.yml | sed -n '2p;7p;21p;39p;40p'
2 server.port: 5601 #暫時就先修改這兩行
7 server.host: "0.0.0.0" #暫時就先修改這兩行
21 #elasticsearch.url: "http://localhost:9200"
39 #elasticsearch.username: "user"
40 #elasticsearch.password: "pass"
chown -R elk:elk /usr/local/kibana/
vim /usr/local/kibana/bin/start.sh
cat /usr/local/kibana/bin/start.sh
nohup /usr/local/kibana/bin/kibana >> /tmp/kibana.log 2>> /tmp/kibana.log &
chmod a+x /usr/local/kibana/bin/start.sh
su -s /bin/bash elk '/usr/local/kibana/bin/start.sh'
ps -ef | grep elk | grep -v grep
若是有防火牆須要開放tcp5601端口
cat /tmp/kibana.log | grep warning | head -5
這裏有個警告,意思是鏈接不上elasticsearch,忽略,由於咱們尚未裝它。
{"type":"log","@timestamp":"2019-01-03T14:12:30Z","tags":["warning","elasticsearch","admin"],"pid":1451,"message":"Unable to revive connection: http://localhost:9200/"}
{"type":"log","@timestamp":"2019-01-03T14:12:30Z","tags":["warning","elasticsearch","admin"],"pid":1451,"message":"No living connections"}
{"type":"log","@timestamp":"2019-01-03T14:12:32Z","tags":["warning","elasticsearch","admin"],"pid":1451,"message":"Unable to revive connection: http://localhost:9200/"}
{"type":"log","@timestamp":"2019-01-03T14:12:32Z","tags":["warning","elasticsearch","admin"],"pid":1451,"message":"No living connections"}
{"type":"log","@timestamp":"2019-01-03T14:12:35Z","tags":["warning","elasticsearch","admin"],"pid":1451,"message":"Unable to revive connection: http://localhost:9200/"}
因爲kibana沒有權限控制,能夠藉助nginx來部署認證和進行ip控制
vim /usr/local/kibana/config/kibana.yml
sed -n '7p' /usr/local/kibana/config/kibana.yml
ps -ef | grep elk
kill -9 1451
ps -ef | grep elk
su -s /bin/bash elk '/usr/local/kibana/bin/start.sh'
ps -ef | grep elk | grep -v grep
yum -y install pcre-devel openssl-devel
tar xf nginx-1.10.2.tar.gz -C /usr/src/
cd /usr/src/nginx-1.10.2/
useradd -s /sbin/nologin -M nginx
./configure --user=nginx --group=nginx --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module
make && make install
ln -s /usr/local/nginx/sbin/* /usr/local/sbin/
nginx -V
cd /usr/local/nginx/
cp conf/nginx.conf{,.bak}
egrep -v "#|^$" conf/nginx.conf.bak > conf/nginx.conf
vim conf/nginx.conf
cat conf/nginx.conf
worker_processes 1;
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"';
sendfile on;
keepalive_timeout 65;
server {
listen 5609;
access_log /usr/local/nginx/logs/kibana_access.log main;
error_log /usr/local/nginx/logs/kibana_error.log error;
location / {
allow 192.168.200.1;
deny all;
proxy_pass http://127.0.0.1:5601;
}
}
}
nginx -t
nginx
netstat -antup | grep nginx
location / {
auth_basic "elk auth";
auth_basic_user_file /usr/local/nginx/conf/htpasswd;
proxy_pass http://127.0.0.1:5601;
}
elasticsearch未安裝以前,kibana網頁上報錯,提示找不到elasticsearch。
elastic search主要用來存儲數據,供kibana調取並進行展示
https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.2.3.tar.gz
ls
tar xf elasticsearch-6.2.3.tar.gz -C /usr/local/
mv /usr/local/elasticsearch-6.2.3 /usr/local/elasticsearch
cp /usr/local/elasticsearch/config/elasticsearch.yml{,.bak}
cat -n /usr/local/elasticsearch/config/elasticsearch.yml | sed -n '33p;37p;55p;59p'
33 #path.data: /path/to/data
37 #path.logs: /path/to/logs
55 #network.host: 192.168.0.1
59 #http.port: 9200
vim /usr/local/elasticsearch/config/elasticsearch.yml
cat -n /usr/local/elasticsearch/config/elasticsearch.yml | sed -n '33p;37p;55p;59p'
33 path.data: /usr/local/elasticsearch/data
37 path.logs: /usr/local/elasticsearch/logs
55 network.host: 127.0.0.1
59 http.port: 9200
chown -R elk:elk /usr/local/elasticsearch
由於咱們實驗環境是虛擬機,1g內存一下子就會被跑滿,就會很慢。因此,咱們要調整內存佔用的限制。
cat -n /usr/local/elasticsearch/config/jvm.options | sed -n '22p;23p'
22 -Xms1g
23 -Xmx1g
vim /usr/local/elasticsearch/config/jvm.options --->這裏沒作修改
cat -n /usr/local/elasticsearch/config/jvm.options | sed -n '22p;23p'
22 -Xms100M
23 -Xmx100M
vim /usr/local/elasticsearch/bin/start.sh
cat /usr/local/elasticsearch/bin/start.sh
/usr/local/elasticsearch/bin/elasticsearch -d >> /tmp/elasticsearch.log 2>> /tmp/elasticsearch.log
chmod a+x /usr/local/elasticsearch/bin/start.sh
su -s /bin/bash elk '/usr/local/elasticsearch/bin/start.sh'
ps -ef | grep elk | grep -v grep
> /tmp/kibana.log
tail -f /tmp/kibana.log
從新刷新url:http://192.168.200.70:5609
觀察日誌,看看還有沒有報錯。
假如elasticsearch若是監聽在非127.0.0.1,那麼須要修改內核參數等,在這裏就很少說了。
用來讀取日誌,正則分析日誌,發送給elasticsearch數據庫
https://artifacts.elastic.co/downloads/logstash/logstash-6.2.3.tar.gz
ls
tar xf logstash-6.2.3.tar.gz -C /usr/local/
mv /usr/local/logstash-6.2.3 /usr/local/logstash
cat -n /usr/local/logstash/config/jvm.options | sed -n '6p;7p;'
6 -Xms1g
7 -Xmx1g
cat -n /usr/local/logstash/config/jvm.options | sed -n '6p;7p;'
6 -Xms150M
7 -Xmx150M
vim /usr/local/logstash/config/logstash.conf
cat /usr/local/logstash/config/logstash.conf
input {
file {
path => "/usr/local/nginx/logs/kibana_access.log" #讀取日誌路徑
}
}
output {
elasticsearch {
hosts => ["http://127.0.0.1:9200"] #保存日誌url
}
}
vim /usr/local/logstash/bin/start.sh
cat /usr/local/logstash/bin/start.sh
nohup /usr/local/logstash/bin/logstash -f /usr/local/logstash/config/logstash.conf >> /tmp/logstash.log 2>> /tmp/logstash.log &
chmod a+x /usr/local/logstash/bin/start.sh
logstash並無監聽端口,所以不須要用elk用戶來啓動
/usr/local/logstash/bin/start.sh
ps -ef | grep logstash
logstash啓動的比較慢,須要多等一下子。
若是在kibana的Discover裏能看到添加索引就說明logstash啓動好了
圖片說明
進行數據展示字段的篩選
對nginx的kibana_access.log進行數據追蹤,對比分析
tail -f /usr/local/nginx/logs/kibana_access.log
ps -ef | grep logstash
kill -9 17120
/usr/local/logstash/bin/logstash -e ""
welcome --->輸入的內容
{
"@version" => "1",
"@timestamp" => 2018-08-16T13:18:13.383Z,
"message" => "welcome",
"type" => "stdin",
"host" => "elkstack"
}
能夠看到logstash結尾自動添加了幾個字段,時間戳@timestamp,版本@version,輸入的類型type,以及主機名host
Logstash使用管道方式進行日誌的蒐集處理和輸出。有點相似於管道命令xxx|ccc|ddd,xxx執行完了會執行ccc,而後執行ddd。
在logstash中,包括了三個階段:
輸入input ---> 處理filter(不是必須的) ---> 輸出output
每一個階段都有不少的插件配合工做,好比file,elasticsearch,redis等
每一個階段也能夠指定多種方式,好比輸出既能夠輸出到elasticsearch中,也能夠指定到stdout在控制檯打印。
因爲這種插件式的組織方式,使得logstash變得易於擴展和定製
-f:經過這個命令能夠指定Logstash的配置文件,根據配置文件配置logstash
-e:後面跟着字符串,該字符串能夠被看成logstash的配置(若是是""則默認使用stdin做爲默認輸入,stdout做爲默認輸出)
-l:日誌輸出的地址(默認就是stdout直接在控制檯中輸出)
-t:測試配置文件是否正確,而後退出。
前面介紹過logstash基本上由三部分組成,input,output以及用戶須要才添加的filter,所以標準的配置文件格式以下:
input {...}
filter {...}
output {...}
在每一個部分中,也能夠指定多個訪問方式,例如我想要指定兩個日誌來源文件,則能夠這樣寫:
input {
file { path => "/var/log/messages" type => "syslog" }
file { path => "/var/log/apache/access.log" type => "apache" }
}
相似的,若是在filter中添加了多種處理規則,則按照它的順序----處理,可是有一些插件並非線程安全的。
好比在filter中指定了兩個同樣的插件,這兩個任務並不能保證準確的按順序執行,所以官方也推薦避免在filter中重複使用插件。
咱們更改一下logstash的配置文件進行正則抓取數據的測試。
cd /usr/local/logstash/config/
vim logstash.conf
cat logstash.conf
input {
stdin{} #從標準輸入讀取數據
}
filter {
grok {
match => {
"message" => '(?<字段名>正則表達式).*'
}
}
}
output {
elasticsearch { #若是要輸入到elasticsearch裏,那麼須要註釋掉stdout{}
hosts => ["http://127.0.0.1:9200"]
}
stdout { #只將信息輸出到屏幕上
codec => rubydebug #用於正則提取測試,將正則抓取結果輸出到屏幕上
}
}
ps -ef | grep logstash --->查詢PID號
kill -9 PID號
/usr/local/logstash/bin/logstash -f /usr/local/logstash/config/logstash.conf
Aug 16 18:29:49 ELK systemd: Startup finished in 789ms (kernel) + 1.465s (initrd) + 18.959s (userspace) = 21.214s.
vim /usr/local/logstash/config/logstash.conf
cat /usr/local/logstash/config/logstash.conf
input {
stdin{}
}
filter {
grok {
match => {
"message" => '(?<mydate>[a-zA-Z]+ [0-9]+ [0-9:]+) (?<hostname>[a-zA-Z]+).*'
}
}
}
output {
elasticsearch {
hosts => ["http://127.0.0.1:9200"]
}
stdout {
codec => rubydebug
}
}
/usr/local/logstash/bin/logstash -f /usr/local/logstash/config/logstash.conf
Aug 16 18:29:49 ELK systemd: Startup finished in 789ms (kernel) + 1.465s (initrd) + 18.959s (userspace) = 21.214s.
{
"hostname" => "ELK", #這就是抓取的字段
"mydate" => "Aug 16 18:29:49", #這就是抓取的字段
"@timestamp" => 2018-08-16T12:47:46.904Z,
"message" => "Aug 16 18:29:49 ELK systemd: Startup finished in 789ms (kernel) + 1.465s (initrd) + 18.959s (userspace) = 21.214s.",
"host" => "elkstack",
"@version" => "1"
}
請經過配置文件進行反覆測試驗證,熟悉logstash正則表達的使用方法
vim /usr/local/logstash/config/logstash.conf
cat /usr/local/logstash/config/logstash.conf
input {
stdin{}
}
filter {
grok {
match => {
"message" => '(?<mydate>[a-zA-Z]+ [0-9]+ [0-9:]+) (?<hostname>[a-zA-Z]+).*'
}
}
}
output {
elasticsearch {
hosts => ["http://127.0.0.1:9200"]
}
# stdout {
# codec => rubydebug
# }
}
/usr/local/logstash/bin/logstash -f /usr/local/logstash/config/logstash.conf
Aug 16 18:29:49 ELK systemd: Startup finished in 789ms (kernel) + 1.465s (initrd) + 18.959s (userspace) = 21.214s.
logstash若是直接把一整行日誌直接發送給elasticsearch,kibana顯示出來就沒有什麼意義,咱們須要提取本身想要的字段。假如說咱們想要提取響應碼,用戶訪問url,響應時間等,就得依靠正則來提取。
input { #日誌輸入來源函數
file {
path => "/usr/local/nginx/logs/kibana_access.log"
}
}
filter { #字段數據提取函數
grok {
match => {
"message" => '(?<字段名>正則表達式).*'
}
}
}
output { #數據輸出目的地函數
elasticsearch {
hosts => ["http://127.0.0.1:9200"]
}
}
vim /usr/local/logstash/config/logstash.conf
cat /usr/local/logstash/config/logstash.conf
input {
file {
path => "/usr/local/nginx/logs/kibana_access.log"
}
}
filter {
grok {
match => {
"message" => '(?<IP>[0-9.]+) .*'
}
}
}
output {
elasticsearch {
hosts => ["http://127.0.0.1:9200"]
}
}
/usr/local/logstash/bin/logstash -f /usr/local/logstash/config/logstash.conf
vim /usr/local/logstash/config/logstash.conf
cat /usr/local/logstash/config/logstash.conf
input {
file {
path => "/usr/local/nginx/logs/kibana_access.log"
}
}
filter {
grok {
match => {
"message" => '(?<IP>[0-9.]+) .*HTTP/[0-9.]+"(?<mark>[0-9]+) (?<size>[0-9]+)[ "]+(?<url>[a-zA-Z]+://[0-9.]+:[0-9]+/[a-zA-Z/]+)".*'
}
}
}
output {
elasticsearch {
hosts => ["http://127.0.0.1:9200"]
}
}
/usr/local/logstash/bin/logstash -f /usr/local/logstash/config/logstash.conf