ELK日志平台(elasticsearch +logstash+kibana)原理和实操(史上最全)

Posted 架构师-尼恩

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ELK日志平台(elasticsearch +logstash+kibana)原理和实操(史上最全)相关的知识,希望对你有一定的参考价值。

文章很长,建议收藏起来慢慢读!疯狂创客圈总目录 语雀版 | 总目录 码云版| 总目录 博客园版 为您奉上珍贵的学习资源 :

推荐:尼恩Java面试宝典(持续更新 + 史上最全 + 面试必备)具体详情,请点击此链接

尼恩Java面试宝典,32个最新pdf,含2000多页不断更新、持续迭代 具体详情,请点击此链接


ELK的高并发场景的问题

elk能支撑50W到100W级qps场景的 大流量日志监控吗?
具体的架构如下:

**答案,当然没法撑住。**解决方案,稍后介绍。

但是,咱们先得把ELK 的原理搞清楚,知己才能知彼

Spring Boot整合ELK+Filebeat构建日志系统

ELK指的是Elastic公司下面Elasticsearch、Logstash、Kibana三大开源框架首字母大写简称。
Elasticsearch、Logstash、Kibana三大开源框架首字母大写简称。

ELK的关系

  1. Logstash可以将数据收集起来统一刷入Elasticsearch中
  2. 数据在Elasticsearch中进行分析然后通过kibana进行展示

Logstash:从各种数据源搜集数据,并对数据进行过滤、分析、丰富、统一格式等操作,然后存储到 ES。

Elasticsearch:对大容量的数据进行接近实时的存储、搜索和分析操作。

Kibana:数据分析和可视化平台。与 Elasticsearch 配合使用,对数据进行搜索、分析和以统计图表的方式展示。

ELK的应用

  • 异常分析

通过将应用的日志内容通过Logstash输入到Elasticsearch中来实现对程序异常的分析排查

  • 业务分析

将消息的通讯结果通过Logstash输入到Elasticsearch中来实现对业务效果的整理

  • 系统分析

将处理内容的延迟作为数据输入到Elasticsearch 中来实现对应用性能的调优

Elasticsearch概述

Elasticsearch 是一个分布式的开源搜索和分析引擎,在 Apache Lucene 的基础上开发而成。

Lucene 是开源的搜索引擎工具包,Elasticsearch 充分利用Lucene,并对其进行了扩展,使存储、索引、搜索都变得更快、更容易, 而最重要的是, 正如名字中的“ elastic ”所示, 一切都是灵活、有弹性的。而且,应用代码也不是必须用Java 书写才可以和Elasticsearc兼容,完全可以通过JSON 格式的HTTP 请求来进行索引、搜索和管理Elasticsearch 集群。

如果你已经听说过Lucene ,那么可能你也听说了Solr,

Solr也是开源的基于Lucene 的分布式搜索引擎,跟Elasticsearch有很多相似之处。

但是Solr 诞生于2004 年,而Elasticsearch诞生于2010,Elasticsearch凭借后发优势和更活跃的社区、更完备的生态系统,迅速反超Solr,成为搜索市场的第二代霸主。

Elasticsearch具有以下优势:

  • Elasticsearch 很快。 由于 Elasticsearch 是在 Lucene 基础上构建而成的,所以在全文本搜索方面表现十分出色。Elasticsearch 同时还是一个近实时的搜索平台,这意味着从文档索引操作到文档变为可搜索状态之间的延时很短,一般只有一秒。因此,Elasticsearch 非常适用于对时间有严苛要求的用例,例如安全分析和基础设施监测。
  • Elasticsearch 具有分布式的本质特征。 Elasticsearch 中存储的文档分布在不同的容器中,这些容器称为分片,可以进行复制以提供数据冗余副本,以防发生硬件故障。Elasticsearch 的分布式特性使得它可以扩展至数百台(甚至数千台)服务器,并处理 PB 量级的数据。
  • Elasticsearch 包含一系列广泛的功能。 除了速度、可扩展性和弹性等优势以外,Elasticsearch 还有大量强大的内置功能(例如数据汇总和索引生命周期管理),可以方便用户更加高效地存储和搜索数据。
  • Elastic Stack 简化了数据采集、可视化和报告过程。 人们通常将 Elastic Stack 称为 ELK Stack(代指ElasticsearchLogstashKibana),目前 Elastic Stack 包括一系列丰富的轻量型数据采集代理,这些代理统称为 Beats,可用来向 Elasticsearch 发送数据。通过与 Beats 和 Logstash 进行集成,用户能够在向 Elasticsearch 中索引数据之前轻松地处理数据。同时,Kibana 不仅可针对 Elasticsearch 数据提供实时可视化,同时还提供 UI 以便用户快速访问应用程序性能监测 (APM)、日志和基础设施指标等数据。

logstash概述

简单来说logstash就是一根具备实时数据传输能力的管道,负责将数据信息从管道的输入端传输到管道的输出端;与此同时这根管道还可以让你根据自己的需求在中间加上滤网,Logstash提供里很多功能强大的滤网以满足你的各种应用场景。


logstash常用于日志系统中做日志采集设备,最常用于ELK中作为日志收集器使用

logstash作用:

集中、转换和存储你的数据,是一个开源的服务器端数据处理管道,可以同时从多个数据源获取数据,并对其进行转换,然后将其发送到你最喜欢的“存储

