日志收集系统

1. 为什么要收集日志?

在项目开发和测试过程中,日志是定位问题的重要依据。

日志级别

通过日志级别进行分级管理。

  • DEBUG (调试)
  • INFO (记录)
  • WARN (警告)
  • ERROE (异常)
日志格式化

通过格式化提高日志可读性。
常用日志格式:时间 模块 行数 日志内容

SpringBoot默认日志格式(集成sleuth zipkin,日志等级中会追加 [项目名,traceId,spanId,result]):

2019-12-13 14:56:46.247  INFO [base-server,,,] 32576 --- [AsyncResolver-bootstrap-executor-0] c.n.d.s.r.aws.ConfigClusterResolver      : Resolving eureka endpoints via configuration$

时间戳 日志级别 [项目名,traceId,spanId,result] 进程ID --- [线程名] log名 : 日志内容

2. Elastic Stack 是什么?

Elastic Stack 包括 Elasticsearch、Kibana、Beats 和 Logstash(也称为 ELK Stack)。能够安全可靠地获取任何来源、任何格式的数据,然后实时地对数据进行搜索、分析和可视化。
官网: ELK Stack

Elasticsearch is the distributed search and analytics engine at the heart of the Elastic Stack. Logstash and Beats facilitate collecting, aggregating, and enriching your data and storing it in Elasticsearch. Kibana enables you to interactively explore, visualize, and share insights into your data and manage and monitor the stack. Elasticsearch is where the indexing, search, and analysis magic happen.

Elasticsearch

是一个分布式搜索和分析引擎,存储数据索引、并提供搜索和分析。
文档:Elasticsearch

Kibana

基于可视化界面访问ES数据索引,分析数据及数据可视化。
管理和监控ES的堆栈。
文档:Kibana

Beats

从数据源中获取数据并存储到ES。
也可以上传到LogStash,通过LogStash格式化再存储到ES。
也可以传送到kafka,通过队列进行缓存、削峰。

日志收集主要是采集日志文件,所以Beats选用FileBeat
FileBeat通过监听文件内容变化,以行为单位采集数据(支持多行合并)
文档:FileBeat

Logstash

负责收集数据,处理数据,上传数据(支持codec)。
input => decode => filter => encode => output
文档:Logstash

3.如何基于ELK搭建日志收集系统?

如图:
ELK Stack

3.1 部署环境

基础环境(点击名称进入对应下载页面)
软件 版本 备注
Liunx CentOS7
jdk 1.8.0_211
node 10.16.0
elasticsearch 7.5.0
kibana 7.5.0
logstash 7.5.0
filebeat 7.5.0
logstash 7.5.0
elasticsearch-head master ES插件,ES可视化
elasticsearch-analysis-ik master ES插件,IK分词器
elasticsearch-analysis-pinyin master ES插件,pinyin分词器
机器环境
NODE IP 节点类型
data-1 X.X.X.210 数据节点(ES/ik/pinyin)
data-2 X.X.X.211 数据节点(ES/ik/pinyin)
data-3 X.X.X.212 数据节点(ES/ik/pinyin)
seek-1 X.X.X.214 搜索节点(ES/kibana/head/ik/pinyin)
other * 业务日志收集节点(filebeats)

3.2 ES集群

部署前准备:

1 安装jdk,并检查版本。1.8以上即可
2 安装node,最新版本即可
3 添加linux系统账号,部署ES需要非root账号

3.2.1 下载解压
tar -xvf elasticsearch-7.5.0-linux-x86_64.tar.gz
3.2.2 配置
  • elasticsearch-7.5.0/config/elasticsearch.yml
# 集群名 保持一致
cluster.name: logging-dev

# 节点名 保证唯一 数据节点[data-x] 搜索节点[seek-x]
node.name: data-1
# 允许作为主节点(默认true),可将搜索节点设为false
node.master: true
# 允许存储数据(默认true),将搜索节点设为false
node.data: true
# 允许预处理数据(默认true),通常会单独部署Ingest node进行数据预处理
# 可将数据节点设为false
node.ingest: true

# 配置数据/日志路径
# 数据路径允许配置多个(属于同一分片的文件会存储在同一路径)
# 为了方便日后ES升级,建议重新配置path.data和path.logs为公共路径
path.data: /opt/es/data/log-data-1
path.logs: /opt/es/logs/log-data-1

# 配置IP地址(有坑)
# 建议阅读文档:https://www.elastic.co/guide/en/elasticsearch/reference/7.5/network.host.html
network.bind_host: 0.0.0.0
network.publish_host: 172.16.131.214
network.host: 172.16.131.214
# 配置HTTP访问端口,默认(9200-9300)
http.port: 9200
# 配置transport监听端口,默认(9300-9400)
transport.port: 9300
# 配置跨域,确保elasticsearch-head和其他服务访问ES
http.cors.enabled: true
http.cors.allow-headers: "*"

# 配置集群节点host列表(不包含搜索节点),保持一致
discovery.seed_hosts: ["X.X.X.210:9300", "X.X.X.211:9300","X.X.X.212:9300"]
# 配置初始选举主节点node列表(不包含搜索节点),保持一致,
cluster.initial_master_nodes: ["data-1", "data-2", "data-3"]
  • elasticsearch-7.5.0/config/jvm.options
    通常只需要修改堆栈大小-xms -xmx,避免ES内存溢出
  • elasticsearch-7.5.0/config/log4j2.properties
3.2.3 安装插件**[可选]
下载elasticsearch-analysis-ik, 解压到elasticsearch-7.5.0/plugins/ik下
下载elasticsearch-analysis-pinyin,解压到elasticsearch-7.5.0/plugins/pinyin
参考路径:
-plugins
    -ik
        -plugin-descriptor.properties
        -略...
    -pinyin
        -plugin-descriptor.properties
        -略...
