夜莺-Nightingale
夜莺V7
项目介绍 功能概览
部署升级 部署升级
数据接入 数据接入
告警管理 告警管理
数据查看 数据查看
功能介绍 功能介绍
API FAQ
夜莺V6
项目介绍 架构介绍
快速开始 快速开始
黄埔营
安装部署 安装部署
升级
采集器 采集器
使用手册 使用手册
API API
数据库表结构 数据库表结构
FAQ FAQ
开源生态
Prometheus
版权声明
第1章:天降奇兵 第1章:天降奇兵
第2章:探索PromQL 第2章:探索PromQL
第3章:Prometheus告警处理 第3章:Prometheus告警处理
第4章:Exporter详解 第4章:Exporter详解
第5章:数据与可视化 第5章:数据与可视化
第6章:集群与高可用 第6章:集群与高可用
第7章:Prometheus服务发现 第7章:Prometheus服务发现
第8章:监控Kubernetes 第8章:监控Kubernetes
第9章:Prometheus Operator 第9章:Prometheus Operator
参考资料

snmp插件

snmp

snmp 插件之前秦老师已经整理过很详细的文章了,这里就不再赘述了,直接访问:

translator

v0.3.44及以后的版本支持gosmi, 之前的版本只支持netsnmp作为translator。translator是配置文本类型的oid时做一次snmptranslate,如果配置为数字型的oid时,是不需要做snmptranslate的。

  • oid=".1.3.6.1.2.1.2.2.1.10" # 不调用translator
  • oid="IF-MIB::ifInOctets" # 调用translator

使用gosmi时要注意,path中一定要包含所有依赖的mib文件,不是只放你的私有mib路径就可以了。

translator="gosmi"
path = ["/usr/share/snmp/mibs", "/path/to/your/other/mibs"]

max_repetitions

一次读取的对象数,但是有的设备有限制,超过限制无数据返回。 建议保持默认值 max_repetitions = 10

unconnected_udp_socket

当设置为真时,SNMP 响应将接受来自任何地址响应,而不仅仅是请求的地址的响应。 一般juniper设备采集不到数据时,请设置true

不同的field

配置中支持两种field

  • instances.field
  • instances.table.field

使用snmpget可以获取到值的oid,用instances.field。 用snmpwalk获取数据的oid使用instances.table.field. 使用instances.table.field 要先配置一个instances.table, 哪怕是一个虚拟表,但是不能少。

虚拟表

[[instances.table]]
name = "interface"

intstances.table不设置oid时候,categraf不会去采集这个table. 此时instances.table是一张虚拟表,用于聚合它的instances.table.field,这样它的instances.table.field指标都会带上前缀 interface_

index_as_tag

index_as_tag 只能用在instances.table,当设置为true时,表示会附加oid对应的index作为标签。

IF-MIB::ifInOctets这张表返回数据如下

# $snmpwalk -v 2c -c private 127.0.0.1 IF-MIB::ifInOctets 

IF-MIB::ifInOctets.1 = Counter32: 2929719593
IF-MIB::ifInOctets.2 = Counter32: 4020819726
IF-MIB::ifInOctets.3 = Counter32: 0
IF-MIB::ifInOctets.4 = Counter32: 816099251
IF-MIB::ifInOctets.5 = Counter32: 0
IF-MIB::ifInOctets.7 = Counter32: 184035929
IF-MIB::ifInOctets.9 = Counter32: 182159256
IF-MIB::ifInOctets.11 = Counter32: 161707290
IF-MIB::ifInOctets.13 = Counter32: 184387456
IF-MIB::ifInOctets.15 = Counter32: 184936929
IF-MIB::ifInOctets.17 = Counter32: 185552762
IF-MIB::ifInOctets.19 = Counter32: 182004023
IF-MIB::ifInOctets.21 = Counter32: 184076634
IF-MIB::ifInOctets.23 = Counter32: 184995236
IF-MIB::ifInOctets.25 = Counter32: 181069060
IF-MIB::ifInOctets.27 = Counter32: 162922666
IF-MIB::ifInOctets.29 = Counter32: 162307954

附加index 作为label 与得到的指标如下

[[instances.table]]
name = "interface"
index_as_tag=true # 附加index

[[instances.table.field]]
oid="IF-MIB::ifInOctets"
# oid=".1.3.6.1.2.1.2.2.1.10"
name="ifInOctets"

