-
Notifications
You must be signed in to change notification settings - Fork 825
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
refactor: change metrics export data model to match OTLP protos #2809
Conversation
Codecov Report
@@ Coverage Diff @@
## main #2809 +/- ##
==========================================
- Coverage 93.48% 93.46% -0.02%
==========================================
Files 163 163
Lines 5541 5543 +2
Branches 1166 1167 +1
==========================================
+ Hits 5180 5181 +1
- Misses 361 362 +1
|
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.
Thank you for your work! 👍
@@ -130,16 +130,21 @@ export class Meter implements metrics.Meter { | |||
* @param collectionTime the HrTime at which the collection was initiated. | |||
* @returns the list of {@link MetricData} collected. | |||
*/ | |||
async collect(collector: MetricCollectorHandle, collectionTime: HrTime): Promise<MetricData[]> { | |||
const result = await Promise.all(Array.from(this._metricStorageRegistry.values()).map(metricStorage => { | |||
async collect(collector: MetricCollectorHandle, collectionTime: HrTime): Promise<MetricsData> { |
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 seems like InstrumentationLibraryMetrics
is what a Meter represents regarding the export model. Maybe we can return a Promise<InstrumentationLibraryMetrics>
here?
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.
Good point, even less code :) Changed it
const collectionTime = hrTime(); | ||
const results = await Promise.all(this._sharedState.meters | ||
.map(meter => meter.collect(this, collectionTime))); | ||
|
||
return results.reduce((cumulation, current) => cumulation.concat(current), []); | ||
return results.reduce((cumulation, current) => cumulation.merge(current), new MetricsData()); |
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.
When the meter returns a plain interface of InstrumentationLibraryMetricsData
, it seems we don't need a MetricsData.merge
here and exporters don't need MetricsData.resourceMetrics
to transform maps of data to plain structures?
i.e. a ResourceMetrics
could be constructed with an array of InstrumentationLibraryMetricsData
and returned.
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.
Thanks! This made it possible to get rid of MetricsData
Will this MR will make sdk-metrics-base to be compatible with OTLP proto 0.11+ ? Thanks ! |
No, we still need to update the metrics-otlp exporter to adopt the changes. |
Perhaps one open question - should metrics data be grouped together here by instrumentation library metrics (need to check for value equality) when doing the collect? Or do we think it's fine to have possible duplicates of instrumentation libraries there? |
It's technically fine to have duplicates there. Grouping them may have some small benefit on the total payload size |
I think we can do it by preventing from creating duplicated meters, so that the burden is at the time creating the meter, rather than duplicating the work at the collection time. Either way, I think we don't need to do it in this PR. We can track the meter identity in #2593 |
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.
Overall LGTM 👍 , just one minor question.
const results = await Promise.all(this._sharedState.meters | ||
.map(meter => meter.collect(this, collectionTime))); | ||
const instrumentationLibraryMetrics = (await Promise.all(this._sharedState.meters | ||
.map(meter => meter.collect(this, collectionTime)))).filter(({ metrics }) => metrics.length > 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.
I'd find we don't need to do this filtering in the SDK. Like, say, with the DELTA aggregation temporality, the metrics for a meter may contain no items if in a period of time there is no metric event reported. It may be confusing that the InstrumentationLibrary sometimes disappears.
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.
So you are suggesting to export empty InstrumentationLibraryMetrics in that case and leave it up to the exporter and/or backend to sort it out?
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.
Yes, exactly.
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.
Removed the filtering
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.
Looks good generally. Think this will be ready to merge soon
experimental/packages/opentelemetry-sdk-metrics-base/src/export/MetricReader.ts
Show resolved
Hide resolved
...rimental/packages/opentelemetry-sdk-metrics-base/src/export/PeriodicExportingMetricReader.ts
Outdated
Show resolved
Hide resolved
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.
lgtm
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.
Thank you for your work!
Which problem is this PR solving?
Refactor metrics export data model to be more in line with metrics protos.
Fixes #2775
Short description of the changes
This introduces
MetricsData
(naming suggestions welcome) class, which internally groups metric datapoints by resource and instrumentation library and provides a helper to "flatten" into the OTLP protos shape.Thus
instrumentationLibrary
andresource
are removed fromBaseMetricData
, saving memory and code duplication.Checklist: