ELK docker-compose 全家桶实现Nginx access log 可视化

  1. 1. ELK docker-compose 全家桶实现Nginx access log可视化

ELK docker-compose 全家桶实现Nginx access log可视化

Elasticsearch Logstash 和 Kibana 组成的log可视化工具链基本已经成为低成本服务的标配。
但是这三个东西繁杂的配置有时候还是会让人奔溃。

尝试寻找可用docker container来解决繁杂的配置问题是一种常用的偷懒思路。
今天从docker-elk这个全家桶开始尝试简单配置即用的log可视化构成。

clone下来之后看说明,其实已经差不多可用了。
修改一下logstash的config。使其能够对应nginx的log格式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
input {
tcp {
port => 5000
}
}

## Add your filters / logstash plugins configuration here
filter {
grok {
match => [ "message" , "%{COMBINEDAPACHELOG}+%{GREEDYDATA:extra_fields}"]
overwrite => [ "message" ]
}

mutate {
convert => ["response", "integer"]
convert => ["bytes", "integer"]
convert => ["responsetime", "float"]
}

geoip {
source => "clientip"
target => "geoip"
add_tag => [ "nginx-geoip" ]
}

date {
match => [ "timestamp" , "dd/MMM/YYYY:HH:mm:ss Z" ]
remove_field => [ "timestamp" ]
}

useragent {
source => "agent"
}
}

output {
elasticsearch {
hosts => "elasticsearch:9200"
}
}

好了已经差不多能跑了试一下。

1
2
3
$ sudo sysctl -w vm.max_map_count=262144
$ docker-compose up -d
nc localhost 5000 < /path/to/logfile.log

果然打开localhost:5601就可以用kibana看到各种统计数据和图表了。
但是默认的设置有个问题,就是无法实时对acess log 进行监控,我们每次都需要跑一下 nc localhost 5000 < /path/to/logfile.log 把log 喂给logstash。这样是很蛋疼的。我们希望logstash能够实时watch log文件然后随时更新数据。

思路很简单,我们可以把/var/log/nginx/access.log symlink到当前目录,然后把目录挂在到docker container中。

1
2
3
$ cd docker-elk
$ mkdir access_log
$ sudo ln -s /var/log/nginx/access.log ./access_log/access.log

修改logstash的config, 将input block 改成 file block。

1
2
3
4
5
6
7
input {
file {
path => "/access_log/access.log"
start_position => "beginning"
}
}
#以下省略

修改docker-compose.yml 将 ./access_log 挂到 /access_log

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#以上省略
logstash:
build: logstash/
command: -f /etc/logstash/conf.d/
volumes:
- ./logstash/config:/etc/logstash/conf.d
- ./access_log:/access_log
ports:
- "5000:5000"
networks:
- docker_elk
depends_on:
- elasticsearch

#以下省略

重新build一下开跑。

1
$docker-compose stop && docker-compose up -d

再此打开localhost:5601,发现特么什么狗屁都没有了。这个是为什么?
翻看docker-compose启动时候的console log,发现logstash说自己没有访问/access_log/access.log的权限。

我们执行docker exec -it dockerelk_logstash_1 /bin/bash 进入到container内部一探究竟。

1
2
3
4
5
6
7
8
root@7c7edc22ff14:/# ps aux |grep logstash
logstash 1 10.2 24.7 4197892 507684 ? Ssl 13:36 2:50 /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:+DisableExplicitGC -Djava.awt.headless=true -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError -Xmx1g -Xms256m -Xss2048k -Djffi.boot.library.path=/usr/share/logstash/vendor/jruby/lib/jni -Xbootclasspath/a:/usr/share/logstash/vendor/jruby/lib/jruby.jar -classpath : -Djruby.home=/usr/share/logstash/vendor/jruby -Djruby.lib=/usr/share/logstash/vendor/jruby/lib -Djruby.script=jruby -Djruby.shell=/bin/sh org.jruby.Main /usr/share/logstash/lib/bootstrap/environment.rb logstash/runner.rb -f /etc/logstash/conf.d/
root@7c7edc22ff14:/# cd /access_log
root@7c7edc22ff14:/access_log# ls -la
total 24
drwxrwxr-x 2 1000 1000 4096 Feb 13 13:15 .
drwxr-xr-x 66 root root 4096 Feb 13 13:36 ..
-rw-rw---- 2 www-data adm 15198 Feb 13 13:37 access.log

跑logstash的是用户logstash,而logstash用户没有access.log的访问权限。
在docker container中挂在的目录,其用户权限是和host相同的。所以我们必须在host中增加logstash用户的权限。
退出docker container,在host中我们尝试个logstash用户添加access.log的访问权限。

1
2
$ sudo setfacl -m u:logstash:r access.log
setfacl: Option -m: Invalid argument near character 6

host系统中并没有logstash用户,所以map不到相关的uid。那就去container中找一下logstash的uid就是了。

1
2
3
4
5
root@7c7edc22ff14:/# cat /etc/passwd

...
...
logstash:x:999:999:LogStash Service User:/usr/share/logstash:/usr/sbin/nologin

container中logstash uid是999,我们在host中直接用uid设置权限。

1
$sudo setfacl -m u:999:r access.log

重新build一下,然后docker-compose up, 再打开kibana,这次终于看到了期待的结果。

如果你觉得本文对你有帮助,请给我点赞助。