安装
下载
目前,Logstash 分为两个包:核心包和社区贡献包。你可以从 www.elasticsearch.org/overview/el… 下载这两个包的源代码或者二进制版本。
- 源代码方式
wget https://download.elasticsearch.org/logstash/logstash/logstash-1.4.2.tar.gz wget https://download.elasticsearch.org/logstash/logstash/logstash-contrib-1.4.2.tar.gz
- Debian 平台
wget https://download.elasticsearch.org/logstash/logstash/packages/debian/logstash_1.4.2-1-2c0f5a1_all.deb wget https://download.elasticsearch.org/logstash/logstash/packages/debian/logstash-contrib_1.4.2-1-efd53ef_all.deb
- Redhat 平台
wget https://download.elasticsearch.org/logstash/logstash/packages/centos/logstash-1.4.2-1_2c0f5a1.noarch.rpm https://download.elasticsearch.org/logstash/logstash/packages/centos/logstash-contrib-1.4.2-1_efd53ef.noarch.rpm
安装
上面这些包,你可能更偏向使用 rpm
,dpkg
等软件包管理工具来安装 Logstash,开发者在软件包里预定义了一些依赖。比如,logstash-1.4.2-1_2c0f5a.narch
就依赖于 jre
包。
另外,软件包里还包含有一些很有用的脚本程序,比如 /etc/init.d/logstash
。
如果你必须得在一些很老的操作系统上运行 Logstash,那你只能用源代码包部署了,记住要自己提前安装好 Java:
yum install openjdk-jre export JAVA_HOME=/usr/java tar zxvf logstash-1.4.2.tar.gz
最佳实践
但是真正的建议是:如果可以,请用 Elasticsearch 官方仓库来直接安装 Logstash!
Debian 平台
wget -O - http://packages.elasticsearch.org/GPG-KEY-elasticsearch | apt-key add - cat >> /etc/apt/sources.list <<EOF deb http://packages.elasticsearch.org/logstash/1.4/debian stable main EOF apt-get update apt-get install logstash
Redhat 平台
rpm --import http://packages.elasticsearch.org/GPG-KEY-elasticsearch cat > /etc/yum.repos.d/logstash.repo <EOF [logstash-1.4] name=logstash repository for 1.4.x packages baseurl=http://packages.elasticsearch.org/logstash/1.4/centos gpgcheck=1 gpgkey=http://packages.elasticsearch.org/GPG-KEY-elasticsearch enabled=1 EOF yum clean all yum install logstash
Hello World
在终端中,像下面这样运行命令来启动 Logstash 进程:
bin/logstash -e 'input{stdin{}}output{stdout{codec=>rubydebug}}'
此时终端会等待数据
输入helloword显示结果
{ "@version" => "1", "host" => "izwz99gyct1a1rh6iblyucz", "@timestamp" => 2018-11-22T08:15:46.454Z, "message" => "helloword" }
解释
每位系统管理员都肯定写过很多类似这样的命令:cat randdata | awk '{print $2}' | sort | uniq -c | tee sortdata
。这个管道符 |
可以算是 Linux 世界最伟大的发明之一(另一个是“一切皆文件”)。
Logstash 就像管道符一样!
你输入 (就像命令行的 cat
)数据,然后处理过滤 (就像 awk
或者 uniq
之类)数据,最后输出 (就像 tee
)到其他地方。
当然实际上,Logstash 是用不同的线程来实现这些的。如果你运行 top
命令然后按下 H 键,你就可以看到下面这样的输出:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 21401 root 16 0 1249m 303m 10m S 18.6 0.2 866:25.46 |worker 21467 root 15 0 1249m 303m 10m S 3.7 0.2 129:25.59 >elasticsearch. 21468 root 15 0 1249m 303m 10m S 3.7 0.2 128:53.39 >elasticsearch. 21400 root 15 0 1249m 303m 10m S 2.7 0.2 108:35.80 <file 21403 root 15 0 1249m 303m 10m S 1.3 0.2 49:31.89 >output 21470 root 15 0 1249m 303m 10m S 1.0 0.2 56:24.24 >elasticsearch.
Logstash 会给事件添加一些额外信息。最重要的就是 @timestamp ,用来标记事件的发生时间。因为这个字段涉及到 Logstash 的内部流转,所以必须是一个 joda 对象,如果你尝试自己给一个字符串字段重命名为 @timestamp
的话,Logstash 会直接报错。所以,请使用 filters/date 插件 来管理这个特殊字段 。
- host 标记事件发生在哪里。
- type 标记事件的唯一类型。
- tags 标记事件的某方面属性。这是一个数组,一个事件可以有多个标签。
长期运行
1. 标准的 service 方式
采用 RPM、DEB 发行包安装的读者,推荐采用这种方式。发行包内,都自带有 sysV 或者 systemd 风格的启动程序/配置,你只需要直接使用即可。
以 RPM 为例,/etc/init.d/logstash
脚本中,会加载 /etc/init.d/functions
库文件,利用其中的 daemon
函数,将 logstash 进程作为后台程序运行。
所以,你只需把自己写好的配置文件,统一放在 /etc/logstash/
目录下(注意目录下所有配置文件都应该是 .conf 结尾,且不能有其他文本文件存在。因为 logstash agent 启动的时候是读取全文件夹 的),然后运行 service logstash start
命令即可。
2. 最基础的 nohup 方式
这是最简单的方式,也是 linux 新手们很容易搞混淆的一个经典问题:
使用配置文件的方式,在Logstash目录下创建.conf
input { stdin {} } output { elasticsearch { hosts => '172.18.118.222' } stdout { codec => rubydebug } }
(遇到OOM问题)
command command > /dev/null command > /dev/null 2>&1 command & command > /dev/null & command > /dev/null 2>&1 & command &> /dev/null nohup command &> /dev/null
3. 更优雅的 SCREEN 方式
screen 算是 linux 运维一个中高级技巧。通过 screen 命令创建的环境下运行的终端命令,其父进程不是 sshd 登录会话,而是 screen 。这样就可以即避免用户退出进程消失的问题,又随时能重新接管回终端继续操作。
创建独立的 screen 命令如下:
screen -dmS elkscreen_1
接管连入创建的 elkscreen_1
命令如下:
screen -r elkscreen_1
然后你可以看到一个一模一样的终端,运行 logstash 之后,不要按 Ctrl+C,而是按 Ctrl+A+D 键,断开环境。想重新接管,依然 screen -r elkscreen_1
即可。
如果创建了多个 screen,查看列表命令如下:
screen -list
4. 最推荐的 daemontools 方式
不管是 nohup 还是 screen,都不是可以很方便管理的方式,在运维管理一个 ELK 集群的时候,必须寻找一种尽可能简洁的办法。所以,对于需要长期后台运行的大量程序(注意大量,如果就一个进程,还是学习一下怎么写 init 脚本吧),推荐大家使用一款 daemontools 工具。
daemontools 是一个软件名称,不过配置略复杂。所以这里我其实是用其名称来指代整个同类产品,包括但不限于 python 实现的 supervisord,perl 实现的 ubic,ruby 实现的 god 等。
- 以 supervisord 为例,因为这个出来的比较早,可以直接通过 EPEL 仓库安装。
yum -y install supervisord --enablerepo=epel
- 在
/etc/supervisord.conf
配置文件里添加内容,定义你要启动的程序:
[program:logstash] environment=LS_HEAP_SIZE=128m directory=/usr/local/software/logstash command=/usr/local/software/logstash/bin/logstash -f /usr/local/software/logstash/logstash.conf --pluginpath /usr/local/software/logstash/plugins/ -w 10 -l /var/log/logstash/pro1.log [program:elkpro_2] environment=LS_HEAP_SIZE=128m directory=/usr/local/software/logstash command=/usr/local/software/logstash/bin/logstash -f /etc/logstash/pro2.conf --pluginpath /opt/logstash/plugins/ -w 10 -l /var/log/logstash/pro2.log
启动然后service supervisord start
即可。
其他办法sudo /bin/systemctl start supervisord.service
查看是否启动
systemctl status supervisord.service
logstash会以supervisord子进程的身份运行,你还可以使用supervisorctl
命令,单独控制一系列logstash子进程中某一个进程的启停操作:
supervisorctl stop elkpro_2
supervisorctl 常用命令
supervisorctl status:查看所有进程的状态
supervisorctl stop :停止
supervisorctl start :启动
supervisorctl restart : 重启
supervisorctl update :配置文件修改后可以使用该命令加载新的配置
supervisorctl reload: 重新启动配置中的所有程序
5. 使用Docker
docker pull docker.elastic.co/logstash/logstash:6.5.1
语法
Logstash 设计了自己的 DSL —— 有点像 Puppet 的 DSL,或许因为都是用 Ruby 语言写的吧 —— 包括有区域,注释,数据类型(布尔值,字符串,数值,数组,哈希),条件判断,字段引用等。
区段(section)
Logstash 用 {}
来定义区域。区域内可以包括插件区域定义,你可以在一个区域内定义多个插件。插件区域内则可以定义键值对设置。示例如下:
input { stdin {} syslog {} }
Logstash 支持少量的数据值类型:
- bool
debug => true
- string
host => "hostname"
- number
port => 514
- array
match => ["datetime", "UNIX", "ISO8601"]
- hash
options => { key1 => "value1", key2 => "value2" }
字段引用(field reference)
字段是 Logstash::Event
对象的属性。我们之前提过事件就像一个哈希一样,所以你可以想象字段就像一个键值对。
小贴士:我们叫它字段,因为 Elasticsearch 里是这么叫的。
如果你想在 Logstash 配置中使用字段的值,只需要把字段的名字写在中括号 []
里就行了,这就叫字段引用 。
对于 嵌套字段 (也就是多维哈希表,或者叫哈希的哈希),每层的字段名都写在 []
里就可以了。比如,你可以从 geoip 里这样获取 longitude 值(是的,这是个笨办法,实际上有单独的字段专门存这个数据的):
[geoip][location][0]
小贴士:logstash 的数组也支持倒序下标,即 [geoip][location][-1] 可以获取数组最后一个元素的值。
Logstash 还支持变量内插,在字符串里使用字段引用的方法是这样:
"the longitude is %{[geoip][location][0]}"
条件判断(condition)
Logstash从 1.3.0 版开始支持条件判断和表达式。
表达式支持下面这些操作符:
- equality, etc: ==, !=, <, >, <=, >=
- regexp: =
, ! - inclusion: in, not in
- boolean: and, or, nand, xor
- unary: !()
通常来说,你都会在表达式里用到字段引用。比如:
if "_grokparsefailure" not in [tags] { } else if [status] !~ /^2\d\d/ and [url] == "/noc.gif" { } else { }
命令行参数
Logstash 提供了一个 shell 脚本叫 logstash
方便快速运行。它支持一下参数:
- -e
意即执行 。我们在 "Hello World" 的时候已经用过这个参数了。事实上你可以不写任何具体配置,直接运行 bin/logstash -e ''
达到相同效果。这个参数的默认值是下面这样:
input { stdin { } } output { stdout { } }
- --config 或 -f
意即文件 。真实运用中,我们会写很长的配置,甚至可能超过 shell 所能支持的 1024 个字符长度。所以我们必把配置固化到文件里,然后通过 bin/logstash -f agent.conf
这样的形式来运行。
此外,logstash 还提供一个方便我们规划和书写配置的小功能。你可以直接用 bin/logstash -f /etc/logstash.d/
来运行。logstash 会自动读取 /etc/logstash.d/
目录下所有的文本文件,然后在自己内存里拼接成一个完整的大配置文件,再去执行。
- --configtest 或 -t
意即测试 。用来测试 Logstash 读取到的配置文件语法是否能正常解析。Logstash 配置语法是用 grammar.treetop 定义的。尤其是使用了上一条提到的读取目录方式的读者,尤其要提前测试。
- --log 或 -l
意即日志 。Logstash 默认输出日志到标准错误。生产环境下你可以通过 bin/logstash -l logs/logstash.log
命令来统一存储日志。
- --filterworkers 或 -w
意即工作线程 。Logstash 会运行多个线程。你可以用 bin/logstash -w 5
这样的方式强制 Logstash 为过滤 插件运行 5 个线程。
注意:Logstash目前还不支持输入插件的多线程。而输出插件的多线程需要在配置内部设置,这个命令行参数只是用来设置过滤插件的!
提示:Logstash 目前不支持对过滤器线程的监测管理。如果 filterworker 挂掉,Logstash 会处于一个无 filter 的僵死状态。这种情况在使用 filter/ruby 自己写代码时非常需要注意,很容易碰上 NoMethodError: undefined method '*' for nil:NilClass 错误。需要妥善处理,提前判断。
- --pluginpath 或 -P
可以写自己的插件,然后用 bin/logstash --pluginpath /path/to/own/plugins
加载它们。
- --verbose
输出一定的调试日志。
小贴士:如果你使用的 Logstash 版本低于 1.3.0,你只能用 bin/logstash -v 来代替。
- --debug
输出更多的调试日志。
小贴士:如果你使用的 Logstash 版本低于 1.3.0,你只能用 bin/logstash -vv 来代替。