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,这次终于看到了期待的结果。