Skip to content

Commit

Permalink
Add tests and ability to disable scope info
Browse files Browse the repository at this point in the history
  • Loading branch information
robertcoltheart committed Dec 7, 2023
1 parent 6753ad9 commit d452ab2
Show file tree
Hide file tree
Showing 14 changed files with 237 additions and 55 deletions.
2 changes: 1 addition & 1 deletion examples/AspNetCore/Instrumentation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public Instrumentation()
string? version = typeof(Instrumentation).Assembly.GetName().Version?.ToString();
this.ActivitySource = new ActivitySource(ActivitySourceName, version);
this.meter = new Meter(MeterName, version);
this.FreezingDaysCounter = this.meter.CreateCounter<long>("weather.days.freezing", "The number of days where the temperature is below freezing");
this.FreezingDaysCounter = this.meter.CreateCounter<long>("weather.days.freezing", description: "The number of days where the temperature is below freezing");
}

public ActivitySource ActivitySource { get; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ Microsoft.AspNetCore.Builder.PrometheusExporterApplicationBuilderExtensions
Microsoft.AspNetCore.Builder.PrometheusExporterEndpointRouteBuilderExtensions
OpenTelemetry.Exporter.PrometheusAspNetCoreOptions
OpenTelemetry.Exporter.PrometheusAspNetCoreOptions.PrometheusAspNetCoreOptions() -> void
OpenTelemetry.Exporter.PrometheusAspNetCoreOptions.ScopeInfoEnabled.get -> bool
OpenTelemetry.Exporter.PrometheusAspNetCoreOptions.ScopeInfoEnabled.set -> void
OpenTelemetry.Exporter.PrometheusAspNetCoreOptions.ScrapeEndpointPath.get -> string
OpenTelemetry.Exporter.PrometheusAspNetCoreOptions.ScrapeEndpointPath.set -> void
OpenTelemetry.Exporter.PrometheusAspNetCoreOptions.ScrapeResponseCacheDurationMilliseconds.get -> int
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,14 @@ public int ScrapeResponseCacheDurationMilliseconds
set => this.ExporterOptions.ScrapeResponseCacheDurationMilliseconds = value;
}

/// <summary>
/// Gets or sets a value indicating whether to export scope info. Default value: true.
/// </summary>
public bool ScopeInfoEnabled
{
get => this.ExporterOptions.ScopeInfoEnabled;
set => this.ExporterOptions.ScopeInfoEnabled = value;
}

internal PrometheusExporterOptions ExporterOptions { get; } = new();
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
OpenTelemetry.Exporter.PrometheusHttpListenerOptions
OpenTelemetry.Exporter.PrometheusHttpListenerOptions.ScopeInfoEnabled.get -> bool
OpenTelemetry.Exporter.PrometheusHttpListenerOptions.ScopeInfoEnabled.set -> void
OpenTelemetry.Exporter.PrometheusHttpListenerOptions.UriPrefixes.get -> System.Collections.Generic.IReadOnlyCollection<string>
OpenTelemetry.Exporter.PrometheusHttpListenerOptions.UriPrefixes.set -> void
OpenTelemetry.Exporter.PrometheusHttpListenerOptions.PrometheusHttpListenerOptions() -> void
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ private ExportResult OnCollect(Batch<Metric> metrics)

try
{
if (this.exporter.OpenMetricsRequested)
if (this.exporter.ScopeInfoEnabled && this.exporter.OpenMetricsRequested)
{
this.scopes.Clear();

Expand Down Expand Up @@ -237,7 +237,8 @@ private ExportResult OnCollect(Batch<Metric> metrics)
cursor,
metric,
this.GetPrometheusMetric(metric),
this.exporter.OpenMetricsRequested);
this.exporter.OpenMetricsRequested,
this.exporter.ScopeInfoEnabled);

break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public PrometheusExporter(PrometheusExporterOptions options)
Guard.ThrowIfNull(options);

this.ScrapeResponseCacheDurationMilliseconds = options.ScrapeResponseCacheDurationMilliseconds;
this.ScopeInfoEnabled = options.ScopeInfoEnabled;

this.CollectionManager = new PrometheusCollectionManager(this);
}
Expand Down Expand Up @@ -65,6 +66,8 @@ public PrometheusExporter(PrometheusExporterOptions options)

internal bool OpenMetricsRequested { get; set; }

internal bool ScopeInfoEnabled { get; set; }

/// <inheritdoc/>
public override ExportResult Export(in Batch<Metric> metrics)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,9 @@ public int ScrapeResponseCacheDurationMilliseconds
this.scrapeResponseCacheDurationMilliseconds = value;
}
}