指标

snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test index=2 4156981106
snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test index=9 182362007
snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test index=19 182206658
snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test index=23 185201785
snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test index=29 162490093
snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test index=21 184282189
snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test index=11 161889686
snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test index=13 184592291
snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test index=27 163104850
snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test index=5 0
snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test index=7 184241127
snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test index=25 181272715
snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test index=4 816997503
snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test index=1 2933872158
snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test index=17 185759529
snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test index=3 0
snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test index=15 185143913

不使用index_as_tag=true 得到的指标

snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test 162791450
snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test 162191982
snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test 182697739
snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test 182542638
snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test 0
snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test 0
snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test 186101019
snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test 184581212
snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test 2940870282
snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test 181609012
snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test 185486731
snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test 163407370
snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test 84568089
snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test 185543869
snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test 818473860
snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test 184622605
snmp_interface_ifInOctets agent_host=127.0.0.1 agent_hostname=test 184932731

指定index的后缀/长度(任选其一 不是非要放到一起用)

注:index=返回的oid-查询oid,例如,查询oid是.1.2.3,返回的oid是.1.2.3.4.5index就是.4.5

  • oid_index_length=10 # 表示取index的前10位
  • oid_index_suffix = “.5” # 表示将index的后缀.5去掉

值转换

当oid对应的值是ip/mac/hex 特殊类型时需要进行转换

[[instances.table.field]]
oid = ".1.3.6.1.4.1.2636.5.1.1.2.1.1.1.11"
name = "peer_addr"
conversion = "ipaddr"
is_tag = true

这样会将.1.3.6.1.4.1.2636.5.1.1.2.1.1.1.11 对应的值 转换为ip 作为label附加到指标上。 conversion支持的类型转换包括

  • conversion=“ipaddr” # 将值转为ip地址
  • conversion=“hwaddr” # 将值转为mac地址
  • conversion=“float(X)” # 将值转为float,并保留X位小数
  • conversion=“float” # 将值转为float, 相当于float(0)
  • conversion=“int” # 将值转为int
  • conversion=“byte” # 将xxGB xx GB xxKiB 转换为float类型,单位byte
  • conversion=“hextoint:X:Y” # 将hex值转为int.
    • hextoint:LittleEndian:uint64 将hex值按照小端序转为无符号64位int
    • hextoint:BigEndian:uint32 将hex值按照大端序转为无符号32位int

relabel

比如index原始值如下, 想把2个字段前3位1.1.4.和1.2.16.去掉,生成新标签peer_addr

# 原始值
index="1.2.16.36.4.255.64.0.1.0.99.0.0.0.0.0.0.0.2"
index="1.1.4.103.140.146.151"
# 目标值
peer_addr="36.4.255.64.0.1.0.99.0.0.0.0.0.0.0.2"
peer_addr="103.140.146.151"

按照如下配置, 即可得到

[[instances.relabel_configs]]
source_labels = [ "index"]
target_label = "peer_addr"
#separator = "/"
regex = "\\d+\\.\\d+\\.\\d+\\.(.*)"
action = "replace"
replacement = "$1"

熟悉prometheus relabel的都知道,上面只是得到了peer_addr,原始的index还在。如果不想要index label那么再配置一条

[[instances.relabel_configs]]
regex = "index"
action = "labeldrop"

两张表关联

两张表关联查询,用到的主要配置secondary_index_tablesecondary_index_usesecondary_outer_join,再辅以oid_index_length oid_index_suffix.

  • secondary_index_table 放在指定的oid下,表示这个oid的index所对应值(并非index本身)会作为令一张表的index引用, 我们称这张表为第一张表
  • secondary_index_use 放在指定的oid下, 表示这个oid的index等于secondary_index_table的index对应的值(并非index) 我们称这张表为第二张表
  • secondary_outer_joinsecondary_index_use类似,如果这里设置为true,第二张表中如果出现了第一张表index的值对应不到的情况,那第二张表的index会展示位Secondary.xxxx

接下来看一个比较综合的case, 假设有两张表需要做关联 , 比如bgp中peer_index对应的oid是.1.3.6.1.4.1.2636.5.1.1.2.1.1.1.14, 另一张receive表对应的oid是.1.3.6.1.4.1.2636.5.1.1.2.6.2.1.7,想对两张表做关联,peer_index表的index中第一位作为 receive表的index的一部分。