logstash的架构:

logstash的基本流程架构:input  |  filter  |  output 如需对数据进行额外处理,filter可省略。

Input(输入):

采集各种样式,大小和相关来源数据,从各个服务器中收集数据。

数据往往以各种各样的形式,或分散或集中地存在于很多系统中。
Logstash 支持各种输入选择 ,可以在同一时间从众多常用来源捕捉事件。
能够以连续的流式传输方式,轻松地从您的日志、指标、Web 应用、数据存储以及各种 AWS 服务采集数据。

inpust:必须,负责产生事件(Inputs generate events),

常用:File、syslog、redis、beats(如:Filebeats)

Filter(过滤器)

用于在将event通过output发出之前,对其实现某些处理功能。

filters:可选,负责数据处理与转换(filters modify them),

常用:grok、mutate、drop、clone、geoip


grok:用于分析结构化文本数据。


Output(输出):

将我们过滤出的数据保存到那些数据库和相关存储中。

outputs:必须,负责数据输出(outputs ship them elsewhere),

常用:elasticsearch、file、graphite、statsd


Logstash的角色与不足

早期的ELK架构中使用Logstash收集、解析日志,

但是:Logstash对内存、cpu、io等资源消耗比较高。

相比Logstash,Beats所占系统的CPU和内存几乎可以忽略不计。

所以,在收集这块,一般使用filebeat 代替 Logstash

filebeat介绍

Filebeat是一个轻量级日志传输Agent,可以将指定日志转发到Logstash、Elasticsearch、Kafka、Redis等中。

Filebeat占用资源少,而且安装配置也比较简单,支持目前各类主流OS及Docker平台。

Filebeat是用于转发和集中日志数据的轻量级传送程序。

作为服务器上的代理安装,Filebeat监视您指定的日志文件或位置,收集日志事件,并将它们转发到Elasticsearch或Logstash进行索引。

Filebeat的工作方式如下:启动Filebeat时,它将启动一个或多个输入,这些输入将在为日志数据指定的位置中查找。

对于Filebeat所找到的每个日志,Filebeat都会启动收割机。

每个收割机都读取一个日志以获取新内容,并将新日志数据发送到libbeat,libbeat会汇总事件并将汇总的数据发送到您为Filebeat配置的输出。

Filebeat下载页面

https://www.elastic.co/cn/downloads/past-releases#filebeat

Filebeat文件夹结构

描述
filebeat用于启动filebeat的二进制文件
data持久化数据文件的位置
logsFilebeat创建的日志的位置
modules.d简化filebeat配置的模板文件夹,如nginx/kafka等日志收集模板
filebeat.ymlfilebeat配置文件
Filebeat启动命令
./filebeat -e -c filebeat配置文件

filebeat和beats的关系

filebeat是Beats中的一员。

Beats在是一个轻量级日志采集器,其实Beats家族有6个成员,目前Beats包含六种工具:

  • Packetbeat:网络数据(收集网络流量数据)
  • Metricbeat:指标(收集系统、进程和文件系统级别的CPU和内存使用情况等数据)
  • Filebeat:日志文件(收集文件数据)
  • Winlogbeat:windows事件日志(收集Windows事件日志数据)
  • Auditbeat:审计数据(收集审计日志)
  • Heartbeat:运行时间监控(收集系统运行时的数据)

一键安装 es+logstash+ kibana

对应的镜像版本

elasticsearch:7.14.0
kibana:7.14.0
logstash:7.14.0
filebeat:7.14.0

docker编码文件

version: "3.5"
services:
  elasticsearch:
     image: andylsr/elasticsearch-with-ik-icu:7.14.0
     container_name: elasticsearch
     hostname: elasticsearch
     restart: always
     ports:
       - 9200:9200
     volumes:
       - ./elasticsearch7/logs:/usr/share/elasticsearch/logs
       - ./elasticsearch7/data:/usr/share/elasticsearch/data
       - ./elasticsearch7/config/single-node.yml:/usr/share/elasticsearch/config/elasticsearch.yml
       - ./elasticsearch7/config/jvm.options:/usr/share/elasticsearch/config/jvm.options
       - ./elasticsearch7/config/log4j2.properties:/usr/share/elasticsearch/config/log4j2.properties
     environment:
       - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
       - "TZ=Asia/Shanghai"
       - "TAKE_FILE_OWNERSHIP=true"   #volumes 挂载权限 如果不想要挂载es文件改配置可以删除
     ulimits:
       memlock:
         soft: -1
         hard: -1
     networks:
       base-env-network:
         aliases:
          - elasticsearch
  kibana:
    image: docker.elastic.co/kibana/kibana:7.14.0
    container_name: kibana
    volumes:
      - ./elasticsearch7/config/kibana.yml:/usr/share/kibana/config/kibana.yml
    ports:
      - 15601:5601
    ulimits:
      nproc: 65535
      memlock: -1
    depends_on:
       - elasticsearch
    networks:                    
       base-env-network:
         aliases:
          - kibana
  logstash:
    image:  logstash:7.14.0
    container_name: logstash
    hostname: logstash
    restart: always
    ports:
      - 19600:9600
      - 15044:5044
    volumes:
      - ./logstash/logstash.conf:/usr/share/logstash/pipeline/logstash.conf:rw
      - ./logstash/logstash.yml:/usr/share/logstash/config/logstash.yml
      - ./logstash/data:/home/logstash/data
    networks:
       base-env-network:
         aliases:
          - logstash
