logstash

logstash
logstash 是一个接收,处理,转发日志的工具。支持系统日志,webserver 日志,错误日志,应用日志,总之包括所有可以抛出来的日志类型
在一个典型的使用场景下(ELK):
用 Elasticsearch 作为后台数据的存储,kibana用来前端的报表展示
Logstash 在其过程中担任搬运工的角色,它为数据存储,报表查询和日志解析创建了一个功能强大的管道链
Logstash 提供了多种多样的 input,filters,codecs 和 output 组件,让使用者轻松实现强大的功能.
 
工作流程
Logstash工作的三个阶段:
input数据输入端,以接收来自任何地方的源数据
* file:从文件中读取
* syslog:监听在514端口的系统日志信息, 并解析成RFC3164格式
* redis:从redis-server list中获取
* beat:接收来自Filebeat的事件  (一般用来做测试)
 
 
Filter数据中转层, 主要进行格式处理, 数据类型转换、数据过滤、字段添加, 修改等, 常用的过滤器如下
* grok:通过正则解析和结构化任何文本Grok目前是logstash最好的方式对非结构化日志数据解析成结构化和可查询化,logstash内置了120个匹配模式, 满足大部分需求
* mutate:在事件字段执行一般的转换可以重命名、删除、替换和修改事件字段
* drop:完全丢弃事件, 如debug事件
* clone:复制事件, 可能添加或者删除字段
* geoip:添加有关IP地址地理位置信息
 
output是logstash工作的最后一个阶段, 负责将数据输出到指定位置, 兼容大多数应用, 常用的有:
* elasticsearch:发送事件数据到Elasticsearch, 便于查询, 分析, 绘图
* file:将事件数据写入到磁盘文件上
* mongodb:将事件数据发送至高性能NoSQL mongodb, 便于永久存储, 查询, 分析, 大数据分片
* redis:将数据发送至redis-server, 常用于中间层暂时缓存
* graphite:发送事件数据到graphitehttp://graphite.wikidot.com/
* statsd:发送事件数据到statsd
 
1.安装logstash
# tar xf logstash-6.4.1.tar.gz -C /usr/local
# ln -s /usr/local/logstash-6.4.1 /usr/local/logstash
 
2.修改配置文件
# cd /usr/local/logstash/
# vim config/logstash.yml
http.host: "0.0.0.0"
 
3.测试
1).配置好后,先不要启动服务. 先配置一个收集远程日志的配置文件进行测试
# cd config/
# cp logstash-sample.conf syslog-test.conf
# cat config/syslog-test.conf
input {
syslog {
type => "system-syslog" #定义类型
port => 51400 #定义监听端口
}
}
 
 
output {
stdout { #将接收到的日志输出到标准输出
codec => rubydebug
}
}
 
2).检测文件有没有错误
# /usr/local/logstash/bin/logstash -f syslog-test.conf -t
Configuration OK #检测成功
 

 
选项:
-f 指定配置文件
-t,--config.test_and_exit 检测配置并退出,如果不加这个就是启动服务了
 
3).如果检测成功,启动测试服务
# /usr/local/logstash/bin/logstash -f syslog-test.conf
 
4).另开一个终端查看端口
# netstat -tuanp |grep 51400
tcp6 0 0 :::51400 :::* LISTEN 10901/java
udp 0 0 0.0.0.0:51400 0.0.0.0:* 10901/java
 
5).在另外的机器上配置将日志发送过来, 这一步在另外一台机器上操作
# vim /etc/rsyslog.conf
*.* @@192.168.10.12:51400
# systemctl restart rsyslog
 
6).在logstash上看有没有输出
上图可以看出, 终端中以JSON的格式打印了收集到的日志, 测试成功
 
4.以上第3步只是测试, 这一步我们需要重新改一下配置文件, 让收集的日志信息输出到es服务器中, 而不是当前终端
# cp syslog-test.conf syslog.conf
# cat syslog.conf
input {
syslog {
type => "system-syslog"
port => 51400
}
}
 
 
output {
elasticsearch {
hosts => ["http://192.168.10.11:9200"]
index => "system-syslog-%{+YYYY.MM.dd}"
}
}
 
5.测试配置文件
# /usr/local/logstash/bin/logstash -f syslog.conf -t
 
6.如果测试没有问题,启动服务
# /usr/local/logstash/bin/logstash -f syslog.conf &
 
7.查看服务启动情况:
# netstat -tanp |grep 9600
tcp6 0 0 :::9600 :::* LISTEN 11024/java
 
# netstat -tanp |grep 51400
tcp6 0 0 :::51400 :::* LISTEN 11024/java
 
 
8.到kibana上配置索引,可以使用通配符,如下:
 
9.配置好索引后就可以去Discover界面查看了
 
logstash插件
input数据输入端,以接收来自任何地方的源数据
* file:从文件中读取
* syslog:监听在514端口的系统日志信息, 并解析成RFC3164格式
* redis:从redis-server list中获取
* beat:接收来自Filebeat的事件
 
Filter数据中转层, 主要进行格式处理, 数据类型转换、数据过滤、字段添加, 修改等, 常用的过滤器如下
* grok:通过正则解析和结构化任何文本Grok目前是logstash最好的方式对非结构化日志数据解析成结构化和可查询化,logstash内置了120个匹配模式, 满足大部分需求
* mutate:在事件字段执行一般的转换可以重命名、删除、替换和修改事件字段
* drop:完全丢弃事件, 如debug事件
* clone:复制事件, 可能添加或者删除字段
* geoip:添加有关IP地址地理位置信息
 
output是logstash工作的最后一个阶段, 负责将数据输出到指定位置, 兼容大多数应用, 常用的有:
* elasticsearch:发送事件数据到Elasticsearch, 便于查询, 分析, 绘图
* file:将事件数据写入到磁盘文件上
* mongodb:将事件数据发送至高性能NoSQL mongodb, 便于永久存储, 查询, 分析, 大数据分片
* redis:将数据发送至redis-server, 常用于中间层暂时缓存
* graphite:发送事件数据到graphitehttp://graphite.wikidot.com/
* statsd:发送事件数据到statsd
 
input:

stdin标准输入

 
例:
# vim stdin.conf
 
# ../bin/logstash -f stdin.conf
 
"type" 和 "tags" 是logstash中两个特殊的字段
• type 用于标记事件的类型 -------- 我们肯定是知道事件是什么类型的
• tags 是在数据处理过程中, 由具体的插件来添加或删除, 例如下面的例子:
 

file文件输入

实例:
 
start_posttion设置为"beginning"会从文件的开头读取, 文件读完不会终止, 变为tail -f
 
syslog输入
用于接收系统日志
实例:
 
best输入
用于接收beat发送过来的日志, 如:
 
 
作为消费者消费队列里的数据, 如:
 
 
fiter:

grok正则捕获

 
grok是一个十分强大的logstash filter插件,他可以通过正则解析任意文本,将非结构化日志数据弄成结构化和方便查询的结构
grok是目前logstash 中解析非结构化日志数据最好的方式
 
grok的语法规则:
1. %{模式名称:字段名称} - 这里的模式名称对应内置模式,参见vendor/bundle/jruby/2.3.0/gems/logstash-patterns-core-4.1.2/patterns目录
2. 如果想自定义模式, 可以使用pattern_definitions参数直接自定义, 或使用patterns_dir参数指定定义文件
3. 如果想直接使用正则表达式, 使用 (?<field_name>pattern) 这种格式
例如:
我们的试验数据是:
192.168.10.11 - - [22/Oct/2019:22:49:53 -0400] "GET / HTTP/1.1" 200 5 "-" "curl/7.29.0"
 
过滤IP
执行时, 将以上试验数据内容输入进去:
 
 
 
 
 
下面这两种写法也能得到一样的结果:
 
 
 
过滤时间戳
执行:
 
过滤ip和时间戳
执行:
 
