-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Add new MetricSet interfaces for Module Developers #3908
Conversation
08c75b0
to
74cc2f5
Compare
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 all usage of the interfaces is 100% clear to me yet, but I assume they will get answered as soon as we have the first implementation.
For the ReportingFetcher: Wouldn't it be enough to have Fetch() (common.MapStr, []error)
as an interface? How will the additional meta data and errors used? I'm aware you are no big fan of having a "special" Error object but perhaps something like this could be used here?
metricbeat/mb/mb.go
Outdated
@@ -84,6 +90,42 @@ type EventsFetcher interface { | |||
Fetch() ([]common.MapStr, error) | |||
} | |||
|
|||
// Reporter is used by a MetricSet to report events, errors, or errors with | |||
// metadata. The methods return false iff publishing failed because the |
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.
s/iff/if
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.
iff is shorthand for "if and only if". I thought it was more common, maybe only common in math. I'll expand it to "if and only if".
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.
lol, makes sense now. Did not make the connection when reading it and just thought: typo :-)
@@ -59,7 +59,9 @@ func (b EventBuilder) Build() (common.MapStr, error) { | |||
metricsetData := common.MapStr{ | |||
"module": b.ModuleName, | |||
"name": b.MetricSetName, | |||
"rtt": b.FetchDuration.Nanoseconds() / int64(time.Microsecond), | |||
} | |||
if b.FetchDuration != 0 { |
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.
Nice, that means we also remove this value in the system module case 👍
default: | ||
return fmt.Errorf("MetricSet '%s/%s' does not implement a Fetcher "+ | ||
"interface", msw.Module().Name(), msw.Name()) | ||
panic(fmt.Sprintf("unexpected fetcher type for %v", msw)) |
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.
Why do you panic here instead of returning an error?
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 an unreachable code path and can never happen due to an earlier check in the caller. So if it does happen I want it to blow up loudly and early so we can catch it in development/unit tests.
metricbeat/mb/mb.go
Outdated
type Reporter interface { | ||
Event(event common.MapStr) bool | ||
ErrorWith(err error, meta common.MapStr) bool | ||
Error(error) bool |
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.
Do we need both interfaces or could we just have Error(err error, meta common.MapStr)
and in case the meta does not exist it is set to nil? Thinking if we could reduce the number of interface methods.
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 think having separate methods for each of the cases (will) improve the readability of MetricSets that implement ReportingFetcher
.
Maybe it's not clear that MetricSets don't implement this interface, they only use it. So reducing the number of methods doesn't change the amount of methods a MetricSet needs to implement (if that was your concern).
I would like to make it clear from the godocs. What would improve your understanding? More docs on the MetricSet types? An example for for each MetricSet type ( |
No, that interface wouldn't be sufficient because you cannot report multiple events. Nor can you send data with an error.
Maybe only a portion of the metrics were able to be collected due to an error. You can report the metrics you have available and also report the problem that occurred. Perhaps @urso had a different vision for |
timestamp := r.start | ||
elapsed := time.Duration(0) | ||
|
||
if !timestamp.IsZero() { |
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.
Minor comment / thought: In Fetch() []common.MapStr
all events have the exact same time which elapsed. In this new interface the first event will have a lower rtt
then the last event. Not sure yet if this is a good or bad thing.
This PR adds new interfaces for MetricSet developers. These interfaces provided additional flexibility for MetricSet implementations. The new interfaces are: - `Closer` - With Metricbeat gaining the ability to dynamically load and unload modules there became a need to properly release resources opened by a MetricSet. If a MetricSet implements the `Closer` interface then the `Close() error` method will be invoked when the MetricSet is unloaded. - `ReportingFetcher` - Some MetricSets needed to report multiple errors, but the existing `Fetch` methods only allowed a single error to be returned. `ReportingFetcher` passes a callback interface to the MetricSet that allows it to report any combination of events, errors, or errors with metadata. - `PushMetricSet` - This is for push event sources. All the current MetricSet implementations are driven by periodic `Fetch` callbacks triggered by timer. A `PushMetricSet` does not receive periodic callbacks, but instead has a `Run` method. Implementations can forward events as they are received from the underlying source.
- Rename ReportingFetcher to ReportingMetricSet. - Update example in godocs to implement ReportingMetricSet. - Change iff in godocs to “if and only if”.
74cc2f5
to
8b8a86d
Compare
if err != nil { | ||
// Report an error if it occurs. | ||
report.Error(err) | ||
return |
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.
That pattern we will probably see quite often. If Error would not return anything, we could use return report.Error(err)
probably.
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.
@andrewkroh Ok for me to move forward on this. We definitively need some of these new capabilities for upcoming Modules. I'm still not 100% sure which interfaces we should keep in the end but time will show.
type EventFetcher interface { | ||
MetricSet | ||
Fetch() (common.MapStr, error) | ||
} | ||
|
||
// EventsFetcher is a MetricSet that returns a multiple events when collecting | ||
// data. | ||
// data. Use ReportingMetricSet for new MetricSet implementations. |
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.
In case we decided to keep both, we need to rename it later to something like EventsMetricSet
to be consistent. I still like the old Fetch
interfaces so not sure yet if Reporter will replace it or just be an other option.
This PR adds new interfaces for MetricSet developers. These interfaces provided additional flexibility for MetricSet implementations. The new interfaces are:
Closer
- With Metricbeat gaining the ability to dynamically load and unload modules there became a need to properly release resources opened by a MetricSet. If a MetricSet implements theCloser
interface then theClose() error
method will be invoked when the MetricSet is unloaded.ReportingFetcher
- Some MetricSets needed to report multiple errors, but the existingFetch
methods only allowed a single error to be returned.ReportingFetcher
passes a callback interface to the MetricSet that allows it to report any combination of events, errors, or errors with metadata.PushMetricSet
- This is for push event sources. All the current MetricSet implementations are driven by periodicFetch
callbacks triggered by timer. APushMetricSet
does not receive periodic callbacks, but instead has aRun
method. Implementations can forward events as they are received from the underlying source.