-
Notifications
You must be signed in to change notification settings - Fork 5.6k
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
Conversation
There was a problem hiding this 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..
func NewNetsnmpTranslator() *netsnmpTranslator { | ||
return &netsnmpTranslator{} | ||
} |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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)
plugins/inputs/snmp/snmp.go
Outdated
if s.Translator == "gosmi" { | ||
s.translator, err = NewGosmiTranslator(s.Path, s.Log) | ||
if err != nil { | ||
return err | ||
} | ||
} else { | ||
s.translator = NewNetsnmpTranslator() | ||
} |
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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.
plugins/processors/ifname/ifname.go
Outdated
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() | ||
} | ||
|
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
plugins/inputs/snmp/snmp.go
Outdated
func (s *Snmp) SetTranslator(name string) { | ||
s.Translator = name | ||
} |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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:"-"` |
There was a problem hiding this comment.
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.
Translator string `toml:"-"` | |
translatorType string |
// Since OIDs in this plugin are always numeric there is no need | ||
// to translate. | ||
d.translator = si.NewNetsnmpTranslator() |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
Hi @reimda, great work! Could you please give some feedback on my comments? |
Download PR build artifacts for linux_amd64.tar.gz, darwin_amd64.tar.gz, and windows_amd64.zip. 📦 Click here to get additional PR build artifactsArtifact URLs |
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. |
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. |
|
||
type TranslatorPlugin interface { | ||
SetTranslator(name string) // Agent calls this on inputs before Init | ||
} |
There was a problem hiding this comment.
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?
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.