Elastic Stack传统上由三个主要组件ELKB(Elasticsearch,Logstash、Kibana和Beats)。
beats下面有几个框架(Filebeat、Packetbeat、Metricbeat、Heartbeat、Auditbeat、Winlogbeat、Functionbeat、)
官方配置文档解析
区别一:
Beats是轻量级(资源高效,无依赖性,小型)和开放源代码日志发送程序的集合。
Logstash是重量级的任务线程,执行需要耗费大量资源
区别二:
Filebeat采集配置更加便捷:可以同时控制多个采集点开关。(使用Filebeat的enabled字段等)
Filebeat由两个主要组件组成:prospector
和harvester
harvester:
prospector:
Filebeat如何保持文件的状态?
Filebeat 保存每个文件的状态并经常将状态刷新到磁盘上的注册文件中。
该状态用于记住harvester正在读取的最后偏移量,并确保发送所有日志行。
如果输出(例如Elasticsearch或Logstash)无法访问,Filebeat会跟踪最后发送的行,并在输出再次可用时继续读取文件
在Filebeat运行时,每个prospector内存中也会保存的文件状态信息,当重新启动Filebeat时,将使用注册文件的数据来重建文件状态,Filebeat将每个harvester在从保存的最后偏移量继续读取
文件状态记录在data/registry文件中
主要是关于filebeat.inputs,和outputs两个的配置。
官方博客
Filebeat支持的输入类型
inputs主要使用的几个配置项:
借鉴博客
Filebeat的高级配置详解借鉴博客
借鉴博客
借鉴博客
filebeat.inputs:
- type: log ①
paths:
- /var/log/system.log
- /var/log/wifi.log
- type: log ②
paths:
- "/var/log/apache2/*"
fields:
apache: true
fields_under_root: true
①表示从system.log和wifi.log收集日志
②表示收集apache2文件夹下的所有内容,并且使用fileds配置项将apache字段添加到输出中的根节点
paths:待收集日志的路径列表,可以为每行指定一个路径,每行以破折号(-)开头。Filebeat会为它在指定路径下找到的每个文件启动一个harvester(收集器)
multiline : 例如配置如下:
multiline.pattern:'^[[:space:]]+'
multiline.negate: false
multiline.match: after
multiline.negate默认为false即逻辑不取反,这时只有符合multiline.pattern匹配条件的日志才会被合并
此时以空格开头的日志会被合并到上一行后面,如以下的日志采集可使用
Caused by: java.io.IOException: null
at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:105) ~[amqp-client-4.0.3.jar:4.0.3]
at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:101) ~[amqp-client-4.0.3.jar:4.0.3]
把后面两行以空格开头的日志合并到第一行上,整体在一起算一条完整的日志
multiline.negate为true,表示逻辑取反,这是只有不符合multiline.pattern匹配条件的日志才会被合并,如上例 将会匹配不以空格开始的行,合并到上一行
fields:可选字段,您可以指定将附加信息添加到输出中。例如,可以添加可用于筛选日志数据的字段。字段可以是标量值、数组、字典或它们的任何嵌套组合。
fields_under_root: 将自定义字段显示为顶级字段
fields:
level: debug
fields:
level: debug
fields_under_root: true
使用 TCP type 来收集日志
filebeat.inputs:
# 添加的部分
- type: tcp
max_message_size: 10MiB
host: "0.0.0.0:9900"
在上面,我们添加了一个 TCP 的输入。它监听的地址是 0.0.0.0:9900。
Filebeat支持的输出类型
原博客
版本不同添加的参数不同
示例
output.elasticsearch:
hosts: ["https://localhost:9200"]
index: "filebeat-%{[beat.version]}-%{+yyyy.MM.dd}"
ssl.certificate_authorities: ["/etc/pki/root/ca.pem"]
ssl.certificate: "/etc/pki/client/cert.pem"
ssl.key: "/etc/pki/client/cert.key"
使用%{[]}可以引用事件中的属性。
如果没有指定index,默认会按照filebeat-版本号-日期格式生成一个索引,默认索引格式:
相关配置参数
index 参数使用 :
如 将索引名称改为elk-file
output.elasticsearch.index: "elk-file-%{[agent.version]}-%{+yyyy.MM.dd}"
setup.template.name: "elk-file"
setup.template.pattern: "elk-file-*"
setup.ilm.enabled: false
从7.0版本开始,索引生命周期管理(ILM)默认是开启状态,当开启状态时候setup.template.name和setup.template.pattern两个参数不生效,所以还需要配置关闭ILM,即setup.ilm.enabled: false
索引生命周期管理(ILM)默认是开启状态,在不关闭ILM情况下更改索引名称。在配置文件filebeat.yml添加以下选项即可。
setup.ilm.enabled: auto
setup.ilm.rollover_alias: "elk-file"
setup.ilm.pattern: "{now/d}-000001"
重启后,索引名称为elk-file-yyyy.MM.dd-000001 格式。
indices 参数使用
indices 包含的可选参数 :
下面举一些例子:
output.elasticsearch:
hosts: ["http://localhost:9200"]
indices:
- index: "warning-%{[beat.version]}-%{+yyyy.MM.dd}"
when.contains: # 如果一个事件中的message字段包含"WARN" ,索引名称就是"warning-%{[beat.version]}-%{+yyyy.MM.dd}"
message: "WARN"
- index: "error-%{[beat.version]}-%{+yyyy.MM.dd}"
when.contains: # 如果一个事件中的message字段包含"ERR" ,索引名称就是"error-%{[beat.version]}-%
message: "ERR"
output.elasticsearch:
hosts: ["http://localhost:9200"]
indices:
- index: "%{[fields.log_type]}"
# 如果事件中"fields.log_type"字段的值是critical,那么索引就是sev1,如果是normal那么索引名就是sev2,没有匹配的项索引名就是sev3;通过 inputs下的fields指定自定义属性与值
mappings:
critical: "sev1"
normal: "sev2"
default: "sev3"
简单的输出模板
#-------------------------- Elasticsearch output ------------------------------
output.elasticsearch:
# Array of hosts to connect to.
hosts: ["localhsot:9200"]
index: "ngnix-%{+yyyy.MM}"
#因为我是分析ngnix 所以...
setup.template.name: "ngnix"
#这是指定分析索引为ngnix-开头的所有
setup.template.pattern: "ngnix-*"
#禁用自定义模板
setup.template.enabled: false
#覆盖原来的模板
setup.template.overwrite: true
#停用ilm 这一步很重要
setup.ilm.enabled: false
示例
output.logstash:
hosts: ["127.0.0.1:5044"]
每个事件都包含如下字段
{
...
"@metadata": {
"beat": "filebeat",
"version": "6.8.14"
"type": "doc"
}
}
配置参数
原文
filebeat.yml 配置如下:
filebeat.inputs:
- type: log
tail_files: true
scan_frequency: 5s
backoff: 1s
max_backoff: 10s
paths:
- /var/log/messages*
fields:
type: messages
ip: 192.168.139.129
fields_under_root: true
- type: log
tail_files: true
scan_frequency: 5s
backoff: 1s
max_backoff: 10s
paths:
- /var/log/secure*
fields:
type: secure
ip: 192.168.139.129
fields_under_root: true
output.logstash:
hosts: ["192.168.139.128:5044"]
logstash.conf 配置如下(不解析):
input {
beats {
host => '0.0.0.0'
port => 5044
}
}
output{
if [type] == "secure" {
elasticsearch {
hosts => ["http://192.168.139.128:9200"]
index => "secure-%{+YYYY.MM.dd}"
}
}
else if [type] == "messages" {
elasticsearch {
hosts => ["http://192.168.139.128:9200"]
index => "messages-%{+YYYY.MM.dd}"
}
}
}
filebeat.yml 配置如下:
filebeat.inputs:
- type: log
tail_files: true
scan_frequency: 5s
backoff: 1s
max_backoff: 10s
paths:
- /var/log/messages*
fields:
type: messages
ip: 192.168.139.129
fields_under_root: true
- type: log
tail_files: true
scan_frequency: 5s
backoff: 1s
max_backoff: 10s
paths:
- /var/log/secure*
fields:
type: secure
ip: 192.168.139.129
fields_under_root: true
output.logstash:
hosts: ["192.168.139.128:5044"]
logstash.conf 配置如下(解析):
input {
beats {
host => '0.0.0.0'
port => 5044
}
}
filter {
if [type] == "access" {
grok {
match => {
"message" => '(?[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}) - (?\S+) \[(?[^ ]+ \+[0-9]+)\] "(?[A-Z]+) (?[^
]+) HTTP/\d.\d" (?\d+) (?\d+) "(?\S+)" "[^"]+"' }
#移除不需要的字段
remove_field => ["message","@version","path"]
}
date {
match => ["requesttime", "dd/MMM/yyyy:HH:mm:ss Z"]
target => "@timestamp"
}
}
}
output{
if [type] == "secure" {
elasticsearch {
hosts => ["http://192.168.139.128:9200"]
index => "secure-%{+YYYY.MM.dd}"
}
}
else if [type] == "messages" {
elasticsearch {
hosts => ["http://192.168.139.128:9200"]
index => "messages-%{+YYYY.MM.dd}"
}
}
else if [type] == "access" {
elasticsearch {
hosts => ["http://192.168.139.128:9200"]
index => "access-%{+YYYY.MM.dd}"
}
}
}
output.redis:
hosts: ["192.168.136.101:6379"]
key: "filebeat-redis"
db: 0
timeout: 5
hosts参数指定了Redis的IP和端口号,key参数指定了在Redis中插入的索引,db指定了Redis的库,timeout参数则指定了超时时间。
其他参数 :
output.redis:
enabled: true
codec.json:
pretty: false
escape_html: false
hosts: ["localhost:6379"]
key: filebeat
password: '*****'
db: 0
##发布事件的Redis数据类型。如果数据类型为list,则使用RPUSH命令;如果数据类型为channel,则使用PUBLISH命令。默认值为list。
datatype: list
##发布事件到每个Redis的工作线程数。将此设置与loadbalance选项一起使用。例如,如果有2台主机和3台工作机,则总共启动6台工作机(每个主机3台)。
worker: 1
#如果设置为true并且配置了多个hosts或worker,则会将发布的事件负载平衡到所有Redis主机上。
#如果设置为false,则只向一个主机发送所有事件(随机确定),如果当前选定的主机无法访问,则将切换到另一个主机。
#默认值为true。
loadbalance: true
timeout: 5s
##发布失败后重试发布事件的次数。在指定的重试次数之后,通常会删除事件。
max_retries: 3
##网络错误后等待多久尝试重新连接到Redis。
backoff.init: 1s
##网络错误后尝试连接到Redis之前等待的最大秒数。默认值为60秒。
#backoff.max: 60s
#单个Redis请求或管道中要批量处理的最大事件数。默认值为2048。
bulk_max_size: 2048
示例代码
output.kafka:
hosts: ["kafka1:9092", "kafka2:9092", "kafka3:9092"]
# 指定主题
topic: '%{[fields.log_topic]}'
partition.round_robin:
reachable_only: false
required_acks: 1
compression: gzip
max_message_bytes: 1000000
这个output适用于0.11到2.0.0之间的所有Kafka版本。旧版本也可以工作,但不在维护。
配置参数
enable: 是否启用配置
hosts: kafka broker节点地址列表
version: kafka的版本号。0.8.2.0 ~ 2.0.0。默认1.0.0
worker: 为每个kafka节点开启的工作线程数量。
username: kafka用户名
password: kafka密码
topic: 指定主题
topics: 这个和上面es中的indices类似
key: 事件的key,用于计算hash值
partition: 指定输出kafka分区策略,三个选项random,round_robin,hash. 默认hash
codec: 输出编码格式,默认json
metadata: Kafka元数据更新相关设置。metadata信息brokers, topics, partition, 和活动的leaders等信息
refresh_frequency: 元数据刷新间隔。默认为10分钟。
retry.max: 集群在leader选举时重试读取元数据次数。缺省值是3。
retry.backoff: 重试时间间隔。
bulk_max_size: 单个kafka处理的最大事件数。默认值为50
timeout: 等待kafka brokers的响应时间。默认30s
broker_timeout:
channel_buffer_size: 每个Kafka broker输出管道中缓冲的消息数。缺省值是256。
keep_alive: 连接的存活时间,默认为0,禁用保持活动连接状态
compression: 压缩类型,none、snappy、lz4、gzip。默认gzip
compression_level: gzip压缩级别。设置为0禁用压缩。压缩级别必须在1(最佳速度)到9(最佳压缩)的范围内。增加压缩级别会减少网络使用,但会增加cpu使用。默认4
max_message_bytes: JSON消息的最大允许大小。超出的消息将被删除。缺省值是1000000(字节)。此值应小于kafka配置中broker的message.max.bytes参数
required_acks: kafka的响应返回值,0位无等待响应返回,继续发送下一条消息;1表示等待本地提交(leader broker已经成功写入,但follower未写入),-1表示等待所有副本的提交,默认为1
ssl: ssl相关配置.https://www.elastic.co/guide/en/beats/filebeat/6.8/configuration-ssl.html
配置filebeat的输出方式为文件
# 采集配置
filebeat.inputs: #收集日志
- type: log #类型
enabled: true #始终收集
paths:
- /etc/log/*.log
# 输出配置
output.file:
path: "/tmp/filebeat" # 输出路径
filename: filebeat # 输出文件名
output.console:
enabled: true
codec.json:
pretty: false
escape_html: false
#从input读取事件源,经过相应解析和处理之后,从output输出到目标存储库(elasticsearch或其他)。
#输入可以从Log、Syslog、Stdin、Redis、UDP、Docker、TCP、NetFlow输入,然后可以输出到Elasticsearch、Logstash、Kafka、Redis、File、Console、Cloud。
############################# Filebeat ######################################
filebeat:
prospectors:
-
# 指定要监控的日志,可以指定具体得文件或者目录
paths:
- /var/log/*.log (这是默认的)(自行可以修改)(比如我放在/home/hadoop/app.log里)
# 指定被监控的文件的编码类型,使用plain和utf-8都是可以处理中文日志的
#encoding: plain
# 指定文件的输入类型log(默认)或者stdin
input_type: log
# 在输入中排除符合正则表达式列表的那些行。
# exclude_lines: ["^DBG"]
# 包含输入中符合正则表达式列表的那些行(默认包含所有行),include_lines执行完毕之后会执行exclude_lines
# include_lines: ["^ERR", "^WARN"]
# 忽略掉符合正则表达式列表的文件
# exclude_files: [".gz$"]
# 向输出的每一条日志添加额外的信息,比如“level:debug”,方便后续对日志进行分组统计。
# 默认情况下,会在输出信息的fields子目录下以指定的新增fields建立子目录,例如fields.level
# 这个得意思就是会在es中多添加一个字段,格式为 "filelds":{"level":"debug"}
#fields:
# level: debug
# review: 1
# 如果该选项设置为true,则新增fields成为顶级目录,而不是将其放在fields目录下。
# 自定义的field会覆盖filebeat默认的field
# 如果设置为true,则在es中新增的字段格式为:"level":"debug"
#fields_under_root: false
# 可以指定Filebeat忽略指定时间段以外修改的日志内容,比如2h(两个小时)或者5m(5分钟)。
#ignore_older: 0
# 如果一个文件在某个时间段内没有发生过更新,则关闭监控的文件handle。默认1h
#close_older: 1h
# 设定Elasticsearch输出时的document的type字段 可以用来给日志进行分类。Default: log
#document_type: log
# Filebeat以多快的频率去prospector指定的目录下面检测文件更新(比如是否有新增文件)
# 如果设置为0s,则Filebeat会尽可能快地感知更新(占用的CPU会变高)。默认是10s
#scan_frequency: 10s
# 每个harvester监控文件时,使用的buffer的大小
#harvester_buffer_size: 16384
# 日志文件中增加一行算一个日志事件,max_bytes限制在一次日志事件中最多上传的字节数,多出的字节会被丢弃,default is 10MB.
#max_bytes: 10485760
# 适用于日志中每一条日志占据多行的情况,比如各种语言的报错信息调用栈
#multiline:
# 多行日志开始的那一行匹配的pattern
#pattern: ^\[
# 是否需要对pattern条件转置使用,不翻转设为true,反转设置为false。 【建议设置为true】
#negate: false
# 匹配pattern后,与前面(before)还是后面(after)的内容合并为一条日志
#match: after
# 合并的最多行数(包含匹配pattern的那一行)
#max_lines: 500
# 到了timeout之后,即使没有匹配一个新的pattern(发生一个新的事件),也把已经匹配的日志事件发送出去
#timeout: 5s
# 如果设置为true,Filebeat从文件尾开始监控文件新增内容,把新增的每一行文件作为一个事件依次发送,
# 而不是从文件开始处重新发送所有内容
#tail_files: false
# Filebeat检测到某个文件到了EOF(文件结尾)之后,每次等待多久再去检测文件是否有更新,默认为1s
#backoff: 1s
# Filebeat检测到某个文件到了EOF之后,等待检测文件更新的最大时间,默认是10秒
#max_backoff: 10s
# 定义到达max_backoff的速度,默认因子是2,到达max_backoff后,变成每次等待max_backoff那么长的时间才backoff一次,
# 直到文件有更新才会重置为backoff
# 根据现在的默认配置是这样的,每隔1s检测一下文件变化,如果连续检测两次之后文件还没有变化,下一次检测间隔时间变为10s
#backoff_factor: 2
# 这个选项关闭一个文件,当文件名称的变化。#该配置选项建议只在windows
#force_close_files: false
# spooler的大小,spooler中的事件数量超过这个阈值的时候会清空发送出去(不论是否到达超时时间)
#spool_size: 2048
# 是否采用异步发送模式(实验功能)
#publish_async: false
# spooler的超时时间,如果到了超时时间,spooler也会清空发送出去(不论是否到达容量的阈值)
#idle_timeout: 5s
# 记录filebeat处理日志文件的位置的文件,默认是在启动的根目录下
#registry_file: .filebeat
# 如果要在本配置文件中引入其他位置的配置文件,可以写在这里(需要写完整路径),但是只处理prospector的部分
#config_dir:
############################# Libbeat Config ##################################
# Base config file used by all other beats for using libbeat features
############################# Output ##########################################
output:
elasticsearch: #(这是默认的,filebeat收集后放到es里)(自行可以修改,比如我有时候想filebeat收集后,然后到redis,再到es,就可以注销这行)
hosts: ["localhost:9200"] (这是默认的,filebeat收集后放到es里)(自行可以修改,比如我有时候想filebeat收集后,然后到redis,再到es,就可以注销这行)
Logstash依赖于JVM,在启动的时候大家也很容易就能发现它的启动速度很慢很慢,但logstash的好处是支持很多类型的插件,支持对数据做预处理。而filebeat很轻量,前身叫logstash-forward,是使用Golang开发的,所以不需要有java依赖,也很轻量,占用资源很小,但功能也很少,不支持对数据做预处理。因此一般都是将filebeat+logstash组合使用,在每个节点部署filbeat,然后将监控的日志推送到数据缓冲层或直接推送到logstash集群内,配合redis或kafka做数据缓冲层来使用。
配置Filebeat :
filebeat.inputs:
- type: log
paths:
- /var/log/nginx/*.log
fields:
log_type: "nginx"
json.key_under_root: true
json.overwite_keys: true
- type: log
enabled: true
paths:
- /var/log/elasticsearch/elasticsearch.log
fields:
log_type: "es"
multiline.pattern: '^\s'
multiline.negate: true
multiline.match: after
- type: log
enabled: true
paths:
- /data/ruoyi/*.log
fields:
log_type: "ruoyi"
multiline.pattern: '^\s'
multiline.negate: true
multiline.match: after
output.logstash:
enabled: true
hosts: ["localhost:5044"]
配置 Logstash :
input {
#从filebeat取数据,端口与filebeat配置文件一致
beats {
port => 5044
}
}
filter {
#只对nginx的json日志做json解析,系统message为其他格式,无需处理
if [fields][log_type] == "nginx"{
json {
source => "message"
remove_field => ["beat","offset","tags","prospector"] #移除字段,不需要采集
}
date {
match => ["timestamp", "dd/MMM/yyyy:HH:mm:ss Z"] #匹配timestamp字段
target => "@timestamp" #将匹配到的数据写到@timestamp字段中
}
}
}
output {
# 输出es,这的filetype就是在filebeat那边新增的自定义字段名
if [fields][log_type] == "es" {
elasticsearch {
hosts => ["node1:9200","node2:9200"]
index => "es-%{+YYYY.MM}"
}
}
if [fields][log_type] == "ruoyi" {
elasticsearch {
hosts => ["node1:9200","node2:9200"]
index => "ruoyi-%{+YYYY.MM.dd}"
}
}
if [fields][log_type] == "nginx" {
elasticsearch {
hosts => ["node1:9200","node2:9200"]
index => "nginx-%{+YYYY.MM}"
}
}
}
先启动logstash,不然的话filebeat会找不到logstash的5044端口