第1章 Kibana
kibana是一款开源的数据分析和可视化平台,它是Elastic Stack成员之一,设计用于和elasticsearch协作。您可以使用 kibana对elasticsearch索引中的数据进行搜索、查看、交互操作。您可以很方便的利用图表、表格及地图对数据进行多元化的分析和呈现。
kibana官方展示页面地址:https://demo.elastic.co/app/kibana#/dashboard/welcome_dashboard
kibana官网链接:https://www.elastic.co/cn/products/kibana
安装kibana,可以和es装在一台机器上,至少得2G内存。
1.1 配置安装
几台服务器需要的内存以及服务划分如下:
elk1:2G-4G
es
kibana
nginx
filebeat
...
elk2:512M-2G
nginx
filebeat
...
# 解压安装包
tar -xvf kibana-6.5.4-linux-x86_64.tar.gz
# 修改配置文件
grep ^[a-Z] kibana.yml
server.port: 5601
server.host: "192.168.172.101" # 对外暴露服务的地址
server.name: "elk1"
elasticsearch.url: "http://192.168.172.101:9200" # 配置Elasticsearch
kibana.index: ".kibana"
# 启动
./bin/kibana
# 通过浏览器进行访问
http://192.168.172.101:5601/app/kibana
可以看到kibana页面,并且可以看到提示,导入数据到Kibana。
1.2 功能说明
1.3 数据探索
添加索引信息
即可查看索引数据
1.4 Metricbeat仪表盘
可以将Metricbeat的数据在Kibana中展示。
# 修改metricbeat配置
setup.kibana:
host: "192.168.172.101:5601"
# 安装仪表盘到Kibana
./metricbeat setup --dashboards
即可在kibana中看到仪表盘数据:
查看系统信息:
1.5 Nginx指标仪表盘
1.6 Nginx日志仪表盘
# 修改配置文件 itcast-nginx.yml
filebeat.inputs:
#- type: log
# enabled: true
# paths:
# - /var/log/nginx/*.log
# tags: ["nginx"]
setup.kibana:
host: "192.168.172.101:5601"
setup.template.settings:
index.number_of_shards: 3
filebeat.config.modules:
path: ${path.config}/modules.d/*.yml
reload.enabled: false
output.elasticsearch:
hosts: ["192.168.172.101:9200"]
# 安装仪表盘到kibana
./filebeat -c itcast-nginx.yml setup
可以看到nginx的FileBeat的仪表盘了:
1.7 kibana自定义图表
在Kibana中,也可以进行自定义图表,如制作柱形图:
默认如果使用filebeat模板导入视图会把所有的服务都导入进去,而我们实际上并不需要这么多视图,而且默认的视图模板只能匹配 filebeat-*
开头的索引,所以这里我们有2个需求需要解决:
- 1.通过一定处理只导入我们需要的模板
- 2.导入的视图模板索引名称为我们需要的索引名称
解决方法:
- 1.备份一份filebeat的kibana视图,删除不需要的视图模板文件
- 2.修改视图文件里默认的索引名称为我们需要的索引名称
filebeat安装路径下也有kibana目录,里面有 kibana5
和 kibana6
的图表。
/usr/local/filebeat/kibana/5
的内容可以删掉,将 /usr/local/filebeat/kibana/6/dashboard和/usr/local/filebeat/kibana/6/index-pattern
两个目录可以备份到root目录下。
cd /usr/local/filebeat/kibana/6/dashboard
sed -n 's#filebeat\-\*#nginx\-\*#g' Filebeat-nginx-logs.json
sed -n 's#filebeat\-\*#nginx\-\*#gp' Filebeat-nginx-logs.json
# 更改文件内容,替换索引名称
sed -i 's#filebeat\-\*#nginx\-\*#gp' Filebeat-nginx-logs.json
sed -i 's#filebeat\-\*#nginx\-\*#gp' Filebeat-nginx-overview.json
cd /usr/local/filebeat/kibana/6/index-pattern
sed -i 's#filebeat\-\*#nginx\-\*#gp' filebeat.json
# 导入
./filebeat setup --dashboards -E setup.dashboards.directory=/usr/local/filebeat/kibana
常用的图表类型:
1.柱状图
2.折线图
3.饼图
4.仪表图
5.拼接大屏展示
可以实现的功能:
1.访问最多的IP地址前10
2.访问最多的url前10
3.访问最多的agent前10
4.访问http状态码比例
将图表添加到自定义Dashboard中:
1.8 开发者工具
在Kibana中,为开发者的测试提供了便捷的工具使用,比如我们用postman对es索引做的一些操作,其实也可以在kibana中完成,如下:
1.9 kibana监控es集群
elk版本统一,一个系列的组件必须都是一个版本,要升级也是同时升级到一个版本。而且只能升级,很难降级,因为数据很难还原成老版本的,所以生产环境中的软件升级版本操作都需要谨慎。
x-pack
收费,后来大家破解,所以逐步开放功能,后续6.6版本后 x-pack
的监控功能也开放了,变免费了。
点击kibana界面的monitoring项就可以了。
第2章 Nginx日志分析系统
2.1 项目需求
Nginx是一款非常优秀的web服务器,往往nginx服务会作为项目的访问入口,那么,nginx的性能保障就变得非常重
要了,如果nginx的运行出现了问题就会对项目有较大的影响。所以,我们需要对nginx的运行有监控措施,实时掌握
nginx的运行情况,那就需要收集nginx的运行指标和分析nginx的运行日志了。
2.2 业务流程
说明:
- 通过Beats采集Nginx的指标数据和日志数据
- Beats采集到数据后发送到Elasticsearch中
- kibana读取数据进行分析
- 用户通过kibana进行查看分析报表
2.3 部署安装nginx
# 安装nginx和压测工具
yum install epel-release.noarch -y
yum install nginx httpd-tools -y
# 启动nginx后可以ab压测,ip后面不加反斜杠会失败
ab -n 100 -c 100 http://192.168.172.101/
# 查看默认格式的访问日志
tail -n 10 /var/log/nginx/access.log
192.168.172.101 - - [09/May/2022:10:59:00 +0800] "GET / HTTP/1.0" 200 4833 "-" "ApacheBench/2.3" "-"
192.168.172.101 - - [09/May/2022:10:59:00 +0800] "GET / HTTP/1.0" 200 4833 "-" "ApacheBench/2.3" "-"
192.168.172.101 - - [09/May/2022:10:59:00 +0800] "GET / HTTP/1.0" 200 4833 "-" "ApacheBench/2.3" "-"
192.168.172.101 - - [09/May/2022:10:59:00 +0800] "GET / HTTP/1.0" 200 4833 "-" "ApacheBench/2.3" "-"
192.168.172.101 - - [09/May/2022:10:59:00 +0800] "GET / HTTP/1.0" 200 4833 "-" "ApacheBench/2.3" "-"
192.168.172.101 - - [09/May/2022:10:59:00 +0800] "GET / HTTP/1.0" 200 4833 "-" "ApacheBench/2.3" "-"
192.168.172.101 - - [09/May/2022:10:59:00 +0800] "GET / HTTP/1.0" 200 4833 "-" "ApacheBench/2.3" "-"
192.168.172.101 - - [09/May/2022:10:59:00 +0800] "GET / HTTP/1.0" 200 4833 "-" "ApacheBench/2.3" "-"
192.168.172.101 - - [09/May/2022:10:59:00 +0800] "GET / HTTP/1.0" 200 4833 "-" "ApacheBench/2.3" "-"
192.168.172.101 - - [09/May/2022:10:59:00 +0800] "GET / HTTP/1.0" 200 4833 "-" "ApacheBench/2.3" "-"
第3章 Beats简介
官网:https://www.elastic.co/cn/products/beats
Beats系列产品:
3.2 filebeat
3.2.1 架构
用于监控、收集服务器日志文件
3.2.2 部署与运行
下载(或使用资料中提供的安装包,版本为:filebeat-6.5.4):https://www.elastic.co/downloads/beats
# 安装filebeat
tar zxf filebeat-6.5.4-linux-x86_64.tar.gz -C /usr/local/
# 配置文件包括:
filebeat.yml以及modules.d目录下的,编辑filebeat.yml之前可以先备份。
# 创建配置文件itcast.yml:
filebeat.inputs:
- type: stdin
enabled: true
setup.template.settings:
index.number_of_shards: 3
output.console:
pretty: true
enable: true
# 启动filebeat:
./filebeat -e -c itcast.yml
# 输入hello运行结果如下:
hello
{
"@timestamp": "2022-05-13T03:14:19.320Z",
"@metadata": { # 元数据信息
"beat": "filebeat",
"type": "doc",
"version": "6.5.4"
},
"prospector": { # 标准输入勘探器
"type": "stdin"
},
"beat": { # beat版本以及主机信息
"name": "elk1",
"hostname": "elk1",
"version": "6.5.4"
},
"host": {
"name": "elk1"
},
"source": "",
"offset": 0,
"message": "hello", # 输入的内容
"input": {
"type": "stdin" # 控制台标准输入
}
}
3.2.3 读取文件
# 配置读取文件项 itcast-log.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/nginx/*.log
setup.template.settings:
index.number_of_shards: 3
output.console:
pretty: true
enable: true
# 启动filebeat
./filebeat -e -c itcast-log.yml
# /itcast/beats/logs/下创建a.log文件,并输入如下内容
hello
world
# 观察filebeat输出
{
"@timestamp": "2022-05-13T03:27:13.285Z",
"@metadata": {
"beat": "filebeat",
"type": "doc",
"version": "6.5.4"
},
"prospector": {
"type": "log"
},
"input": {
"type": "log"
},
"beat": {
"name": "elk1",
"hostname": "elk1",
"version": "6.5.4"
},
"host": {
"name": "elk1"
},
"message": "hello",
"source": "/itcast/beats/logs/a.log",
"offset": 0
}
{
"@timestamp": "2022-05-13T03:27:13.285Z",
"@metadata": {
"beat": "filebeat",
"type": "doc",
"version": "6.5.4"
},
"prospector": {
"type": "log"
},
"beat": {
"name": "elk1",
"hostname": "elk1",
"version": "6.5.4"
},
"host": {
"name": "elk1"
},
"source": "/itcast/beats/logs/a.log",
"offset": 6,
"message": "world",
"input": {
"type": "log"
}
}
可以看到,已经检测到日志文件有更新,立刻就会读取到更新的内容,并且输出到控制台。
3.2.4 自定义字段
# 配置读取文件itcast-log.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /itcast/beats/logs/*.log
# 添加自定义tag,便于后续的处理
tags: ["web"]
# 添加自定义字段
fields:
from: itcast-im
# true为添加到根节点,false为添加到子节点中
fields_under_root: true
setup.template.settings:
index.number_of_shards: 3
output.console:
pretty: true
enable: true
# 启动filebeat
./filebeat -e -c itcast-log.yml
# 在/itcast/beats/logs下创建b.log,并输入如下内容:
123
# 执行结果:
{
"@timestamp": "2022-05-13T03:41:16.813Z",
"@metadata": {
"beat": "filebeat",
"type": "doc",
"version": "6.5.4"
},
"tags": [
"web"
],
"prospector": {
"type": "log"
},
"input": {
"type": "log"
},
"beat": {
"name": "elk1",
"hostname": "elk1",
"version": "6.5.4"
},
"host": {
"name": "elk1"
},
"source": "/itcast/beats/logs/b.log",
"offset": 0,
"message": "123",
"from": "itcast-im"
}
3.2.5 输出到Elasticsearch
# filebeat.yml文件内容 egrep -v "#|^$" filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/nginx/access.log
filebeat.config.modules:
path: ${path.config}/modules.d/*.yml
reload.enabled: false
setup.template.settings:
index.number_of_shards: 3 # 指定索引的分区数
setup.kibana:
output.elasticsearch: # 指定ES的配置
hosts: ["192.168.172.101:9200"]
processors:
- add_host_metadata: ~
- add_cloud_metadata: ~
# 最精简的版本是:
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/nginx/access.log
output.elasticsearch:
hosts: ["192.168.172.101:9200"]
# 启动filebeat
./filebeat -e -c filebeat.yml
这种方式收集nginx日志有一个缺点是,内容没有经过处理,所有的字段都放在一个message字段里了,只是读取到原数据,这对于我们后期操作时不利的,也不利于在kibana界面添加关键词。
3.2.6 Filebeat工作原理
Filebeat由两个主要组件组成:prospector
和 harvester
,这两个组件协同工作将文件变动发送到指定的输出中。
- Harvester(收割机):
负责读取单个文件内容。每个文件会启动一个Harvester,每个Harvester会逐行读取各个文件,并将文件内容发送到指定输出中。Harvester负责打开和关闭文件,意味在Harvester运行的时候,文件描述符处于打开状态,如果文件在收集中被重命名或者被删除,Filebeat会继续读取此文件。所以在Harvester关闭之前,磁盘不会被释放。默认情况filebeat会保持文件打开的状态,直到达到close_inactive
(如果此选项开启,filebeat会在指定时间内将不再更新的文件句柄关闭,时间从harvester读取最后一行的时间开始计时。若文件句柄被关闭后,文件发生变化,则会启动一个新的harvester。关闭文件句柄的时间不取决于文件的修改时间,若此参数配置不当,则可能发生日志不实时的情况,由scan_frequency
参数决定,默认10s。Harvester使用内部时间戳来记录文件最后被收集的时间。例如:设置5m,则在Harvester读取文件的最后一行之后,开始倒计时5分钟,若5分钟内文件无变化,则关闭文件句柄。默认5m)。 - prospector(勘探者):管理Harvester并找到所有要读取的文件来源。Filebeat目前支持两种prospector类型:log和stdin。
filebeat.prospectors:
- input_type: log
paths:
- /apps/logs/*/info.log
Prospector会找到 /apps/logs/*
目录下的所有 info.log
文件,并为每个文件启动一个Harvester。Prospector会检查每个文件,看Harvester是否已经启动,是否需要启动,或者文件是否可以忽略。若Harvester关闭,只有在文件大小发生变化的时候Prospector才会执行检查。只能检测本地的文件。
Filebeat如何记录文件状态:
将文件状态记录在文件中(默认在 /var/lib/filebeat/registry
)。此状态可以记住Harvester收集文件的偏移量。若连接不上输出设备,如ES等,filebeat会记录发送前的最后一行,并再可以连接的时候继续发送。Filebeat在运行的时候,Prospector状态会被记录在内存中。Filebeat重启的时候,利用registry记录的状态来进行重建,用来还原到重启之前的状态。每个Prospector会为每个找到的文件记录一个状态,对于每个文件,Filebeat存储唯一标识符以检测文件是否先前被收集。
cat /usr/local/filebeat/data/registry
[{"source":"/var/log/nginx/access.log","offset":0,"timestamp":"2022-05-13T11:24:47.383885505+08:00","ttl":-2,"type":"log","meta":null,"FileStateOS":{"inode":1952430,"device":64768}},{"source":"/var/log/nginx/error.log","offset":0,"timestamp":"2022-05-13T11:24:47.38635557+08:00","ttl":-2,"type":"log","meta":null,"FileStateOS":{"inode":1952431,"device":64768}},{"source":"/var/log/tomcat/localhost_access_log.2022-05-10.txt","offset":1538,"timestamp":"2022-05-10T14:07:09.20403083+08:00","ttl":-2,"type":"log","meta":null,"FileStateOS":{"inode":1607199,"device":64768}},{"source":"/var/log/elasticsearch/elasticsearch.log","offset":5426,"timestamp":"2022-05-10T14:07:09.206505213+08:00","ttl":-2,"type":"log","meta":null,"FileStateOS":{"inode":201340004,"device":64768}},{"source":"/itcast/beats/logs/a.log","offset":12,"timestamp":"2022-05-13T13:40:29.577318337+08:00","ttl":-2,"type":"log","meta":null,"FileStateOS":{"inode":136020015,"device":64768}},{"source":"/itcast/beats/logs/b.log","offset":4,"timestamp":"2022-05-13T13:40:29.577817554+08:00","ttl":-2,"type":"log","meta":null,"FileStateOS":{"inode":136020014,"device":64768}},{"source":"/itcast/beats/logs/q.log","offset":4,"timestamp":"2022-05-13T13:46:54.62428932+08:00","ttl":-2,"type":"log","meta":null,"FileStateOS":{"inode":136020018,"device":64768}},{"source":"/itcast/logs/app.log","offset":8482,"timestamp":"2022-05-14T14:16:25.01718088+08:00","ttl":-1,"type":"log","meta":null,"FileStateOS":{"inode":205062805,"device":64768}}]
Filebeat如何保证事件至少被输出一次:
Filebeat之所以能保证事件至少被传递到配置的输出一次,没有数据丢失,是因为filebeat将每个事件的传递状态保存在文件中。在未得到输出方确认时,filebeat会尝试一直发送,直到得到回应。若filebeat在传输过程中被关闭,则不会再关闭之前确认所有时事件。任何在filebeat关闭之前为确认的时间,都会在filebeat重启之后重新发送。这可确保至少发送一次,但有可能会重复。可通过设置shutdown_timeout
参数来设置关闭之前的等待事件回应的时间(默认禁用)。
Filebeat如何保持文件的状态:
- Filebeat 保存每个文件的状态并经常将状态刷新到磁盘上的注册文件中。该状态用于记住harvester正在读取的最后偏移量,并确保发送所有日志行。如果输出(例如Elasticsearch或Logstash)无法访问,Filebeat会跟踪最后发送的行,并在输出再次可用时继续读取文件。在Filebeat运行时,每个prospector内存中也会保存的文件状态信息,当重新启动Filebeat时,将使用注册
文件的数据来重建文件状态,Filebeat将每个harvester在从保存的最后偏移量继续读取。
启动命令:
./filebeat -e -c itcast.yml
./filebeat -e -c itcast.yml -d "publish"
# 参数说明
-e: 输出到标准输出,默认输出到syslog和logs下
-c: 指定配置文件
-d: 输出debug信息
# 测试
DEBUG [publish] pipeline/processor.go:308 Publish event: {
"@timestamp": "2022-05-13T05:41:49.586Z",
"@metadata": {
"beat": "filebeat",
"type": "doc",
"version": "6.5.4"
},
"source": "/itcast/beats/logs/q.log",
"tags": [
"haoke-im"
],
"beat": {
"hostname": "elk1",
"version": "6.5.4",
"name": "elk1"
},
"host": {
"name": "elk1"
},
"fields": {
"from": "haoke-im"
},
"offset": 0,
"message": "456",
"prospector": {
"type": "log"
},
"input": {
"type": "log"
}
}
3.2.7 读取Nginx日志文件
将nginx日志的每行转换为json格式,便于在kibana中根据关键字段查看。
# 原来的默认格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# json格式的nginx日志
log_format main '{ "time_local": "$time_local", '
'"remote_addr": "$remote_addr", '
'"referer": "$http_referer", '
'"request": "$request", '
'"status": "$status", '
'"bytes": "$body_bytes_sent", '
'"agent": "$http_user_agent",'
'"x_forwarded": "$http_x_forwarded_for", '
'"up_addr": "$upstream_addr", '
'"up_host": "$upstream_http_host", '
'"upstream_time": "$upstream_response_time", '
'"request_time": "$request_time"'
' } ';
# 修改nginx配置文件,添加json格式的日志,并将默认的日志格式改为json
log_format json '{ "time_local": "$time_local", '
'"remote_addr": "$remote_addr", '
'"referer": "$http_referer", '
'"request": "$request", '
'"status": "$status", '
'"bytes": "$body_bytes_sent", '
'"agent": "$http_user_agent", '
'"x_forwarded": "$http_x_forwarded_for", '
'"up_addr": "$upstream_addr", '
'"up_host": "$upstream_http_host", '
'"upstream_time": "$upstream_response_time", '
'"request_time": "$request_time"'
' } ';
access_log /var/log/nginx/access.log json;
# 检查有无语法错误
nginx -t
# 清空原有日志
> /var/log/nginx/access.log
# 重载nginx
systemctl reload nginx
# 重新压测
ab -n 100 -c 100 http://192.168.172.101/
# 查看新生成的nginx日志格式
tail -f 10 /var/log/nginx/access.log
{
"time_local":"09/May/2022:15:47:35 +0800",
"remote_addr":"192.168.172.101",
"referer":"-",
"request":"GET / HTTP/1.0",
"status":"200",
"bytes":"4833",
"agent":"ApacheBench/2.3",
"x_forwarded":"-",
"up_addr":"-",
"up_host":"-",
"upstream_time":"-",
"request_time":"0.000"
}
是json格式,此时因为数据格式已经发生变化,需要在es-head界面删掉filebeat索引,重新生成新的filebeat索引
# 重启filebeat
./filebeat -e -c filebeat.yml
# 压测
ab -n 100 -c 100 http://192.168.172.101/
filebeat会记录一下上一次读到什么位置了,重新启动后会从上一次记录的位置开始读取数据(类似于tail -f)
此时kibana中的日志还是没有变成k-v格式,仍然是都在message字段里。
需要给filebeat配置文件input的位置添加以下两行内容,和path对齐:
json.keys_under_root: true # 传输给es之前已经解析成json格式完毕
json.overwrite_keys: true
然后再在es-head上和kibana上删除一次filebeat索引,再重启filebeat。
# 压测
ab -n 100 -c 100 http://192.168.172.101/
自定义索引名称,修改filebeat配置文件output部分的内容,和hosts对齐
index: "nginx-%{[beat.version]}-%{+yyyy.MM}"
重启filebeat会报错,需要在output部分加上下面4行,顶格写:
setup.template.name: "nginx"
setup.template.pattern: "nginx-*"
setup.template.enabled: false
setup.template.overwrite: true
# 综上所述,filebeat_nginx_tags.yml的最终版为:
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/nginx/access.log
json.keys_under_root: true
json.overwrite_keys: true
tags: ["access"]
- type: log
enabled: true
paths:
- /var/log/nginx/error.log
tags: ["error"]
setup.kibana:
host: "192.168.172.101:5601"
output.elasticsearch:
hosts: ["192.168.172.101:9200"]
# index: "nginx-%{[beat.version]}-%{+yyyy.MM}"
indices:
- index: "nginx-access-%{[beat.version]}-%{+yyyy.MM}"
when.contains:
tags: "access"
- index: "nginx-error-%{[beat.version]}-%{+yyyy.MM}"
when.contains:
tags: "error"
setup.template.name: "nginx"
setup.template.pattern: "nginx-*"
setup.template.enabled: false
setup.template.overwrite: true
# 上述配置如果是在7.x中,则为
index: "nginx-%{[agent.version]}-%{+yyyy.MM}"
# 压测
ab -n 100 -c 100 http://192.168.172.101/
总结
上述做了收集nginx日志的以下几条:
1.收集普通格式的日志
不能拆分显示,所有的日志记录成了一条
2.收集json格式的nginx日志
修改nginx日志格式为json
filebeat添加json解析的参数
3.自定义索引名称
修改filebeat添加4条配置
给elk2和elk3也安装filebeat和nginx,直接使用elk1的filebeat配置文件和nginx配置文件
用ab压测产生日志
4.把 access.log
和 error.log
存在不同的index索引中,所以需要修改filebeat的output内容。
打标签(设置k值)然后判断标签,error.log
也通过filebeat过滤,配置文件也改为下面这样,error.log
不需要json两行的原因是它不是json格式,根据es-head里显示的任意一个key值都可以作为判断条件,这里选择的判断条件是tags。
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/nginx/access.log
json.keys_under_root: true
json.overwrite_keys: true
tag: ["access"]
- type: log
enabled: true
paths:
- /var/log/nginx/error.log
tag: ["error"]
setup.kibana:
host: "192.168.172.101:5601"
output.elasticsearch:
hosts: ["192.168.172.101:9200"]
# index: "nginx-%{[beat.version]}-%{+yyyy.MM}"
indices:
- index: "nginx-access-%{[beat.version]}-%{+yyyy.MM}"
when.contains:
tags: "access"
- index: "nginx-error-%{[beat.version]}-%{+yyyy.MM}"
when.contains:
tags: "error"
setup.template.name: "nginx"
setup.template.pattern: "nginx-*"
setup.template.enabled: false
setup.template.overwrite: true
将修改好的nginx文件备份一份,方便以后相同情况可以直接使用(以后使用时还是需要将名字改回filebeat.yml的)。
cp filebeat.yml /root/filebeat_nginx_tags.yml
3.2.8 收集tomcat日志
# 安装tomcat
yum install tomcat tomcat-webapps tomcat-admin-webapps tomcat-docs-webapp tomcat-javadoc -y
# 启动tomcat
systemctl start tomcat
# tomcat日志文件
/var/log/tomcat/localhost_access_log.2022-05-10.txt
# 修改/etc/tomcat/server.xml第139行,删掉后添加下面内容:
# 清空tomcat日志
> /var/log/tomcat/localhost_access_log.2022-05-10.txt
# 重启tomcat
systemctl restart tomcat
# 此时访问192.168.172.101:8080后产生的日志
{"clientip":"192.168.172.1","ClientUser":"-","authenticated":" -","AccessTime":"[10/May/2022:10:51:48 +0800]","method":"GET / HTTP/1.1","status":"200","SendBytes":"11217","Query?string":"","partner":"-","AgentVersion":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36 Edg/101.0.1210.39"}
去浏览器的json格式检验,发现上述日志确实是json格式。
# 编辑filebeat.yml,可以借鉴nginx的access.log
- type: log
enabled: true
paths:
- /var/log/tomcat/localhost_access_log.*.txt
json.keys_under_root: true
json.overwrite_keys: true
tags: ['tomcat']
setup.kibana:
host: "192.168.172.101:5601"
output.elasticsearch:
hosts: ["192.168.172.101:9200"]
# index: "nginx-%{[beat.version]}-%{+yyyy.MM}"
indices:
- index: "nginx-access-%{[beat.version]}-%{+yyyy.MM}"
when.contains:
tags: "access"
- index: "nginx-error-%{[beat.version]}-%{+yyyy.MM}"
when.contains:
tags: "error"
- index: "tomcat-access-%{[beat.version]}-%{+yyyy.MM}"
when.contains:
tags: "tomcat"
# 只需要提前运行过这部分就行,叫什么名字不重要
setup.template.name: "nginx"
setup.template.pattern: "nginx-*"
setup.template.enabled: false
setup.template.overwrite: true
3.2.9 收集java日志
官方文档说明:https://www.elastic.co/guide/en/beats/filebeat/6.6/multiline-examples.html
这里以收集elasticsearch的日志为例,因为elasticsearch就是java语言开发的。修改filebeat配置文件:
filebeat.inputs:
###########es-java###############
- type: log
enabled: true
paths:
- /var/log/elasticsearch/elasticsearch.log
tags: ["es-java"]
multiline.pattern: '^\['
multiline.negate: true
multiline.match: after
setup.kibana:
host: "192.168.172.101:5601"
output.elasticsearch:
hosts: ["192.168.172.101:9200"]
# index: "nginx-%{[beat.version]}-%{+yyyy.MM}"
indices:
- index: "es-java-%{[beat.version]}-%{+yyyy.MM}"
when.contains:
tags: "es-java"
setup.template.name: "nginx"
setup.template.pattern: "nginx-*"
setup.template.enabled: false
setup.template.overwrite: true
multi三行的含义是到下一个[中括号出现时,才停止匹配,否则将认为到下一个[前的内容都是一条日志的内容,当然这里的匹配模式可以具体的正则表达式修改
3.2.10 收集docker日志
- 第一种方式,编辑filebeat配置文件,这个很少使用。
# 启动一个nginx容器
docker pull nginx
docker run --name nginx -p 80:80 -d nginx
docker exec -it 661a1d2fcc52 /bin/bash # 容器id,是debian操作系统,内核新,比centos精简
此时可以在浏览器中通过http://192.168.172.102:80访问了(80端口可省略)
# 查看容器日志
docker logs -f nginx
# 编辑filebeat配置文件:
filebeat.inputs:
- type: docker
containers.ids:
- '661a1d2fcc5294500ab0fb7b08fcaf7271f1741cfce682035a21462acde60a4a'
setup.kibana:
host: "192.168.172.101:5601"
output.elasticsearch:
hosts: ["192.168.172.101:9200"]
index: "docker-%{[beat.version]}-%{+yyyy.MM}"
setup.template.name: "docker"
setup.template.pattern: "docker-*"
setup.template.enabled: false
setup.template.overwrite: true
# 重启filebeat,这种方式的缺点是access.log和error.log日志没有分开
- 第二种方式,以stream作为key,stdout代表
access.log
,stderr代表error.log
。
filebeat.yml
改成下面这样:
filebeat.inputs:
- type: docker
containers.ids:
- '661a1d2fcc5294500ab0fb7b08fcaf7271f1741cfce682035a21462acde60a4a'
setup.kibana:
host: "192.168.172.101:5601"
output.elasticsearch:
hosts: ["192.168.172.101:9200"]
index: "docker-access-%{[beat.version]}-%{+yyyy.MM}"
setup.template.name: "docker"
setup.template.pattern: "docker-*"
setup.template.enabled: false
setup.template.overwrite: true
# 再启动一个nginx容器,产生日志
docker run --name nginx-v2 -p 8080:80 -d nginx
# 有多个容器时,filebeat配置可以这样写:
filebeat.inputs:
- type: docker
containers.ids:
- '*'
setup.kibana:
host: "192.168.172.101:5601"
output.elasticsearch:
hosts: ["192.168.172.101:9200"]
index: "docker-access-%{[beat.version]}-%{+yyyy.MM}"
setup.template.name: "docker"
setup.template.pattern: "docker-*"
setup.template.enabled: false
setup.template.overwrite: true
# 修改完后重启filebeat
这种方式的缺点是,在kibana或es-head界面没有办法把不同容器区分开来
- 第三种方式,根据服务类型收集多个容器日志:
yum install python2-pip -y
# 升级pip
/usr/bin/python -m pip install --upgrade pip
# 临时使用清华源
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple some-package --trusted-host pypi.tuna.tsinghua.edu.cn
yum install docker-compose -y
docker-compose version
# 编写docker-compose.yml,内容如下:
version: '3'
services:
nginx:
image: nginx
# 设置labels
labels:
service: nginx
# logging设置增加labels.service,日志中会增加打标签的内容
logging:
options:
labels: "service"
ports:
- "8080:80"
db:
image: nginx:latest
# 设罝labels
labels:
service: db
# 1ogging设置增加labels.service
logging:
options:
labels: "service"
ports:
- "80:80"
# 前台启动
docker-compose up
# 此时要收集filebeat日志,filebeat.yml可以这样写:
filebeat.inputs:
- type: log
paths:
- /var/lib/docker/containers/*/*-json.log
json.keys_under_root: true
json.overwrite_keys: true
setup.kibana:
host: "192.168.172.101:5601"
output.elasticsearch:
hosts: ["192.168.172.101:9200"]
# index: "docker-access-%{[beat.version]}-%{+yyyy.MM}"
indices:
- index: "docker-nginx-%{[beat.version]}-%{+yyyy.MM}"
when.contains:
attrs.service: "nginx"
- index: "docker-db-%{[beat.version]}-%{+yyyy.MM}"
when.contains:
attrs.service: "db"
setup.template.name: "docker"
setup.template.pattern: "docker-*"
setup.template.enabled: false
setup.template.overwrite: true
# 根据服务类型和日志类型(access/error)来判断。filebeat.yml文件的output部分需要修改,两个条件写一起就变成and关系。
output.elasticsearch:
hosts: ["192.168.172.101:9200"]
# index: "docker-access-%{[beat.version]}-%{+yyyy.MM}"
indices:
- index: "docker-nginx-access-%{[beat.version]}-%{+yyyy.MM}"
when.contains:
attrs.service: "nginx"
stream: "stdout"
- index: "docker-nginx-error-%{[beat.version]}-%{+yyyy.MM}"
when.contains:
attrs.service: "nginx"
stream: "stderr"
- index: "docker-db-access-%{[beat.version]}-%{+yyyy.MM}"
when.contains:
attrs.service: "db"
stream: "stdout"
- index: "docker-db-error-%{[beat.version]}-%{+yyyy.MM}"
when.contains:
attrs.service: "db"
stream: "stderr"
setup.template.name: "docker"
setup.template.pattern: "docker-*"
setup.template.enabled: false
setup.template.overwrite: true
修改完后重启filebeat。
3.2.10.1 总结
做了哪些工作:
nginx日志:
1.默认配置收集
- 索引名固定
- 所有类型放在一个message字段
2.自定义模板
- 自定义了索引名称
- 根据日志类型打tag标签拆分
3.把nginx日志转换为json格式
- 可以按照需要的字段过滤分析
tomcat日志:
- 转换为json格式
docker日志:
1.默认配置不能按照容器类型拆分
2.使用docker-compose添加了一个字段service
3.根据服务类型和日志类型生成不同的容器类型的索引
java日志:
1.多行匹配模式
3.2.11 filebeat自带的模块modules收集日志
前面要想实现日志数据的读取以及处理都是自己手动配置的,其实,在Filebeat中,有大量的Module,可以简化我们的配置,直接就可以使用,如下:
1.nginx
2.mongo
3.redis
4.mysql
以nginx module的设置为例,操作步骤如下:
0.filebeat配置文件配置模块路径
1.激活模块
2.修改模块配置文件
3.修改nginx日志为普通格式,清空nginx日志
4.安装es2个插件
5.重启es
6.重启filebeat
# 0.在filebeat.yml中修改这几行:
filebeat.config.modules:
path: ${path.config}/modules.d/*.yml
reload.enabled: true
reload.period: 10s
setup.kibana:
host: "192.168.172.101:5601"
output.elasticsearch:
hosts: ["192.168.172.101:9200"]
# index: "nginx-%{[beat.version]}-%{+yyyy.MM}"
indices:
- index: "nginx-access-%{[beat.version]}-%{+yyyy.MM}"
when.contains:
fileset.name: "access"
- index: "nginx-error-%{[beat.version]}-%{+yyyy.MM}"
when.contains:
fileset.name: "error"
setup.template.name: "nginx"
setup.template.pattern: "nginx-*"
setup.template.enabled: false
setup.template.overwrite: true
# 1.查看所有disabled的模块
./filebeat modules list
Enabled:
Disabled:
apache2
auditd
elasticsearch
haproxy
icinga
iis
kafka
kibana
logstash
mongodb
mysql
nginx
osquery
postgresql
redis
suricata
system
traefik
# 激活nginx模块,直接修改后缀名效果一样。
./filebeat modules enable nginx
修改filebeat的nginx模板配置文件,只用添加路径就可以了
- module: nginx
access:
enabled: true
var.paths: ["/var/log/nginx/access.log"]
error:
enabled: true
var.paths: ["/var/log/nginx/error.log"]
# 3.恢复nginx日志格式,修改main后重启
# 4.filebeat启动失败,需要在elasticsearch中安装ingest-user-agent和ingest-geoip两个插件:
./bin/elasticsearch-plugin install ingest-user-agent
./bin/elasticsearch-plugin install ingest-geoip
当然了,其他的module的用法参加官方文档:https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-modules.html
3.3 Metricbeat
- 定期收集操作系统或应用服务的指标数据
- 存储到elasticsearch中,进行实时分析
3.3.1 Metricbeat组成
Metricbeat有2部分组成,一部分是Module,另一部分为Metricset。
- Module
- 收集的对象,如:mysql、redis、nginx、操作系统等;
- Metricset
- 收集指标的集合,如:cpu、memory、network等;
以Redis Module为例:
3.3.2 部署与收集系统指标
# 部署过程:
tar zxf metricbeat-6.5.4-linux-x86_64.tar.gz -C /usr/local/
# 编辑配置文件
egrep -v "#|^$" metricbeat.yml
metricbeat.config.modules:
path: ${path.config}/modules.d/*.yml
reload.enabled: false
setup.template.settings:
index.number_of_shards: 1
index.codec: best_compression
setup.kibana:
host: "192.168.172.101:5601"
output.elasticsearch:
hosts: ["192.168.172.101:9200"]
processors:
- add_host_metadata: ~
- add_cloud_metadata: ~
# 启动
./metricbeat -e
在elasticsearch中可以看到,系统的一些指标数据已经写进去了。
system module配置:
[root@elk1 /usr/local/metricbeat/modules.d]# cat system.yml
# Module: system
# Docs: https://www.elastic.co/guide/en/beats/metricbeat/6.5/metricbeat-module-system.html
- module: system
period: 10s
metricsets:
- cpu
- load
- memory
- network
- process
- process_summary
#- core
#- diskio
#- socket
process.include_top_n:
by_cpu: 5 # include top 5 processes by CPU
by_memory: 5 # include top 5 processes by memory
- module: system
period: 1m
metricsets:
- filesystem
- fsstat
processors:
- drop_event.when.regexp:
system.filesystem.mount_point: '^/(sys|cgroup|proc|dev|etc|host|lib)($|/)'
- module: system
period: 15m
metricsets:
- uptime
#- module: system
# period: 5m
# metricsets:
# - raid
# raid.mount_point: '/'
3.3.3 Module
# 查看列表
./metricbeat modules list
# 默认启用
Enabled:
system
Disabled:
aerospike
apache
ceph
couchbase
docker
dropwizard
elasticsearch
envoyproxy
etcd
golang
graphite
haproxy
http
jolokia
kafka
kibana
kubernetes
kvm
logstash
memcached
mongodb
munin
mysql
nginx
php_fpm
postgresql
prometheus
rabbitmq
redis
traefik
uwsgi
vsphere
windows
zookeeper
3.3.4 Nginx Module
3.3.4.1 开启nginx的状态查询
在nginx中,需要开启状态查询,才能查询到指标数据。
# 重新编译nginx,需要加入--with-http_stub_status_module模块
参考链接:https://www.cnblogs.com/even160941/p/15064925.html
# 查询版本信息
nginx -V
nginx version: nginx/1.20.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx --user=nginx --group=nginx --with-file-aio --with-ipv6 --with-http_auth_request_module --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-debug --with-stream
# 配置nginx
vim nginx.conf
location /nginx-status {
stub_status on;
access_log off;
}
测试:
结果说明:
- Active connections:正在处理的活动连接数
- server accepts handled requests
- 第一个 server 表示Nginx启动到现在共处理了9个连接
- 第二个 accepts 表示Nginx启动到现在共成功创建 9 次握手
- 第三个 handled requests 表示总共处理了 21 次请求
- 请求丢失数 = 握手数 - 连接数 ,可以看出目前为止没有丢失请求
- Reading: 0 Writing: 1 Waiting: 1
- Reading:Nginx 读取到客户端的 Header 信息数
- Writing:Nginx 返回给客户端 Header 信息数
- Waiting:Nginx 已经处理完正在等候下一次请求指令的驻留链接(开启keep-alive的情况下,这个值等于Active - (Reading+Writing))
3.3.4.2 配置Nginx Module
# 启用nginx Module
./metricbeat modules enable nginx
# 修改nginx module配置
cat modules.d/nginx.yml
# Module: nginx
# Docs: https://www.elastic.co/guide/en/beats/metricbeat/6.5/metricbeat-module-nginx.html
- module: nginx
#metricsets:
# - stubstatus
period: 10s
# Nginx hosts
hosts: ["http://192.168.172.101"]
# Path to server status. Default server-status
server_status_path: "nginx-status"
#username: "user"
#password: "secret"
# 启动
./metricbeat -e
# 压测
ab -n 100 -c 100 http://192.168.172.101/nginx-status
测试:
可以看到,nginx的指标数据已经写入到了Elasticsearch。
更多的Module使用参见官方文档:
https://www.elastic.co/guide/en/beats/metricbeat/current/metricbeat-modules.html
3.3.4.3 Metricbeat仪表盘
可以把Metricbeat的数据在kibana中展示
# 修改metricbeat配置
setup.kibana:
host: "192.168.40.133:5601"
# 安装仪表盘到kibana
./metricbeat setup --dashboards
Loading dashboards (Kibana must be running and reachable)
Loaded dashboards
即可在kibana中看到仪表盘数据:
查看系统信息:
3.3.4.4 Nginx指标仪表盘
3.3.4.5 Nginx日志仪表盘
# 修改filebeat的配置文件 cat itcast-nginx.yml
filebeat.inputs:
#- type: log
# enabled: true
# paths:
# - /var/log/nginx/*.log
# tags: ["nginx"]
setup.kibana:
host: "192.168.172.101:5601"
setup.template.settings:
index.number_of_shards: 3
filebeat.config.modules:
path: ${path.config}/modules.d/*.yml
reload.enabled: false
output.elasticsearch:
hosts: ["192.168.172.101:9200"]
# 安装仪表盘到kibana
./filebeat -c itcast-nginx.yml setup
Loaded index template
Loading dashboards (Kibana must be running and reachable)
Loaded dashboards
Loaded machine learning job configurations
可以看到nginx的FileBeat的仪表盘了:
3.3.4.6 自定义图表
在Kibana中,也可以进行自定义图表,如制作柱形图:
将图表添加到自定义Dashboard中:
3.3.4.7 开发者工具
在Kibana中,为开发者的测试提供了便捷的工具使用,如下:
第5章 Logstash
5.1 简介
用途:
5.2 部署安装
# 检查jdk环境,要求jdk1.8+
java -version
# 解压安装包
tar -zxf logstash-6.5.4.tar.gz
# 第一个logstash示例
bin/logstash -e 'input { stdin { } } output { stdout {} }'
# 执行效果如下:
[2022-05-13T22:36:01,604][INFO ][logstash.agent ] Successfully started Logstash API endpoint {:port=>9600}
hello
{
"@timestamp" => 2022-05-13T14:36:09.750Z,
"message" => "hello",
"@version" => "1",
"host" => "elk1"
}
5.3 配置详解
logstash的配置有三部分,如下:
input { # 输入
stdin { ... } # 标准输入
}
filter { # 过滤,对数据进行分割、截取等处理
...
}
output { # 输出
stdout { ... } # 标准输出
}
Input:输入数据到logstash。
一些常用的输入为:
- file:从文件系统的文件中读取,类似于
tail -f
命令 - syslog: 在514端口上监听系统日志消息,并根据RFC3164标准进行解析
- redis: 从redis service中读取
- beats: 从filebeat中读取
Filters:数据中间处理,对数据进行操作。
一些常用的过滤器为:
- grok:解析任意文本数据,Grok 是 Logstash 最重要的插件。它的主要作用就是将文本格式的字符串,转换成为具体的结构化的数据,配合正则表达式使用。内置120多个解析语法。
官方提供的grok表达式:[https://github.com/logstash-plugins/logstash-patterns-core/tree/master/patterns](https://github.com/logstash-plugins/logstash-patterns-core/tree/master/patterns)
grok在线调试:[https://grokdebug.herokuapp.com/](https://grokdebug.herokuapp.com/)
- mutate:对字段进行转换。例如对字段进行删除、替换、修改、重命名等。
- drop: 丢弃一部分events不进行处理。
- clone: 拷贝 event,这个过程中也可以添加或移除字段。
- geoip: 添加地理信息(为前台kibana图形化展示使用)
Outputs:outputs是logstash处理管道的最末端组件。一个event可以在处理过程中经过多重输出,但是一旦所有的outputs都执行结束,这个event也就完成生命周期。
一些常见的outputs为:
- elasticsearch: 可以高效的保存数据,并且能够方便和简单的进行查询。
- file: 将event数据保存到文件中。
- graphite: 将event数据发送到图形化组件中,一个很流行的开源存储图形化展示的组件。
Codecs:codecs 是基于数据流的过滤器,它可以作为input,output的一部分配置 。
Codecs可以帮助你轻松的分割发送过来已经被序列化的数据。
一些常见的codecs:
- json:使用json格式对数据进行编码/解码。
- multiline:将汇多个事件中数据汇总为一个单一的行。比如:java异常信息和堆栈信息。
5.3.1 输入
- 采集各种样式、大小和来源的数据,数据往往以各种各样的形式,或分散或集中地存在于很多系统中。
- Logstash 支持各种输入选择 ,可以在同一时间从众多常用来源捕捉事件。能够以连续的流式传输方式,轻松地
从您的日志、指标、Web 应用、数据存储以及各种 AWS 服务采集数据。
5.3.2 过滤
- 实时解析和转换数据
- 数据从源传输到存储库的过程中,Logstash 过滤器能够解析各个事件,识别已命名的字段以构建结构,并将它
们转换成通用格式,以便更轻松、更快速地分析和实现商业价值。
5.3.3 输出
Logstash 提供众多输出选择,您可以将数据发送到您要指定的地方,并且能够灵活地解锁众多下游用例。
日志:
2022-03-31 00:00:00.007 [WARN] [pool-6-thread-12] c.s.resthelper.utils.LoggerHelper - RestInvokeAspect,prepareBeforeInvoke,Y,"no parameters found, method: getCsgoMaps."
grok:
%{GREEDYDATA:timestamp}\[%{WORD:loglevel}\]%{GREEDYDATA:message}
%{GREEDYDATA:timestamp}%{SPACE}\[%{WORD:loglevel}\]%{SPACE}%{GREEDYDATA:message}
日志:
192.168.172.101 - - [15/May/2022:18:23:37 +0800] "GET / HTTP/1.1" 200 4833 "-" "curl/7.29.0"
grok匹配规则:
%{GREEDYDATA:remote_addr}%{SPACE}\-%{SPACE}\-%{SPACE}\[%{GREEDYDATA:timestamp}\]%{SPACE}"%{GREEDYDATA:request}"%{SPACE}%{INT:http_code}%{SPACE}%{INT:http_body_bytes_sent}%{SPACE}"%{GREEDYDATA:http_referer}"%{SPACE}"%{GREEDYDATA:http_user_agent}"
5.4 读取自定义日志
前面我们通过Filebeat读取了nginx的日志,如果是自定义结构的日志,就需要读取处理后才能使用,所以,这个时
候就需要使用Logstash了,因为Logstash有着强大的处理能力,可以应对各种各样的场景。
5.4.1 日志结构
2019-03-15 21:21:21|ERROR|读取数据出错|参数:id=1002
可以看到,日志中的内容是使用“|”进行分割的,使用,我们在处理的时候,也需要对数据做分割处理。
5.4.2 编写配置文件
vim itcast-pipeline.conf
input {
file {
path => "/itcast/logstash/logs/app.log"
start_position => "beginning"
}
}
filter {
mutate {
split => {"message" => "|"}
}
}
output {
stdout { codec => rubydebug }
}
5.4.3 启动测试
# 启动
./bin/logstash -f config/itcast-pipeline.conf
# 写日志到文件
echo "2019-03-15 21:21:21|ERROR|读取数据出错|参数:id=1002" >> /itcast/logstash/logs/app.log
# 输出的结果
{
"path" => "/itcast/logstash/logs/app.log",
"@timestamp" => 2022-05-13T15:05:02.392Z,
"host" => "elk1",
"@version" => "1",
"message" => [
[0] "2019-03-15 21:21:21",
[1] "ERROR",
[2] "读取数据出错",
[3] "参数:id=1002"
]
}
可以看到,数据已经被分割了。
5.4.4 输出到Elasticsearch
input {
file {
path => "/itcast/logstash/logs/app.log"
start_position => "beginning"
}
}
filter {
mutate {
split => {"message" => "|"}
}
}
output {
elasticsearch {
hosts => ["192.168.172.101:9200"]
}
}
# 启动
./bin/logstash -f config/itcast-pipeline.conf
# 写入数据
echo "2019-03-15 21:21:21|ERROR|读取数据出错|参数:id=1003" >> /itcast/logstash/logs/app.log
测试:
第6章 综合练习
下面我们将前面所学习到的Elasticsearch + Logstash + Beats + Kibana整合起来做一个综合性的练习,目的就是让
学生们能够更加深刻的理解Elastic Stack的使用。
6.1 流程说明
- 用APP生产日志,用来记录用户的操作
- [INFO] 2019-03-15 22:55:20 [cn.itcast.dashboard.Main] - DAU|5206|使用优惠券|2019-03-15
03:37:20 - [INFO] 2019-03-15 22:55:21 [cn.itcast.dashboard.Main] - DAU|3880|浏览页面|2019-03-15 07:25:09
- [INFO] 2019-03-15 22:55:20 [cn.itcast.dashboard.Main] - DAU|5206|使用优惠券|2019-03-15
- 通过Filebeat读取日志文件中的内容,并且将内容发送给Logstash,原因是需要对内容做处理
- Logstash接收到内容后,进行处理,如分割操作,然后将内容发送到Elasticsearch中
- Kibana会读取Elasticsearch中的数据,并且在Kibana中进行设计Dashboard,最后进行展示
说明:日志格式、图表、Dashboard都是自定义的。
6.2 APP介绍
APP在生产环境应该是真实的系统,然而,我们现在仅仅的学习,为了简化操作,所以就做数据的模拟生成即可。
业务代码如下:
运行结果:
[INFO] 2019-03-15 22:54:42 [cn.itcast.dashboard.Main] - DAU|4645|领取优惠券|2019-03-15 07:40:29
[INFO] 2019-03-15 22:54:44 [cn.itcast.dashboard.Main] - DAU|3482|领取优惠券|2019-03-15 18:34:04
[INFO] 2019-03-15 22:54:48 [cn.itcast.dashboard.Main] - DAU|5607|加入收藏|2019-03-15 22:44:09
[INFO] 2019-03-15 22:54:50 [cn.itcast.dashboard.Main] - DAU|9619|加入收藏|2019-03-15 21:39:47
[INFO] 2019-03-15 22:54:53 [cn.itcast.dashboard.Main] - DAU|7666|加入收藏|2019-03-15 17:47:18
[INFO] 2019-03-15 22:54:54 [cn.itcast.dashboard.Main] - DAU|4871|提交订单|2019-03-15 02:36:27
[INFO] 2019-03-15 22:54:55 [cn.itcast.dashboard.Main] - DAU|7126|加入收藏|2019-03-15 16:11:06
[INFO] 2019-03-15 22:55:00 [cn.itcast.dashboard.Main] - DAU|9606|评论商品|2019-03-15 02:12:00
[INFO] 2019-03-15 22:55:02 [cn.itcast.dashboard.Main] - DAU|7698|查看订单|2019-03-15 08:17:02
代码在资料中可以找到,itcast-dashboard-generate.zip。
部署:
# 打包成jar包,在linux中运行
java -jar itcast-dashboard-generate-1.0-SNAPSHOT.jar
#运行之后,就可以将日志写入到/itcast/logs/app.log文件中
6.3 Filebeat
cat itcast-dashboard.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /itcast/logs/*.log
setup.template.settings:
index.number_of_shards: 3
output.logstash:
hosts: ["192.168.172.101:5044"]
# 启动
./filebeat -e -c itcast-dashboard.yml
6.4 Logstash
cat config/itcast-dashboard.conf
input {
beats {
port => "5044"
}
}
filter {
mutate {
split => {"message" => "|"}
}
mutate {
add_field => {
"userId" => "%{message[1]}"
"visit" => "%{message[2]}"
"date" => "%{message[3]}"
}
}
mutate {
convert => {
"userId" => "integer"
"visit" => "string"
"date" => "string"
}
}
}
output {
elasticsearch {
hosts => ["192.168.172.101:9200"]
}
}
# 启动
./bin/logstash -f config/itcast-dashboard.conf
6.5 Kibana
# 启动
./bin/kibana
# 通过浏览器访问
http://192.168.172.101:5601/app/kibana
6.5.1 时间间隔的柱形图
说明:x轴是时间,以天为单位,y轴是count数
保存:(my-dashboard-时间间隔的柱形图)
6.5.2 各个操作的饼图分布
统计各个操作的数量,形成饼图。
保存:(my-dashboard-各个操作的饼图)
6.5.3 数据表格
在数据探索中进行保存,并且保存,将各个操作的数据以表格的形式展现出来。
保存:(my-dashboard-表格)
6.5.4 制作Dashboard
第7章 利用缓存收集日志
7.1 利用缓存的优点
当日志的数量非常多的时候,可能需要引入缓存层作为临时存储数据的地方,防止因为ES处理不过来导致日志丢失的情况。
filbeat支持将日志发送到redis或者kafka作为消息队列缓存,但是使用了缓存层,就不能使用模板来配置日志收集了,所以最好日志是json格式。
7.2 使用redis作为缓存
适用于es性能瓶颈时
nginx -----> redis -----> logstash -----> es
+
filebeat
yum安装redis后启动
即使logstash和es机器都宕机了,数据也都会先存储在redis里。后续再从redis里读取数据
有一个缺陷是只支持filebeat将数据传输到redis单节点,不支持传输到redis集群或哨兵模式。
官网地址:https://www.elastic.co/guide/en/beats/filebeat/6.5/redis-output.html
filebeat_redis_tags.yml:
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/nginx/access.log
json.keys_under_root: true
json.overwrite_keys: true
tags: ["access"]
setup.kibana:
host: "192.168.172.101:5601"
output.redis:
hosts: ["192.168.172.101"]
key: "filebeat"
db: 0
timeout: 5
重启filebeat
./filebeat -e -c filebeat_redis_tags.yml
连接redis
redis-cli -h 192.168.172.101
输入keys *
查看有无filebeat这个键,没出现的话访问nginx,有日志增加应该会出现,filebeat键是list列表类型的
type filebeat
LLEN filebeat
LRANGE filebeat 1 10
此时日志也是json格式
安装logstash
在logstash的配置目录下,新建logstash有关redis的配置文件
vim redis.conf
input {
redis {
host => '192.168.172.101'
port => '6379'
db => '0'
key => 'filebeat'
data_type => 'list'
}
}
filter {
mutate {
# nginx和php解析的时间,变成浮点数后可以按照大小排序。
convert => ["upstream_time" , "float"]
convert => ["request_time" , "float"]
}
}
output {
stdout {}
elasticsearch {
hosts => "http://192.168.172.101:9200"
manage_template => false
index => "nginx-access-%{+yyyy.MM.dd}"
}
}
# 启动logstash
./bin/logstash -f /usr/local/logstash/config/redis.conf
logstash启动后可以看到redis中未消费的数据在逐渐减少,这就说明redis可以为es分担一些读写方面的存储方面的压力。
此时只会有一个索引,nginx-access-年月生成
要对access和error日志分别生成索引。filebeat文件可以这样改:
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/nginx/access.log
json.keys_under_root: true
json.overwrite_keys: true
tags: ["access"]
- type: log
enabled: true
paths:
- /var/log/nginx/error.log
tags: ["error"]
setup.kibana:
host: "192.168.172.101:5601"
output.redis:
hosts: ["192.168.172.101"]
keys:
- key: "nginx-access"
when.contains:
tags: "access"
- key: "nginx-error"
when.contains:
tags: "error"
db: 0
timeout: 5
# 编辑logstash的redis.conf:
input {
redis {
host => '192.168.172.101'
port => '6379'
db => '0'
key => 'nginx-access'
data_type => 'list'
}
redis {
host => '192.168.172.101'
port => '6379'
db => '0'
key => 'nginx-error'
data_type => 'list'
}
}
filter {
mutate {
convert => ["upstream_time" , "float"]
convert => ["request_time" , "float"]
}
}
output {
stdout {}
if "access" in [tags] {
elasticsearch {
hosts => "http://192.168.172.101:9200"
manage_template => false
index => "nginx-access-%{+yyyy.MM}"
}
}
if "error" in [tags] {
elasticsearch {
hosts => "http://192.168.172.101:9200"
manage_template => false
index => "nginx-error-%{+yyyy.MM}"
}
}
}
此时连接redis,查看所有key不一定会看到有索引出现,因为es都将数据读取并存储完了,所以redis中没有key。
logstash根据filebeat里定义的tags来判断将什么数据存到什么索引里,在redis里数据也是根据tags来区分的。
由于是通过tags来进行区分的,所以logstash的配置文件key的部分都可以做以优化,修改key的值,将input的第二部分可以删掉,减轻一下logstash的工作量。
input {
redis {
host => '192.168.172.101'
port => '6379'
db => '0'
key => 'nginx'
data_type => 'list'
}
}
filter {
mutate {
convert => ["upstream_time" , "float"]
convert => ["request_time" , "float"]
}
}
output {
stdout {}
if "access" in [tags] {
elasticsearch {
hosts => "http://192.168.172.101:9200"
manage_template => false
index => "nginx-access-%{+yyyy.MM}"
}
}
if "error" in [tags] {
elasticsearch {
hosts => "http://192.168.172.101:9200"
manage_template => false
index => "nginx-error-%{+yyyy.MM}"
}
}
}
将filebeat配置文件中
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/nginx/access.log
json.keys_under_root: true
json.overwrite_keys: true
tags: ["access"]
- type: log
enabled: true
paths:
- /var/log/nginx/error.log
tags: ["error"]
setup.kibana:
host: "192.168.172.101:5601"
output.redis:
hosts: ["192.168.172.101"]
key: "nginx"
db: 0
timeout: 5
7.3 使用kafka作为缓存
elk结合kafka用的好处:
- kafka使用起来比较简单,业内公司用得很多,logstash可以借助kafka解决单点问题实现高可用
- kafka吐的数据是json格式,方便解析
- 多个logstash并行连接kafka的topic还能提高吞吐率
- 用不同topic分别存储不同类型的数据也方便管理
3台服务器,主机之间互相通信,hosts文件配置好。
部署zookeeper
参考链接: https://www.cnblogs.com/even160941/p/14666971.html
部署kafka
参考链接:https://www.cnblogs.com/even160941/p/14667974.html
编辑logstash的 kafka.conf
配置文件:
input {
kafka {
bootstrap_servers => "192.168.172.101:9092"
topics => ["elklog"]
group_id => "logstash"
codec => "json"
}
}
filter {
mutate {
convert => ["upstream_time" , "float"]
convert => ["request_time" , "float"]
}
}
output {
if "access" in [tags] {
elasticsearch {
hosts => "http://192.168.172.101:9200"
manage_template => false
index => "nginx-access-%{+yyyy.MM}"
}
}
if "error" in [tags] {
elasticsearch {
hosts => "http://192.168.172.101:9200"
manage_template => false
index => "nginx-error-%{+yyyy.MM}"
}
}
}
编辑filebeat的 filebeat_kafka_tags.yml
配置文件:
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/nginx/access.log
json.keys_under_root: true
json.overwrite_keys: true
tags: ["access"]
- type: log
enabled: true
paths:
- /var/log/nginx/error.log
tags: ["error"]
setup.kibana:
host: "192.168.172.101:5601"
output.kafka:
hosts: ["192.168.172.101:9092","192.168.172.102:9092","192.168.172.103:9092"]
topic: elklog
启动filebeat:
./filebeat -e -c filebeat_kafka_tags.yml
启动logstash:
./bin/logstash -f /usr/local/logstash/config/kafka.conf
终极架构
nginx+keepalived --> redis --> logstash --> es --> kibana
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析