/// <summary>
/// Gets or sets a value indicating whether to export scope info. Default value: true.
/// </summary>
public bool ScopeInfoEnabled { get; set; } = true;
}
Original file line number Diff line number Diff line change
Expand Up @@ -379,16 +379,16 @@ public static int WriteTimestamp(byte[] buffer, int cursor, long value, bool use
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int WriteTags(byte[] buffer, int cursor, Metric metric, ReadOnlyTagCollection tags, bool openMetricsRequested, bool writeEnclosingBraces = true)
public static int WriteTags(byte[] buffer, int cursor, Metric metric, ReadOnlyTagCollection tags, bool scopeInfoEnabled, bool writeEnclosingBraces = true)
{
if (tags.Count > 0 || openMetricsRequested)
if (tags.Count > 0 || scopeInfoEnabled)
{
if (writeEnclosingBraces)
{
buffer[cursor++] = unchecked((byte)'{');
}

if (openMetricsRequested)
if (scopeInfoEnabled)
{
cursor = WriteLabel(buffer, cursor, "otel_scope_name", metric.MeterName);
buffer[cursor++] = unchecked((byte)',');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public static bool CanWriteMetric(Metric metric)
return true;
}

public static int WriteMetric(byte[] buffer, int cursor, Metric metric, PrometheusMetric prometheusMetric, bool openMetricsRequested = false)
public static int WriteMetric(byte[] buffer, int cursor, Metric metric, PrometheusMetric prometheusMetric, bool openMetricsRequested = false, bool scopeInfoEnabled = true)
{
cursor = WriteTypeMetadata(buffer, cursor, prometheusMetric);
cursor = WriteUnitMetadata(buffer, cursor, prometheusMetric);
Expand All @@ -49,7 +49,7 @@ public static int WriteMetric(byte[] buffer, int cursor, Metric metric, Promethe

// Counter and Gauge
cursor = WriteMetricName(buffer, cursor, prometheusMetric);
cursor = WriteTags(buffer, cursor, metric, metricPoint.Tags, openMetricsRequested);
cursor = WriteTags(buffer, cursor, metric, metricPoint.Tags, scopeInfoEnabled);

buffer[cursor++] = unchecked((byte)' ');

Expand Down Expand Up @@ -100,7 +100,7 @@ public static int WriteMetric(byte[] buffer, int cursor, Metric metric, Promethe

cursor = WriteMetricName(buffer, cursor, prometheusMetric);
cursor = WriteAsciiStringNoEscape(buffer, cursor, "_bucket{");
cursor = WriteTags(buffer, cursor, metric, tags, openMetricsRequested, writeEnclosingBraces: false);
cursor = WriteTags(buffer, cursor, metric, tags, scopeInfoEnabled, writeEnclosingBraces: false);

cursor = WriteAsciiStringNoEscape(buffer, cursor, "le=\"");

Expand All @@ -126,7 +126,7 @@ public static int WriteMetric(byte[] buffer, int cursor, Metric metric, Promethe
// Histogram sum
cursor = WriteMetricName(buffer, cursor, prometheusMetric);
cursor = WriteAsciiStringNoEscape(buffer, cursor, "_sum");
cursor = WriteTags(buffer, cursor, metric, metricPoint.Tags, openMetricsRequested);
cursor = WriteTags(buffer, cursor, metric, metricPoint.Tags, scopeInfoEnabled);

buffer[cursor++] = unchecked((byte)' ');

Expand All @@ -140,7 +140,7 @@ public static int WriteMetric(byte[] buffer, int cursor, Metric metric, Promethe
// Histogram count
cursor = WriteMetricName(buffer, cursor, prometheusMetric);
cursor = WriteAsciiStringNoEscape(buffer, cursor, "_count");
cursor = WriteTags(buffer, cursor, metric, metricPoint.Tags, openMetricsRequested);
cursor = WriteTags(buffer, cursor, metric, metricPoint.Tags, scopeInfoEnabled);

buffer[cursor++] = unchecked((byte)' ');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,11 @@ public static MeterProviderBuilder AddPrometheusHttpListener(this MeterProviderB
private static MetricReader BuildPrometheusHttpListenerMetricReader(
PrometheusHttpListenerOptions options)
{
var exporter = new PrometheusExporter(new PrometheusExporterOptions { ScrapeResponseCacheDurationMilliseconds = 0 });
var exporter = new PrometheusExporter(new PrometheusExporterOptions
{
ScrapeResponseCacheDurationMilliseconds = 0,
ScopeInfoEnabled = options.ScopeInfoEnabled,
});

var reader = new BaseExportingMetricReader(exporter)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ public class PrometheusHttpListenerOptions
public string ScrapeEndpointPath { get; set; } = "/metrics";

/// <summary>
/// Gets or sets a value indicating whether to export OpenMetrics compatible scrape responses. Default value: true.
/// Gets or sets a value indicating whether to export scope info. Default value: true.
/// </summary>
public bool OpenMetricsEnabled { get; set; } = true;
public bool ScopeInfoEnabled { get; set; } = true;

/// <summary>
/// Gets or sets the URI (Uniform Resource Identifier) prefixes to use for the http listener.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ namespace OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests;

public sealed class PrometheusExporterMiddlewareTests
{
private const string MeterVersion = "1.0.1";

private static readonly string MeterName = Utils.GetCurrentMethodName();

[Fact]
Expand Down Expand Up @@ -247,6 +249,16 @@ public Task PrometheusExporterMiddlewareIntegration_TextPlainResponse()
acceptHeader: "text/plain");
}

[Fact]
public Task PrometheusExporterMiddlewareIntegration_TextPlainResponse_NoScopeInfo()
{
return RunPrometheusExporterMiddlewareIntegrationTest(
"/metrics",
app => app.UseOpenTelemetryPrometheusScrapingEndpoint(),
acceptHeader: "text/plain",
scopeInfoEnabled: false);
}

[Fact]
public Task PrometheusExporterMiddlewareIntegration_UseOpenMetricsVersionHeader()
{
Expand All @@ -256,6 +268,15 @@ public Task PrometheusExporterMiddlewareIntegration_UseOpenMetricsVersionHeader(
acceptHeader: "application/openmetrics-text; version=1.0.0");
}

[Fact]
public Task PrometheusExporterMiddlewareIntegration_NoScopeInfo()
{
return RunPrometheusExporterMiddlewareIntegrationTest(
"/metrics",
app => app.UseOpenTelemetryPrometheusScrapingEndpoint(),
scopeInfoEnabled: false);
}

private static async Task RunPrometheusExporterMiddlewareIntegrationTest(
string path,
Action<IApplicationBuilder> configure,
Expand All @@ -264,7 +285,8 @@ public Task PrometheusExporterMiddlewareIntegration_UseOpenMetricsVersionHeader(
bool registerMeterProvider = true,
Action<PrometheusAspNetCoreOptions> configureOptions = null,
bool skipMetrics = false,
string acceptHeader = "application/openmetrics-text")
string acceptHeader = "application/openmetrics-text",
bool scopeInfoEnabled = true)
{
var requestOpenMetrics = acceptHeader.StartsWith("application/openmetrics-text");

Expand All @@ -279,6 +301,7 @@ public Task PrometheusExporterMiddlewareIntegration_UseOpenMetricsVersionHeader(
.AddMeter(MeterName)
.AddPrometheusExporter(o =>
{
o.ScopeInfoEnabled = scopeInfoEnabled;
configureOptions?.Invoke(o);
}));
}
Expand All @@ -294,7 +317,7 @@ public Task PrometheusExporterMiddlewareIntegration_UseOpenMetricsVersionHeader(
new KeyValuePair<string, object>("key2", "value2"),
};

using var meter = new Meter(MeterName);
using var meter = new Meter(MeterName, MeterVersion);

var beginTimestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds();

Expand Down Expand Up @@ -331,14 +354,7 @@ public Task PrometheusExporterMiddlewareIntegration_UseOpenMetricsVersionHeader(
}

string content = await response.Content.ReadAsStringAsync();

string expected = requestOpenMetrics
? "# TYPE counter_double_total counter\n"
+ "counter_double_total{key1='value1',key2='value2'} 101.17 (\\d+\\.\\d{3})\n"
+ "# EOF\n"
: "# TYPE counter_double_total counter\n"
+ "counter_double_total{key1='value1',key2='value2'} 101.17 (\\d+)\n"
+ "# EOF\n";
string expected = GetExpectedContent(requestOpenMetrics, scopeInfoEnabled);

var matches = Regex.Matches(content, ("^" + expected + "$").Replace('\'', '"'));

Expand All @@ -357,5 +373,36 @@ public Task PrometheusExporterMiddlewareIntegration_UseOpenMetricsVersionHeader(

await host.StopAsync();
}

private static string GetExpectedContent(bool requestedOpenMetrics, bool scopeInfoEnabled)
{
if (requestedOpenMetrics && scopeInfoEnabled)
{
return "# TYPE otel_scope_info info\n"
+ "# HELP otel_scope_info Scope metadata\n"
+ $"otel_scope_info{{otel_scope_name='{MeterName}'}} 1\n"
+ "# TYPE counter_double_total counter\n"
+ $"counter_double_total{{otel_scope_name='{MeterName}',otel_scope_version='{MeterVersion}',key1='value1',key2='value2'}} 101.17 (\\d+\\.\\d{{3}})\n"
+ "# EOF\n";
}

if (!requestedOpenMetrics && scopeInfoEnabled)
{
return "# TYPE counter_double_total counter\n"
+ $"counter_double_total{{otel_scope_name='{MeterName}',otel_scope_version='{MeterVersion}',key1='value1',key2='value2'}} 101.17 (\\d+)\n"
+ "# EOF\n";
}

if (requestedOpenMetrics && !scopeInfoEnabled)
{
return "# TYPE counter_double_total counter\n"
+ "counter_double_total{key1='value1',key2='value2'} 101.17 (\\d+\\.\\d{3})\n"
+ "# EOF\n";
}

return "# TYPE counter_double_total counter\n"
+ "counter_double_total{key1='value1',key2='value2'} 101.17 (\\d+)\n"
+ "# EOF\n";
}
}
#endif
Loading

0 comments on commit d452ab2

Please sign in to comment.