结构化所有的信息
执行:
 
 
date
在上面grok中我们有个例子是讲解timestamp字段,表示取出日志中的时间。但是在显示的时候除了显示你指定的timestamp外,还有一行是@timestamp信息,这两个时间是不一样的,@timestamp表示系统当前时间。两个时间并不是一回事,在ELK的日志处理系统中,@timestamp字段会被elasticsearch用到,用来标注日志的生产时间,如此一来,日志生成时间就会发生混乱,要解决这个问题,需要用到另一个插件,即date插件,这个时间插件用来转换日志记录中的时间字符串,变成Logstash::Timestamp对象,然后转存到@timestamp字段里面
 
我们的试验数据是:
192.168.10.11 - - [22/Oct/2019:22:49:53 -0400] "GET / HTTP/1.1" 200 5 "-" "curl/7.29.0"
180.15.16.17 - - [22/Oct/2019:22:49:53 -0400] "GET / HTTP/1.1" 200 5 "-" "curl/7.29.0"
为了区分它们, 我在这里用 time 表示日志中的时间:
 
执行, 输入前面的试验数据:
 
时间戳改了, 但我们发现比日志中的时间晚了 8 小时
这是因为在Elasticsearch内部,对时间类型字段都是统一采用UTC时间,而日志统一采用UTC时间存储,是国际安全、运维界的一个共识。
这并不影响什么,ELK已经给出了解决方案,那就是在Kibana平台上,程序会自动读取浏览器的当前时区,然后在web页面自动将UTC时间转换为当前时区的时间。
 

mutate数据修改插件

mutate插件是logstash另一个非常重要的插件,它提供了丰富的基础类型数据处理能力,包括重命名、删除、替换、修改日志事件中的字段。
几个常用的mutate插件功能:
• remove_field - 删除字段功能
• convert - 字段类型转换功能
• gsub - 正则表达式替换字段功能
• split - 分割字符串功能
• rename - 重命名字段功能
• lowercase - 将大写字母全部转换成小写. 这个需求非常常见, 因为ES默认是按照小写字母进行检索的, 建议对常用检索字段启用lowercase配置
另外, 还有以下功能
• uppercase - 将小写字母全部转换成大写
• join - 合并数组中的元素
• merge - 合并数组或哈希字段
• strip - 去除字段前后的空格
• update - 更新某个字段的内容, 如果字段不存在, 不会新建
• replace - 作用类似于update, 但是如果字段不存在, 会起到和 add_field 参数一样的效果, 自动添加字段
 
执行次序
rename update replace convert gsub uppercase lowercase strip remove split join merge
 
  • remove_field很常用,
他的作用就是去重, 它也可以直接用在grok里面
在前面的例子中我们看到了,不管是我们过滤什么样的信息,都是有两份数据,即message里面是一份,结构化的数据中又一份
这样既浪费存储空间又对查询速度带来影响, 我们可以使用remove_field去重:
 
我们的试验数据是:
192.168.10.11 - - [22/Oct/2019:22:49:53 -0400] "GET / HTTP/1.1" 200 5 "-" "curl/7.29.0"
 
先贴一份去重前的:
 
接下来, 如果我们想去掉 "message" 和 "auth"
可以看到, 已经去掉了
 
  • convert
主要用于数据类型的转换, 可以设置的转换类型包括: "integer", "float" 和"string"
例如: 我们前面实验中的 "response" 字段得到的是字符串, 我想把它转换为整型:
 
我们的试验数据是:
192.168.10.11 - - [22/Oct/2019:22:49:53 -0400] "GET / HTTP/1.1" 200 5 "-" "curl/7.29.0"
执行:
 
 
  • gsub正则表达式替换匹配字段
gsub可以通过正则表达式替换字段中匹配到的值,但是这本身只对字符串字段有效。
 
我们的试验数据是:
192.168.10.11 - - [22/Oct/2019:22:49:53 -0400] "GET / HTTP/1.1" 200 5 "-" "curl/7.29.0"
比如我要把ip地址中的"."替换成"_"
执行:
 
 
  • split
用于分割字符串, 将字符串分割为一个数组
 