# docker network create base-env-network          
networks:
  base-env-network:
    external:
      name: "base-env-network"
    

访问kibana

http://cdh1:15601

SkyWalking

http://cdh2:13800/

kibana

读取filebeat-输出到es集群

在分布式系统中,一台主机可能有多个应用,应用将日志输出到主机的指定目录,这时由logstash来搬运日志并解析日志,然后输出到elasticsearch上。

由于于logstash是java应用,解析日志是非的消耗cpu和内存,logstash安装在应用部署的机器上显得非常的笨重。

最常见的做法是用filebeat部署在应用的机器上,logstash单独部署,然后由filebeat将日志输出给logstash解析,解析完由logstash再传给elasticsearch。

在上面的配置中,输入数据源为filebeat,输出源为elasticsearch。

修改logstash的安装目录的config目录下的logstash.conf文件,配置如下:

input 
  beats 
    port => "5044"
  



filter 
    
    if "message-dispatcher" in [tags]
        grok 
            match => ["message", "%TIMESTAMP_ISO8601:time\\s* \\s*%NOTSPACE:thread-id\\s* \\s*%LOGLEVEL:level\\s* \\s*%JAVACLASS:class\\s* \\- \\s*%JAVALOGMESSAGE:logmessage\\s*"]
        
        
    

    if "ExampleApplication" in [tags]
        grok 
            match => ["message", "%TIMESTAMP_ISO8601:time\\s* \\s*%NOTSPACE:thread-id\\s* \\s*%LOGLEVEL:level\\s* \\s*%JAVACLASS:class\\s* \\- \\s*%JAVALOGMESSAGE:logmessage\\s*"]
        
        
    
    mutate 
        remove_field => "log"
        remove_field => "beat"
        remove_field => "meta"
        remove_field => "prospector"
        remove_field => "[host][os]"
    



output 
    stdout  codec => rubydebug 
    if "message-dispatcher" in [tags]
        elasticsearch 
           hosts => [ "elasticsearch:9200" ]
           index => "message-dispatcher-%+yyyy.MM.dd"      
        
    
    if "ExampleApplication" in [tags]
        elasticsearch 
           hosts => [ "elasticsearch:9200" ]
           index => "ExampleApplication-%+yyyy.MM.dd"      
        
        


更多的输入和输出源的配置见官网

https://www.elastic.co/guide/en/logstash/current/advanced-pipeline.html

在kibana显示的效果

在kibana组件上查看,可以看到创建了一个filebeat开头的数据索引,如下图:

在日志搜索界面,可以看到service-hi应用输出的日志,如图所示:

使用filebeat发送日志

制作filebeat镜像

官方文档

https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-getting-started.html

下载filebeat,下载命令如下:

https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.14.0-linux-x86_64.tar.gz

 wget  https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.2.0-linux-x86_64.tar.gz
 
 
tar -zxvf filebeat-7.2.0-linux-x86_64.tar.gz
mv filebeat-7.2.0-linux-x86_64 /usr/share/
cd /usr/share/filebeat-7.2.0-linux-x86_64/

制作基础的unbantu镜像

why unbantu? not alpine? not centos?

Alpine 只有仅仅 5 MB 大小,并且拥有很友好的包管理机制。

Docker 官方推荐使用 Alpine 替代 Ubuntu 做为容器的基础镜像。

曾经尝试使用alpine:3.7作为底层镜像, 按照zookeeper,但是一直启动不来,换成了centos的镜像,排查过程反复实验,耗时很久。

网上小伙伴构建filebeat镜像,基于alpine:3.7, 构建后的镜像运行时报“standard_init_linux.go:190: exec user process caused “no such file or directory””,故最后还是选择ubuntu。

这里选择ubuntu的原因,是其作为底层打包出来的镜像比centos要小很多。

# 基础镜像 生成的镜像作为基础镜像
FROM ubuntu:18.04


# 指定维护者的信息
MAINTAINER 尼恩@疯狂创客圈

# RUN apt-get update  && apt-get -y install openjdk-8-jdk



#install wget,sudo,python,vim,ping and ssh command

RUN sed -i s@/archive.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list   && apt-get  clean && \\
    apt-get update && apt-get -y install wget && apt-get -y install sudo && \\
    apt-get -y install iputils-ping && \\
    apt-get -y install net-tools && \\
    apt install -y tzdata && \\
    rm -rf /etc/localtime  && ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime &&  dpkg-reconfigure -f noninteractive tzdata && \\
    apt-get  clean

 #    echo "Asia/Shanghai" > /etc/timezone &&  dpkg-reconfigure -f noninteractive tzdata && \\
 


# RUN dpkg-reconfigure -f noninteractive tzdata
    
# RUN apt-get clean


 #apt-get -y install python && \\
 # apt-get -y install vim && \\
 #  apt-get -y install openssh-server && \\
 # apt-get -y install python-pip  && \\


# 复制并解压
ADD jdk-8u121-linux-x64.tar.gz /usr/local/


ENV work_path /usr/local
WORKDIR $work_path

# java
ENV JAVA_HOME /usr/local/jdk1.8.0_121
ENV JRE_HOME  /usr/local/jdk1.8.0_121/jre
ENV CLASSPATH .:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
ENV PATH $PATH:$JAVA_HOME/bin

