1、概述

1.1 什么是Elastic (ELK) Stack(ELKB)

“ELK”是三个开源项目的首字母缩写,这三个项目分别是:Elasticsearch、Logstash 和 Kibana。Elasticsearch 是一个搜索和分析引擎。Logstash 是服务器端数据处理管道,能够同时从多个来源采集数据,转换数据,然后将数据发送到诸如 Elasticsearch 等“存储库”中。Kibana 则可以让用户在 Elasticsearch 中使用图形和图表对数据进行可视化。

Elastic Stack 是 ELK Stack 的更新换代产品

1.2 Elastic Stack 的发展历程(名字的由)

1.2.1 一切都起源于 Elasticsearch…

这个开源的分布式搜索引擎基于 JSON 开发而来,具有 RESTful 风格。它使用简单,可缩放规模,十分灵活,因此受到用户的热烈好评,而且如大家所知,围绕这一产品还形成了一家专门致力于搜索的公司。

1.2.2 引入 Logstash 和 Kibana

Elasticsearch 的核心是搜索引擎,所以用户开始将其用于日志搜索,并希望能够轻松地对日志进行采集和可视化。有鉴于此,我们引入了强大的采集管道 Logstash 和灵活的可视化工具 Kibana。

Elastic Stack 包含各种功能(之前统一称为 X-Pack),从企业级安全性和开发人员友好型 API,到 Machine Learning 和图表分析,非常全面;借助这些功能,您能够对所有类型的数据进行大规模采集、分析、搜索和可视化。

1.2.3 向 ELK 中加入了 Beats

无论是在混乱如麻的文本型文档中找到前 N 个结果,还是分析安全事件,再或是自由地对指标进行切片和切块,全球社区一直都在使用 ELK 不断地拓展使用范围。

“我只想对某个文件进行 tail 操作,”用户表示。我们用心倾听。在 2015 年,我们向 ELK Stack 中加入了一系列轻量型的单一功能数据采集器,并把它们叫做 Beats。

1.2.4 Elastic Stack 名字的由来

ELK 这个名称又要变了,的确如此。把它叫做 BELK?BLEK?ELKB?当时的确有过继续沿用首字母缩写的想法。然而,对于扩展速度如此之快的堆栈而言,一直采用首字母缩写的确不是长久之计。

就这样,Elastic Stack 这个名字应运而生了
在这里插入图片描述

和用户一直以来熟知并喜爱的开源产品一模一样,只是集成程度更高了,功能更加强大了,入门也更加容易了,而且可以带来无限可能。

1.3 Elastic Stack的组成部分

  • Elasticsearch:Elasticsearch(以下简称ES) 是一个分布式、RESTful 风格的搜索和数据分析引擎,能够解决不断涌现出的各种用例。 ES是 Elastic Stack 的核心,采用集中式数据存储,可以通过机器学习来发现潜在问题。ES能够执行及合并多种类型的搜索(结构化数据、非结构化数据、地理位置、指标)。支持 PB级数据的秒级检索。
  • Kibana:Kibana 是一个免费且开放的用户界面,能够让您对 Elasticsearch 数据进行可视化,并让您在 Elastic Stack 中进行导航。您可以进行各种操作,从跟踪查询负载,到理解请求如何流经您的整个应用,都能轻松完成
  • Logstash:Logstash 是免费且开放的服务器端数据处理管道,能够从多个来源采集数据,转换数据,然后将数据发送到合适的的“存储库”中。
  • Beats:Beats 是一套免费且开源的轻量级数据采集器,集合了多种单一用途数据采集器。它们从成百上千或成千上万台机器和系统向 Logstash 或 Elasticsearch 发送数据。

2、用途和使用场景

2.1 为什么要使用ELK

  • 严格按照开发标准来说,开发人员是不能登录生产服务器查看日志数据的
  • 一个应用可能分布于多态服务器,难以查找
  • 同一台服务区可能部署多个应用,日志分散难以管理
  • 日志可能很大,单个文件通常能达到GB级别,日志无法准确定位,日志查询不方便且速度慢
  • 通常日志文件以非结构化存储,不支持数据可视化查询。
  • 不支持日志分析(比如慢查询日志分析、分析用户画像等)。

2.2 使用场景

  • 采集业务日志
  • 采集Nginx日志
  • 采集数据库日志,如MySQL
  • 监控集群性能指标
  • 监听网络端口
  • 心跳检测

3、Logstash简介:管道