我们的试验数据是:
192.168.10.11 - - [22/Oct/2019:22:49:53 -0400] "GET / HTTP/1.1" 200 5 "-" "curl/7.29.0"
例如: 将 ip 地址以"."为分隔符分割:
执行:
 
 
  • rename重命名字段

 
rename可以实现重命名某个字段的功能, 如果目标字段已存在,会被覆盖掉
 
我们的试验数据是:
192.168.10.11 - - [22/Oct/2019:22:49:53 -0400] "GET / HTTP/1.1" 200 5 "-" "curl/7.29.0"
 
将 clientip 重命名为 ip
执行:
 
 
  • lowercase
将大写字母转换为小写字母
 
执行时输入 ABCDEF
 
 

geoip地址查询归类

 
geoip是常见的免费的IP地址归类查询库,geoip可以根据IP地址提供对应的地域信息,包括国别,省市,经纬度等等,此插件对于可视化地图和区域统计非常有用。
例:
 
执行时输入一个公网IP:
 
成功了。
但是上面的内容并不是每个都是我们想要的,因此我们可以选择性的输出。
继续修改内容如下:
再执行:
 
 
output:
是logstash工作的最后一个阶段, 负责将数据输出到指定位置, 兼容大多数应用, 常用的有:
* elasticsearch:发送事件数据到Elasticsearch, 便于查询, 分析, 绘图
* mongodb:将事件数据发送至高性能NoSQL mongodb, 便于永久存储, 查询, 分析, 大数据分片
* redis:将数据发送至redis-server, 常用于中间层暂时缓存
* kafka:将数据发送至kafka
 
输出到ES:
 
输出到redis:
 
输出到kafka:
 

案例:收集nginx日志

方案一

nginx:
修改 nginx server 的配置文件
log_format json '{"@timestamp":"$time_iso8601",'
'"@version":"1",'
'"client":"$remote_addr",'
'"url":"$uri",'
'"status":"$status",'
'"domain":"$host",'
'"host":"$server_addr",'
'"size":$body_bytes_sent,'
'"responsetime":$request_time,'
'"referer": "$http_referer",'
'"ua": "$http_user_agent"'
'}';
access_log /var/log/nginx/access_json.log json;
 
logstash:
input {
file {
path => "/var/log/nginx/access_json.log"
codec => "json" #输入预定义好的 JSON 数据, 可以省略掉 filter/grok 配置, 从而减轻logstash的负载
start_position => "beginning"
}
}
output {
elasticsearch {
hosts => ["192.168.10.130:9200"]
index => "nginx-log-%{+YYYY.MM.dd}"
}
}

方案二

Logstash 默认自带了 apache标准日志的 grok正则:
COMMONAPACHELOG %{IPORHOST:clientip} %{USER:ident} %{NOTSPACE:auth} \[%{HTTPDATE:timestamp}\] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})" %{NUMBER:response} (?:%{NUMBER:bytes}|-)
COMBINEDAPACHELOG %{COMMONAPACHELOG} %{QS:referrer} %
对于 nginx 标准日志格式, 可以发现只是最后多了一个 $http_x_forwarded_for 变量所以 nginx 标准日志的 grok 正则定义是:
MAINNGINXLOG %{COMBINEDAPACHELOG} %{QS:x_forwarded_for}
 
logstash:直接使用访问日志
input {
file {
path => "/var/log/nginx/access.log"
start_position => beginning
}
}
filter {
grok {
match => { "message" => "%{COMBINEDAPACHELOG} %{QS:x_forwarded_for}"}
}
date {
match => [ "timestamp" , "dd/MMM/YYYY:HH:mm:ss Z" ]
}
geoip {
source => "clientip"
}
}
output {
elasticsearch {
hosts => "192.168.130.10:9200"
}
}
 
 

 
或家目录下的 ./vendor/bundle/jruby/2.3.0/gems/logstash-patterns-core-4.1.2/patterns 目录
 
 
 
 
 
 
 
 
 
 
posted @ 2020-10-20 22:09  梦里花落知多少sl  阅读(529)  评论(0编辑  收藏  举报