【Go】基于telegraf进行自定义插件开发(二)

2023-05-16

基于telegraf进行自定义插件开发(二)

  • 前言
  • 正文
    • 设计
    • 开发过程
      • 单个服务的处理
      • 结构体同时定义了string和数值类型
      • 适配本机服务或者多个ip来源
    • 程序打包
  • 结语

前言

书接上会,这次记录一下我基于telegraf进行的hdfs监控组件的开发工作,这其中也包括了开发完成后如何进行打包等事项。

我的应用场景是,依赖于telegraf去监控大数据组件,所以第一个开发的就是hdfs的采集插件。

正文

设计

开始写代码前,大概规划一下整体的目录,我的想法是,除去README.mdsample.conf文件以外,将Namenode、JournalNode、DataNode组件的个性指标获取方法分开存放,然后把指标的清单放在单独的文件中:
在这里插入图片描述
metrics.go中定义了全部的指标:
在这里插入图片描述

接下来是input的配置块部分,原先我考虑把组件拆分开来,后来觉得那样要整好几个目录,太麻烦,而且从设计的概念上来说,我希望在所有有服务的节点上都部署telegraf,所以每一个telegraf只需要负责自己本机的服务的指标采集,最终定义这样的HDFS结构体:

type HDFS struct {
	Scheme          string          `toml:"scheme"`
	ResponseTimeout config.Duration `toml:"response_timeout"`
	NameNode        *NameNode       `toml:"namenode"`
	JournalNode     *JournalNode    `toml:"journalnode"`
	DataNode        *DataNode       `toml:"datanode"`
	// tls option
	tls.ClientConfig

	// http client
	client *http.Client
	Log    telegraf.Logger
}

type NameNode struct {
	Servers  []string `toml:"servers"`
	HttpPort int      `toml:"http_port"`
	RpcPort  int      `toml:"rpc_port"`
}

三种角色的结构体和NameNode一致,只需要提供服务器清单、http端口和rpc端口即可。

开发过程

单个服务的处理

以Namenode指标数据的获取为例,其实就是通过jmx获取json数据,然后进行解析,以RPC指标为例,结构体细节如下:

type RpcMetrics struct {
	ReceivedBytes              float32 `json:"ReceivedBytes"`
	SentBytes                  float32 `json:"SentBytes"`
	RpcQueueTimeNumOps         float32 `json:"RpcQueueTimeNumOps"`
	RpcQueueTimeAvgTime        float32 `json:"RpcQueueTimeAvgTime"`
	RpcProcessingTimeNumOps    float32 `json:"RpcProcessingTimeNumOps"`
	RpcProcessingTimeAvgTime   float32 `json:"RpcProcessingTimeAvgTime"`
	RpcAuthenticationFailures  float32 `json:"RpcAuthenticationFailures"`
	RpcAuthenticationSuccesses float32 `json:"RpcAuthenticationSuccesses"`
	RpcAuthorizationFailures   float32 `json:"RpcAuthorizationFailures"`
	RpcAuthorizationSuccesses  float32 `json:"RpcAuthorizationSuccesses"`
	NumActiveRpcHandler        float32 `json:"NumActiveRpcHandler"`
	RpcClientBackoff           float32 `json:"RpcClientBackoff"`
	RpcSlowCalls               float32 `json:"RpcSlowCalls"`
	NumOpenConnections         float32 `json:"NumOpenConnections"`
	CallQueueLength            float32 `json:"CallQueueLength"`
	NumDroppedConnections      float32 `json:"NumDroppedConnections"`
}

每一块的指标数据都用单独的方法进行处理,这样方便进行代码的划分,处理rpc指标的方法在这里就是gatherRpcMetrics

func (h *HDFS) gatherRpcMetrics(data map[string]interface{}, role string, acc telegraf.Accumulator, tags map[string]string, rpcMetrics *RpcMetrics) error {
	if err := bindToStruct(rpcMetrics, data); err != nil {
		return err
	}
	rpcFields, err := convertor.StructToMap(*rpcMetrics)
	if err != nil {
		return err
	}
	acc.AddGauge(fmt.Sprintf("hdfs_%s_rpc", role), rpcFields, tags)
	return nil
}

传入的data数据就是指标数据,是个map,role变量是为了方法能够复用,hdfs的journanodedatanodenamenode都有rpc指标,在进行获取的时候打上role,acc和tags不用多说,是为了生成指标用的,rpcMetrics就是我们生成的一个空的结构体,rpc的指标比较特殊,全都是浮点型,所以可以借助lancet库的StructToMap方法直接把指标结构转成map,这样就省去了写field结构体的功夫了;

