Logstash的一次问题排查

来源:互联网 发布:淘宝追加评论怎么找 编辑:程序博客网 时间:2024/05/22 15:40

Logstash简介

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 startLogstash 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参数指定配置文件是生效的!!

问题分析过程

1. 首先查看了使用服务方式启动时的进程参数

# 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   //启用该目录下所有配置

通过与手动启动的方式对比并没有什么区别,但结果却不同,于是我们追溯使用服务方式启动时的具体环境参数和命令

2. 分析/etc/init.d/logstash的启动过程

通过第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)权限不足导致的。

3. 修改文件属主和权限方法(失败)

给/etc/init.d/logstash下面文件尝试赋予最大的权限并修改为logstash属主,但依然没有解决。

4. 直接以root用户运行(成功)

根据上述72行代码可以知道,logstash是以logstash用户启动的,我们将其修改为root,即:

 29 LS_USER=root    //原来默认为logstash 30 LS_GROUP=root  //原为默认为logstash

这次成功!!!哈哈!!

0 0