dockfile add命令:

ADD指令的功能是将主机构建环境(上下文)目录中的文件和目录、以及一个URL标记的文件 拷贝到镜像中。

其格式是: ADD 源路径 目标路径

注意事项:

1、如果源路径是个文件,且目标路径是以 / 结尾, 则docker会把目标路径当作一个目录,会把源文件拷贝到该目录下。

如果目标路径不存在,则会自动创建目标路径。

2、如果源路径是个文件,且目标路径是不是以 / 结尾,则docker会把目标路径当作一个文件。

如果目标路径不存在,会以目标路径为名创建一个文件,内容同源文件;

如果目标文件是个存在的文件,会用源文件覆盖它,当然只是内容覆盖,文件名还是目标文件名。

如果目标文件实际是个存在的目录,则会源文件拷贝到该目录下。 注意,这种情况下,最好显示的以 / 结尾,以避免混淆。

3、如果源路径是个目录,且目标路径不存在,则docker会自动以目标路径创建一个目录,把源路径目录下的文件拷贝进来。

如果目标路径是个已经存在的目录,则docker会把源路径目录下的文件拷贝到该目录下。

4、如果源文件是个归档文件(压缩文件,比如 .tar文件),则docker会自动帮解压。

推送镜像到dockerhub

这个镜像解决了jdk问题,时区问题

推送到了dockerhub,大家可以直接作为基础镜像使用

docker login

docker tag 8d0abdffe76f nien/ubuntu:18.04

docker push nien/ubuntu:18.04

制作filebeat镜像

官方文档

https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-getting-started.html

下载filebeat,下载命令如下:

https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.14.0-linux-x86_64.tar.gz

 wget  https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.2.0-linux-x86_64.tar.gz
 
 
tar -zxvf filebeat-7.2.0-linux-x86_64.tar.gz
mv filebeat-7.2.0-linux-x86_64 /usr/share/
cd /usr/share/filebeat-7.2.0-linux-x86_64/

dockerfile

# 基础镜像 生成的镜像作为基础镜像
FROM nien/ubuntu:18.04


# 指定维护者的信息
MAINTAINER 尼恩@疯狂创客圈


# 复制并解压
ADD filebeat-7.14.0-linux-x86_64.tar.gz /usr/local/

构建镜像

docker build -t filebeat:7.14.0  .

构建之后,进入容器,可以看到 /usr/local 目录下的filebeat-7.14.0-linux-x86_64

[root@cdh2 filebeat]# docker run -it filebeat:7.14.0 /bin/bash
root@7ba04f21f26e:/usr/local# ll
total 48
drwxr-xr-x 1 root root 4096 Apr  2 09:26 ./
drwxr-xr-x 1 root root 4096 Mar 16 03:27 ../
drwxr-xr-x 2 root root 4096 Mar 16 03:27 bin/
drwxr-xr-x 2 root root 4096 Mar 16 03:27 etc/
drwxr-xr-x 5 root root 4096 Apr  2 09:26 filebeat-7.14.0-linux-x86_64/
drwxr-xr-x 2 root root 4096 Mar 16 03:27 games/
drwxr-xr-x 2 root root 4096 Mar 16 03:27 include/
drwxr-xr-x 8 uucp  143 4096 Dec 13  2016 jdk1.8.0_121/
drwxr-xr-x 2 root root 4096 Mar 16 03:27 lib/
lrwxrwxrwx 1 root root    9 Mar 16 03:27 man -> share/man/
drwxr-xr-x 2 root root 4096 Mar 16 03:27 sbin/
drwxr-xr-x 1 root root 4096 Apr  2 00:44 share/
drwxr-xr-x 2 root root 4096 Mar 16 03:27 src/

推送镜像到dockerhub

这个镜像解决了jdk问题,时区问题

推送到了dockerhub,大家可以直接作为基础镜像使用

[root@cdh2 filebeat]# docker tag fb44037ab5f9 nien/filebeat:7.14.0

[root@cdh2 filebeat]# docker push nien/filebeat:7.14.0
The push refers to repository [docker.io/nien/filebeat]
069c957c7a4e: Pushing [=======>                                           ]  19.99MB/140MB
b17e3cbc28a1: Mounted from nien/ubuntu
5695cc8dd56c: Mounted from nien/ubuntu
9d6787a516e7: Mounted from nien/ubuntu


如果要收集日志,就可以用这个基础镜像加点配置就ok啦

message-dispatcher微服务的filebeat.yml配置:

filebeat.inputs:
- type: message-dispatcher
  enabled: true
  paths:
    - /work/logs/output.log
output.logstash:
  hosts: ["logstash:5044"]

filebeat.yml的参考配置:

#=========================== Filebeat inputs =============================

filebeat.inputs:

- type: log
  enabled: true     #默认为false,修改为true则启用该配置
  paths:
    - /home/logs/*.log
  fields:
    filetype: test1    #自定义字段,用来区分多个类型日志
  fields_under_root: true    #如果该选项设置为true,则新增fields成为顶级目录,而不是将其放在fields目录下

#============================= 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
  #index.codec: best_compression
  #_source.enabled: false

#================================ Outputs =====================================
#直接将log数据传输到Elasticsearch
#-------------------------- Elasticsearch output ------------------------------
output.elasticsearch:
  # Array of hosts to connect to.
  hosts: ["localhost:9200"]
  username: "elastic"
  password: "elastic"

#----------------------------- Logstash output --------------------------------#将log数据传输到logstash#先启动logstash,不然的话filebeat会找不到logstash的5044端口
output.logstash:
  # The Logstash hosts
  hosts: ["localhost:5044"]

message-dispatcher微服务的filebeat.yml配置:

主要配置的是日志的搜集目录为/work/logs/output.log,这个目录是应用message-dispatcher输出日志的文件。

由于其他的微服务也是固定在这个 文件,

所以这个路径,基本可以固定。

message-dispatcher微服务的filebeat.yml配置:

输出到logstsh的地址为logstash,这里用的是容器的名称, logstash和 这个微服务,需要在同一个网络。

如果不是,可以使用虚拟机的名称,然后把 5044,映射到15044

filebeat.inputs:
- type: message-dispatcher
  enabled: true
  paths:
    - /work/logs/output.log
output.logstash:
  hosts: ["cdh2:15044"]

启动filebeat,执行一下命令:

nohup  /user/local/filebeat-7.14.0-linux-x86_64/filebeat  -c /work/filebeat/filebeat.yaml   >> /work/filebeat/out.log 2>&1  &

修改message-dispatcher的dockerfile

FROM  nien/filebeat:7.14.0

# 指定维护者的信息
MAINTAINER 尼恩@疯狂创客圈


ADD dispatcher-provider-1.0-SNAPSHOT.jar  /app/message-dispatcher.jar
ADD deploy-sit.sh  /app/run.sh
RUN chmod +x /app/run.sh

# WORKDIR /app/

ENTRYPOINT /bin/bash -c  "/app/run.sh start"
# ENTRYPOINT /bin/bash 

一键发布message-dispatcher

mkdir -p  /home/docker-compose/sit-ware/message-dispatcher

cd /home/docker-compose/sit-ware/message-dispatcher

docker-compose down
 
docker image  rm message-dispatcher:1.0-SNAPSHOT

rm -rf  /home/docker-compose/sit-ware/message-dispatcher

cp -rf /vagrant/sit-ware/message-dispatcher  /home/docker-compose/sit-ware


cd /home/docker-compose/sit-ware

chmod 777 -R  message-dispatcher

cd message-dispatcher

docker-compose --compatibility  up  -d

docker-compose  logs -f


docker-compose down

mysql/5.7.31

docker save mysql:5.7.31  -o /vagrant/3G-middleware/mysql.5.7.31.tar

docker save registry.cn-hangzhou.aliyuncs.com/zhengqing/canal-server:v1.1.5        -o /vagrant/3G-middleware/canal-server.v1.1.5.tar

docker save registry.cn-hangzhou.aliyuncs.com/zhengqing/canal-admin:v1.1.5        -o /vagrant/3G-middleware/canal-admin.v1.1.5.tar


docker exec -it message-dispatcher /bin/bash

tail -f /work/filebeat/out.log 


java -server -Xms64m -Xmx256m   -Dserver.port=7790 -Dspring.profiles.active=sit  -jar  /vagrant/sit-ware/springcloud-gateway/springcloud-gateway-1.0-SNAPSHOT.jar com.crazymaker.cloud.nacos.demo.gateway.starter.GatewayProviderApplication


java -server -Xms64m -Xmx256m -javaagent: -Dskywalking.agent.service_name=springcloud-gateway -Dskywalking.collector.backend_service=127.0.0.1  -Dserver.port=7790 -Dspring.profiles.active=sit  -jar /app/springcloud-gateway.jar com.crazymaker.cloud.nacos.demo.gateway.starter.GatewayProviderApplication

启动之后

spatcher    | ----------------------------------------------------------
message-dispatcher    |         UAA 推送中台 push-provider is running! Access URLs:
message-dispatcher    |         Local:          http://127.0.0.1:7703/message-dispatcher-provider/
message-dispatcher    |         swagger-ui:     http://127.0.0.1:7703/message-dispatcher-provider/swagger-ui.html
message-dispatcher    |         actuator:       http://127.0.0.1:7703/message-dispatcher-provider/actuator/info
message-dispatcher    |         ----------------------------------------------------------
message-di

http://cdh2:7703/message-dispatcher-provider/swagger-ui.html

message-dispatcher微服务的日志

在SpringBoot应用message-dispatcher微服务的日志,输出日志如下:

[root@cdh2 filebeat]# cd  /home/docker-compose/sit-ware/message-dispatcher/work/logs/
[root@cdh2 logs]# cat output.log
2022-04-02 09:03:30.103 [background-preinit] DEBUG o.h.v.m.ResourceBundleMessageInterpolator:89 - Loaded expression factory via original TCCL
2022-04-02 09:03:59.633 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:330 - Bean 'org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$e81692de] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2022-04-02 09:04:05.331 [main] INFO  c.a.n.client.config.impl.LocalConfigInfoProcessor:195 - LOCAL_SNAPSHOT_PATH:/root/nacos/config
2022-04-02 09:04:06.034 [main] INFO  com.alibaba.nacos.client.config.impl.Limiter:53 - limitTime:5.0
2022-04-02 09:04:06.899 [main] INFO  com.alibaba.nacos.client.config.utils.JVMUtil:47 - isMultiInstance:false
2022-04-02 09:04:07.068 [main] WARN  c.a.cloud.nacos.client.NacosPropertySourceBuilder:87 - Ignore the empty nacos configuration and get it based on dataId[message-dispatcher-provider] & group[DEFAULT_GROUP]
2022-04-02 09:04:07.100 [main] WARN  c.a.cloud.nacos.client.NacosPropertySourceBuilder:87 - Ignore the empty nacos configuration and get it based on dataId[message-dispatcher-provider.yml] & group[DEFAULT_GROUP]
2022-04-02 09:04:07.191 [main] INFO  o.s.c.b.c.PropertySourceBootstrapConfiguration:101 - Located property source: CompositePropertySource name='NACOS', propertySources=[NacosPropertySource name='message-dispatcher-provider-sit.yml,DEFAULT_GROUP', NacosPropertySource name='message-dispatcher-provider.yml,DEFAULT_GROUP', NacosPropertySource name='message-dispatcher-provider,DEFAULT_GROUP', NacosPropertySource name='sharding-db-dev.yml,DEFAULT_GROUP']
2022-04-02 09:04:07.304 [main] INFO  c.c.s.message.start.MessageDispatchApplication:652 - The following profiles are active: sit
2022-04-02 09:04:28.417 [main] INFO  o.s.d.r.config.RepositoryConfigurationDelegate:247 - Multiple Spring Data modules found, entering strict repository configuration mode!
2022-04-02 09:04:28.418 [main] INFO  o.s.d.r.config.RepositoryConfigurationDelegate:127 - Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2022-04-02 09:04:34.251 [main] INFO  o.s.d.r.config.RepositoryConfigurationDelegate:185 - Finished Spring Data repository scanning in 5673ms. Found 3 JPA repository interfaces.
2022-04-02 09:04:37.630 [main] WARN  o.springframework.boot.actuate.endpoint.EndpointId:131 - Endpoint ID 'nacos-config' contains invalid characters, please migrate to a valid format.
2022-04-02 09:07:17.969 [main] ERROR org.springframework.boot.SpringApplication:823 - Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'messageController': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'messagePushServiceImpl': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'rocketmqMessageService' defined in URL [jar:file:/app/message-dispatcher.jar!/BOOT-INF/classes!/com/crazymaker/springcloud/message/service/impl/RocketmqMessageService.class]: Initialization of bean failed; nested exception is java.lang.IllegalStateException: org.apache.rocketmq.remoting.exception.RemotingTimeoutException: wait response on the channel <dh2/192.168.56.122:9876> timeout, 3000(ms)
        at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessProperties(CommonAnnotationBeanPostProcessor.java:325)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1404)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)

然后在部署了filebeat的机器上部署该应用,应用的输出文件为/var/log/service-hi.log,应用启动命令如下:

1 nohup java -jar  elk-test-0.0.1-SNAPSHOT.jar > /var/log/service-hi.log 2>&1  &

应用启动成功后日志输出如下:

1 2019-07-02 17:13:13.530  INFO 31579 --- [pool-1-thread-1] com.example.elktest.ElkTestApplication   : seed:562779
2 2019-07-02 17:13:13.630  INFO 31579 --- [pool-1-thread-1] com.example.elktest.ElkTestApplication   : seed:963836
3 2019-07-02 17:13:13.730  INFO 31579 --- [pool-1-thread-1] com.example.elktest.ElkTestApplication   : seed:825694
4 2019-07-02 17:13:13.830  INFO 31579 --- [pool-1-thread-1] com.example.elktest.ElkTestApplication   : seed:33228
5 2019-07-02 17:13:13.930  INFO 31579 --- [pool-1-thread-1] com.example.elktest.ElkTestApplication   : seed:685589

这时的日志数据的传输路径如下图:

查看日志索引

docker run --name filebeat -d  \\
-v /home/qw/elk/filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml \\
-v /home/qw/elk/testlog/:/home/ \\
 elastic/filebeat:7.2.0

效果

可以看到 在kibana中多了两个索引
需要配置


创建一个

选择

最终展示


到这里简单收集日志就完成了,需要更多复杂业务配置,需要大家根据需求自己配置详细信息.

logstash 详解

Logstash 是一款强大的数据处理工具,它可以实现数据传输,格式处理,格式化输出,

logstash 还有强大的插件功能,常用于日志处理.
logstash我们只让它进行日志处理,处理完之后将其输出到elasticsearch。

官方文档

https://www.elastic.co/guide/en/logstash/7.17/index.html

stash第一个事件

Logstash管道有两个必需元素,输入和输出,以及一个可选元素filter。

输入插件使用来自源的数据,过滤器插件在您指定时修改数据,输出插件将数据写入目标。
如下图

根据官方文档Logstash对数据的处理主要流程是

  1. 首先数据传入logstash,在其内部对数据进行过滤和处理
  2. logstash将处理过的数据传递给Elasticsearch
  3. Elasticsearch对数据进行存储、创建索引等内容
  4. kibana对数据提供可视化的支持

Logstash的核心流程的三个环节

Logstash核心分三个环节:

  • 数据输入
  • 数据处理
  • 数据输出

其数据输入、处理、输出主要在配置中间中下面部分进行配置

input 
filter 
output 

logstash数值类型

  • 数组

match =>[“datetime”, “UNIX”, “ISO8601”]

  • 布尔

必须是一个true或false

ssl_enable => true

  • 字节

一个字段是字节字符串字段表示有效字节的单元。它是一种方便的方式在特定尺寸的插件选项。

支持SI (k M G T P E Z Y)和Binary (TiKimigipiziyiei)单位。

二进制单元在基座单元和Si-1024在基底1000。

这个字段是大小写敏感的。如果未指定单位,则整数表示的字符串的字节数。

my_bytes => "1113" # 1113 bytes 

my_bytes => "10MiB" # 10485760 bytes

 my_bytes => "100kib" # 102400bytes 

my_bytes => "180 mb"# 180000000 bytes
  • 编解码器

codec => “json”

  • 哈希

哈希是一个键值对的集合中指定的格式,多个键值对的条目以空格分隔而不是逗号。

match => “field1” => “value1” “field2” =>“value2” …

  • 数字

数字必须有效的数字值(浮点或整数)。

port => 33

  • 密码

密码是一个字符串的单个值,则不对其进行记录或打印。

my_password => “password”

  • uri

my_uri =>“http://foo:bar@example.net”

  • 路径

一个路径是一个字符串,表示系统运行的有效路径。

my_path =>“/tmp/logstash”

  • 转义序列

默认地,转义字符没有被启用。如果你希望使用转义字符串序列,您需要在你的logstash.yml中设置config.support_escapes: true

TextResult
\\rcarriage return (ASCII 13)
\\nnew line (ASCII 10)
\\ttab (ASCII 9)
\\backslash (ASCII 92)
"double quote (ASCII 34)
single quote (ASCII 39)

logstash 条件判断

有时您只想在特定条件下过滤或输出事件。为此,您可以使用条件。

Logstash中的条件查看和行为与编程语言中的条件相同。条件语句支持if,else if以及else报表和可以被嵌套。

条件语法

if EXPRESSION … else if EXPRESSION … else …

logstash 比较运算符

等于: ==, !=, <, >, <=, >=
  正则: =~, !~ (checks a pattern on the right against a string value on the left)
  包含关系: in, not in

支持的布尔运算符:and, or, nand, xor

支持的一元运算符: !

作用符号
等于==
不等于!=
小于<
大于>
小于等于<=
大于等于>=
匹配正则=~
不匹配正则!~
包含in
不包含not in
and
or
非与nand
非或xor
复合表达式()
取反符合!()

数据输入环节

input配置定义了数据的来源。其主要支持下面方式

事件源可以是从stdin屏幕输入读取,可以从file指定的文件,也可以从es,filebeat,kafka,redis等读取

stdin

监控控制台输入。

要测试Logstash安装成功,运行最基本的Logstash管道。 执行以下的命令

bin/logstash -e 'input  stdin    output  stdout  '

-e 标志使您可以直接从命令行指定配置。

通过在命令行指定配置,可以快速测试配置,而无需在迭代之间编辑文件。

示例中的管道从标准输入stdin获取输入,并以结构化格式将输入移动到标准输出stdout。

启动Logstash后,等到看到“Pipeline main started”,然后在命令提示符下输入hello world,显示的如下:

hello world

     "host" => "VM_0_13_centos",
     "message" => "hello world",
     "@version" => "1",
    "@timestamp" => 2019-07-02T06:26:28.684Z

file

监控文件内容

file
    path => ['/var/log/nginx/access.log']  #要输入的文件路径
    type => 'nginx_access_log'
    start_position => "beginning"


  • path 可以用/var/log/.log,/var/log/**/.log,

  • type 通用选项. 用于激活过滤器

  • start_position 选择logstash开始读取文件的位置,begining或者end。

