snmp_exporter icon indicating copy to clipboard operation
snmp_exporter copied to clipboard

Should we allow multiple modules per target?

Open RichiH opened this issue 3 years ago • 5 comments

This is an ongoing discussion between @SuperQ and I; input very much appreciated.

Pro:

  • Less config bloat
  • Allows for modular configs, which might be nice for modular chassis and such

Con:

  • Non-obvious precedence, merging, etc
  • Harder to debug

Neutral:

  • Through https://github.com/prometheus/snmp_exporter/issues/619 and others, we may be able to reduce pressure on snmp.yml to be touched at all, thus reducing the need for any human to ever touch snmp.yml

Currently, @SuperQ is slightly in favor, I am slightly against, but could easily change. I am, however, strongly in favor of doing this later rather than sooner due to reduced pressure on snmp.yml.

RichiH avatar Feb 25 '21 08:02 RichiH

Pro:

  • Less config bloat for configurations that handle multiple versions of the same device: (ex. 24 port switch monitor only uplinks, 24 port switch monitor all ports, 24 port switch monitor all ports named "MON.*", etc.

Con:

  • Code will get a bit more complexity to handle ordering the module data to an intermediate in-memory module config (my suggestion)

Implementation:

Must not introduce config complexity in prometheus.yml and its dependant targets.json files (ex. Due to having to provide a list of modules or other funky stuff) I would see an implementation that uses import module statements in the device module of generator.yml. The order of imports would impart the merging ordering logic. Doing it this way should not make it overly complexe to troubleshoot. As the generator would essentially build an intermediate module with all the sections ordered by the import order. This intermediate module would then be used to generate the output module for snmp.yml I hope this makes sense.

xkilian avatar Feb 25 '21 12:02 xkilian

I like this idea, it reduces the manual config work and lets the generator do the heavy lifting. While I agree merging and such does become a pain but at the same time, a dumb merging strategy (no de-dup etc.) would mean the onus is on the user to ensure their generator input is sane.

It would be so much easier to be able to define e.g.:

metrics:
	ifmib:
	  table: <oid>
    ifbgp4:
      table: <oid>
module:
    juniper_switch:
		metrics:
			- ifmib
	juniper_router:
		metrics: 
			- ifmib
			- ifbgp4

https://github.com/toni-moreno/snmpcollector actually does a very good job of defining SNMP objects and tables into metrics like this and allow you to collect them into "metric groups" for defining to devices.

tardoe avatar Jun 24 '21 01:06 tardoe

Allowing multiple modules will be beneficial for the people to minimize level of effort and clear confusion

ikroumov avatar Sep 11 '21 22:09 ikroumov

Hopefully, this feature will be implemented as soon as possible, because it really makes configuration work much easier!!!

shulianwang avatar Nov 24 '21 10:11 shulianwang

I also like this. IF_MIB is IF_MIB; every vendor's IF_MIB is the same (or at least, it has a subset of the data - e.g. very old devices might not have ifXTable)

The approach which occurred to me first was to specify multiple modules in a scrape request:

/snmp?target=x.x.x.x&module=foo&module=bar&module=baz

That maps nicely to an NMS front-end where you might just select a bunch of checkboxes for the modules to scrape for a particular target or target group.

The problem with this approach is that in a Prometheus scrape job, whilst you can specify multiple values for the same parameter statically, you cannot do it via relabelling (that is, __param_module can only have a single value), making it harder to configure this dynamically.

You could allow an alternative way like a comma-separated list:

/snmp?target=x.x.x.x&module=foo,bar,baz

Actually, it's even possible out-of-the-box with today's snmp_exporter if you create three scrape jobs which scrape the same target for each module, but that's a pain to manage in prometheus.yml - every new module needs a new scrape job, and relabelling rules to drop the targets that shouldn't be scraped with that module.

Looking at @tardoe's approach, another option would be for one module to include/inherit other modules:

module:
  ifmib:
    table: <oid>
  ifbgp4:
    table: <oid>
  juniper_switch:
    include: [ifmib]
  juniper_router:
    include: [ifmib, ifbgp4]
  juniper_ex4200_switch:
    include: [juniper_switch]
    table: <oid>   # specific to this model

This still requires the user to pre-define every combination of MIBs that they want to use though.

candlerb avatar Apr 19 '23 10:04 candlerb