Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
6916c84
[Prometheus.HttpListener] Add env vars support
martincostello Apr 25, 2026
8495e5a
[Prometheus.HttpListener] Fix lint warnings
martincostello Apr 25, 2026
1d08846
[Prometheus.HttpListener] Add coverage
martincostello Apr 25, 2026
bfbc246
[Prometheus.HttpListener] Fix README snippets
martincostello Apr 25, 2026
e598fbb
[Exporter.Prometheus] Fix-up merge
martincostello Apr 27, 2026
7adc4f4
[Prometheus.HttpListener] Fix merge
martincostello Apr 28, 2026
2faa7ae
[Exporter.Prometheus] Update Accept handling
martincostello Apr 30, 2026
d61ed6c
[Exporter.Prometheus] Address review comments
martincostello May 1, 2026
ab6f944
[Exporter.Prometheus] Use canonical representations
martincostello Apr 29, 2026
8544d12
[Exporter.Prometheus] Update CHANGELOGs
martincostello Apr 29, 2026
2fef7d3
[Exporter.Prometheus] Extend test coverage
martincostello Apr 29, 2026
135b40b
[Exporter.Prometheus] Remove unreachable code
martincostello Apr 29, 2026
534ef9c
[Exporter.Prometheus] Address feedback
martincostello Apr 29, 2026
38772fb
[Exporter.Prometheus] Fix untyped for OpenMetrics
martincostello Apr 29, 2026
e38b8a7
[Exporter.Prometheus] Fix OpenMetrics histograms
martincostello Apr 29, 2026
4656b1f
[Exporter.Prometheus] Fix CHANGELOGs
martincostello Apr 29, 2026
aaf830e
[Exporter.Prometheus] Export _created series
martincostello Apr 29, 2026
e26bafb
[Exporter.Prometheus] Address feedback
martincostello Apr 29, 2026
f6d8c67
[Exporter.Prometheus] Address feedback
martincostello May 1, 2026
ffb6559
[Exporter.Prometheus] Fix-up merge
martincostello May 1, 2026
b8609aa
[Exporter.Prometheus] Fix SA1507 warning
martincostello May 1, 2026
9454950
[Exporter.Prometheus] Fix test
martincostello May 1, 2026
995e4cc
[Exporter.Prometheus] Fix scope metadata
martincostello May 1, 2026
138f4ef
[Exporter.Prometheus] Update test cases
martincostello May 1, 2026
5b82173
[Exporter.Prometheus] Update CHANGELOGs
martincostello May 1, 2026
fa5ddcc
[Exporter.Prometheus] Address feedback
martincostello May 1, 2026
767aa01
[Exporter.Prometheus] Extend coverage
martincostello May 1, 2026
d7ad536
[Exporter.Prometheus] Add target_info fallback
martincostello May 1, 2026
574fde1
[Exporter.Prometheus] Update CHANGELOGs
martincostello May 1, 2026
9bfbdb1
[Exporter.Prometheus] Merge colliding label keys
martincostello May 1, 2026
6507246
[Exporter.Prometheus] Update CHANGELOGs
martincostello May 1, 2026
70ef846
[Exporter.Prometheus] Address feedback
martincostello May 1, 2026
67be1ee
[Exporter.Prometheus] Extend coverage
martincostello May 1, 2026
8d97d02
[Exporter.Prometheus] Dedupe metadata
martincostello May 1, 2026
7d3aad5
[Exporter.Prometheus] Address feedback
martincostello May 1, 2026
3851591
[Exporter.Prometheus] Extend coverage
martincostello May 1, 2026
d91f75e
Fix Prometheus merge regressions
martincostello May 3, 2026
c4a2242
[Exporter.Prometheus] Tweak formatting
martincostello May 3, 2026
936b177
[Exporter.Prometheus] Validate with promtool
martincostello May 3, 2026
2c678a6
[Exporter.Prometheus] Fix warnings
martincostello May 3, 2026
1d426b9
[Exporter.Prometheus] Fix build
martincostello May 3, 2026
b007718
[Exporter.Prometheus] Fix tests
martincostello May 3, 2026
260aa7f
[Exporter.Prometheus] Fix tests
martincostello May 3, 2026
7dd8ebe
[Exporter.Prometheus] FIx namespace
martincostello May 3, 2026
7cdfc97
[Exporter.Prometheus] Fix tests
martincostello May 3, 2026
b98a644
[Exporter.Prometheus] Fix tests
martincostello May 3, 2026
a65aad3
[Exporter.Prometheus] Update comment
martincostello May 3, 2026
2bba11e
[Exporter.Prometheus] Update tests
martincostello May 3, 2026
0c4a4ed
[Exporter.Prometheus] Address comments
martincostello May 3, 2026
2aba375
[Exporter.Prometheus] Fix CHANGELOGs
martincostello May 3, 2026
1fccc58
Merge branch 'main' into prometheus-compatibility-fixes
martincostello May 4, 2026
5b98a4e
[Exporter.Prometheus] Fix fuzz tests
martincostello May 4, 2026
aec37e8
Merge branch 'main' into prometheus-compatibility-fixes
martincostello May 4, 2026
530b6c7
[Prometheus.AspNetCore] Extend integration tests
martincostello May 4, 2026
b7052a0
[Prometheus.AspNetCore] Fix warnings
martincostello May 4, 2026
e143acf
[Prometheus.AspNetCore] Fix typo
martincostello May 4, 2026
e447fa3
[Prometheus.AspNetCore] Fix build
martincostello May 4, 2026
3c9ac81
[Prometheus.AspNetCore] Add extra host
martincostello May 4, 2026
f655912
[Prometheus.AspNetCore] Fix-up asserts
martincostello May 4, 2026
23fb958
[Prometheus.AspNetCore] Output logs
martincostello May 4, 2026
a133dca
[Prometheus.AspNetCore] Set file permissions
martincostello May 4, 2026
52353f6
Merge branch 'main' into prometheus-compatibility-fixes
martincostello May 5, 2026
019a826
[Prometheus.AspNetCore] Extend integration tests
martincostello May 5, 2026
0f018e2
[Exporter.Prometheus] Observe request timeout
martincostello May 5, 2026
9bdc57a
[Exporter.Prometheus] Update CHANGELOGs
martincostello May 5, 2026
83a2c13
[Prometheus.AspNetCore] Address review comments
martincostello May 5, 2026
0823dd0
[Exporter.Prometheus] Extend content negotiation
martincostello May 6, 2026
c23bf43
[Exporter.Prometheus] Use immutable collections
martincostello May 6, 2026
260a367
[Exporter.Prometheus] Update CHANGELOGs
martincostello May 6, 2026
b7ff4db
[Exporter.Prometheus] Address feedback
martincostello May 6, 2026
4752f5e
Merge branch 'main' into prometheus-compatibility-fixes
martincostello May 7, 2026
8a23f77
Merge remote-tracking branch 'origin/extend-prometheus-integration-te…
martincostello May 7, 2026
e67837a
Merge remote-tracking branch 'origin/Observe-X-Prometheus-Scrape-Time…
martincostello May 7, 2026
d0f7441
Merge remote-tracking branch 'origin/extend-content-negotiation' into…
martincostello May 7, 2026
14938cc
[Prometheus.AspNetCore] Fix merge
martincostello May 7, 2026
0458ee8
[Prometheus.AspNetCore] Support OTEL_SDK_DISABLED
martincostello May 7, 2026
54bc9f1
[Prometheus.AspNetCore] Fix test
martincostello May 7, 2026
75234c4
[Prometheus.AspNetCore] Update CHANGELOG
martincostello May 7, 2026
fb0b57b
[Prometheus.AspNetCore] Address feedback
martincostello May 7, 2026
5e90244
[Prometheus.AspNetCore] Extend integration tests
martincostello May 5, 2026
ca448e5
[Prometheus.AspNetCore] Address review comments
martincostello May 5, 2026
af91589
[Prometheus.AspNetCore] Support GZip
martincostello May 7, 2026
9019f3b
Merge branch 'prometheus-handle-OTEL_SDK_DISABLED' into prometheus-co…
martincostello May 8, 2026
51f7f74
Merge branch 'gh-7213' into prometheus-compatibility-fixes
martincostello May 8, 2026
ecbf64c
Merge branch 'main' into prometheus-compatibility-fixes
martincostello May 14, 2026
8f537c1
Merge branch 'main' into prometheus-compatibility-fixes
martincostello May 18, 2026
d64c5f7
[Prometheus.AspNetCore] Fix merge
martincostello May 18, 2026
62845b2
Merge branch 'main' into prometheus-compatibility-fixes
martincostello May 19, 2026
67e17dc
Merge branch 'main' into prometheus-compatibility-fixes
martincostello May 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 41 additions & 12 deletions src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,53 +26,82 @@ Notes](../../RELEASENOTES.md).