还有一些常用的例如:discover_interval,exclude,sincedb_path,sincedb_write_interval等可以参考官网

syslogs

从syslogs读取数据

syslog
    port =>"514" 
    type => "syslog"


# port 指定监听端口(同时建立TCP/UDP的514端口的监听)

#从syslogs读取需要实现配置rsyslog:
# cat /etc/rsyslog.conf   加入一行
*.* @172.17.128.200:514   #指定日志输入到这个端口,然后logstash监听这个端口,如果有新日志输入则读取
# service rsyslog restart   #重启日志服务

beats

从Elastic beats接收数据

beats 
    port => 5044   #要监听的端口

# 还有host等选项

# 从beat读取需要先配置beat端,从beat输出到logstash。
# vim /etc/filebeat/filebeat.yml 
..........
output.logstash:
hosts: ["localhost:5044"]

kafka

从kafka topic中读取数据

kafka
    bootstrap_servers=> "kafka01:9092,kafka02:9092,kafka03:9092"
    topics => ["access_log"]
    group_id => "logstash-file"
    codec => "json"

kafka
    bootstrap_servers=> "kafka01:9092,kafka02:9092,kafka03:9092"
    topics => ["weixin_log","user_log"]  
    codec => "json"



# bootstrap_servers 用于建立群集初始连接的Kafka实例的URL列表。
# topics  要订阅的主题列表,kafka topics
# group_id 消费者所属组的标识符,默认为logstash。kafka中一个主题的消息将通过相同的方式分发到Logstash的group_id
# codec 通用选项,用于输入数据的编解码器。

