利用docker syslog pipeline 來分析nginx log
概念
在nginx 的contain 設定將logging 導入syslog
另建立elk-docker 來接收分析
很簡單但可以作到視覺化的分析。
設定步驟:
1. 在nginx 的docker file
設定
a.要把access log 導入/dev/stdout
nginx docker file
RUN ln -sf /dev/stdout /var/log/nginx/access.log
2.
在docker-compose.yaml 設定logging driver syslog
nginx:
image: nginx:latest
links:
- nginx
ports:
- 443:443
- 80:80
logging:
driver: syslog
options:
syslog-address: "udp://syslogserver_ip:5000"
restart: always
syslogserver_ip 我們要設定接收的logstash port (TCP UDP 都可以但要注意要跟以下logstash 一致)
另外我們使用 elk docker
https://github.com/deviantony/docker-elk.git
目前最新版是elk 6.4.0
修改logstash/pipeline/logstash.conf
以下的修改須配合nginx 的
先確認我們nginx access log mode
log_format main $remote_addr - - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for" $request_time $upstream_response_time;
resolver 127.0.0.11 ipv6=off;
logstash.conf
這是這裡最主要的設定檔在這裡我們要對應nginx 的access_log 並且對資料做一些簡單的轉換
與切割。
input {
udp {
port => 5000
}
}
## Add your filters / logstash plugins configuration here
filter {
grok {
match => {
type => nginx_access
"message" => "%{DATA:c1} %{DATA:c2} %{DATA:c3} %{DATA:c4} %{IPORHOST:remote_addr} - %{USERNAME:remote_user} - \[%{HTTPDATE:time_local}\] \"%{DATA:request}\" %{INT:status} %{NUMBER:bytes_sent} \"%{DATA:http_referer}\" \"%{DATA:http_user_agent}\" %{NUMBER:reqtime:float} %{NUMBER:ups_restime:float}"
}
}
mutate {
#這裡可以移除一些我們不要的資料欄位
remove_field => ["c1","c2","c3","c4"]
copy => { "time_local" => "ATS" }
copy => { "request" => "logreq" }
# remove_field => ["message","port","type"]
}
mutate {
gsub => [
"logreq", "GET ", ""
]
}
mutate {
gsub => [
"logreq", "POST ", ""
]
}
mutate {
gsub => [
"logreq", " HTTP/1.1", ""
]
}
mutate {
convert => {
"reqtime" => "float"
}
}
mutate {
convert => {
"ups_restime" => "float"
}
}
#這裡會呼叫geoip plugin 之後會看到多出好幾個欄位
geoip {
source => "remote_addr" #指定哪个字段过滤成物理地址肯定是来源IP啊
}
#這裡我把時間複製到ATS 欄位,這是考慮這個LOG 時間。一般kibana 在分析時是預設使用
#塞入時間作為主要時間欄位,但這樣如果我日後要補塞log 會讓時間不正確。
#所以可以讓ATS 作為主要時間欄位,這設定在kibana 要create index-pattern 會問
#
date {
match => [ "ATS", "dd/MMM/yyyy:HH:mm:ss Z" ]
target => "ATS"
timezone => "Asia/Hong_Kong"
}
}
output {
stdout { codec => rubydebug }
elasticsearch {
hosts => "elasticsearch:9200"
}
}
就OK了
要注意一下elk 的docker-compose bind 的port
docker-compose.yaml
logstash
..
ports:
- "5000:5000/udp"
這裡要改成udp 要與 logstah.conf 一致