3.2.4 运行
启动(不要用root账号启动)
    ./bin/elasticsearch [-Ehttp.port=9200] [-d]
    -Ekey=val 可以覆盖配置属性
    -d 后台运行ES
    
    运行成功后,访问http://X.X.X.210:9200返回信息即可
    
停止
    jps
    kill -9 [pid]
    或者
    jps | grep Elasticsearch | awk '{print $1}' | xargs kill -9
3.2.5 运行Elasticsearch-head**[可选]
在seek-1节点(X.X.X.214)上部署即可
1. 下载并解压Elasticsearch-head
    unzip elasticsearch-head-master.zip
2. 修改配置
    2.1 elasticsearch-head/Gruntfile.js
        vi Gruntfile.js 编辑Gruntfile.js
        /connect    查找connect,格式如下,修改配置即可
            connect: {
                    server: {
                            options: {
                                    hostname: '*',
                                    port: 9100,
                                    base: '.',
                                    keepalive: true
                            }
                    }
            }
    2.2 elasticsearch-head/_site/app.js
        vi ./_site/app.js
        /app-base_uri 查找app-base_uri,通常再按n查找下一次即可找到,大概在4374行
            init: function(parent) {
                        this._super();
                        this.prefs = services.Preferences.instance();
                        // 在此处配置ES集群IP
                        this.base_uri = this.config.base_uri || this.prefs.get("app-base_uri")
                                || "http://X.X.X.210:9200" || "http://X.X.X.211:9200" || "http://X.X.X.212:9200" || "http://X.X.X.214:9200";
                        if( this.base_uri.charAt( this.base_uri.length - 1 ) !== "/" ) {
                                // XHR request fails if the URL is not ending with a "/"
                                this.base_uri += "/";
                        }
                        ...

3. 运行
    启动
        npm run start
        nohup npm run start & //后台运行
        
        运行成功 访问http://X.X.X.214:9100, 返回集群信息即可
        
    停止
        netstat -lntp | grep 9100
        kill -9 [pid]
        

3.3 Kibana

在seek-1节点(X.X.X.214)上部署即可

3.3.1 下载解压
tar -xvf kibana-7.5.0-linux-x86_64.tar.gz
3.3.2 配置
  • kibana-7.5.0-linux-x86_64/config/kibana.yml
# 配置端口
server.port: 5601
# 配置host
server.host: "0.0.0.0"
# 配置界面为中文
i18n.locale: "zh-CN"
3.3.3 运行
启动
    nohup ./bin/kibana > kibana.log 2>&1 &
    tail -f kibana.log

    执行成功,访问http://X.X.X.214:5601

停止
    netstat -lntp|grep 5601
    kill -9 [pid]

3.4 logstash

logstash 暂时先在seek-1节点(X.X.X.214)上部署

3.4.1 下载解压
tar -xvf logstash-7.5.0.tar.gz
3.4.2 配置
  • logstash-7.5.0/config/logging-dev.conf
# Sample Logstash configuration for creating a simple
# Beats -> Logstash -> Elasticsearch pipeline.

input {
# 从beats中读取数据
    beats {
        port => 5044
    }
}

filter {
# 通过grok插件对SpringBoot日志进行格式化,基于正则,性能较差
#    grok { match => [ "message", "%{TIMESTAMP_ISO8601:time}\s+%{LOGLEVEL:level}\s+\[(?<application_name>.*),(?<traceId>.*),(?<spanId>.*),(?<result>.*)\]\s+%{NUMBER:t_id}\s+---\s+\[(?<t_name>.*?)\]\s+(?<log>.*?)\s+:(?<content>.*)" ] }
# 通过dissert插件对SpringBoot日志进行格式化,严格按照格式分割,性能要比正则好。
    dissect {
        mapping => {
            "message" => "%{[@metadata][timestamp]} %{+[@metadata][timestamp]} %{log_level} [%{application_name},%{traceId},%{spanId},%{result}] %{t_id} --- [%{t_name}] %{log} :%{content}"
        }
    }
    date { 
        match => [ "[@metadata][timestamp]", "yyyy-MM-dd HH:mm:ss.SSS" ] 
    }
}

output {
# 上传到ES中
    elasticsearch {
        hosts => ["http://172.16.131.210:9200","http://172.16.131.211:9200","http://172.16.131.212:9200"]
        index => ""
    }
}
配置修改后,记得执行配置校验命令
./bin.logstash -f config/logging-dev.conf -t
3.4.3 运行
启动
    nohup ./bin/logstash -n node-1 -f config/logging-dev.conf -r >/dev/null 2>&1 &
    tail -99f 
    
停止
    jps | grep Logstash
    kill -9 [pid]

3.5 部署filebeat

在业务服务器上部署(需要收集的日志所在服务器)

3.5.1 下载并解压filebeat
tar -xvf filebeat-7.5.0-linux-x86_64.tar.gz
3.5.2 配置filebeat
  • filebeat-7.5.0-linux-x86_64/filebeat.yml
filebeat.inputs:
    - type: log
    paths:
        - /var/log/*.log

filebeat.config.modules:
    path: ${path.config}/modules.d/*.yml
    reload.enabled: false
    
setup.template.settings:
    index.number_of_shards: 1

setup.kibana:
    host: "X.X.X.214:5601"
    
output.logstash:
    hosts: ["172.16.131.214:5044"]
3.5.3 运行filebeat

启动
    nohup ./filebeat >/dev/null 2>&1 &


roylion
204 声望25 粉丝

读书破万卷