最后通过AddGauge方法把直接增加上,就完成了一个指标的获取、处理、注册了。

结构体同时定义了string和数值类型

在进行指标获取的过程中,遇到了一个问题,那就是指标结构体中既有string类型又有float32类型,因为我在把结构体转成map的时候,统一使用的StructToMap这个方法,虽然这个方法能够自动的也把string转化,但是这在telegraf的指标注册是会有问题,如下:

	threadingField := map[string]interface{}{
		"CurrentThreadCpuTime":    "123123",
		"CurrentThreadUserTime":   1
	}
	acc.AddGauge(fmt.Sprintf("hdfs_test_threading", role), threadingField, tags)

上面的这个指标,注册后会产生一个hdfs_test_threading{"CurrentThreadCpuTime"="123123"} 1的指标,字符串数据会被自动打成label,有这种特征的指标在进行结构体设计的时候要这样做:

	FSNamesystem struct {
		IsActive        float32 `json:"IsActive"`
		FSNamesystemMsg `json:",inline"`
	}
	FSNamesystemMsg struct {
		ExpiredHeartbeats                            float32 `json:"ExpiredHeartbeats"`
		TransactionsSinceLastCheckpoint              float32 `json:"TransactionsSinceLastCheckpoint"`
		TransactionsSinceLastLogRoll                 float32 `json:"TransactionsSinceLastLogRoll"`
		LastWrittenTransactionId                     float32 `json:"LastWrittenTransactionId"`
		LastCheckpointTime                           float32 `json:"LastCheckpointTime"`
		CapacityTotal                                float32 `json:"CapacityTotal"`
		CapacityTotalGB                              float32 `json:"CapacityTotalGB"`
	}

把数值的指标放在一个结构体中,其他类型的放在上层里,在进行解析的时候就能正常的进行解析了。

适配本机服务或者多个ip来源

一开始在进行设计的时候,考虑到可能会在一个节点上采集多个其他节点的服务指标,所以就允许服务器信息写成list,比如servers = ["host01", "host02"],在进行指标获取时,直接启动协程进行操作:

	if h.NameNode != nil {
		servers := getNodeList(h.NameNode.Servers)
		var wg sync.WaitGroup
		wg.Add(len(servers))
		for _, nn := range servers {
			go func(namenode string) {
				defer wg.Done()
				conf := make(map[string]string)
				var nameservice string
				url := setConfUrl(h.Scheme, namenode, h.NameNode.HttpPort)
				if err := h.getXml(url, conf); err == nil {
					nameservice = conf["dfs.nameservices"]
				}
				tags := map[string]string{"nn": namenode, "nameservice": nameservice}
				if err := h.gatherAllNamenodeMetrics(namenode, acc, tags); err != nil {
					acc.AddGauge("hdfs_namenode_state", map[string]interface{}{"Healthy": 0}, tags)
					acc.AddError(fmt.Errorf("can not get jmx data from namenode %s", namenode))
				}
			}(nn)
		}
		wg.Wait()
	}

程序打包

telegraf提供了makefile文件进行打包操作,可以直接输入make help查看具体的使用方式,注意,打包文件中使用fpm命令作为打包工具,因此需要自己安装ruby语言环境和fpm工具,我的建议是安装尽量高版本的ruby,否则可能出现各种问题,原先我安装的2.3版本在执行fpm的时候就有问题,可以选择我用的2.6.5p114版本:

[root@bigdata-m-002 telegraf]# ruby --version
ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-linux]
[root@bigdata-m-002 telegraf]# fpm -v
1.15.1

这里举个例子,比如我们准备编译成tag.gz包,使用以下命令:

make package include_packages="linux_amd64.tar.gz"

如果想要自定义一部分打包的操作,比如希望打包的tag.gz包中有自己增加的脚本文件,只需要在install部分进行增加:

.PHONY: install
install: $(buildbin)
        @mkdir -pv $(DESTDIR)$(bindir)
        @mkdir -pv $(DESTDIR)$(sysconfdir)
        @mkdir -pv $(DESTDIR)$(localstatedir)
        @if [ $(GOOS) != "windows" ]; then mkdir -pv $(DESTDIR)$(sysconfdir)/logrotate.d; fi
        @if [ $(GOOS) != "windows" ]; then mkdir -pv $(DESTDIR)$(localstatedir)/log/telegraf; fi
        @if [ $(GOOS) != "windows" ]; then mkdir -pv $(DESTDIR)$(sysconfdir)/telegraf/telegraf.d; fi
        @cp -fv $(buildbin) $(DESTDIR)$(bindir)
        @if [ $(GOOS) != "windows" ]; then cp -fv etc/telegraf.conf $(DESTDIR)$(sysconfdir)/telegraf/telegraf.conf$(conf_suffix); fi
        @if [ $(GOOS) != "windows" ]; then cp -fv etc/logrotate.d/telegraf $(DESTDIR)$(sysconfdir)/logrotate.d; fi
        @if [ $(GOOS) = "windows" ]; then cp -fv etc/telegraf_windows.conf $(DESTDIR)/telegraf.conf; fi
        @if [ $(GOOS) = "linux" ]; then scripts/check-dynamic-glibc-versions.sh $(buildbin) $(glibc_version); fi
        @if [ $(GOOS) = "linux" ]; then mkdir -pv $(DESTDIR)$(prefix)/lib/telegraf/scripts; fi
        @if [ $(GOOS) = "linux" ]; then cp -fv scripts/telegraf.service $(DESTDIR)$(prefix)/lib/telegraf/scripts; fi
        @if [ $(GOOS) = "linux" ]; then cp -fv scripts/init.sh $(DESTDIR)$(prefix)/lib/telegraf/scripts; fi
        @if [ $(GOOS) = "linux" ]; then cp -fv scripts/install_telegraf_cs6.sh $(DESTDIR)$(prefix)/install_telegraf_cs6.sh; fi

如上,我添加了最后一个部分,增加了centos6的telegraf安装脚本,方便我的一键部署,接下来直接进行打包即可:
在这里插入图片描述
打包完成后,程序包会放在build/dist/下:
在这里插入图片描述

结语

本文介绍了基于telegraf实现了一个自己的hdfs指标采集器,下一次要面对将node-exporter采集的指标替换成telegraf的改造过程,完成整个平台的采集器all-in-one变革!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Go】基于telegraf进行自定义插件开发(二) 的相关文章

  • C语言实现关系的闭包运算

    问题描述 xff1a 利用矩阵求解有限集上给定关系的自反和对称闭包 输入格式 xff1a 首先输入关系矩阵R的维数 xff0c 回车之后输入矩阵每个元素 xff0c 以空格或回车分开 只能输入0或1 输出格式 xff1a 输出自反闭包关系矩
  • 简单易懂的C语言课程设计图书管理系统

    最近几天一直在做课程设计的作业 xff0c 图书管理系统是其中的第六题 xff0c 和同学交流的时候发现好多人都用了链表去写 xff0c 但是我感觉没必要 xff0c 所以使用的代码比较基础 xff0c 适合初学者借鉴 先看一下题目 xff
  • C语言程序设计——前两道题(判断有效三角形和高精度计算的加减法)

    第1题 1 原题 xff1a 假设平面上有1 N x y 个坐标点 xff0c 编程判断这N x y 个点能组成多少个有效三角形 问题分析 xff1a 本题为一道基本编程题 xff0c 要点就是判断三个点能构成三角形的条件 解决方案 xff
  • C语言程序设计之RLE压缩解压算法

    先介绍一下RLE压缩算法 xff1a 游程编码 xff08 Run Length Encoding RLE xff09 又称行程长度编码或者变动长度编码法 xff0c 在控制理论中对于二值图像而言是一种编码方法 xff0c 对连续的黑 xf
  • 浅析洛谷P4924(一道普及/提高-的题目)的解决方法

    题目描述 xff1a Scarlet最近学会了一个数组魔法 xff0c 她会在n n二维数组上将一个奇数阶方阵按照顺时针或者逆时针旋转90 首先 xff0c Scarlet会把1到n 2的正整数按照从左往右 xff0c 从上至下的顺序填入初
  • 判断图的连通性

    上机系统的判分功能目前还没开放 xff0c 所以以下所给代码仅供参考 xff0c 并不能保证完全正确 xff08 自己分别测试了强连通 xff0c 单向连通 xff0c 弱连通 xff0c 不连通的一个样例 xff0c 都过了 xff09
  • BMP格式详解

    BMP xff08 全称Bitmap xff09 是Windows操作系统中的标准图像文件格式 xff0c 可以分成两类 xff1a 设备相关位图 xff08 DDB xff09 和设备无关位图 xff08 DIB xff09 xff0c
  • 标准数独的求解

    上机题目中有一道题目的要求是通过编程实现数独的求解 xff0c 然后想起了初三去后来所在的高中面试提前录取的时候里面的压轴题便是数独 xff0c 当时做了好长时间也没搞出来 xff0c 我还记得监考老师当时和我说 xff1a 做不出来就别勉
  • 利用定义求解传递闭包的关系矩阵

    题目描述 给定有限集合上二元关系的关系矩阵 xff0c 利用传递闭包的定义式 xff08 不是warshall算法 xff09 求其传递闭包的关系矩阵 源代码 span class token macro property span cla
  • 【Android】解决Expecting member declaration

    问题截图 刚刚安装的android studio安装完成就出现异常错误 原因 新建project的时候 xff0c language项选错了 xff0c 应选java 解决错误的办法 新建一个Project的时候 xff0c Languag
  • 矩阵乘法的实现(一般形式及单个矩阵的n次幂)

    目录 一般矩阵乘法实现矩阵的n次幂的实现 一般矩阵乘法实现 题目描述1 给定m k的布尔矩阵A xff0c 和k n的布尔矩阵B xff0c 求布尔矩阵的乘积AB 源代码1 span class token macro property s
  • 根据给出的关系矩阵,判断该关系所具有的特性

    目录 自反性与反自反性的判断对称性与反对称性的判断传递性的判断 自反性与反自反性的判断 关系R是自反的 xff0c 当且仅当其关系矩阵的主对角线上元素都为1 xff1b 关系R是反自反的 xff0c 当且仅当其关系矩阵的主对角线上元素都为0
  • 输出所有满足条件的关系

    目录 for循环解决简单问题调用库函数解决全排列问题 for循环解决简单问题 题目描述 源代码 span class token macro property span class token directive keyword inclu
  • 按字典序输出给定序列

    上机题目里面有不少挨着的相似的题 xff0c 下面所给的这两道偏简单 xff0c 就介绍一下用python和c实现的代码 题目描述 python实现的代码用到了sorted函数 xff0c 该函数在python3里面有三个参数 xff0c
  • 求给定图中某两点之间某一长度的路径条数

    无向图的一道例题 输出c到d长度为以下长度的路径条数 xff1a 源代码 span class token macro property span class token directive keyword include span spa

