个人学习笔记,谢绝转载!!!
原文:https://www.cnblogs.com/wshenjin/p/13673593.html
Logstash必须要有input和output。
input插件
这里只介绍 stdin、file 和beats 插件
标准输入:stdin
一个标准输入配置实例:
input {
stdin {
add_field => {"key" => "value"}
codec => "plain"
tags => ["add"]
type => "stdin"
}
}
输出结果:
{
"host" => "localhost",
"@version" => "1",
"type" => "stdin",
"tags" => [
[0] "add"
],
"message" => "hello world",
"@timestamp" => 2020-09-12T07:49:00.044Z,
"key" => "value"
}
参数:
- add_field:用于向Event中添加字段,hash类型,默认值:{} 。
- codec:输入数据之后对数据进行解码,常见的就是在output指定输出结果为rubydebug 格式,string类型,默认值:"line"。
- tags: 可以在Event中增加标签,以便于在后续的处理流程中使用,array类型。
- type:如果采用elasticsearch做store,在默认情况下将作为elasticsearch的type,string类型。type字段作为事件本身的一部分存储,在kibana中通过type字段进行索引。
读取文件:file
文件读取插件主要用来抓取文件的变化信息,将变化信息封装成Event进程处理或者传递。
Logstash使用一个叫FileWatch的 Ruby Gem 库来监听文件变化。这个库支持glob展开文件路劲(只支持绝对路径,不会自动递归目录),而且会记录一个隐藏的数据文件来跟踪被监听的日志文件的当前读取位置(默认这个文件叫.sincedb)。该数据库文件记录了每个被监听文件的inode、major number、minor number 和 pos。
一个读取文件配置实例:
input {
file {
path => ["/data/logs/*.log"]
exclude => ["nginx_error.log"]
discover_interval => 5
sincedb_path => "/data/elk/logstash/.sincedb_nginx_log"
sincedb_write_interval => 10
type => "nginx_log"
}
}
}
参数:
- discover_interval:logstash每隔多久去检查一次被监听的path路径下是否有新文件,默认15秒。
- exclude:不想监听的文件路径。
- close_older:一个已经被监听的文件,如果超过这个时间没有新内容更新,则关闭这个文件的句柄,默认3600秒。
- ignore_older:每次检查文件列表时,如果一个文件的最后修改时间超过这个值,就忽略这个文件,默认86400秒,一天。
- sincedb_path:sincedb文件的位置,默认$HOME/.sincedb。
- sincedb_write_interval:多久写一次sincedb文件,默认15秒。
- star_interval:每隔多久检查一次被监听文件状态是否有更新,默认15秒。
- start_position:从什么位置开始读取文件数据,默认是结束位置。“beginning”从头开始读取。该选项仅对第一次被监听的文件起作用,如果sincedb文件已经记录了这个文件了,那么logstash依然会从记录过的pos开始读取,可以删除sincedb文件来让logstash从头开始读取被监听文件。
详细参考:https://www.elastic.co/guide/en/logstash/7.9/plugins-inputs-file.html
获取Nginx日志,并输出到标准输出:
[root@ ~]# vim /etc/logstash/conf.d/nginx_access.conf
input {
file {
path => ["/data/logs/*.log"]
exclude => ["nginx_error.log"]
discover_interval => 5
sincedb_path => "/data/elk/logstash/.sincedb_nginx_log"
sincedb_write_interval => 10
type => "nginx_log"
}
}
output {
stdout {
codec => rubydebug
}
}
测试效果:
[root@conf.d]# logstash -f nginx_access.conf
{
"host" => "localhost",
"path" => "/data/logs/127.0.0.1.log",
"@version" => "1",
"message" => "0.001 127.0.0.1 - [14/Sep/2020:15:02:21 +0800] "HEAD http://127.0.0.1:80/sdk/test/123?plat=xxxx HTTP/1.1" "" 200 0 "" "curl/7.29.0" ",
"@timestamp" => 2020-09-14T07:02:24.172Z,
"type" => "nginx_log"
}
beats插件
Beats插件用于建立监听服务,接收Filebeat或者其他beat发送的Events
filebeat 是基于原先 logstash-forwarder 的源码改造出来的。换句话说:filebeat 就是新版的 logstash-forwarder,也会是 Elastic Stack 在 shipper 端的第一选择。
filebeat 配置:
filebeat.inputs:
- type: log
enabled: true
tail_files: true
paths:
- /data/logs/*.log
exclude_files: ['nginx_error.log']
output.logstash:
enabled: true
hosts: ["127.0.0.1:5044"]
logstash 配置:
input {
beats {
port => 5044
}
}
output {
stdout {
codec => rubydebug
}
}
效果:
[root@ conf.d]# logstash -f filebeat_input.conf
{
"ecs" => {
"version" => "1.5.0"
},
"@timestamp" => 2020-09-14T07:16:21.519Z,
"host" => {
"name" => "localhost"
},
"tags" => [
[0] "beats_input_codec_plain_applied"
],
"log" => {
"offset" => 12896,
"file" => {
"path" => "/data/logs/127.0.0.1.log"
}
},
"input" => {
"type" => "log"
},
"@version" => "1",
"agent" => {
"name" => "localhost",
"type" => "filebeat",
"ephemeral_id" => "eb47810d-3979-4935-b0ff-16a70be965f8",
"hostname" => "localhost",
"version" => "7.9.1",
"id" => "bbe90ab2-68e3-44c0-bfc0-e501580dea84"
},
"message" => "0.000 127.0.0.1 - [14/Sep/2020:15:16:15 +0800] "HEAD /ttt/test/123?plat=xxxx HTTP/1.0" "" 200 0 "" "curl/7.29.0" 127.0.0.1"
}
参数:
- port:监听的端口,数值类型,必填字段。
- host:监听的IP,默认值为"0.0.0.0",string类型,非必填。
- client_inactivity_timeout:多长时间关闭连接,默认值60s,数值类型,非必填。
- ssl:是否启动SSL,默认值false,布尔类型,非必填。
- ssl_certificate:证书路径,string类型,非必填。
- 如果logstash使用IP访问,证书里的subjectAltName字段需要包含logstash的IP,否则报错:
- x509: cannot validate certificate for 192.168.1.241 because it doesn't contain any IP SANs
- ssl_key:SSL秘钥,string类型,非必填。
- ssl_key_passphrase:SSL秘钥密码,string类型,非必填。
- ssl_verify_mode:是否认证客户端,可选值“none”、”peer”、”force_peer”,默认none,非必填。
详细参考:https://www.elastic.co/guide/en/logstash/7.9/plugins-inputs-beats.html
beats SSL:
这里采用 easyrsa 生成logstash证书。
如果logstash使用IP访问,证书里的subjectAltName字段需要包含logstash的IP。easyrsa签署证书时,可以采用--subject-alt-name来添加:
./easyrsa gen-req logstash_server nopass # 生成证书签署文件
./easyrsa --subject-alt-name="IP:192.168.31.140" sign server logstash_server # 签署证书
Filter插件
grok
Logstash使用grok模块对任意文本解析并结构化输出,Logstash默认带有120中匹配模式。
grok的语法格式为 %{SYNTAX:SEMANTIC},前面是grok-pattrens中定义的变量,后面可以自定义变量的名称,如果有双引号""或者中括号[],需要加 进行转义。
-
SYNTAX 是要匹配的模式,例如3.14匹配 NUMBER 模式,127.0.0.1 匹配 IP 模式。
-
SEMANTIC 是匹配到的文本片段的标识,例如 “3.14” 可以是一个时间的持续时间,所以可以简单地叫做"duration" ,字符串"55.3.244.1"可以被标识为“client”。
所以,grok过滤器表达式可以写成: %{NUMBER:duration} %{IP:client}
默认情况下,所有的SEMANTIC是以字符串的方式保存,如果想要转换一个SEMANTIC的数据类型,例如转换一个字符串为整形,可以写成如下的方式: %{NUMBER:num:int}
一个例子,示例日志如下所示:
127.0.0.1 GET http://127.0.0.1/sdk/test/123?plat=xxxx HTTP/1.1 0 0.001
filter 配置如下所示:
filter {
grok {
match => {
"message" => "%{IP:client} %{WORD:method} %{DATA:request} %{NUMBER:bytes} %{NUMBER:duration}"
}
}
}
效果如下所示:
{
"duration" => "0.043",
"request" => "/index.html",
"@timestamp" => 2017-06-22T01:49:27.773Z,
"method" => "GET",
"bytes" => "15824",
"@version" => "1",
"host" => "baseos-1",
"client" => "55.3.244.1",
"message" => "55.3.244.1 GET /index.html 15824 0.043",
"tags" => []
}
一个nginx日志例子:
'$request_time $remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'
filter 配置如下所示:
filter {
grok {
match => {
"message" => "%{NUMBER:request_time} %{IPORHOST:remote_addr} - %{USERNAME:remote_user} [%{HTTPDATE:[@metadata][timestamp]}] "%{DATA:request}" %{INT:status} %{INT:body_bytes_sent} "%{DATA:http_referer}" "%{DATA:http_user_agent}" "%{USERNAME:http_x_forwarded_for}""
}
}
}
效果如下所示:
{
"message" => "0.002 127.0.0.1 - - [15/Sep/2020:15:02:09 +0800] "GET http://tk.gz4399.com/sdk/test/123?plat=xxxx HTTP/1.1" 200 4 "-" "curl/7.29.0" "-"",
"request" => "GET http://127.0.0.1/sdk/test/123?plat=xxxx HTTP/1.1",
"http_x_forwarded_for" => "-",
"remote_user" => "-",
"host" => "localhost",
"status" => "200",
"remote_addr" => "127.0.0.1",
"type" => "nginx_log",
"@version" => "1",
"body_bytes_sent" => "4",
"http_user_agent" => "curl/7.29.0",
"request_time" => "0.002",
"http_referer" => "-",
"@timestamp" => 2020-09-15T07:02:10.130Z,
"path" => "/data/logs/127.0.0.1.log"
}
message是每段读进来的日志,IPORHOST、USERNAME、HTTPDATE等都是patterns/grok-patterns中定义好的正则格式名称,对照日志进行编写。
logstash 默认自带120种正则格式,参考:https://github.com/logstash-plugins/logstash-patterns-core/tree/master/patterns
自定义正则
很多时候,日志格式都是自定义的,这时候我们需要根据实际情况自定义正则。
这里以 remote_addr、request为例子,定义三个正则:
IPADDR [0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}
REQUESTPATH (?:/[\A-Za-z0-9$.+!*'(){},~:;=@#% []_<>^-&?]*)+
REQUESTPRO ([^"]*)
使用上面的自定义正则:
IPADDR [0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}
REQUESTPRO ([^"]*)
REQUESTPATH (?:/[\A-Za-z0-9$.+!*'(){},~:;=@#% []_<>^-&?]*)+
NGXACCESSLOG %{NUMBER:request_time} %{IPADDR:remote_addr} - %{USERNAME:remote_user} [%{HTTPDATE:[@metadata][timestamp]}] "%{WORD:request_mathod} %{REQUESTPATH:request_path} %{REQUESTPRO:request_protocol}" %{INT:status} %{INT:body_bytes_sent} "%{DATA:http_referer}" "%{DATA:http_user_agent}" "%{USERNAME:http_x_forwarded_for}"
logstash 的配置:
filter {
grok {
patterns_dir => "/etc/logstash/patterns/nginx_access_log"
match => {
"message" => "%{NGXACCESSLOG}"
}
}
}
output {
stdout {
codec => rubydebug
}
}
效果如下所示:
{
"host" => "localhost",
"http_referer" => "-",
"http_x_forwarded_for" => "127.0.0.1",
"request_time" => "0.000",
"remote_user" => "-",
"type" => "nginx_log",
"@timestamp" => 2020-09-15T08:19:27.001Z,
"request_mathod" => "GET",
"path" => "/data/logs/127.0.0.1.log",
"remote_addr" => "127.0.0.1",
"body_bytes_sent" => "4",
"status" => "200",
"http_user_agent" => "curl/7.29.0",
"message" => "0.000 127.0.0.1 - - [15/Sep/2020:16:19:26 +0800] "GET /ttt/test/123?plat=xxxx HTTP/1.0" 200 4 "-" "curl/7.29.0" "127.0.0.1"",
"request_protocol" => "HTTP/1.0",
"@version" => "1",
"request_path" => "/ttt/test/123?plat=xxxx"
}
正则调试:https://grokdebug.herokuapp.com
date
格式化日期
date {
match => [ "log_timestamp", "YYYY-MM-dd HH:mm:ss"]
}
geoip
借助GeoIP数据库来实现显示请求来源的地理位置,GeoIP 库可以根据 IP 地址提供对应的地域信息,包括国别,省市,经纬度等。
获取GeoIP数据库
wget https://raw.githubusercontent.com/wp-statistics/GeoLite2-City/master/GeoLite2-City.mmdb.gz
wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz
gzip -d GeoLite2-City.mmdb.gz
配置:
filter {
***
geoip {
source => "client_ip"
fields => ["city_name" , "country_name" ,"continent_code" , "continent_name" ]
database => "/etc/logstash/GeoLite2-City.mmdb"
}
}
参数:
- source:设置解析IP地址的字段
- fields:geoip数据库重需要的字段,主要有:city_name, continent_code, country_code2, country_code3, country_name, dma_code, ip, latitude, longitude, postal_code, region_name,timezone。
- target:将geoip数据保存到一个字段内
- database:IP地址数据库
output插件
redis
output配置如下:
output {
redis {
host => "127.0.0.1"
port => 6000
password => "8a6715"
data_type => "channel"
key => "logstash-%{+yyyy.MM.dd}"
}
}
redis效果:
127.0.0.1:6000> subscribe logstash-2017.06.22
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "logstash-2017.06.22"
3) (integer) 1
1) "message"
2) "logstash-2017.06.22"
3) "{"remote_addr":"192.168.31.130","request":"GET / HTTP/1.1","body_bytes_sent":"33","message":"192.168.31.130 - - [22/Jun/2017:15:51:22 +0800] \"GET / HTTP/1.1\" 200 33 \"-\" \"curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.14.0.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2\" \"-\"","type":"nginx-access-log","tags":[],"http_user_agent":"curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.14.0.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2","remote_user":"-","path":"/data/logs/nginx/logstash.wangshenjin.com_access.log","@timestamp":"2017-06-22T07:51:23.484Z","http_referer":"-","@version":"1","host":"baseos-1","http_x_forwarded_for":"-","status":"200"}"
参数:
- batch:设为true,通过发送一条rpush命令,存储一批的数据
- 默认为false:1条rpush命令,存储1条数据
- 设为true之后,1条rpush会发送batch_events条数据或发送batch_timeout秒(取决于哪一个先到达)
- batch_events:一次rpush多少条
- 默认50条
- batch_timeout:一次rpush最多消耗多少s
- 默认5s
- codec:对输出数据进行codec,避免使用logstash的separate filter
- congestion_interval:每多长时间进行一次拥塞检查(拥塞保护(仅用于data_type为list)
- 默认1s,设为0,表示对每rpush一个,都进行检测
- congestion_threshold:list中最多可以存在多少个item数据,默认是0:表示禁用拥塞检测
- 当list中的数据量达到congestion_threshold,会阻塞直到有其他消费者消费list中的数据
- 作用:防止OOM
- data_type
- list:使用rpush
- channel:使用publish
- db:使用redis的数据库,默认使用0号
- host:数组
- eg.["127.0.0.1:6380", "127.0.0.1"]
- 可以指定port,会覆盖全局port
- port:全局port,默认6379
- key:list或channel的名字
- 支持动态key,例如:logstash-%{type}
- password:redis密码,默认不使用密码
- reconnect_interval:失败重连的间隔,默认为1s
- timeout:连接超时,默认5s
elasticsearch
output配置如下:
output {
elasticsearch {
hosts => ["192.168.1.147:9200","192.168.1.151:9200"]
index => "nginx-access-log-%{+YYYY.MM.dd}" #定义index pattern
}
}
参数:
-
hosts:elasticsearch服务列表
- Default value is ["127.0.0.1"]
- Value type is string
-
action:指定es的行为,index, delete, create, update
- Default value is "index":index a document(该document就是一个来自于logstash的event)
- delete:通过id删除一个document(需要指定document_id)
- create:index a document(如果该document已经在index中存在,则失败)
- update:通过id更新一个document
-
index:指定文档索引,支持字符扩展%{foo}
- Value type is string
- Default value is "logstash-%{+YYYY.MM.dd}"
- 便于删除老数据
- 在语法解析的时候,看到+号开头的,会自动认为后面是时间格式,尝试用时间格式来解析后续字符串。所以,之前处理过程中不要给自定义的字段起一个+号开头的名字
- 索引名中不能有大写字母
- 有时也会自定义为:logstash-%{servicename}-%{+YYYY.MM.dd}
-
cacert:验证server合法性的.cer或.pem文件路径
- Value type is path
- There is no default value for this setting.
-
codec:用于输出数据之前对数据 进行解码的的编解码器,而不需要一个单独的LogStash过滤器。
- Value type is codec
- 默认值:"plain"
-
document_id:文档索引ID,用来覆盖es中现有相同ID文档
- Value type is string
- There is no default value for this setting.
-
document_type:文档索引类型,支持字符扩展%{foo},不设置文档类型,文档类型会被设置为logs
- Value type is string
- There is no default value for this setting.
-
user:进入es cluster的用户
-
password:进入es cluster的密码
-
timeout:Set the timeout for network operations and requests sent Elasticsearch. If a timeout occurs,the request will be retried.
-
flush_size:默认500,logstash攒够500条数据再一次性向es发送。从5.0开始,flush_size值不能超过batch_size,否者以batch_size为批量发送的大小
- Value type is number
- Default value is 500
-
idle_flush_time:默认1s,如果1s内没攒够500条还是会一次性将攒的数据发出去给es
-
ssl:开启SSL与ES集群通信,未指定该参数,是否启动SSL将由ES的URL决定,如果显式禁用SSL,在主机中给出一个HTTPS URL,该插件也将拒绝启动。
- Value type is boolean
- There is no default value for this setting.
详细参考:https://www.elastic.co/guide/en/logstash/7.9/plugins-outputs-elasticsearch.html