ELKB日志收集系统[4]-收集springBoot日志实例

532 阅读5分钟

本实例将基于上述服务已部署的情况下, 将一台spring Boot服务的日志使用ELKB系统进行收集管理

服务概述

服务是一个很简单的服务, 打了部分日志, 以模拟日志的产生.

image.png

配置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, 而根据我们的配置, 我们的索引是每天按照时间戳分索引存放的(索引相当于关系型数据库的表), 我们这么做是为了数据的分片,更好的分时间段处理数据.

image.png 但这样的话, 我们需要每天都建一个新索引, 为了避免此项工作, 我们引入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"
        }
      }
    
  }
}

执行结果如下:

image.png

这个步骤我们可以使用elasticsearch-head执行, 也可以使用kibana带的开发工具执行, 也可以自己使用代码调用ES的API执行.

elasticsearch-head执行:

进入elasticsearch-head, 在符合查询下, 输入命令, 点击提交请求:

image.png

kibana执行:

进入kibana, 在首页点击开发工具,

image.png 或在任意位置, 点击菜单栏下的开发工具菜单:

image.png

进入, 输入命令, 点击执行:

image.png

启动服务

至此准备工作已完成, 分别启动ES,Kibana,LogStash,Filebeat

生成两条日志, 查看索引是否生成: 进入elasticsearch-head查看:

image.png 如图, 即生成成功, 如未生成成功, 则需要检查配置

配置kibana可视化DisCover

配置kibana索引模式

进入主页 http://127.0.0.1:5601/app/home#/ , 点击管理

image.png

点击索引模式, 点击创建索引模式

image.png

按提示输入索引名称, 点击下一步

image.png

选择时间字段, 这个时间字段是我们在配置logstash时配置的, 用来进行时间筛选. 点击创建

image.png 至此, 索引模式创建成功

进入仪表盘查看

进入主页 http://127.0.0.1:5601/app/home#/ , 点击可视化和分析

image.png

进入DisCover

image.png

选择刚才新建的索引模板

image.png 可以看出, 日志已经正常展示

配置多个项目的日志收集

多个项目可以共用一个ES, kibana, 甚至可以共用一个ES的模板索引(只要我们保证生成索引的规则符合索引模板的规则即可).

我们也可以选择不同的项目使用不同的Beats去收集日志, 最终汇总到Logstash, 再汇总到ES

这里做一个示例, 配置两个项目, 每个项目配置一个自己的Filebeat去收集日志, 最终在同一个Logstash中处理, 再分给不同的ES索引模板, 配置不同的DisCover查看

结构如下:

image.png

几个关键的配置点如下:

image.png

image.png

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"
  }
}

创建索引的语句类似, 差异如下:

image.png

至此, 重启服务, kibana添加索引模板即可

image.png


ES系统还有很多的功能, 都很强大, 后续再更新