Skip to content
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

[Geneva.Metrics] Add option to disable name validation #1006

Merged
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.Drop = 0 -> OpenTelemetry
OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.ExportAsString = 1 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode
OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.get -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode
OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.set -> void
OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.DisableMetricNameValidation.get -> bool
OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.DisableMetricNameValidation.set -> void
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.Drop = 0 -> OpenTelemetry
OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.ExportAsString = 1 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode
OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.get -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode
OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.set -> void
OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.DisableMetricNameValidation.get -> bool
OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.DisableMetricNameValidation.set -> void
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.Drop = 0 -> OpenTelemetry
OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.ExportAsString = 1 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode
OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.get -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode
OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.set -> void
OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.DisableMetricNameValidation.get -> bool
OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.DisableMetricNameValidation.set -> void
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using OpenTelemetry.Internal;
using OpenTelemetry.Metrics;

Expand Down Expand Up @@ -108,6 +110,11 @@ public GenevaMetricExporter(GenevaMetricExporterOptions options)
{
this.fixedPayloadStartIndex = sizeof(BinaryHeader);
}

if (options.DisableMetricNameValidation)
{
DisableOpenTelemetrySdkMetricNameValidation();
}
}

public override ExportResult Export(in Batch<Metric> batch)
Expand Down Expand Up @@ -258,6 +265,22 @@ protected override void Dispose(bool disposing)
base.Dispose(disposing);
}

internal static PropertyInfo GetOpenTelemetryInstrumentNameRegexProperty()
{
var meterProviderBuilderSdkType = typeof(Sdk).Assembly.GetType("OpenTelemetry.Metrics.MeterProviderBuilderSdk", throwOnError: false)
?? throw new InvalidOperationException("OpenTelemetry.Metrics.MeterProviderBuilderSdk type could not be found reflectively.");

var instrumentNameRegexProperty = meterProviderBuilderSdkType.GetProperty("InstrumentNameRegex", BindingFlags.Public | BindingFlags.Static)
?? throw new InvalidOperationException("OpenTelemetry.Metrics.MeterProviderBuilderSdk.InstrumentNameRegex property could not be found reflectively.");

return instrumentNameRegexProperty;
}

internal static void DisableOpenTelemetrySdkMetricNameValidation()
{
GetOpenTelemetryInstrumentNameRegexProperty().SetValue(null, new Regex(".*", RegexOptions.Compiled));
}

internal unsafe ushort SerializeMetric(
MetricEventType eventType,
string metricName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,11 @@ public IReadOnlyDictionary<string, object> PrepopulatedMetricDimensions
this._prepopulatedMetricDimensions = copy;
}
}

/// <summary>
/// Gets or sets a value indicating whether or not OpenTelemetry SDK metric
/// name validation should be disabled. Default value: <see
/// langword="false"/>.
/// </summary>
public bool DisableMetricNameValidation { get; set; }
CodeBlanch marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,56 @@ public void SuccessfulExportOnLinux()
}
}

[Theory]
[InlineData(true)]
[InlineData(false)]
public void DisableMetricNameValidationTest(bool disableMetricNameValidation)
{
var instrumentNameRegexProperty = GenevaMetricExporter.GetOpenTelemetryInstrumentNameRegexProperty();
var initialInstrumentNameRegexValue = instrumentNameRegexProperty.GetValue(null);
try
{
var exportedMetrics = new List<Metric>();

using var meter = new Meter(Guid.NewGuid().ToString());

using (var provider = Sdk.CreateMeterProviderBuilder()
.AddMeter(meter.Name)
.AddGenevaMetricExporter(options =>
{
options.DisableMetricNameValidation = disableMetricNameValidation;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
options.ConnectionString = "Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace";
}
else
{
var path = GenerateTempFilePath();
options.ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace";
}
})
.AddInMemoryExporter(exportedMetrics)
.Build())
{
var counter = meter.CreateCounter<int>("count/invalid");
counter.Add(1);
}

if (disableMetricNameValidation)
{
Assert.Single(exportedMetrics);
}
else
{
Assert.Empty(exportedMetrics);
}
}
finally
{
instrumentNameRegexProperty.SetValue(null, initialInstrumentNameRegexValue);
}
}

private static string GenerateTempFilePath()
{
while (true)
Expand Down