开源的流数据处理、转换(解析)和发送引擎,可以采集来自不同数据源的数据,并对数据进行处理后输出到多种输出源。Logstash是Elastic Stack的重要组成部分

3.1 工作原理

Logstash的每个处理过程均已插件的形式实现,Logstash的数据处理过程主要包括: Inputs , Filters , Outputs 三部分,如图:

image.png

3.2 数据采集:Inputs

Logstash 能够动态地采集、转换和传输数据,不受格式或复杂度的影响。利用 Grok 从非结构化数据中派生出结构,从 IP 地址解码出地理坐标,匿名化或排除敏感字段,并简化整体处理过程。

数据往往以各种各样的形式,或分散或集中地存在于很多系统中。Logstash 支持[各种输入选择]

(https://www.elastic.co/guide/en/logstash/current/input-plugins.html),可以同时从众多常用来源捕捉事件。能够以连续的流式传输方式,轻松地从您的日志、指标、Web 应用、数据存储以及各种 AWS 服务采集数据。

在这里插入图片描述

此过程(inputs)用于从数据源获取数据,常见的插件如beats、file、kafka、rabbitmq、log4j、redis等。

参考:https://www.elastic.co/guide/en/logstash/current/input-plugins.html

3.3 数据过滤:Filter

数据从源传输到存储库的过程中,Logstash 过滤器能够解析各个事件,识别已命名的字段以构建结构,并将它们转换成通用格式,以便进行更强大的分析和实现商业价值。

Logstash 能够动态地转换和解析数据,不受格式或复杂度的影响:

  • 利用 Grok 从非结构化数据中派生出结构
  • 从 IP 地址破译出地理坐标
  • 将 PII 数据匿名化,完全排除敏感字段
  • 简化整体处理,不受数据源、格式或架构的影响

过滤器是Logstash管道中的数据处理器,input 时会触发事件,触发 filter 对数据进行 transport,即转换解析各种格式的数据,常见的过滤器插件如下:

  • grok :解析和构造任意文本。是Logstash过滤器的基础,广泛用于从非结构化数据中导出结构,当前,Grok是Logstash中将非结构化日志数据解析为结构化和可查询内容的最佳方法。
  • mutate :对事件字段执行常规转换。支持对事件中字段进行重命名,删除,替换和修改。
  • date :把字符串类型的时间字段转换成时间戳类型
  • drop :完全删除事件,例如调试事件。
  • clone :复制事件,可能会添加或删除字段。
  • geoip :添加有关IP地址地理位置的信息。
Groke常见匹配

参考链接:https://github.com/logstash-plugins/logstash-patterns-core/tree/master/patterns

USERNAME [a-zA-Z0-9._-]+
USER %{USERNAME}
EMAILLOCALPART [a-zA-Z0-9!#$%&'*+\-/=?^_`{|}~]{1,64}(?:\.[a-zA-Z0-9!#$%&'*+\-/=?^_`{|}~]{1,62}){0,63}
EMAILADDRESS %{EMAILLOCALPART}@%{HOSTNAME}
INT (?:[+-]?(?:[0-9]+))
BASE10NUM (?<![0-9.+-])(?>[+-]?(?:(?:[0-9]+(?:\.[0-9]+)?)|(?:\.[0-9]+)))
NUMBER (?:%{BASE10NUM})
BASE16NUM (?<![0-9A-Fa-f])(?:[+-]?(?:0x)?(?:[0-9A-Fa-f]+))
BASE16FLOAT \b(?<![0-9A-Fa-f.])(?:[+-]?(?:0x)?(?:(?:[0-9A-Fa-f]+(?:\.[0-9A-Fa-f]*)?)|(?:\.[0-9A-Fa-f]+)))\b

POSINT \b(?:[1-9][0-9]*)\b
NONNEGINT \b(?:[0-9]+)\b
WORD \b\w+\b
NOTSPACE \S+
SPACE \s*
DATA .*?
GREEDYDATA .*
QUOTEDSTRING (?>(?<!\\)(?>"(?>\\.|[^\\"]+)+"|""|(?>'(?>\\.|[^\\']+)+')|''|(?>`(?>\\.|[^\\`]+)+`)|``))
UUID [A-Fa-f0-9]{8}-(?:[A-Fa-f0-9]{4}-){3}[A-Fa-f0-9]{12}
# URN, allowing use of RFC 2141 section 2.3 reserved characters
URN urn:[0-9A-Za-z][0-9A-Za-z-]{0,31}:(?:%[0-9a-fA-F]{2}|[0-9A-Za-z()+,.:=@;$_!*'/?#-])+

# Networking
MAC (?:%{CISCOMAC}|%{WINDOWSMAC}|%{COMMONMAC})
CISCOMAC (?:(?:[A-Fa-f0-9]{4}\.){2}[A-Fa-f0-9]{4})
WINDOWSMAC (?:(?:[A-Fa-f0-9]{2}-){5}[A-Fa-f0-9]{2})
COMMONMAC (?:(?:[A-Fa-f0-9]{2}:){5}[A-Fa-f0-9]{2})
IPV6 ((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?
IPV4 (?<![0-9])(?:(?:[0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])[.](?:[0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])[.](?:[0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])[.](?:[0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5]))(?![0-9])
IP (?:%{IPV6}|%{IPV4})
HOSTNAME \b(?:[0-9A-Za-z][0-9A-Za-z-]{0,62})(?:\.(?:[0-9A-Za-z][0-9A-Za-z-]{0,62}))*(\.?|\b)
IPORHOST (?:%{IP}|%{HOSTNAME})
HOSTPORT %{IPORHOST}:%{POSINT}

# paths (only absolute paths are matched)
PATH (?:%{UNIXPATH}|%{WINPATH})
UNIXPATH (/[[[:alnum:]]_%!$@:.,+~-]*)+
TTY (?:/dev/(pts|tty([pq])?)(\w+)?/?(?:[0-9]+))
WINPATH (?>[A-Za-z]+:|\\)(?:\\[^\\?*]*)+
URIPROTO [A-Za-z]([A-Za-z0-9+\-.]+)+
URIHOST %{IPORHOST}(?::%{POSINT})?
# uripath comes loosely from RFC1738, but mostly from what Firefox doesn't turn into %XX
URIPATH (?:/[A-Za-z0-9$.+!*'(){},~:;=@#%&_\-]*)+
URIQUERY [A-Za-z0-9$.+!*'|(){},~@#%&/=:;_?\-\[\]<>]*
# deprecated (kept due compatibility):
URIPARAM \?%{URIQUERY}
URIPATHPARAM %{URIPATH}(?:\?%{URIQUERY})?
URI %{URIPROTO}://(?:%{USER}(?::[^@]*)?@)?(?:%{URIHOST})?(?:%{URIPATH}(?:\?%{URIQUERY})?)?

# Months: January, Feb, 3, 03, 12, December
MONTH \b(?:[Jj]an(?:uary|uar)?|[Ff]eb(?:ruary|ruar)?|[Mm](?:a|ä)?r(?:ch|z)?|[Aa]pr(?:il)?|[Mm]a(?:y|i)?|[Jj]un(?:e|i)?|[Jj]ul(?:y|i)?|[Aa]ug(?:ust)?|[Ss]ep(?:tember)?|[Oo](?:c|k)?t(?:ober)?|[Nn]ov(?:ember)?|[Dd]e(?:c|z)(?:ember)?)\b
MONTHNUM (?:0?[1-9]|1[0-2])
MONTHNUM2 (?:0[1-9]|1[0-2])
MONTHDAY (?:(?:0[1-9])|(?:[12][0-9])|(?:3[01])|[1-9])

# Days: Monday, Tue, Thu, etc...
DAY (?:Mon(?:day)?|Tue(?:sday)?|Wed(?:nesday)?|Thu(?:rsday)?|Fri(?:day)?|Sat(?:urday)?|Sun(?:day)?)

# Years?
YEAR (?>\d\d){1,2}
HOUR (?:2[0123]|[01]?[0-9])
MINUTE (?:[0-5][0-9])
# '60' is a leap second in most time standards and thus is valid.
SECOND (?:(?:[0-5]?[0-9]|60)(?:[:.,][0-9]+)?)
TIME (?!<[0-9])%{HOUR}:%{MINUTE}(?::%{SECOND})(?![0-9])
# datestamp is YYYY/MM/DD-HH:MM:SS.UUUU (or something like it)
DATE_US %{MONTHNUM}[/-]%{MONTHDAY}[/-]%{YEAR}
DATE_EU %{MONTHDAY}[./-]%{MONTHNUM}[./-]%{YEAR}
ISO8601_TIMEZONE (?:Z|[+-]%{HOUR}(?::?%{MINUTE}))
ISO8601_SECOND %{SECOND}
TIMESTAMP_ISO8601 %{YEAR}-%{MONTHNUM}-%{MONTHDAY}[T ]%{HOUR}:?%{MINUTE}(?::?%{SECOND})?%{ISO8601_TIMEZONE}?
DATE %{DATE_US}|%{DATE_EU}
DATESTAMP %{DATE}[- ]%{TIME}
TZ (?:[APMCE][SD]T|UTC)
DATESTAMP_RFC822 %{DAY} %{MONTH} %{MONTHDAY} %{YEAR} %{TIME} %{TZ}
DATESTAMP_RFC2822 %{DAY}, %{MONTHDAY} %{MONTH} %{YEAR} %{TIME} %{ISO8601_TIMEZONE}
DATESTAMP_OTHER %{DAY} %{MONTH} %{MONTHDAY} %{TIME} %{TZ} %{YEAR}
DATESTAMP_EVENTLOG %{YEAR}%{MONTHNUM2}%{MONTHDAY}%{HOUR}%{MINUTE}%{SECOND}

# Syslog Dates: Month Day HH:MM:SS
SYSLOGTIMESTAMP %{MONTH} +%{MONTHDAY} %{TIME}
PROG [\x21-\x5a\x5c\x5e-\x7e]+
SYSLOGPROG %{PROG:[process][name]}(?:\[%{POSINT:[process][pid]:int}\])?
SYSLOGHOST %{IPORHOST}
SYSLOGFACILITY <%{NONNEGINT:[log][syslog][facility][code]:int}.%{NONNEGINT:[log][syslog][priority]:int}>
HTTPDATE %{MONTHDAY}/%{MONTH}/%{YEAR}:%{TIME} %{INT}

# Shortcuts
QS %{QUOTEDSTRING}

# Log formats
SYSLOGBASE %{SYSLOGTIMESTAMP:timestamp} (?:%{SYSLOGFACILITY} )?%{SYSLOGHOST:[host][hostname]} %{SYSLOGPROG}:

# Log Levels
LOGLEVEL ([Aa]lert|ALERT|[Tt]race|TRACE|[Dd]ebug|DEBUG|[Nn]otice|NOTICE|[Ii]nfo?(?:rmation)?|INFO?(?:RMATION)?|[Ww]arn?(?:ing)?|WARN?(?:ING)?|[Ee]rr?(?:or)?|ERR?(?:OR)?|[Cc]rit?(?:ical)?|CRIT?(?:ICAL)?|[Ff]atal|FATAL|[Ss]evere|SEVERE|EMERG(?:ENCY)?|[Ee]merg(?:ency)?)

3.4 数据存储:output

Elasticsearch 是官方首选输出方式,但并非唯一选择。Logstash 提供多种输出选择,目前官方支持200 多个插件。
在这里插入图片描述

output 用于数据输出,常见的插件如

  • elasticsearch:最高效、方便、易于查询的存储器,最有选择,官方推荐!
  • file:将输出数据以文件的形式写入磁盘。stupid
  • graphite:将事件数据发送到graphite,graphite是一种流行的开源工具,用于存储和绘制指标。http://graphite.readthedocs.io/en/latest/
  • statsd:将事件数据发送到statsd,该服务“通过UDP侦听统计信息(如计数器和计时器),并将聚合发送到一个或多个可插拔后端服务”。

3.5 服务的安装与启动

官方文档**:**https://www.elastic.co/guide/en/logstash/current/index.html

下载地址:https://www.elastic.co/cn/downloads/past-releases#logstash(选择需要的版本即可,环境中为6.4.2)

服务安装:安装与启动过程与 ES 一致,直接解压即可。

4、Beats简介:轻量级日志采集器

Beats 是一套免费且开源的轻量级数据采集器,集合了多种单一用途数据采集器。它们从成百上千或成千上万台机器和系统向 Logstash 或 Elasticsearch 发送数据。

4.1 Logstash功能如此强大,为什么还要用Beats

就功能而言,Beats是弟弟,得益于Java生态优势,Logstash功能明显更加强大。但是Logstash在数据收集上的性能表现饱受诟病,Beats的诞生,其目的就是为了取代Logstash Inputs

4.2 Beats的基本特性

  • 开源:Beats 是一个免费且开放的平台,集合了多种单一用途数据采集器,各司其职,功能分离。社区中维护了上百个beat,社区地址:戳我
  • 轻量级:体积小,职责单一、基于go语言开发,具有先天性能优势,不依赖于Java环境,开发包比较小所以跑起来对服务器资源占用极小。Beats 可以采集符合 Elastic Common Schema (ECS) 要求的数据,可以将数据转发至 Logstash 进行转换和解析。
  • 可插拔:Filebeat 和 Metricbeat 中包含的一些模块能够简化从关键数据源(例如云平台、容器和系统,以及网络技术)采集、解析和可视化信息的过程。只需运行一行命令,即可开始探索。
  • 高性能:对CPU、内存和IO的资源占用极小。
  • 可扩展:由于Beats开源的特性,如果现有Beats不能满足开发需要,我们可以自行构建,并且完善Beats社区

4.3 组件

image.png

  • Filebeat:文件日志监控采集 ,主要用于收集日志数据
  • Metricbeat:进行服务器硬件的指标采集,指标可以是系统的,也可以是众多中间件产品的,主要用于监控系统和软件的性能
  • Packetbeat: 是一个实时网络数据包分析器,通过网络抓包、协议分析,基于协议和端口对一些系统通信进行监控和数据收集。可以将其与Elasticsearch一起使用,以提供应用程序监视和性能分析系统。
  • Heartbeat:心跳检测 (在配置的Url中喊一句:喂,有活着的么?有的话吱个声!)
  • Winlogbeat:Windows事件日志
  • Auditbeat:审计数据(收集审计日志)
  • Functionbeat:云服务生成的日志和指标收集器

5、Kibana简介:可视化和数据分析

Kibana 是一个免费且开放的可视化系统,能够让您对 Elasticsearch 数据进行可视化,并让您在 Elastic Stack 中进行导航。您可以进行各种操作,从跟踪查询负载,到理解请求如何流经您的整个应用,都能轻松完成。

一张图片,胜过千万行日志

6、基于ELK搭建日志采集系统

6.1 日志采集基本流程

image.png

6.2 Logstash服务

6.2.1 Stdin(标准化输入)和Stdout(标准化输出)

启动配置标准化输入/输出

./bin/logstash -e 'input{stdin{}} output{stdout{}}'

指定配置文件

bin/logstash -f apilog.conf

6.2.2 Filter

https://www.elastic.co/guide/en/logstash/7.13/plugins-filters-grok.html

6.2.3 调试输出

head -n 3 /var/log/elk/elasticsearch.log|./bin/logstash -f config/apilog.conf 

6.2 部署Filebeat

文件日志监控采集 ,主要用于收集日志数据

6.2.1 下载和安装

地址:https://www.elastic.co/cn/downloads/past-releases/filebeat-6-4-2

6.2.1 工作原理

当启动 Filebeat 时,它会启动一个或多个inputs,这些输入会在日志数据指定的位置中查找。对于 Filebeat 定位的每个日志,Filebeat 都会启动一个harvester。每个harvester 读取单个日志以获取新内容并将新日志数据发送到libbeat,libbeat 聚合事件并将聚合数据发送到配置的输出地址。【sppoler:缓冲区队列,存入写入事件】

image.png

6.2.2 配置

inputs 配置

启动filebeat

6.3 Filebeat+Logstash+Elasticsearch

6.3.1 ELK基本基本组件

image.png

6.3.2 目标架构

image.png

6.4 ES日志自动清除

下面是一个示例 shell 脚本,可以用于删除 Elasticsearch 中某个索引中前一个月产生的数据:

#!/bin/bash

# 定义 Elasticsearch 的地址和索引名称
ES_HOST="192.168.1.1"
INDEX_NAME="test

# 计算一个月前的时间戳
ONE_MONTH_AGO=$(date -d "1 month ago" +%s)
# 时间转换
iso8601_time=$(date -u -d "${ONE_MONTH_AGO}" +"%Y-%m-%dT%H:%M:%SZ")
# 构建 Elasticsearch 删除请求
REQUEST_BODY='{"query": {"range": {"timestamp_field": {"lte": '$iso8601_time'}}}}'

# 发送 Elasticsearch 删除请求
curl -XDELETE "$ES_HOST/$INDEX_NAME/_doc/_delete_by_query" -H 'Content-Type: application/json' -d "$REQUEST_BODY"
在这个脚本中,首先定义 Elasticsearch 的地址和要删除的索引名称。然后使用 date 命令计算一个月前的时间戳。接下来,构建一个 Elasticsearch 删除请求的请求体,其中使用了一个 Range 查询来匹配时间戳字段小于等于一个月前的文档。最后,使用 curl 命令发送 Elasticsearch 删除请求,删除匹配的文档。

请注意,这个脚本中的时间戳格式取决于你在 Elasticsearch 中使用的时间戳字段的格式。如果你的时间戳字段不是 Unix 时间戳格式,请修改脚本中的时间戳计算方式和查询语句以适应你的情况。
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