ELK技术栈 - logstash学习笔记(一) 安装 长期

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动

安装

下载

目前,Logstash 分为两个包:核心包和社区贡献包。你可以从 www.elasticsearch.org/overview/el… 下载这两个包的源代码或者二进制版本。

  • 源代码方式
1
2
ruby复制代码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 平台
1
2
ruby复制代码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 平台
1
2
ruby复制代码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

安装

上面这些包,你可能更偏向使用 rpmdpkg 等软件包管理工具来安装 Logstash,开发者在软件包里预定义了一些依赖。比如,logstash-1.4.2-1_2c0f5a.narch 就依赖于 jre 包。

另外,软件包里还包含有一些很有用的脚本程序,比如 /etc/init.d/logstash

如果你必须得在一些很老的操作系统上运行 Logstash,那你只能用源代码包部署了,记住要自己提前安装好 Java:

1
2
3
javascript复制代码yum install openjdk-jre
export JAVA_HOME=/usr/java
tar zxvf logstash-1.4.2.tar.gz

最佳实践

但是真正的建议是:如果可以,请用 Elasticsearch 官方仓库来直接安装 Logstash!

Debian 平台

1
2
3
4
5
6
bash复制代码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 平台

1
2
3
4
5
6
7
8
9
10
11
ini复制代码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 进程:

1
bash复制代码bin/logstash -e 'input{stdin{}}output{stdout{codec=>rubydebug}}'

此时终端会等待数据

输入helloword显示结果

1
2
3
4
5
6
ini复制代码{
"@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 键,你就可以看到下面这样的输出:

1
perl复制代码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 插件 来管理这个特殊字段

  1. host 标记事件发生在哪里。
  2. type 标记事件的唯一类型。
  3. 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 命令即可。

  1. 最基础的 nohup 方式

这是最简单的方式,也是 linux 新手们很容易搞混淆的一个经典问题:

使用配置文件的方式,在Logstash目录下创建.conf

1
2
3
4
5
6
7
ini复制代码input { stdin {} }
output {
elasticsearch {
hosts => '172.18.118.222'
}
stdout { codec => rubydebug }
}

(遇到OOM问题)

1
2
3
4
5
6
7
8
javascript复制代码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
  1. 更优雅的 SCREEN 方式

screen 算是 linux 运维一个中高级技巧。通过 screen 命令创建的环境下运行的终端命令,其父进程不是 sshd 登录会话,而是 screen 。这样就可以即避免用户退出进程消失的问题,又随时能重新接管回终端继续操作。

创建独立的 screen 命令如下:

1
复制代码screen -dmS elkscreen_1

接管连入创建的 elkscreen_1 命令如下:

1
复制代码screen -r elkscreen_1

然后你可以看到一个一模一样的终端,运行 logstash 之后,不要按 Ctrl+C,而是按 Ctrl+A+D 键,断开环境。想重新接管,依然 screen -r elkscreen_1 即可。

如果创建了多个 screen,查看列表命令如下:

1
复制代码screen -list
  1. 最推荐的 daemontools 方式

不管是 nohup 还是 screen,都不是可以很方便管理的方式,在运维管理一个 ELK 集群的时候,必须寻找一种尽可能简洁的办法。所以,对于需要长期后台运行的大量程序(注意大量,如果就一个进程,还是学习一下怎么写 init 脚本吧),推荐大家使用一款 daemontools 工具。

daemontools 是一个软件名称,不过配置略复杂。所以这里我其实是用其名称来指代整个同类产品,包括但不限于 python 实现的 supervisord,perl 实现的 ubic,ruby 实现的 god 等。

  1. supervisord 为例,因为这个出来的比较早,可以直接通过 EPEL 仓库安装。
1
ini复制代码yum -y install supervisord --enablerepo=epel
  1. /etc/supervisord.conf 配置文件里添加内容,定义你要启动的程序:
1
2
3
4
5
6
7
8
9
bash复制代码[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子进程中某一个进程的启停操作:

1
arduino复制代码supervisorctl stop elkpro_2

supervisorctl 常用命令

supervisorctl status:查看所有进程的状态

supervisorctl stop :停止

supervisorctl start :启动

supervisorctl restart : 重启

supervisorctl update :配置文件修改后可以使用该命令加载新的配置

supervisorctl reload: 重新启动配置中的所有程序

  1. 使用Docker

1
Bash复制代码docker pull docker.elastic.co/logstash/logstash:6.5.1

语法

Logstash 设计了自己的 DSL —— 有点像 Puppet 的 DSL,或许因为都是用 Ruby 语言写的吧 —— 包括有区域,注释,数据类型(布尔值,字符串,数值,数组,哈希),条件判断,字段引用等。

区段(section)

Logstash 用 {} 来定义区域。区域内可以包括插件区域定义,你可以在一个区域内定义多个插件。插件区域内则可以定义键值对设置。示例如下:

1
2
3
4
lua复制代码input {
stdin {}
syslog {}
}

Logstash 支持少量的数据值类型:

  • bool
1
ini复制代码debug => true
  • string
1
ini复制代码host => "hostname"
  • number
1
ini复制代码port => 514
  • array
1
ini复制代码match => ["datetime", "UNIX", "ISO8601"]
  • hash
1
2
3
4
ini复制代码options => {
key1 => "value1",
key2 => "value2"
}

字段引用(field reference)

字段是 Logstash::Event 对象的属性。我们之前提过事件就像一个哈希一样,所以你可以想象字段就像一个键值对。

小贴士:我们叫它字段,因为 Elasticsearch 里是这么叫的。

如果你想在 Logstash 配置中使用字段的值,只需要把字段的名字写在中括号 [] 里就行了,这就叫字段引用

对于 嵌套字段 (也就是多维哈希表,或者叫哈希的哈希),每层的字段名都写在 [] 里就可以了。比如,你可以从 geoip 里这样获取 longitude 值(是的,这是个笨办法,实际上有单独的字段专门存这个数据的):

1
css复制代码[geoip][location][0]

小贴士:logstash 的数组也支持倒序下标,即 [geoip][location][-1] 可以获取数组最后一个元素的值。

Logstash 还支持变量内插,在字符串里使用字段引用的方法是这样:

1
css复制代码"the longitude is %{[geoip][location][0]}"

条件判断(condition)

Logstash从 1.3.0 版开始支持条件判断和表达式。

表达式支持下面这些操作符:

  • equality, etc: ==, !=, <, >, <=, >=
  • regexp: =, !
  • inclusion: in, not in
  • boolean: and, or, nand, xor
  • unary: !()

通常来说,你都会在表达式里用到字段引用。比如:

1
2
3
4
javascript复制代码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 '' 达到相同效果。这个参数的默认值是下面这样:

1
2
3
4
5
6
lua复制代码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 来代替。

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%