influxdata / telegraf

Agent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.
https://influxdata.com/telegraf
MIT License
14.89k stars 5.6k forks source link

[inputs.snmp] TruthValue conversion #16058

Open llamafilm opened 1 month ago

llamafilm commented 1 month ago

Use Case

Some MIBs have a TruthValue convention where 1 means true and 2 means false. I'd like to record this data in a more standard way where 0 means false and 1 means true. I propose adding a new conversion type called truthvalue for this input plugin that simply converts 2 to 0 and 1 to 1.

Example from the MIB:

cdcp4415RgbSystemLightSourceOn OBJECT-TYPE
    SYNTAX      TruthValue
    MAX-ACCESS  read-only
    STATUS      current
    DESCRIPTION
            "True if light source is on"
    ::= { cdcp4415RgbSystemStatus 6 }

Example config:

[agent]
  snmp_translator = "gosmi"

[[inputs.snmp]]
  name_override = "snmp_christie_4415"
  path = ["$MIBDIRS"]
  agents = ["10.37.154.146"]
  version = 2
  community = "public"
  agent_host_tag = "source"
  [[inputs.snmp.field]]
    name = "system_light_source_on"
    oid = "CDS-PJTR-CP4415RGB::cdcp4415RgbSystemLightSourceOn.0" # 1.3.6.1.4.1.25766.1.12.1.157.2.5.6.0

Expected behavior

I'd like to get a field like system_light_source_on=0i

Actual behavior

I get this

> snmp_christie_4415,host=Elliott-M2-4.local,source=10.37.154.146 system_light_source_on=2i 1729575093000000000

Additional info

I can make it work today by using the enum conversion followed by a enum processor. But this seems silly.

[[processors.enum]]
  namepass = ["snmp_christie*"]
  [[processors.enum.mapping]]
    field = "*"
    [processors.enum.mapping.value_mappings]
      false = 0
      true = 1
srebhan commented 1 month ago

@llamafilm I would then use true and false as value i.e. a boolean field. Is this what you had in mind?

@Hipska any thoughts?

Hipska commented 1 month ago

What about conversion = "enum" and then use converter:

[[processors.converter]]
  namepass = ["snmp_christie*"]

  [processors.converter.fields]
    boolean = ["system_light_source_on"]
llamafilm commented 1 month ago

I forgot that influx supports boolean fields! Since Telegraf is primarily designed for influx, your suggestion makes sense @srebhan. In general, I thought it would be nice if the SNMP input plugin handles all possible SNMP data types without needing additional processors.

But since I'm writing to Prometheus and it only supports floats, I will continue using the enum processor for this.

Hipska commented 1 month ago

What happens if you send this boolean field to Prometheus? Doesn’t it get converted to 1 and 0?

llamafilm commented 1 month ago

Ah, you're right actually. So then I agree, it makes sense to output the values as true and false.

srebhan commented 2 weeks ago

@llamafilm so this issue can be closed?

llamafilm commented 2 weeks ago

Philosophically, I think it would be best for the snmp input plugin to support all possible data types of the snmp specification without requiring any additional processor. By the same logic, it should also have some additional fix for the bits type as I described at the end of #15963 comments.

There is a workaround: Use conversion=enum with processors.converter. But when you have many fields that need this conversion, you have to list them all in the processor. So I don't think this is ideal. But I don't have the skills to implement this myself, so the decision is yours if this feature is worth adding.

[agent]
  snmp_translator = "gosmi"

[[inputs.snmp]]
  name_override = "snmp_christie_projector"
  path = ["$MIBDIRS"]
  agents = ["10.37.154.146"]
  version = 2
  community = "public"
  agent_host_tag = "source"
  [[inputs.snmp.field]]
    name = "system_light_source_on"
    oid = "CDS-PJTR-CP4415RGB::cdcp4415RgbSystemLightSourceOn.0"  # 1.3.6.1.4.1.25766.1.12.1.157.2.5.6.0
    conversion = 'enum'
  [[inputs.snmp.field]]
    name = "system_douser_open"
    oid = "CDS-PJTR-CP4415RGB::cdcp4415RgbSystemDouserOpen.0"  # 1.3.6.1.4.1.25766.1.12.1.157.2.5.5.0
    conversion = 'enum'
[[processors.converter]]
  namepass = ["snmp_christie*"]
  [processors.converter.fields]
    boolean = ["system_light_source_on", "system_douser_open"]
srebhan commented 2 weeks ago

@llamafilm understood and I agree that it would be good to support standard types. Leaving this open for now.

Hipska commented 1 week ago

The snmp plugin supports all standard (base) types, only TruthValue isn't one, it is a TEXTUAL-CONVENTION for the base type integer. The plugin supports this in 2 ways; either by conversion enum or displayhint. If you leave the conversion to the default value, it will be emitted as an integer.

To me this fulfils the request.