查看telegraf关于diskio输出的文档
https://github.com/influxdata/telegraf/tree/master/plugins/inputs/diskio
## Device metadata tags to add on systems supporting it (Linux only)## Use 'udevadm info -q property -n <device>' to get a list of properties.## Note: Most, but not all, udev properties can be accessed this way. Properties## that are currently inaccessible include DEVTYPE, DEVNAME, and DEVPATH.# device_tags = ["ID_FS_TYPE", "ID_FS_USAGE"]
telegraf 在linux 添加设备元数据标签
使用 “udevadm info -q property -n
-q property: 指定输出信息的类型为设备属性
-n
输出示例
DEVLINKS=/dev/disk/by-id/ata-WDC_WD10EZEX-00RQHB0_WD-WCC4K0E89672-part1 /dev/disk/by-id/wwn-0x50014ee20b1b5c42-part1 /dev/disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0-part1 /dev/disk/by-uuid/12345678-9abc-def0-1234-56789abcdef0
DEVNAME=/dev/sda1
DEVPATH=/devices/pci0000:00/0000:00:1f.2/ata1/host0/target0:0:0/0:0:0:0/block/sda/sda1
DEVTYPE=partition
ID_BUS=ata
ID_FS_TYPE=ext4
ID_FS_UUID=12345678-9abc-def0-1234-56789abcdef0
ID_FS_UUID_ENC=12345678-9abc-def0-1234-56789abcdef0
ID_FS_VERSION=1.0
ID_MODEL=WDC_WD10EZEX-00RQHB0
ID_MODEL_ENC=WDC_WD10EZEX-00RQHB0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
ID_PART_ENTRY_DISK=8:0
ID_PART_ENTRY_NUMBER=1
ID_PART_ENTRY_SCHEME=dos
ID_PART_ENTRY_SIZE=209715200
ID_PART_ENTRY_START=2048
ID_PART_ENTRY_TYPE=0x83
ID_PART_TABLE_TYPE=dos
ID_PATH=pci-0000:00:1f.2-scsi-0:0:0:0
ID_PATH_TAG=pci-0000_00_1f_2-scsi-0_0_0_0
ID_SERIAL=WD-WCC4K0E89672
ID_SERIAL_SHORT=WD-WCC4K0E89672
ID_TYPE=disk
ID_WWN=0x50014ee20b1b5c42
ID_WWN_WITH_EXTENSION=0x50014ee20b1b5c42
MAJOR=8
MINOR=1
SUBSYSTEM=block
USEC_INITIALIZED=1234567890说明
DEVLINKS: 设备的符号链接。
DEVNAME: 设备节点名称。
DEVPATH: 设备在设备树中的路径。
DEVTYPE: 设备类型,例如 partition。
ID_BUS: 设备的总线类型,例如 ata。
ID_FS_TYPE: 文件系统类型,例如 ext4。
ID_FS_UUID: 文件系统的UUID。
ID_MODEL: 设备的型号。
ID_PART_ENTRY_DISK: 分区所在的磁盘设备。
ID_PART_ENTRY_NUMBER: 分区编号。
ID_PART_ENTRY_SCHEME: 分区表类型,例如 dos。
ID_PART_ENTRY_SIZE: 分区大小(以512字节为单位)。
ID_PART_ENTRY_START: 分区起始扇区。
ID_PART_ENTRY_TYPE: 分区类型,例如 0x83 表示Linux分区。
ID_PATH: 设备的路径。
ID_SERIAL: 设备的序列号。
ID_TYPE: 设备类型,例如 disk。
MAJOR: 主设备号。
MINOR: 次设备号。
SUBSYSTEM: 设备所属的子系统,例如 block。
USEC_INITIALIZED: 设备初始化时间(以微秒为单位)
目前需要用到设备的序列号,所以在配置文件[[inputs.diskio]] 部分增加
[[inputs.diskio]]
device_tags = ["ID_SERIAL"]
然后在虚拟机里面使用telegraf测试命令,可以看到disk_io的监控信息里面增加名为"ID_SERIAL"的tag。
telegraf --config /etc/telegraf/telegraf.conf --test
到此disk_io相关的监控指标值上都有了名为"ID_SERIAL"的tag。
但是希望disk相关的监控值,也加上名为"ID_SERIAL"的tag,
但是查看https://github.com/influxdata/telegraf/tree/master/plugins/inputs/disk里面,并没有相关配置可以进行配置。
只能从protheutheus监控指标加tag的方向入手,找到了Prometheus 两个label相关的函数。
简单了解了一下这两个函数的用法。
label_replace()
允许基于正则表达式匹配、修改和创建指标的标签。
label_replace(<vector selector>, "<dst_label>", "<replacement>", "<src_label>","<regex>"
)
"
"<dst_label>": 目标标签的名称,新的标签将创建或者更新这个标签。
"
"<src_label>": 源标签的名称,将从这个标签中读取数据。
"
工作原理:
- label_replace() 函数会遍历
选择的所有指标 - 对于每个指标,它会尝试用
匹配 <src_label> 的值。 - 如果匹配成功,则会根据
创建或更新 <dst_label> 的值。在 中,可以使用 $1, $2, … 来引用正则表达式捕获的分组 - 如果匹配失败,则不进行任何操作,<dst_label> 的值保持不变(如果存在)或者不创建(如果不存在)
使用示例:
prometheus_http_requests_total{code="200", container="prometheus", endpoint="web", handler="/api/v1/labels", job="prometheus-k8s", namespace="kube-system", pod="prometheus-k8s-0", service="prometheus-k8s"}
增加tag值
eg:
- 从 handler中提取 API 版本并放入 api_version 标签
label_replace(prometheus_http_requests_total, "api_version", "$1", "handler", "/api/(v[0-9]+)/.*")
结果
prometheus_http_requests_total - 将handler中提取最后一部分放入 api_version标签
label_replace(prometheus_http_requests_total, "api_version", "\(1", "handler", "/[^/]+/([^/]+)\)") - 将handler的所有值放入 api_version 标签
label_replace(prometheus_http_requests_total, "api_version", "$1", "handler", "(.+)")
(.+) 表示匹配任何非空字符序列,并将其捕获为第一个组
prometheus_http_requests_total - 将endpoint的值赋值给instance
label_replace(prometheus_http_requests_total, "instance", "$1", "endpoint", "(.+)")
结果
prometheus_http_requests_total
label_join()
将多个标签的值连接成一个字符串,并将其设置为新的标签的值。
label_join(
"<dst_label>",
"
"<src_label_1>",
"<src_label_2>",
...
)
"<dst_label>": 目标标签的名称,将创建或更新这个标签。
"
`”“, ““, …: 要连接的源标签的名称。
工作原理:
1.label_join() 函数会遍历
2. 对于每个指标,它会获取所有指定的 <src_label> 的值。
3. 它会将这些值使用
4. 将连接后的字符串设置为 <dst_label> 的值。
eg:
node_bonding_slaves{endpoint="https-metrics",job="node-exporter", master="bond1", namespace="kube-system", pod="node-exporter-p7nkv", service="node-exporter"}
将 job 和 pod 连接到 job_pod 标签:
label_join(node_bonding_slaves, "job_pod", "-", "job", "pod")
node_bonding_slaves{endpoint="https-metrics", job="node-exporter", job_pod="node-exporter-node-exporter-p7nkv", master="bond1", namespace="kube-system", pod="node-exporter-p7nkv", service="node-exporter"}
ps:过度使用 label_replace() 和 label_join() 会影响 Prometheus 的查询性能。 在不需要时避免使用。
发现这两个函数,其实都是将一个指标的tag,用于给自己重新增加新的tag或者修改掉某个tag的值,并不能满足需要。
只能另寻他法,发现可以通过自己造一个disk_io指标的0值,然后再通过与disk相关的指标进行相加运算后使用group_left函数,获取disk的tag。
简单介绍一下,group_left和group_right函数的用法。
主要用于处理向量之间的聚合运算,控制哪些标签会被保留,哪些标签会被丢弃。
默认情况下,只有两个向量中都存在的标签才会保留。 group_left 和 group_right 允许你指定 左侧向量的标签 或 右侧向量的标签,即使它们在另一个向量中不存在,也需要保留。
<聚合操作> ( <向量> ) <group_left|group_right> ( [<标签列表>] ) [<向量>]
<聚合操作> ( <向量> ) [<向量>] <group_left|group_right> ( [<标签列表>] ) <聚合操作>: sum, avg, max, min, count, stddev, stdvar, topk, bottomk, quantile, 等
<向量>: PromQL查询的结果,代表时间序列数据。
group_left: 保留左侧向量的标签 (除了用于聚合的标签)。
group_right: 保留右侧向量的标签 (除了用于聚合的标签)。
[<标签列表>]: (可选) 要保留的标签列表。如果不指定,则保留所有未参与聚合的标签。
sum(rate(http_requests_total[5m])) by (job, instance)
/ on(job, instance)
group_left(service)
kube_pod_info
首先计算每个 job 和 instance 的 HTTP 请求速率,然后使用 on(job, instance) 将其与 kube_pod_info 指标关联。最后,使用 group_left(service) 将结果按照 service 进行分组.
on 关键字用于指定在聚合操作时需要匹配的标签
在prometheusrule里面增加指标- expr: diskio_io_time-diskio_io_timerecord: diskio_0这个是包含diskio_io_time所有tag的一个指标名通过这个指标名称和disk指标相加,在uuid和name相匹配的情况下获取disk的标签,来将ID_Serial的标签加到disk上面disk_used + on (uuid, name) group_left(ID_SERIAL) diskio_0