【Beats】Beats 简介

1. Beats介绍

Beats是 Elastic 公司开发提供的开源数据收集器集合,只需要将其端(Agent)安装到服务器上,通过简单的配置,就可以将指定的数据发送到 Elasticsearch。Elastic 提供了多种类的 Beats 用来收集不同的数据。其列表如下

表 1 Elastic 提供的 Beats 列表
数据类型Beats 名称资源
审计数据Auditbeathttps://www.elastic.co/cn/products/beats/auditbeat
日志文件Filebeathttps://www.elastic.co/cn/products/beats/filebeat
云端数据Functionbeathttps://www.elastic.co/cn/products/beats/functionbeat
运行时间监控Heartbeathttps://www.elastic.co/cn/products/beats/heartbeat
指标Metricbeathttps://www.elastic.co/cn/products/beats/metricbeat
网络数据Packetbeathttps://www.elastic.co/cn/products/beats/packetbeat
Windows 事件日志Winlogbeathttps://www.elastic.co/cn/products/beats/winlogbeat

Beats

图 1 Beats的数据收集体系图(来源于官方文档)

Tips:Elastic 公司基于 Go 开发了一个公共组件——libbeat,该组件提供所有 Beats 使用的基础 API,通过这个 API 可以发送数据到 Elasticsearch、配置输入源(input)参数,实现日志打印等等功能,开发人员可以基于该组件开发符合自己需求的 Beat 数据采集器。

2. 第三方开源 Beats

  得益于 Elastic 公司的开源组件libbeat,开发者们开发了众多的第三方 Beats,用于在特定领域环境下的数据指标收集,该列表包括了许多常用的环境和组件,例如:Kafka、Nginx、Prometheus等等,其详细信息见链接:https://www.elastic.co/guide/en/beats/libbeat/7.0/community-beats.html

3. 开发 Beats

开发语言为 GO,开发基础组件为libbeat,需要用到其它开发组件Python、virtualenv

从整体上来讲,一个 Beat 应该包含以下两部分:

  • 一个数据收集组件,用来收集数据
  • 一个数据推送组件(publisher),用来将收集到的数据推送到指定的输出源(output)

需要注意的是,publisher 已经由libbreat封装好了,开发者仅需要关心,如何定义事件(也就是收集数据),并将该事件信息发送到 publisher去。libbeat提供了一些通用服务,例如:配置管理、日志打印、守护进程(daemonzing)、Windows 服务处理、数据处理等模块。
libbeat功能

图 2 libbeat 模块功能图

事件(event)是一个 类似JSON 的对象,用来承载用于发送到publisher的收集数据,最小的事件信息,应该包括@timestamptype字段,除了这些字段外,还可以包括一些附加字段。下面是一个事件的典型示例:

{
  "@timestamp": "2016-07-13T21:33:58.355Z",
  "beat": {
    "hostname": "mar.local",
    "name": "mar.local"
  },
  "directory": false,
  "filename": "winlogbeat.yml",
  "filesize": 2895,
  "modtime": "2016-07-13T20:56:21.000Z",
  "path": "./vendor/github.com/elastic/beats/winlogbeat/winlogbeat.yml",
  "type": "lsbeat"
}

{
  "@timestamp": "2016-07-13T21:33:58.354Z",
  "beat": {
    "hostname": "mar.local",
    "name": "mar.local"
  },
  "directory": true,
  "filename": "system",
  "filesize": 238,
  "modtime": "2016-07-13T20:56:21.000Z",
  "path": "./vendor/github.com/elastic/beats/winlogbeat/tests/system",
  "type": "lsbeat"
}

3.1. 创建项目

  • 第一步:拉取 beats 代码
mkdir -p ${GOPATH}/src/github.com/elastic
git clone https://github.com/elastic/beats ${GOPATH}/src/github.com/elastic/beats
git checkout 7.0
  • 第二步:建立自己的 beat 项目
mkdir ${GOPATH}/src/github.com/{user}
cd ${GOPATH}/src/github.com/{user}
  • 第三步:生成通用代码
python $GOPATH/src/github.com/elastic/beats/script/generate.py
Beat Name [Examplebeat]: Countbeat
Your Github Name [your-github-name]: {username}
Beat Path [github.com/{github id}/{beat name}]:
Firstname Lastname: {Full Name}
  • 第四步:拉取依赖数据
cd ${GOPATH}/src/github.com/{user}/countbeat
make setup

注意:执行到这一步,我们自定义的 Beat 已经包含了基本的配置文件countbeat.yml和模板文件,从某种层度上来说,这个 beat 已建立成功,可以编译执行了。如果想要完善这个 beat 的功能,则需要添加用户自定义的逻辑,以及一些需要额外添加的配置参数信息。

  • 第五步:编译文件,生成一个二进制可执行文件 countbeat
mage build
  • 第六步:执行
./countbeat -e -d "*"

3.2. Beater接口

每个 beat 都需要实现 libbeat中定义的 Beater 接口

