本实例将基于上述服务已部署的情况下, 将一台spring Boot服务的日志使用ELKB系统进行收集管理
服务概述
服务是一个很简单的服务, 打了部分日志, 以模拟日志的产生.
配置filebeat
复制标准的filebeat, 重命名为filebeat-message
,
复制一份filebeat.yml
, 命名为filebeat-message.yml
, 配置内容如下:
# ============================== Filebeat inputs ===============================
filebeat.inputs:
- type: log
enabled: true
paths:
- E:\logs\message-*.log
fields:
service: message-log
multiline.pattern: '^[[:space:]]+(at|\.{3})\b|^Caused by:'
multiline.negate: false
multiline.match: after
- type: filestream
enabled: false
paths:
- E:\logs\message-*.log
fields:
service: message-log
# ============================== Filebeat modules ==============================
filebeat.config.modules:
path: ${path.config}/modules.d/*.yml
reload.enabled: false
# ======================= Elasticsearch template setting =======================
setup.template.settings:
index.number_of_shards: 1
# =================================== Kibana ===================================
setup.kibana:
host: "localhost:5601"
# ================================== Outputs ===================================
# ------------------------------ Logstash Output -------------------------------
output.logstash:
hosts: ["localhost:5043"]
# ================================= Processors =================================
processors:
- add_host_metadata:
when.not.contains.tags: forwarded
- add_cloud_metadata: ~
- add_docker_metadata: ~
- add_kubernetes_metadata: ~
准备好备用
配置logstash
复制config下logstash-sample.conf
文件, 重命名
修改, 如下:
# Sample Logstash configuration for creating a simple
# Beats -> Logstash -> Elasticsearch pipeline.
input {
beats {
port => 5043
}
}
filter {
# message项目的日志收集处理
if [fields][service] == "message-log" { # 依据filebeat-message.yml中的设定确定
grok {
# 官方提供的grok-patterns 地址:https://github.com/elastic/logstash/blob/v1.4.2/patterns/grok-patterns
match => { "message" => "%{COMBINEDAPACHELOG} %{QS:gzip_ratio}" } # 格式处理, 这里使用官方提供的
remove_field => ["beat", "input_type", "message", "offset", "tags"] # 去除不需要的字段
}
# 更改匹配到的字段的数据类型
mutate {
convert => ["response", "integer"]
convert => ["bytes", "integer"]
convert => ["responsetime", "float"]
# 因为agent字段是一个json,es无法将其以text的形式存储, 且以为agent字段只有一个字段id, 故将id的值取出来重新赋给agent
# 原字符串: "agent"=>{"id"=>"9ce2edfd-ab41-45e7-a848-186d988200ed"}
rename => { "[agent][id]" => "agent" }
}
# 指定时间戳字段以及具体的格式
date {
match => ["timestamp", "dd/MMM/YYYY:HH:mm:ss Z"]
remove_field => ["timestamp"]
}
}
}
# 输出配置
output {
elasticsearch {
hosts => ["http://localhost:9200"]
#index => "%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}"
# 索引配置
index => "%{[fields][service]}-%{+YYYY.MM.dd}" # index中含有时间戳
#user => "elastic"
#password => "changeme"
}
}
准备好备用
ElasticSearch 创建Index Template
所有的数据, 最终将写入ES, 而根据我们的配置, 我们的索引是每天按照时间戳分索引存放的(索引相当于关系型数据库的表), 我们这么做是为了数据的分片,更好的分时间段处理数据.
但这样的话, 我们需要每天都建一个新索引, 为了避免此项工作, 我们引入Index Template技术, 这是ES自带的功能, 如不了解, 可以查看文档, 或者等后面的分享.
新建索引模板的代码如下:
PUT _template/message
{
"index_patterns": ["message*"],
"order" : 0,
"version": 1,
"settings": {
"number_of_replicas": 0,
"number_of_shards": 1
},
"mappings": {
"properties": {
"clientip": {
"type": "text"
},
"ident": {
"type": "text"
},
"auth": {
"type": "text"
},
"verb": {
"type": "text"
},
"request": {
"type": "text"
},
"httpversion": {
"type": "text"
},
"rawrequest": {
"type": "text"
},
"response": {
"type": "text"
},
"bytes": {
"type": "text"
},
"referrer": {
"type": "text"
},
"agent": {
"type": "text"
},
"gzip_ratio": {
"type": "text"
}
}
}
}
执行结果如下:
这个步骤我们可以使用elasticsearch-head
执行, 也可以使用kibana带的开发工具执行, 也可以自己使用代码调用ES的API执行.
elasticsearch-head执行:
进入elasticsearch-head
, 在符合查询下, 输入命令, 点击提交请求:
kibana执行:
进入kibana
, 在首页点击开发工具,
或在任意位置, 点击菜单栏下的开发工具菜单:
进入, 输入命令, 点击执行:
启动服务
至此准备工作已完成, 分别启动ES,Kibana,LogStash,Filebeat
生成两条日志, 查看索引是否生成: 进入elasticsearch-head
查看:
如图, 即生成成功, 如未生成成功, 则需要检查配置
配置kibana可视化DisCover
配置kibana索引模式
进入主页 http://127.0.0.1:5601/app/home#/ , 点击管理
点击索引模式, 点击创建索引模式
按提示输入索引名称, 点击下一步
选择时间字段, 这个时间字段是我们在配置logstash时配置的, 用来进行时间筛选. 点击创建
至此, 索引模式创建成功
进入仪表盘查看
进入主页 http://127.0.0.1:5601/app/home#/ , 点击可视化和分析
进入DisCover
选择刚才新建的索引模板
可以看出, 日志已经正常展示
配置多个项目的日志收集
多个项目可以共用一个ES, kibana, 甚至可以共用一个ES的模板索引(只要我们保证生成索引的规则符合索引模板的规则即可).
我们也可以选择不同的项目使用不同的Beats去收集日志, 最终汇总到Logstash, 再汇总到ES
这里做一个示例, 配置两个项目, 每个项目配置一个自己的Filebeat去收集日志, 最终在同一个Logstash中处理, 再分给不同的ES索引模板, 配置不同的DisCover查看
结构如下:
几个关键的配置点如下:
logstash配置:
# Sample Logstash configuration for creating a simple
# Beats -> Logstash -> Elasticsearch pipeline.
input {
beats {
port => 5044
}
beats {
port => 5043
}
}
filter {
# nginx-house项目的日志收集处理
if [fields][service] == "nginx-house" {
grok {
match => { "message" => "%{COMBINEDAPACHELOG} %{QS:gzip_ratio}" }
remove_field => ["beat", "input_type", "message", "offset", "tags"]
}
mutate {
convert => ["response", "integer"]
convert => ["bytes", "integer"]
convert => ["responsetime", "float"]
rename => { "[agent][id]" => "agent" }
}
date {
match => ["timestamp", "dd/MMM/YYYY:HH:mm:ss Z"]
remove_field => ["timestamp"]
}
}
# message项目的日志收集处理
if [fields][service] == "message-log" { # 依据filebeat-message.yml中的设定确定
grok {
# 官方提供的grok-patterns 地址:https://github.com/elastic/logstash/blob/v1.4.2/patterns/grok-patterns
match => { "message" => "%{COMBINEDAPACHELOG} %{QS:gzip_ratio}" } # 格式处理, 这里使用官方提供的
remove_field => ["beat", "input_type", "message", "offset", "tags"] # 去除不需要的字段
}
# 更改匹配到的字段的数据类型
mutate {
convert => ["response", "integer"]
convert => ["bytes", "integer"]
convert => ["responsetime", "float"]
# 因为agent字段是一个json,es无法将其以text的形式存储, 且以为agent字段只有一个字段id, 故将id的值取出来重新赋给agent
# 原字符串: "agent"=>{"id"=>"9ce2edfd-ab41-45e7-a848-186d988200ed"}
rename => { "[agent][id]" => "agent" }
}
# 指定时间戳字段以及具体的格式
date {
match => ["timestamp", "dd/MMM/YYYY:HH:mm:ss Z"]
remove_field => ["timestamp"]
}
}
}
# 输出配置
output {
elasticsearch {
hosts => ["http://localhost:9200"]
#index => "%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}"
# 索引配置
index => "%{[fields][service]}-%{+YYYY.MM.dd}" # index中含有时间戳
#user => "elastic"
#password => "changeme"
}
}
创建索引的语句类似, 差异如下:
至此, 重启服务, kibana添加索引模板即可
ES系统还有很多的功能, 都很强大, 后续再更新