数据处理环节

filter plugin 过滤器插件,主要是对数据进行处理。

grok解析文本并构造

Grok 是一个十分强大的 Logstash Filter 插件,它可以通过正则解析任意文本,将非结构化日志数据格式转换为结构化的、方便查询的结构。

它是目前 Logstash 中解析非结构化日志数据最好的方式。

Grok 的语法规则是:
这里的 “语法” 指的是匹配模式,例如,使用 NUMBER 模式可以匹配出数字,IP 模式则会匹配出 127.0.0.1 这样的 IP 地址。比如按以下格式输入内容:

172.16.213.132 [16/Jun/2020:16:24:19 +0800] "GET / HTTP/1.1" 403 5039

那么,
• %IP:clientip 匹配模式将获得的结果为:clientip: 172.16.213.132
• %HTTPDATE:timestamp 匹配模式将获得的结果为:timestamp: 16/Jun/2020:16:24:19 +0800
• %QS:referrer 匹配模式将获得的结果为:referrer: “GET / HTTP/1.1”
到这里为止,我们已经获取了上面输入中前三个部分的内容,分别是 clientip、timestamp 和 referrer 三个字段。

如果要获取剩余部分的信息,方法类似。

要在线调试 Grok,可以点击在线调试,可点击这里进行在线调试,非常方便。