// Beater is the interface that must be implemented by every Beat. A Beater
// provides the main Run-loop and a Stop method to break the Run-loop.
// Instantiation and Configuration is normally provided by a Beat-`Creator`.
//
// Once the beat is fully configured, the Run() method is invoked. The
// Run()-method implements the beat its run-loop. Once the Run()-method returns,
// the beat shuts down.
//
// The Stop() method is invoked the first time (and only the first time) a
// shutdown signal is received. The Stop()-method normally will stop the Run()-loop,
// such that the beat can gracefully shutdown.
type Beater interface {
        // The main event loop. This method should block until signalled to stop by an
        // invocation of the Stop() method.
        Run(b *Beat) error

        // Stop is invoked to signal that the Run method should finish its execution.
        // It will be invoked at most once.
        Stop()
}
  • 定义一个 Beat 对象,实现两个方法Run()Stop()
type Countbeat struct {
        done   chan struct{} 
        config config.Config 
        client publisher.Client 

        ...
}

func (bt *Countbeat) Run(b *beat.Beat) error {
        ...
}


func (bt *Countbeat) Stop() {
        ...
}

注意: 默认情况下,一个 Beat 对象需要包含以下信息:

  • done:Channel used by the Run() method to stop when the Stop() method is called.
  • config:Configuration options for the Beat
  • client:Publisher that takes care of sending the events to the defined output.

注意:每个 Beat 需要实现以下方法:

  • New:创建 Beat对象
  • Run:核心代码,用来收集数据,发送数据
  • Stop:停止进程

3.2.1. New 函数

New()函数接收 Beat 的配置参数,创建一个 Beat 对象,New()函数位于 beater/countbeat.go文件中。

func New(b *beat.Beat, cfg *common.Config) (beat.Beater, error) {
        config := config.DefaultConfig
        if err := cfg.Unpack(&config); err != nil {
                return nil, fmt.Errorf("Error reading config file: %v", err)
        }

        bt := &Countbeat{
                done:   make(chan struct{}),
                config: config,
        }
        return bt, nil
}
  • Beat生成器生成的默认代码中,一个最简单的 config 对象位于
    config/config.go
package config

import "time"

type Config struct {
        Period time.Duration `config:"period"`
}

var DefaultConfig = Config{
        Period: 1 * time.Second,
}
  • 配置文件位于countbeat.yml
countbeat:
  # Defines how often an event is sent to the output
  period: 10s
  • 如果想要添加自定义参数,那么需要修改结构体(config/config.go)信息,同时在(_meta/beat.yml)添加对应的参数信息
type Config struct {
    Period time.Duration `config:"period"`
    Path   string        `config:"path"`
}

var DefaultConfig = Config{
    Period: 1 * time.Second,
    Path:   ".",
}
countbeat:
  period: 10s
  path: "."
  • 修改完配置信息后执行make update让这些配置生效

3.2.2. Run方法

  • 主要的处理逻辑
func (bt *Countbeat) Run(b *beat.Beat) error {
        logp.Info("countbeat is running! Hit CTRL-C to stop it.")

        bt.client = b.Publisher.Connect()
        ticker := time.NewTicker(bt.config.Period)
        counter := 1
        for {
                select {
                case <-bt.done:
                        return nil
                case <-ticker.C:
                }
				// 创建一个 event 对象
                event := common.MapStr{ 
                		// 两必备字段,@timestamp 和 type
                        "@timestamp": common.Time(time.Now()), 
                        "type":       b.Name,
                        "counter":    counter,
                }
                // 发送数据
                bt.client.PublishEvent(event) 
                logp.Info("Event sent")
                counter++
        }
}
  • 当给事件(envent)中添加字段信息(除去@timestamp 和 type)时,必须同时更新_meta/fields.yml配置文件信息
- key: countbeat
  title: countbeat
  description:
  fields:
    - name: counter
      type: long
      required: true
      description: >
        PLEASE UPDATE DOCUMENTATION
  • 修改完配置信息后执行make update让这些配置生效

3.2.3. Stop 方法

  • 用来停止服务
func (bt *Countbeat) Stop() {
        bt.client.Close()
        close(bt.done)
}

3.2.4. 主函数

package main

import (
        "os"

        "github.com/elastic/beats/libbeat/beat"
        "github.com/elastic/beats/libbeat/cmd"
        "github.com/elastic/beats/libbeat/cmd/instance"

        "github.com/kimjmin/countbeat/beater"
)

var RootCmd = cmd.GenRootCmdWithSettings(beater.New, instance.Settings{Name: "countbeat"})

func main() {
        if err := RootCmd.Execute(); err != nil {
                os.Exit(1)
        }
}

3.3. 事件命名规约

  • 字段名规约
    1. 所有字段必须是小写字符
    2. 复合单次使用下划线连接
    3. 组参数使用.体现组信息,例如:cpu.load和 cpu.system
    4. 避免在字段名中出现重复的命名空间,例如:使用 cpu.load而不是 cpu.cpu_load
    5. 假如释义不明,选择全称,避免使用简写
    6. 字段排序遵循从通用到特殊的规律
    7. 如果两个字段一样,但是单位不同,那么就移除那个不常用的字段,例如:timeout.sec和 timeout.min
    8. 如果字段名和嵌套命名空间匹配,那么字段名添加.value后缀
    9. 如果是单一字段,那么不要使用.,这代表是一个组参数
      10.注意字段名的单数复数形式

3.4. 标准化命名

参数(推荐)参数(不推荐)
avgaverage
connectionconn
count
daydays, d
maxmaximum
minminimum
pctpercentage
requestreq
secseconds, second, s
msmillisecond, millis
mbmegabytes
msgmessage
nsnanoseconds
normnormalized
usmicroseconds
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值