Logstash is a tool for managing events and logs. You can use it to collect logs, parse them, and store them for later use (like, for searching). – http://logstash.net
我们通常使用Logstashg来收集和分析日志,详细使用和配置方法可以参考ELKstack中文指南
zabbix插件安装方法:
# logstash-plugin install logstash-output-zabbix
我们这里使用CentOS 6.5和其默认源安装的Logstash-2.3,据说下一版本直接上5.0,哈哈
根据logstash的配置方法写了一个配置文件,并放入/etc/logstash/conf.d/目录下,然后我们运行logstash
# service logstash start
Logstash started.
丢入测试的日志,但这时我们的ES并没有收集到预期的日志信息,zabbix也没有收到相应的报警信息(这个是我们自己做的基于日志的报警),查看/var/log/logstash/logstash.log只有Logstash启动信息,没有日志相关的信息。
然后停止logstash使用,logstash -f /etc/logstash/conf.d 方式再次启动logstash进行测试,输入测试的日志结果ES可以收到相关的日志,zabbix也可以报警。
也就是说以服务的方式启动logstash,/etc/logstash/conf.d下的配置文件不生效,使用-f参数指定配置文件是生效的!!
# ps aux | grep 'logstash' | grep -v 'grep'
root 20921 86.0 1.0 9344268 521780 pts/2 SNl 16:42 0:55 /usr/bin/java -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -Djava.awt.headless=true -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:+HeapDumpOnOutOfMemoryError -Djava.io.tmpdir=/var/lib/logstash -Xmx1g -Xss2048k -Djffi.boot.library.path=/opt/logstash/vendor/jruby/lib/jni -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -Djava.awt.headless=true -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:+HeapDumpOnOutOfMemoryError -Djava.io.tmpdir=/var/lib/logstash -XX:HeapDumpPath=/opt/logstash/heapdump.hprof -Xbootclasspath/a:/opt/logstash/vendor/jruby/lib/jruby.jar -classpath : -Djruby.home=/opt/logstash/vendor/jruby -Djruby.lib=/opt/logstash/vendor/jruby/lib -Djruby.script=jruby -Djruby.shell=/bin/sh org.jruby.Main --1.9 /opt/logstash/lib/bootstrap/environment.rb logstash/runner.rb agent -f /etc/logstash/conf.d -l /var/log/logstash/logstash.log
其中最核心的是最后面的:
logstash/runner.rb agent -f /etc/logstash/conf.d //启用该目录下所有配置
通过与手动启动的方式对比并没有什么区别,但结果却不同,于是我们追溯使用服务方式启动时的具体环境参数和命令
通过第1点的分析,我们追溯到服务的启动环境可能是导致结果不一样的原因,而在CentOS中的启动是由/etc/init.d/logstash控制的,所以我们分析该脚本中的启动代码:
54 start() {
55
56 LS_JAVA_OPTS="${LS_JAVA_OPTS} -Djava.io.tmpdir=${LS_HOME}"
57 HOME=${LS_HOME}
58 export PATH HOME LS_HEAP_SIZE LS_JAVA_OPTS LS_USE_GC_LOGGING LS_GC_LOG_FILE
59
60 # chown doesn't grab the suplimental groups when setting the user:group - so we have to do it for it.
61 # Boy, I hope we're root here.
62 SGROUPS=$(id -Gn "$LS_USER" | tr " " "," | sed 's/,$//'; echo '')
63
64 if [ ! -z $SGROUPS ]
65 then
66 EXTRA_GROUPS="--groups $SGROUPS"
67 fi
68 # set ulimit as (root, presumably) first, before we drop privileges
69 ulimit -n ${LS_OPEN_FILES}
70
71 # Run the program!
72 nice -n ${LS_NICE} chroot --userspec $LS_USER:$LS_GROUP $EXTRA_GROUPS / sh -c "
73 cd $LS_HOME
74 ulimit -n ${LS_OPEN_FILES}
75 exec \"$program\" $args
76 " > "${LS_LOG_DIR}/$name.stdout" 2> "${LS_LOG_DIR}/$name.err" &
77
78 # Generate the pidfile from here. If we instead made the forked process
79 # generate it there will be a race condition between the pidfile writing
80 # and a process possibly asking for status.
81 echo $! > $pidfile
82
83 echo "$name started."
84 return 0
85 }
上述代码可以知道,其执行过程为初始化环境变量->设置打开文件数->运行logstash,其核心为72~76行
我们查找其中的环境变量并一一打印输出:
nice -n 19 chroot --userspec logstash:logstash --groups logstash //72行
ulimit -n 16384 //74行
exec /opt/logstash/bin/logstash agent -f /etc/logstash/conf.d -l /var/log/logstash/logstash.log //75
我们使用手动命令直接在bash中以root用户执行上述命令同样是有效的,Logstash正确工作,所以我们几乎确认是由于logstash的默认执行用户(logstash)权限不足导致的。
给/etc/init.d/logstash下面文件尝试赋予最大的权限并修改为logstash属主,但依然没有解决。
根据上述72行代码可以知道,logstash是以logstash用户启动的,我们将其修改为root,即:
29 LS_USER=root //原来默认为logstash
30 LS_GROUP=root //原为默认为logstash
这次成功!!!哈哈!!