Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Add option to select translator #10802

Merged
merged 14 commits into from
Mar 18, 2022
Merged

fix: Add option to select translator #10802

merged 14 commits into from
Mar 18, 2022

Conversation

reimda
Copy link
Contributor

@reimda reimda commented Mar 10, 2022

This PR adds back the ability to call netsnmp's snmptranslate and snmptable to translate names and OIDs.

Telegraf recently switched translation to use gosmi to address performance concerns. (see #9518, released in 1.21.0) This resulted in translation not being backward compatible with the previous release, 1.20.4.

This PR makes gosmi translation a config option, but defaults to netsnmp translation.

Users of 1.21.0 and later who have transitioned to gosmi will need to set translator = "gosmi" in their agent config. Users who have not upgraded past 1.20.4 in order to keep using netsnmp translation should be able to use this without config changes.

@telegraf-tiger telegraf-tiger bot added the fix pr to fix corresponding bug label Mar 10, 2022
@Hipska Hipska added area/snmp plugin/input 1. Request for new input plugins 2. Issues/PRs that are related to input plugins labels Mar 10, 2022
Copy link
Contributor

@Hipska Hipska left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some remarks before continuing..

plugins/inputs/snmp/snmp.go Outdated Show resolved Hide resolved
Comment on lines +20 to +22
func NewNetsnmpTranslator() *netsnmpTranslator {
return &netsnmpTranslator{}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could maybe return error when net-snmp commands are not found?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be a good idea, but this isn't how it worked before so I'm not going to do it in this PR. I'd hate to break things for people who (for example) only use numeric oids.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You know telegraf is doing lookups in that case as well, right? (in order to get a name and conversion)

Comment on lines 126 to 133
if s.Translator == "gosmi" {
s.translator, err = NewGosmiTranslator(s.Path, s.Log)
if err != nil {
return err
}
} else {
s.translator = NewNetsnmpTranslator()
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could maybe better done in a separate method? func (s *Snmp) initTranslator() error { Then this Init method could return error fmt.Errorf("initialising translator %s: %w", s.Translator, err)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's only done once so I don't think it needs a separate method. There's a similar pattern in snmp_trap.go too, but it uses a different interface.

Comment on lines 142 to 151
if d.Translator == "gosmi" {
var err error
d.translator, err = si.NewGosmiTranslator(d.Path, d.Log)
if err != nil {
return err
}
} else {
d.translator = si.NewNetsnmpTranslator()
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't make much sense, since I made the plugin independent from any MIBs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although it's independent from MIBS because it hard codes numeric OIDs, the table and field initialization code still needs a translator. Inside those init functions, I don't expect any translation to happen. I did change ifname's code so it doesn't switch between translators.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You made the init functions depenant on a translator interface in this PR, so it can still be fixed.

@Hipska Hipska self-assigned this Mar 15, 2022
Comment on lines 119 to 121
func (s *Snmp) SetTranslator(name string) {
s.Translator = name
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about calling this InitTranslator and initiating the translator, returning error on failure?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is kind of an ugly hack to share the agent's translator setting with the plugins. I didn't want to add more error handling code to the agent to handle an error where it calls this function. There's already a well defined way for inputs to report config errors to the agent- Init func's return value.

@@ -13,7 +13,7 @@ type ClientConfig struct {
// Path to mib files
Path []string `toml:"path"`
// Translator implementation
Translator string `toml:"translator"`
Translator string `toml:"-"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed to be exported.

Suggested change
Translator string `toml:"-"`
translatorType string

plugins/inputs/snmp/snmp.go Show resolved Hide resolved
plugins/inputs/snmp/snmp_test.go Outdated Show resolved Hide resolved
Comment on lines +137 to +139
// Since OIDs in this plugin are always numeric there is no need
// to translate.
d.translator = si.NewNetsnmpTranslator()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then why initiating it anyway?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just because it needs to be something. I don't expect it to be used. We should consider changing ifname so it doesn't call table Init() at all. Then we won't need a translator at all.

Copy link
Contributor

@Hipska Hipska Mar 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As said before, better would be the table.Init not expect a translator as argument.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about that @reimda?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see how we can make table.Init() not expect a translator. Here in ifname, Init() shouldn't need to look up anything in the mibs because we only use numeric oids, but in the main use case in the snmp input allows names so it does need to use mibs.

Maybe here in ifname we should change the code to manually initialize the table and then not call Init() at all. That would probably mean removing makeTableNoMock() completely and changing makeTable() to fill in all the fields of snmp.Table that table.Init() would.

Copy link
Contributor

@Hipska Hipska Apr 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Easiest way would be by adding translator to the struct. But don't know if that is a good thing memory-wise.

Edit: It looks like the call of Init shouldn't even be needed, as we already initialise all necessary parameters. The only problem remaining would be the call of Table.Build that expects a translator, but it would not be called in case of ifName plugin usage, so I'm wondering if you can just pass a null value?

@Hipska
Copy link
Contributor

Hipska commented Mar 17, 2022

Hi @reimda, great work! Could you please give some feedback on my comments?

@telegraf-tiger
Copy link
Contributor

@reimda reimda marked this pull request as ready for review March 17, 2022 22:25
@reimda
Copy link
Contributor Author

reimda commented Mar 17, 2022

Hi @reimda, great work! Could you please give some feedback on my comments?

Hi @Hipska, thanks for taking a look at the code. I just got it ready enough to review and marked it not a draft. A few of the things you the things you asked about were just because it wasn't ready yet.

You shared some improvements that could be good ideas on their own, but I don't want to add to this PR. This PR's only job is to revert to using netsnmp by default. My focus is to go back to behavior of 1.20.4 because of the compatibility issues that came up when we switched to gosmi. I also want to keep the option of using gosmi for others who found it an improvement, but require them to explicitly choose it. Making other changes while doing this makes everything more confusing for users and risks adding bugs.

@reimda reimda requested a review from powersj March 17, 2022 22:44
@reimda
Copy link
Contributor Author

reimda commented Mar 18, 2022

Since PR builds are not available at the moment I'm going to merge this even though it still needs more review, so it will be in the nightly build and available for testing. I will make a follow-up PR for any changes required by reviews and testing.

@reimda reimda merged commit 77040ef into master Mar 18, 2022
@reimda reimda deleted the snmp-translator-setting branch March 18, 2022 03:43

type TranslatorPlugin interface {
SetTranslator(name string) // Agent calls this on inputs before Init
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be added in the translate.go file?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/snmp fix pr to fix corresponding bug plugin/input 1. Request for new input plugins 2. Issues/PRs that are related to input plugins
Projects
None yet
2 participants