下面是一个组合匹配模式,它可以获取上面输入的所有内容:

%IP:clientip\\ \\[%HTTPDATE:timestamp\\]\\ %QS:referrer\\ %NUMBER:response\\ %NUMBER:bytes

正则匹配是非常严格的匹配,在这个组合匹配模式中,使用了转义字符 \\,这是因为输入的内容中有空格和中括号。

通过上面这个组合匹配模式,我们将输入的内容分成了 5 个部分,即 5 个字段。

将输入内容分割为不同的数据字段,这对于日后解析和查询日志数据非常有用,这正是我们使用 grok 的目的。

Logstash 默认提供了近 200 个匹配模式(其实就是定义好的正则表达式)让我们来使用,可以在 Logstash 安装目录下找到。

例如,我这里的路径为:

/usr/local/logstash/vendor/bundle/jruby/2.5.0/gems/logstash-patterns-core-4.1.2/patterns

此目录下有定义好的各种匹配模式,基本匹配定义在 grok-patterns 文件中。

从这些定义好的匹配模式中,可以查到上面使用的四个匹配模式对应的定义规则。

除此之外,还有很多默认定义好的匹配模式文件,比如 httpd、java、linux-syslog、redis、mongodb、nagios 等,这些已经定义好的匹配模式,可以直接在 Grok 过滤器中进行引用。

当然也可以定义自己需要的匹配模式。

在了解完 Grok 的匹配规则之后,下面通过一个配置实例深入介绍下 Logstash 是如何将非结构化日志数据转换成结构化数据的。

首先看下面的一个事件配置文件:

input
  stdin

filter
   grok
     match => ["message", "%IP:clientip\\ \\[%HTTPDATE:timestamp\\]\\ %QS:referrer\\ %         NUMBER:response\\ %NUMBER:bytes"]
   

output
   stdout
     codec => "rubydebug"
   

在这个配置文件中,输入配置成了 stdin,在 filter 中添加了 grok 过滤插件,并通过 match 来执行正则表达式解析,

grok 中括号中的正则表达式就是上面提到的组合匹配模式,然后通过 rubydebug 编码格式输出信息。

这样的组合有助于调试和分析输出结果。

通过此配置启动 Logstash 进程后,我们仍然输入之前给出的那段内容:

172.16.213.132 [16/Jun/2020:16:24:19 +0800] "GET / HTTP/1.1" 403 5039

然后,查看 rubydebug 格式的日志输出,内容如下:


     "timestamp" => "16/Jun/2020:16:24:19 +0800",
      "response" => "403",
         "bytes" => "5039",
      "@version" => "1",
      "clientip" => "172.16.213.132",
          "host" => "nnmaster.cloud",
      "referrer" => "\\"GET / HTTP/1.1\\"",
       "message" => "172.16.213.132 [16/Jun/2020:16:24:19 +0800] \\"GET / HTTP/1.1\\" 403 5039",
    "@timestamp" => 2020-06-16T07:46:53.120Z

从这个输出可知,通过 Grok 定义好的 5 个字段都获取到了内容,并正常输出了。

date日期解析

解析字段中的日期,然后转存到@timestamp

[2018-07-04 17:43:35,503]

grok
      match => "message"=>"%DATA:raw_datetime"

date
      match => ["raw_datetime","YYYY-MM-dd HH:mm:ss,SSS"]
      remove_field =>["raw_datetime"]

#将raw_datetime存到@timestamp 然后删除raw_datetime



#24/Jul/2018:18:15:05 +0800
date 
      match => ["timestamp","dd/MMM/YYYY:HH:mm:ss Z]




mutate字段转换

mutate字段转换, 对字段做处理 重命名、删除、替换和修改字段。

Mutate过滤器的配置选项

选项类型是否必须简述
convert

以上是关于ELK日志平台(elasticsearch +logstash+kibana)原理和实操(史上最全)的主要内容,如果未能解决你的问题,请参考以下文章

Docker安装部署ELK教程 (Elasticsearch+Kibana+Logstash+Filebeat)

elasticsearch重复采集问题

log4net直切ElasticSearch,小步快跑首选

elk启动(elasticsearchlogstashkibana)

elasticsearch索引按日期拆分和定期删除

ELK-整体架构-简介

(c)2006-2024 SYSTEM All Rights Reserved IT常识