-
Notifications
You must be signed in to change notification settings - Fork 779
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
Revive using Batch for metric export #2327
Changes from all commits
672a6bf
f67c9c9
748ee0b
f08cc50
21ff3f7
104bd32
a7403da
ef58b68
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,9 +40,11 @@ public static MeterProviderBuilder AddOtlpExporter(this MeterProviderBuilder bui | |
var options = new OtlpExporterOptions(); | ||
configure?.Invoke(options); | ||
|
||
var metricExporter = new OtlpMetricsExporter(options); | ||
var metricReader = new PeriodicExportingMetricReader(metricExporter, options.MetricExportIntervalMilliseconds); | ||
return builder.AddMetricReader(metricReader); | ||
// var metricExporter = new OtlpMetricsExporter(options); | ||
// var metricReader = new PeriodicExportingMetricReader(metricExporter, options.MetricExportIntervalMilliseconds); | ||
// return builder.AddMetricReader(metricReader); | ||
Comment on lines
+43
to
+45
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same thing with the OtlpExporter |
||
|
||
return builder; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,14 +37,17 @@ public static MeterProviderBuilder AddPrometheusExporter(this MeterProviderBuild | |
|
||
var options = new PrometheusExporterOptions(); | ||
configure?.Invoke(options); | ||
var exporter = new PrometheusExporter(options); | ||
|
||
var metricReader = new BaseExportingMetricReader(exporter); | ||
exporter.CollectMetric = metricReader.Collect; | ||
// var exporter = new PrometheusExporter(options); | ||
|
||
var metricsHttpServer = new PrometheusExporterMetricsHttpServer(exporter); | ||
metricsHttpServer.Start(); | ||
return builder.AddMetricReader(metricReader); | ||
// var metricReader = new BaseExportingMetricReader(exporter); | ||
// exporter.CollectMetric = metricReader.Collect; | ||
|
||
// var metricsHttpServer = new PrometheusExporterMetricsHttpServer(exporter); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh yea and Prometheus too 😄 |
||
// metricsHttpServer.Start(); | ||
// return builder.AddMetricReader(metricReader); | ||
|
||
return builder; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ | |
using System; | ||
using System.Threading; | ||
using OpenTelemetry.Internal; | ||
using OpenTelemetry.Metrics; | ||
|
||
namespace OpenTelemetry | ||
{ | ||
|
@@ -105,6 +106,14 @@ public void Dispose() | |
GC.SuppressFinalize(this); | ||
} | ||
|
||
public virtual AggregationTemporality GetAggregationTemporality() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we do There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably just call it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, so I tried this out originally, the stickiness I ran into is that we'd like to be able to do Though, we might be fighting the type hierarchy too hard. It may make more sense to move this common logic to separate classes and have a handle to it. This would enable us to do something like I plan to experiment with this in a follow up. |
||
{ | ||
// TODO: One suggestion is to have SupportedTemporality | ||
// and PreferredTemporality. | ||
// see https://github.com/open-telemetry/opentelemetry-dotnet/pull/2306#discussion_r701532743 | ||
return AggregationTemporality.Cumulative; | ||
} | ||
|
||
/// <summary> | ||
/// Called by <c>Shutdown</c>. This function should block the current | ||
/// thread until shutdown completed or timed out. | ||
|
Original file line number | Diff line number | Diff line change | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -19,6 +19,7 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
using System.Collections.Generic; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
using System.Diagnostics; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
using OpenTelemetry.Internal; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
using OpenTelemetry.Metrics; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
namespace OpenTelemetry | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -31,12 +32,14 @@ namespace OpenTelemetry | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private readonly T item; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private readonly CircularBuffer<T> circularBuffer; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private readonly T[] metrics; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private readonly long targetCount; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
internal Batch(T item) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.item = item ?? throw new ArgumentNullException(nameof(item)); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.circularBuffer = null; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.metrics = null; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just to call out loud here, do we need to initialize these to null, or they are null by default? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see, thanks! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @CodeBlanch I guess a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we cannot define a default ctor like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe something like a default copy constructor? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.targetCount = 1; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -45,10 +48,21 @@ internal Batch(CircularBuffer<T> circularBuffer, int maxSize) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Debug.Assert(maxSize > 0, $"{nameof(maxSize)} should be a positive number."); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.item = null; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.metrics = null; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.circularBuffer = circularBuffer ?? throw new ArgumentNullException(nameof(circularBuffer)); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.targetCount = circularBuffer.RemovedCount + Math.Min(maxSize, circularBuffer.Count); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
internal Batch(T[] metrics, int maxSize) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Debug.Assert(maxSize > 0, $"{nameof(maxSize)} should be a positive number."); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.item = null; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.circularBuffer = null; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.metrics = metrics ?? throw new ArgumentNullException(nameof(metrics)); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.targetCount = maxSize; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/// <inheritdoc/> | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
public void Dispose() | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -70,6 +84,8 @@ public Enumerator GetEnumerator() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return this.circularBuffer != null | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
? new Enumerator(this.circularBuffer, this.targetCount) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
: this.metrics != null | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
? new Enumerator(this.metrics, this.targetCount) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
: new Enumerator(this.item); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -79,20 +95,35 @@ public Enumerator GetEnumerator() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
public struct Enumerator : IEnumerator<T> | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private readonly CircularBuffer<T> circularBuffer; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private readonly T[] metrics; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private long targetCount; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private int metricIndex; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
internal Enumerator(T item) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.Current = item; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.circularBuffer = null; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.metrics = null; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.targetCount = -1; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.metricIndex = 0; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
internal Enumerator(CircularBuffer<T> circularBuffer, long targetCount) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.Current = null; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.metrics = null; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.circularBuffer = circularBuffer; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.targetCount = targetCount; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.metricIndex = 0; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
internal Enumerator(T[] metrics, long targetCount) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.Current = null; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.circularBuffer = null; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.metrics = metrics; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.targetCount = targetCount; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.metricIndex = 0; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/// <inheritdoc/> | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -109,6 +140,24 @@ public void Dispose() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/// <inheritdoc/> | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
public bool MoveNext() | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (typeof(T) == typeof(Metric)) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @cijothomas's thought was that this would get optimized out when There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. alternate option to try. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I haven't yet had the chance to try the alternate approach you've suggested, but before I make those changes here's some perf numbers with and without this The benchmark simulates what the Benchmark [MemoryDiagnoser]
public class BatchBenchmarks
{
[Benchmark]
public void ActivityBatch()
{
var activity = new Activity("activity");
var batch = new Batch<Activity>(activity);
foreach (var item in batch)
{
item.Start();
item.Stop();
}
}
} With
Without
I've gotten some pretty varied results. Sometimes the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tried similar benchmarks and results are not consistent. Sometimes the new Batch is fast!
Run1:
Run2:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @reyang The benchmarks doesn't show any consistently measurable regression (sometimes new one is faster). Given that adding metrics to Batch is not affecting other signals in measurable way, we should be okay to add metrics support to Batch and achieve cleaner exporter code. Please let us know your comments. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1. |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
var metrics = this.metrics; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (metrics != null) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (this.metricIndex < this.targetCount) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.Current = metrics[this.metricIndex]; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.metricIndex++; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return true; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.Current = null; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return false; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
var circularBuffer = this.circularBuffer; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (circularBuffer == null) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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'll fix the InMemoryExporter right after this PR lands