Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main' into di-configuretracing…
Browse files Browse the repository at this point in the history
…-withservices
  • Loading branch information
CodeBlanch committed May 25, 2023
2 parents a022ff6 + eb12f9b commit 26d2131
Show file tree
Hide file tree
Showing 8 changed files with 160 additions and 5 deletions.
66 changes: 66 additions & 0 deletions src/OpenTelemetry.Api/Internal/HttpSemanticConventionHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// <copyright file="HttpSemanticConventionHelper.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>

namespace OpenTelemetry.Internal;

/// <summary>
/// Helper class for Http Semantic Conventions.
/// </summary>
/// <remarks>
/// Due to a breaking change in the semantic convention, affected instrumentation libraries
/// must inspect an environment variable to determine which attributes to emit.
/// This is expected to be removed when the instrumentation libraries reach Stable.
/// <see href="https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md"/>.
/// </remarks>
internal static class HttpSemanticConventionHelper
{
[Flags]
internal enum HttpSemanticConvention
{
/// <summary>
/// Instructs an instrumentation library to emit the old experimental HTTP attributes.
/// </summary>
Old = 0x1,

/// <summary>
/// Instructs an instrumentation library to emit the new, stable Http attributes.
/// </summary>
New = 0x2,

/// <summary>
/// Instructs an instrumentation library to emit both the old and new attributes.
/// </summary>
Dupe = Old | New,
}

public static HttpSemanticConvention GetSemanticConventionOptIn()
{
try
{
var envVarValue = Environment.GetEnvironmentVariable("OTEL_SEMCONV_STABILITY_OPT_IN");
return envVarValue?.ToLowerInvariant() switch
{
"http" => HttpSemanticConvention.New,
"http/dup" => HttpSemanticConvention.Dupe,
_ => HttpSemanticConvention.Old,
};
}
catch
{
return HttpSemanticConvention.Old;
}
}
}
17 changes: 15 additions & 2 deletions src/OpenTelemetry.Exporter.Console/ConsoleMetricExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,21 @@ public override ExportResult Export(in Batch<Metric> batch)
}
else
{
// TODO: Consider how/if to display buckets for exponential histograms.
bucketsBuilder.AppendLine("Buckets are not displayed for exponential histograms.");
var exponentialHistogramData = metricPoint.GetExponentialHistogramData();
var scale = exponentialHistogramData.Scale;

if (exponentialHistogramData.ZeroCount != 0)
{
bucketsBuilder.AppendLine($"Zero Bucket:{exponentialHistogramData.ZeroCount}");
}

var offset = exponentialHistogramData.PositiveBuckets.Offset;
foreach (var bucketCount in exponentialHistogramData.PositiveBuckets)
{
var lowerBound = Base2ExponentialBucketHistogram.LowerBoundary(offset, scale).ToString(CultureInfo.InvariantCulture);
var upperBound = Base2ExponentialBucketHistogram.LowerBoundary(++offset, scale).ToString(CultureInfo.InvariantCulture);
bucketsBuilder.AppendLine($"({lowerBound}, {upperBound}]:{bucketCount}");
}
}

valueDisplay = bucketsBuilder.ToString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\OpenTelemetrySdkEventSource.cs" Link="Includes\OpenTelemetrySdkEventSource.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\PeriodicExportingMetricReaderHelper.cs" Link="Includes\PeriodicExportingMetricReaderHelper.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\TagTransformer.cs" Link="Includes\TagTransformer.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Metrics\Base2ExponentialBucketHistogram.LowerBoundary.cs" Link="Includes\Base2ExponentialBucketHistogram.LowerBoundary.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Api\Internal\ExceptionExtensions.cs" Link="Includes\ExceptionExtensions.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Api\Internal\Guard.cs" Link="Includes\Guard.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Api\Internal\SpanAttributeConstants.cs" Link="Includes\SpanAttributeConstants.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#endif
using OpenTelemetry.Internal;
using OpenTelemetry.Trace;
using static OpenTelemetry.Internal.HttpSemanticConventionHelper;

namespace OpenTelemetry.Instrumentation.AspNetCore.Implementation
{
Expand Down Expand Up @@ -62,13 +63,16 @@ internal class HttpInListener : ListenerHandler
#endif
private readonly PropertyFetcher<Exception> stopExceptionFetcher = new("Exception");
private readonly AspNetCoreInstrumentationOptions options;
private readonly HttpSemanticConvention httpSemanticConvention;

public HttpInListener(AspNetCoreInstrumentationOptions options)
: base(DiagnosticSourceName)
{
Guard.ThrowIfNull(options);

this.options = options;

this.httpSemanticConvention = GetSemanticConventionOptIn();
}

public override void OnEventWritten(string name, object payload)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Instrumentation.GrpcNetClient\GrpcTagHelper.cs" Link="Includes\GrpcTagHelper.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Instrumentation.GrpcNetClient\StatusCanonicalCode.cs" Link="Includes\StatusCanonicalCode.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Api\Internal\Guard.cs" Link="Includes\Guard.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Api\Internal\HttpSemanticConventionHelper.cs" Link="Includes\HttpSemanticConventionHelper.cs" />
</ItemGroup>

<ItemGroup>
Expand Down
7 changes: 5 additions & 2 deletions src/OpenTelemetry/Internal/ActivityInstrumentationHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

using System.Diagnostics;
using System.Linq.Expressions;
using System.Reflection;
#pragma warning restore IDE0005

namespace OpenTelemetry.Instrumentation
Expand All @@ -29,15 +30,17 @@ private static Action<Activity, ActivitySource> CreateActivitySourceSetter()
{
ParameterExpression instance = Expression.Parameter(typeof(Activity), "instance");
ParameterExpression propertyValue = Expression.Parameter(typeof(ActivitySource), "propertyValue");
var body = Expression.Assign(Expression.Property(instance, "Source"), propertyValue);
PropertyInfo sourcePropertyInfo = typeof(Activity).GetProperty("Source");
var body = Expression.Assign(Expression.Property(instance, sourcePropertyInfo), propertyValue);
return Expression.Lambda<Action<Activity, ActivitySource>>(body, instance, propertyValue).Compile();
}

private static Action<Activity, ActivityKind> CreateActivityKindSetter()
{
ParameterExpression instance = Expression.Parameter(typeof(Activity), "instance");
ParameterExpression propertyValue = Expression.Parameter(typeof(ActivityKind), "propertyValue");
var body = Expression.Assign(Expression.Property(instance, "Kind"), propertyValue);
PropertyInfo kindPropertyInfo = typeof(Activity).GetProperty("Kind");
var body = Expression.Assign(Expression.Property(instance, kindPropertyInfo), propertyValue);
return Expression.Lambda<Action<Activity, ActivityKind>>(body, instance, propertyValue).Compile();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public void EnsureAotCompatibility()
Assert.True(process.ExitCode == 0, "Publishing the AotCompatibility app failed. See test output for more details.");

var warnings = expectedOutput.ToString().Split('\n', '\r').Where(line => line.Contains("warning IL"));
Assert.Equal(58, warnings.Count());
Assert.Equal(48, warnings.Count());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// <copyright file="HttpSemanticConventionHelperTest.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>

using Xunit;
using static OpenTelemetry.Internal.HttpSemanticConventionHelper;

namespace OpenTelemetry.Api.Tests.Internal;

public class HttpSemanticConventionHelperTest
{
[Fact]
public void VerifyFlags()
{
var testValue = HttpSemanticConvention.Dupe;
Assert.True(testValue.HasFlag(HttpSemanticConvention.Old));
Assert.True(testValue.HasFlag(HttpSemanticConvention.New));

testValue = HttpSemanticConvention.Old;
Assert.True(testValue.HasFlag(HttpSemanticConvention.Old));
Assert.False(testValue.HasFlag(HttpSemanticConvention.New));

testValue = HttpSemanticConvention.New;
Assert.False(testValue.HasFlag(HttpSemanticConvention.Old));
Assert.True(testValue.HasFlag(HttpSemanticConvention.New));
}

[Fact]
public void VerifyGetSemanticConventionOptIn()
{
this.RunTestWithEnvironmentVariable(null, HttpSemanticConvention.Old);
this.RunTestWithEnvironmentVariable(string.Empty, HttpSemanticConvention.Old);
this.RunTestWithEnvironmentVariable("junk", HttpSemanticConvention.Old);
this.RunTestWithEnvironmentVariable("none", HttpSemanticConvention.Old);
this.RunTestWithEnvironmentVariable("NONE", HttpSemanticConvention.Old);
this.RunTestWithEnvironmentVariable("http", HttpSemanticConvention.New);
this.RunTestWithEnvironmentVariable("HTTP", HttpSemanticConvention.New);
this.RunTestWithEnvironmentVariable("http/dup", HttpSemanticConvention.Dupe);
this.RunTestWithEnvironmentVariable("HTTP/DUP", HttpSemanticConvention.Dupe);
}

private void RunTestWithEnvironmentVariable(string value, HttpSemanticConvention expected)
{
try
{
Environment.SetEnvironmentVariable("OTEL_SEMCONV_STABILITY_OPT_IN", value);

Assert.Equal(expected, GetSemanticConventionOptIn());
}
finally
{
Environment.SetEnvironmentVariable("OTEL_SEMCONV_STABILITY_OPT_IN", null);
}
}
}

0 comments on commit 26d2131

Please sign in to comment.