* Fix non-ASCII characters in metric names and unit strings not being sanitized
correctly during Prometheus serialization.
([#7184](https://github.com/open-telemetry/opentelemetry-dotnet/issues/7184))
([#7184](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7184))

* Fix case where reader tracking could be reset while readers were still active.
([#7190](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7190))

* Improve `Accept` header handling for format negotiation so OpenMetrics is
selected correctly by considering whitespace and `q` weights.
([#7208](https://github.com/open-telemetry/opentelemetry-dotnet/issues/7208))
([#7208](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7208))

* Emit OpenMetrics exemplars for counters and histogram buckets.
([#7222](https://github.com/open-telemetry/opentelemetry-dotnet/issues/7222))
([#7222](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7222))

* Fix incorrect handling of untyped metrics when using OpenMetrics format.
([#7219](https://github.com/open-telemetry/opentelemetry-dotnet/issues/7219))
([#7219](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7219))

* Fix Prometheus/OpenMetrics serialization to emit metric and label names
containing `_` instead of dropping them and prefixing leading digits.
containing `:` and `_` instead of dropping them and prefixing leading digits.
Invalid characters are replaced with `_` instead of being dropped.
([#7209](https://github.com/open-telemetry/opentelemetry-dotnet/issues/7209))
([#7209](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7209))

* Add `escaping=underscores` to the `Accept` header handling for content
negotiation so OpenMetrics are handled correctly.
([#7209](https://github.com/open-telemetry/opentelemetry-dotnet/issues/7209))
([#7209](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7209))

* Use the canonical representation for histogram "le" label values when using
OpenMetrics.
([#7218](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7218))

* Omit histogram `_sum` and `_count` in OpenMetrics when negative bucket
thresholds are present.
([#7221](https://github.com/open-telemetry/opentelemetry-dotnet/issues/7221))
([#7221](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7221))

* Fix `ArgumentException` if `OTEL_SDK_DISABLED=true`.
([#7273](https://github.com/open-telemetry/opentelemetry-dotnet/issues/7273))
([#7273](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7273))

* Update `Accept` header parsing to more closely follow the Prometheus
[Scrape protocol content negotiation](https://prometheus.io/docs/instrumenting/content_negotiation/)
specification.
([#7266](https://github.com/open-telemetry/opentelemetry-dotnet/issues/7266))
([#7266](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7266))

* Abort scrape request processing if request exceeds the value specified by the
`X-Prometheus-Scrape-Timeout-Seconds` HTTP request header.
([#7252](https://github.com/open-telemetry/opentelemetry-dotnet/issues/7252))
([#7252](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7252))

* GZip compress scrape endpoint responses when `Accept-Encoding: gzip` is
specified by the HTTP request headers.
([#7274](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7274))

* Export `{name}_created` series for counters and histograms when using
OpenMetrics and a start time is available.
([#7223](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7223))

* Emit OpenMetrics scope metadata as a single `otel_scope` metric family with
`otel_scope_info` samples instead of repeating metadata for every scope.
([#7237](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7237))

* Include instrumentation scope metadata on samples using `otel_scope_*` labels
including scope version, schema URL, and prefixed scope attributes.
([#7237](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7237))

* Drop conflicting scope attributes named `name`, `version`, and `schema_url`.
([#7237](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7237))

* Add Prometheus text fallback `target_info` output as a gauge.
([#7238](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7238))

* Merge colliding sanitized label keys.
([#7239](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7239))

## 1.15.3-beta.1

Released 2026-Apr-21

* Fixed metric unit strings containing invalid Prometheus characters (e.g. `# RU`)
not being sanitized, resulting in malformed metric names.
([#6187](https://github.com/open-telemetry/opentelemetry-dotnet/issues/6187))
([#6187](https://github.com/open-telemetry/opentelemetry-dotnet/pull/6187))

* Fixed Prometheus metric serialization to handle empty label names without
throwing during scrape rendering.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<PackageTags>$(PackageTags);prometheus;metrics</PackageTags>
<MinVerTagPrefix>coreunstable-</MinVerTagPrefix>
<DefineConstants>$(DefineConstants);PROMETHEUS_ASPNETCORE</DefineConstants>
<NoWarn>$(NoWarn);CA2007</NoWarn>
</PropertyGroup>

<ItemGroup Condition="'$(RunningDotNetPack)' != 'true'">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO.Compression;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Headers;
using Microsoft.Net.Http.Headers;
using OpenTelemetry.Exporter.Prometheus;
using OpenTelemetry.Internal;
Expand Down Expand Up @@ -73,9 +75,11 @@ public async Task InvokeAsync(HttpContext httpContext)

using var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(requestCancelled.Token, httpContext.RequestAborted);

var protocol = Negotiate(httpContext.Request);
var requestHeaders = httpContext.Request.GetTypedHeaders();

var collectionResponse = await this.exporter.CollectionManager.EnterCollect(protocol.IsOpenMetrics).ConfigureAwait(false);
var protocol = Negotiate(requestHeaders);

var collectionResponse = await this.exporter.CollectionManager.EnterCollect(protocol.IsOpenMetrics);

try
{
Expand All @@ -90,7 +94,7 @@ public async Task InvokeAsync(HttpContext httpContext)
response.Headers.Append("Last-Modified", collectionResponse.GeneratedAtUtc.ToString("R"));
response.ContentType = PrometheusProtocol.GetContentType(protocol);

await response.Body.WriteAsync(dataView.Array.AsMemory(0, dataView.Count), linkedCts.Token).ConfigureAwait(false);
await WriteResponseAsync(response, dataView.Array.AsMemory(0, dataView.Count), AcceptsGZip(requestHeaders), linkedCts.Token);
}
else
{
Expand Down Expand Up @@ -144,9 +148,9 @@ static bool TryGetScrapeTimeout(
}
}

internal static PrometheusProtocol Negotiate(HttpRequest request)
internal static PrometheusProtocol Negotiate(RequestHeaders headers)
{
var acceptHeader = request.GetTypedHeaders().Accept;
var acceptHeader = headers.Accept;

if (acceptHeader is not { Count: > 0 })
{
Expand Down Expand Up @@ -284,4 +288,44 @@ private static bool TryParse(
protocol = new(mediaType, escaping, version, isOpenMetrics);
return true;
}

private static bool AcceptsGZip(RequestHeaders headers)
{
if (headers.AcceptEncoding is { Count: > 0 } acceptEncoding)
{
foreach (var parameter in acceptEncoding)
{
if (parameter.Value.Equals("gzip", StringComparison.OrdinalIgnoreCase))
{
return true;
}
}
}

return false;
}

private static async Task WriteResponseAsync(
HttpResponse response,
ReadOnlyMemory<byte> content,
bool compress,
CancellationToken cancellationToken)
{
if (compress)
{
response.Headers.Append("Content-Encoding", "gzip");

await using var gzip = new GZipStream(
response.Body,
CompressionLevel.Optimal,
leaveOpen: true);

await gzip.WriteAsync(content, cancellationToken);
await gzip.FlushAsync(cancellationToken);
}
else
{
await response.BodyWriter.WriteAsync(content, cancellationToken);
}
}
}
57 changes: 45 additions & 12 deletions src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Notes](../../RELEASENOTES.md).

* Fix non-ASCII characters in metric names and unit strings not being sanitized
correctly during Prometheus serialization.
([#7184](https://github.com/open-telemetry/opentelemetry-dotnet/issues/7184))
([#7184](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7184))

* Add support for caching the scrape endpoint HTTP responses using the
`PrometheusHttpListenerOptions.ScrapeResponseCacheDurationMilliseconds` option.
Expand All @@ -45,13 +45,13 @@ Notes](../../RELEASENOTES.md).

* Improve `Accept` header handling for format negotiation so OpenMetrics is
selected correctly by considering whitespace and `q` weights.
([#7208](https://github.com/open-telemetry/opentelemetry-dotnet/issues/7208))
([#7208](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7208))

* Emit OpenMetrics exemplars for counters and histogram buckets.
([#7222](https://github.com/open-telemetry/opentelemetry-dotnet/issues/7222))
([#7222](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7222))

* Fix incorrect handling of untyped metrics when using OpenMetrics format.
([#7219](https://github.com/open-telemetry/opentelemetry-dotnet/issues/7219))
([#7219](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7219))

* Add support for configuring the HTTP listener endpoint host and port using
the `OTEL_EXPORTER_PROMETHEUS_HOST` and `OTEL_EXPORTER_PROMETHEUS_PORT`
Expand All @@ -60,34 +60,67 @@ Notes](../../RELEASENOTES.md).
[#7255](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7255))

* Fix Prometheus/OpenMetrics serialization to emit metric and label names
containing and `_` instead of dropping them and prefixing leading digits.
containing `_` instead of dropping them and prefixing leading digits.
Invalid characters are replaced with `_` instead of being dropped.
([#7209](https://github.com/open-telemetry/opentelemetry-dotnet/issues/7209))
([#7209](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7209))

* Add `escaping=underscores` to the `Accept` header handling for content
negotiation so OpenMetrics are handled correctly.
([#7209](https://github.com/open-telemetry/opentelemetry-dotnet/issues/7209))
([#7209](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7209))

* Omit histogram `_sum` and `_count` in OpenMetrics when negative bucket
thresholds are present.
([#7221](https://github.com/open-telemetry/opentelemetry-dotnet/issues/7221))
([#7221](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7221))

* Update `Accept` header parsing to more closely follow the Prometheus
[Scrape protocol content negotiation](https://prometheus.io/docs/instrumenting/content_negotiation/)
specification.
([#7266](https://github.com/open-telemetry/opentelemetry-dotnet/issues/7266))
([#7266](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7266))

* Abort scrape request processing if request exceeds the value specified by the
`X-Prometheus-Scrape-Timeout-Seconds` HTTP request header.
([#7252](https://github.com/open-telemetry/opentelemetry-dotnet/issues/7252))
([#7252](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7252))

* Add `escaping=underscores` to the `Accept` header handling for content
negotiation so OpenMetrics are handled correctly.
([#7209](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7209))

* Use the canonical representation for histogram "le" label values when using
OpenMetrics.
([#7218](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7218))

* Omit histogram `_sum` and `_count` in OpenMetrics when negative bucket
thresholds are present.
([#7221](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7221))

* Export `{name}_created` series for counters and histograms when using
OpenMetrics and a start time is available.
([#7223](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7223))

* Emit OpenMetrics scope metadata as a single `otel_scope` metric family with
`otel_scope_info` samples instead of repeating metadata for every scope.
([#7237](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7237))

* Include instrumentation scope metadata on samples using `otel_scope_*` labels
including scope version, schema URL, and prefixed scope attributes.
([#7237](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7237))

* Drop conflicting scope attributes named `name`, `version`, and `schema_url`.
([#7237](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7237))

* Add Prometheus text fallback `target_info` output as a gauge.
([#7238](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7238))

* Merge colliding sanitized label keys.
([#7239](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7239))

## 1.15.3-beta.1

Released 2026-Apr-21

* Fixed metric unit strings containing invalid Prometheus characters (e.g. `# RU`)
not being sanitized, resulting in malformed metric names.
([#6187](https://github.com/open-telemetry/opentelemetry-dotnet/issues/6187))
([#7033](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7033))

* Fixed Prometheus metric serialization to handle empty label names without
throwing during scrape rendering.
Expand Down Expand Up @@ -383,7 +416,7 @@ Released 2022-Feb-02
Released 2021-Nov-29

* Bug fix for handling Histogram with empty buckets.
([#2651](https://github.com/open-telemetry/opentelemetry-dotnet/issues/2651))
([#2651](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2651))

## 1.2.0-beta2

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ internal sealed class PrometheusCollectionManager
private int metricsCacheCount;
private byte[] plainTextBuffer = new byte[85000]; // encourage the object to live in LOH (large object heap)
private byte[] openMetricsBuffer = new byte[85000]; // encourage the object to live in LOH (large object heap)
private int targetInfoBufferLength = -1; // zero or positive when target_info has been written for the first time
private int plainTextTargetInfoBufferLength = -1;
private int openMetricsTargetInfoBufferLength = -1;
private ArraySegment<byte> previousPlainTextDataView;
private ArraySegment<byte> previousOpenMetricsDataView;
private int globalLockState;
Expand Down Expand Up @@ -237,11 +238,12 @@ private ExportResult OnCollect(in Batch<Metric> metrics)

try
{
cursor = this.WriteTargetInfo(ref buffer);

if (this.exporter.OpenMetricsRequested)
{
cursor = this.WriteTargetInfo(ref buffer);

this.scopes.Clear();
var scopeInfoMetadataWritten = false;

foreach (var metric in metrics)
{
Expand All @@ -250,13 +252,19 @@ private ExportResult OnCollect(in Batch<Metric> metrics)
continue;
}

if (this.scopes.Add(metric.MeterName))
if (this.scopes.Add(PrometheusSerializer.CreateScopeIdentity(metric)))
{
while (true)
{
try
{
cursor = PrometheusSerializer.WriteScopeInfo(buffer, cursor, metric.MeterName, openMetricsRequested: true);
if (!scopeInfoMetadataWritten)
{
cursor = PrometheusSerializer.WriteScopeInfoMetadata(buffer, cursor);
scopeInfoMetadataWritten = true;
}

cursor = PrometheusSerializer.WriteScopeInfoMetric(buffer, cursor, metric);

break;
}
Expand Down Expand Up @@ -292,11 +300,11 @@ private ExportResult OnCollect(in Batch<Metric> metrics)
metricState.Metric,
metricState.PrometheusMetric,
this.exporter.OpenMetricsRequested,
metricState.WriteType,
metricState.WriteUnit,
metricState.WriteHelp,
metricState.Unit,
metricState.Help);
writeType: metricState.WriteType,
writeUnit: metricState.WriteUnit,
writeHelp: metricState.WriteHelp,
unitOverride: metricState.Unit,
helpOverride: metricState.Help);

break;
}
Expand Down Expand Up @@ -356,13 +364,18 @@ private ExportResult OnCollect(in Batch<Metric> metrics)

private int WriteTargetInfo(ref byte[] buffer)
{
if (this.targetInfoBufferLength < 0)
ref var targetInfoBufferLength = ref this.exporter.OpenMetricsRequested
? ref this.openMetricsTargetInfoBufferLength
: ref this.plainTextTargetInfoBufferLength;

if (targetInfoBufferLength < 0)
{
while (true)
{
try
{
this.targetInfoBufferLength = PrometheusSerializer.WriteTargetInfo(buffer, 0, this.exporter.Resource, openMetricsRequested: true);
targetInfoBufferLength = PrometheusSerializer.WriteTargetInfo(buffer, 0, this.exporter.Resource, this.exporter.OpenMetricsRequested);
targetInfoBufferLength = PrometheusSerializer.WriteTargetInfo(buffer, 0, this.exporter.Resource, this.exporter.OpenMetricsRequested);

break;
}
Expand All @@ -376,7 +389,7 @@ private int WriteTargetInfo(ref byte[] buffer)
}
}

return this.targetInfoBufferLength;
return targetInfoBufferLength;
}

private PrometheusMetric GetPrometheusMetric(Metric metric)
Expand Down
Loading
Loading