先看peer_index的返回

.1.3.6.1.4.1.2636.5.1.1.2.1.1.1.1.14.0.1.128.1.130.176.1.128.1.130.178  = 0
.1.3.6.1.4.1.2636.5.1.1.2.1.1.1.1.14.0.1.128.1.130.176.1.128.1.130.179  = 1
.1.3.6.1.4.1.2636.5.1.1.2.1.1.1.1.14.0.1.128.1.130.176.1.128.1.130.180  = 2
.1.3.6.1.4.1.2636.5.1.1.2.1.1.1.1.14.0.2.38.4.9.128.224.5.47.255.0.0.0.0.0.0.0.1.2.38.4.9.128.224.5.47.255.0.0.0.0.0.2  = 3
.1.3.6.1.4.1.2636.5.1.1.2.1.1.1.1.14.0.2.38.4.9.128.224.5.47.255.0.0.0.0.0.0.0.1.2.38.4.9.128.224.5.47.255.0.0.0.0.0.3  = 4
.1.3.6.1.4.1.2636.5.1.1.2.1.1.1.1.14.0.2.38.4.9.128.224.5.47.255.0.0.0.0.0.0.0.1.2.38.4.9.128.224.5.47.255.0.0.0.0.0.4  = 5

再看receive表的返回

.1.3.6.1.4.1.2636.5.1.1.2.6.2.1.7.0.1.1 = 2071
.1.3.6.1.4.1.2636.5.1.1.2.6.2.1.7.3.2.1 = 0 

两张表的index和返回值对比

.0.1.128.1.130.176.1.128.1.130.178=0
.0.1.128.1.130.176.1.128.1.130.179=1
.0.1.128.1.130.176.1.128.1.130.180=2
.0.2.38.4.9.128.224.5.47.255.0.0.0.0.0.0.0.1.2.38.4.9.128.224.5.47.255.0.0.0.0.0.2=3
.0.2.38.4.9.128.224.5.47.255.0.0.0.0.0.0.0.1.2.38.4.9.128.224.5.47.255.0.0.0.0.0.3=4
.0.2.38.4.9.128.224.5.47.255.0.0.0.0.0.0.0.1.2.38.4.9.128.224.5.47.255.0.0.0.0.0.4=5
...
.0.1.1=2071
.3.2.1=0

这两张表关联查询,那就用peer_index对应的值0/1/2/3/4/5 和rececive表中的index 0.1.1/3.2.1 关联匹配,但是因为他们长度不同(peer_index的值只有一位),所以长度对齐就用到了一个oid_index_length 配置。 比如 oid_index_length=1 表示receive表的index的第一位只要匹配到0/1/2/3/4/5 中任意一位就认为匹配成功。

peer_index的配置如下

[[instances.table.field]]
oid = ".1.3.6.1.4.1.2636.5.1.1.2.1.1.1.14"
name = "peer_index"
is_tag = true
secondary_index_table = true  # 这个表的index对应的值0/1/2/3/4/5要被其他表使用

receive表配置如下

[[instances.table.field]]
oid = ".1.3.6.1.4.1.2636.5.1.1.2.6.2.1.7"
name = "receive_total_prefix"
oid_index_length=1  # 只取index的第一位(因为上面的index得值只有一位)
secondary_index_use = true # 使用上面指定的index

这样最终取到值

snmp_juniper_bgp_prefix_receive_total_prefix{index="0.1.128.1.130.176.1.128.1.130.178",  peer_index="0"} 2071
snmp_juniper_bgp_prefix_receive_total_prefix{index=".0.2.38.4.9.128.224.5.47.255.0.0.0.0.0.0.0.1.2.38.4.9.128.224.5.47.255.0.0.0.0.0.2",  peer_index="3"} 0

oid_index_suffix 用法

oid_index_suffix 用于两张表的index 相差一个固定后缀的场景。配置后,长的index后缀被trim掉,与短的index匹配一致,这样短index对应的字段即可作为长index字段的标签。

[[instances.table.field]]
oid = ".1.3.6.1.4.1.30065.4.1.1.2.1.2"
name = "addr_type"
is_tag = true

[[instances.table.field]]
oid = ".1.3.6.1.4.1.30065.4.1.1.2.1.10"
name = "peer_as"
is_tag = true

[[instances.table.field]]
oid = ".1.3.6.1.4.1.30065.4.1.1.8.1.3"
name = "receive_total_prefix"
oid_index_suffix=".1.1"

[[instances.relabel_configs]]
source_labels = ["peer_as"]
regex = ".+"
action = "keep"

新特性

categraf从v0.3.9版本开始,支持

  • 正则过滤端口号、端口类型等
  • 支持批量设置label

过滤

在table section中设置如下

[[instances.table]]
oid = "IF-MIB::ifTable"
name = "interface"
inherit_tags = ["source"]
filters = ["A:ifIndex:^2$","B:ifDescr:^eno.*", "C:ifOperStatus:1"]
filters_expression = "(A && B) || C"
  • oid 定义了采集的对象 IF-MIB::ifTable
  • name 定义指标名称
  • inherit_tags 定义了要继承的标签,这里继承了source标签 就是把前面的source=xxxx 附加到指标上
  • filters 定义表达式A 是匹配ifIndex == 2, 表达式B是匹配ifDescreno开头的对象,C是匹配ifOperStatus为1的对象,
  • filters_expression 定义了过滤表达式,表示filters中表达式的逻辑关系, 这里是A和B的结果取交集,再和C取并集

假设oid对应的数据如下,

IF-MIB::ifIndex.1 = INTEGER: 1
IF-MIB::ifIndex.2 = INTEGER: 2
IF-MIB::ifIndex.3 = INTEGER: 3
IF-MIB::ifIndex.6 = INTEGER: 6
IF-MIB::ifIndex.7 = INTEGER: 7
IF-MIB::ifIndex.9 = INTEGER: 9
IF-MIB::ifIndex.10 = INTEGER: 10
IF-MIB::ifIndex.1210 = INTEGER: 1210
....
IF-MIB::ifDescr.1 = STRING: lo
IF-MIB::ifDescr.2 = STRING: eno1
IF-MIB::ifDescr.3 = STRING: eno2
IF-MIB::ifDescr.6 = STRING: virbr0
IF-MIB::ifDescr.7 = STRING: tun0
IF-MIB::ifDescr.9 = STRING: macvtap1
IF-MIB::ifDescr.10 = STRING: docker0
IF-MIB::ifDescr.1210 = STRING: tun1
....
IF-MIB::ifOperStatus.1 = INTEGER: up(1)
IF-MIB::ifOperStatus.2 = INTEGER: up(1)
IF-MIB::ifOperStatus.3 = INTEGER: down(2)
IF-MIB::ifOperStatus.6 = INTEGER: down(2)
IF-MIB::ifOperStatus.7 = INTEGER: up(1)
IF-MIB::ifOperStatus.9 = INTEGER: down(2)
IF-MIB::ifOperStatus.10 = INTEGER: down(2)
IF-MIB::ifOperStatus.1210 = INTEGER: up(1)
  • A 匹配到的是ifIndex为2的对象
  • B 是匹配eno开头的对象, 也就是ifIndex 为2 或者3
  • A&&B 最终匹配的是 eno1 这块网卡
  • C 匹配的是所有UP的对象 ,对应的是ifIndex 为1、2、7、1210的对象
  • A&&B || C 最终匹配的是 lo eno1tun0 tun1 这些网卡

注意: v0.3.7 和 v0.3.8 版本中用的是include_filter这个配置,并且只支持 两段式的配置 ifIndex:2 这种,不支持正则表达式,而且默认是所有表达式做OR(||)运算。 v0.3.9 版本,使用filters 代替 include_filter。虽然依然支持include_filter并且兼容两段式配置,但是建议使用filters+三段式配置,这样可以使用更丰富的逻辑运算。

批量设置label

[mappings]
"udp://192.168.11.102:161" = { name = "switch001.bj", region = "beijing", ip = "192.168.11.102"}
"udp://192.168.11.103:161" = { name = "switch002.bj", region = "shanghai", ip = "192.168.11.103"}

[[instances]]
agents = [
"udp://192.168.11.102:161",
...
]

[[instances]]
agents = [
"udp://192.168.11.103:161",
...
]

可以通过[mappings] 给每个agent设置label,采集的时候,就会自动带上这些label。注意格式,mappings是单个[], key 不带引号,value带引号。

快猫星云 联系方式 快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云
OpenSource
开源版
Flashcat
Flashcat