随机推荐

  • 洛谷题目CF96B Lucky Numbers的分析

    题目描述 xff1a 佩佳喜欢幸运数字 每个人都知道 xff0c 如果正整数的小数表示不包含除4和7以外的数字 xff0c 那么它们是幸运的 例如 xff0c 数字47 744 xff0c 4是幸运的 xff0c 5 xff0c 17 46
  • VMware Player 虚拟机中音乐播放无声音 问题

    虚拟机中安装的Win7 xff0c 音乐播放无声音 解决办法 xff1a VMware Player 右下角 Sound Card gt connect 即可解决
  • 解决M1芯片 MAC 下 Goland(Intellij系列都适用) 无法 Debug 的问题

    解决M1芯片 MAC 下 Goland xff08 Intellij系列都适用 xff09 无法 Debug 的问题 解决M1芯片 MAC 下 Goland xff08 Intellij系列都适用 xff09 无法 Debug 的问题报错信
  • Java例15.13——使用MVC结构计算三角形面积

    MVC是一种通过模型 视图 控制器构造一个软件或组件的理想办法 在例15 13中首先编一个封装三角形的类 xff0c 然后再编写一个窗口 要求窗口使用3个文本框和1个文本区为三角形对象中的数据提供视图 xff0c 其中3个文本框用来显示和更
  • 网卡远程唤醒功能

    远程唤醒功能配置文档 功能简介 网络唤醒功能可以让用户从一个局域网或者是跨网络环境中远程管理一台或者是多台计算机的开关机状态 下面是在ubuntu桌面版上实现远程唤醒功能的设置步骤 第一步 xff1a 计算机BIOS设置 在计算机开机时按F
  • Python 典藏篇-Microsoft Visual C++ 14.0 is required,官方vc++运行库工具一键式解决!

    Python 典藏篇 Microsoft Visual C 43 43 14 0 is required xff0c 官方vc 43 43 运行库工具一键式解决 xff01 前言 xff1a error Microsoft Visual C
  • LwIP在stm32上的无操作系统移植

    LwIP是一个轻型IP协议 xff0c 有无操作系统的支持都可以运行 这里的移植是无操作系统移植 LwIP虽然是一个轻型的IP协议 xff0c 但是TCP IP基本功能都有 而且占用的资源不多 xff0c 非常适合用于嵌入式系统 移植的平台
  • HTML5初体验——蛮神奇的

    记得去年在一个公司实习的时候 xff0c 听当时的领导说起过HTML5 xff0c 当时就大体了解了一下 知道了是新的下一代HTML的新标准 xff0c 去掉了HTML4中的一些标签 xff0c 扩展了一些标签内容 其他的就没有继续深入的去
  • Serilog初识(一)————分别Console、Web程序简单使用Serilog

    Serilog简介 Serilog是 NET应用程序的诊断日志库 它易于设置 xff0c 具有干净的API xff0c 并可在所有最新的 NET平台上运行 虽然它在最简单的应用程序中也很有用 xff0c 但Serilog对结构化日志记录的支
  • intellij idea 开发中,创建Maven项目中的子模块以及相关错误解决

    现在开发 xff0c 很多企业都用Maven来进行项目构建 xff0c 关于Maven的优点 xff0c 本文在此不再赘述 而平时我们学习或者做练习基本用到的都是 单项目 单模块模式 xff0c 即一个Maven项目仅包含一个模块 xff0
  • Windows server 2012 出现大量无名已断开连接用户解决办法

    打开cmd命令窗口 xff0c 执行 taskkill f im winlogon exe t
  • 关于HDFS Balancer的一些小技巧

    关于HDFS Balancer的一些小技巧 前言正文原因分析Balancer工具做均衡带宽设置限定均衡范围参数调优 结语 前言 使用HDFS的过程中 xff0c 难免会出现数据不均衡的情况 xff0c 直观表现就是有的服务器磁盘使用率高的吓
  • 【安全】Goby使用初探

    Goby使用初探 基础配置语言设置npcap安装 使用记录端口扫描 基础配置 语言设置 这里使用的环境是Windows10 64机器 xff0c 下载的方式不再多说 xff0c 直接官网无脑下载即可 xff0c 解压即用 xff0c 不需要
  • 【LDAP】在Centos7环境搭建LDAP服务端

    在Centos7环境搭建LDAP服务端 前言正文OpenLDAP介绍LDIF文件书写规则OpenLDAP部署安装服务配置ldap修改管理员密码初始化配置直接修改配置文件 不建议 使用ldapmodify 建议 添加模式其他配置修改修改服务端
  • 【HDFS】JN回滚大量edit日志导致Namenode主备切换的故障记录

    JN回滚大量edit日志导致Namenode主备切换的故障记录 前言正文问题排查调度服务状态HDFS服务状态 问题分析NameNode日志JN服务器主机指标JN日志 故障恢复 结语过程复盘思考 前言 集群大了 xff0c 这莫名其妙的问题就
  • 【Linux】关于我删文件力度过大导致IO占用太高的解决思路

    关于我删文件力度过大导致IO占用太高的解决思路 前言正文现象描述问题分析处理过程nice命令限制优先级ionice命令限制改造perl脚本 结语 前言 书接上回 xff0c 前两天刚找到删文件性能比较OK的方式后 xff0c 测试没啥问题就
  • ‘docker0‘ already bound to a zone 问题解决

    1 检查firewall cmd中是否存在docker zone 96 firewall cmd get active zones 96 2 如果 docker 区域可用 xff0c 将接口更改为 docker0 xff08 非持久化 xf
  • 【Go】内存模型中的内存可见性

    前言 使用go必然会使用到协程以及其他的并发操作 xff0c 初期学习的时候 xff0c 经常在启动协程时操作变量出现问题 xff0c 要么就是变量没更新 xff0c 要么就是各种崩溃 xff0c 或者vscode报告警之类的 xff0c
  • 【Go】基于telegraf进行自定义插件开发(一)

    基于telegraf进行插件的自定义 xff08 一 xff09 前言正文环境准备目录结构插件结构示例代码注册插件 结语 前言 以长期使用Prometheus和各种exporter的经验来说 xff0c 大量的exporter会占用物理机的
  • 【Go】基于telegraf进行自定义插件开发(二)

    基于telegraf进行自定义插件开发 xff08 二 xff09 前言正文设计开发过程单个服务的处理结构体同时定义了string和数值类型适配本机服务或者多个ip来源 程序打包 结语 前言 书接上会 xff0c 这次记录一下我基于tele