Skip to content

Commit

Permalink
add asp.net core instrumentation
Browse files Browse the repository at this point in the history
  • Loading branch information
cijothomas committed Jun 2, 2020
1 parent 5b836a4 commit f1e5108
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 106 deletions.
3 changes: 1 addition & 2 deletions samples/Exporters/Web/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public void ConfigureServices(IServiceCollection services)
});

OpenTelemetrySdk.EnableOpenTelemetry(
(builder) => builder.AddActivitySource(string.Empty)
(builder) => builder.AddRequestInstrumentation()
.UseConsoleActivityExporter(opt => opt.DisplayAsJson = opt.DisplayAsJson));

services.AddOpenTelemetry((sp, builder) =>
Expand All @@ -50,7 +50,6 @@ public void ConfigureServices(IServiceCollection services)
options.ServiceName = "test-zipkin";
options.Endpoint = new Uri(this.Configuration.GetValue<string>("Zipkin:Endpoint"));
})
.AddRequestInstrumentation()
.AddDependencyInstrumentation();
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
// </copyright>
using System;
using OpenTelemetry.Instrumentation.AspNetCore.Implementation;
using OpenTelemetry.Trace;

namespace OpenTelemetry.Instrumentation.AspNetCore
{
Expand All @@ -29,20 +28,18 @@ public class AspNetCoreInstrumentation : IDisposable
/// <summary>
/// Initializes a new instance of the <see cref="AspNetCoreInstrumentation"/> class.
/// </summary>
/// <param name="tracer">Tracer to record traced with.</param>
public AspNetCoreInstrumentation(Tracer tracer)
: this(tracer, new AspNetCoreInstrumentationOptions())
public AspNetCoreInstrumentation()
: this(new AspNetCoreInstrumentationOptions())
{
}

/// <summary>
/// Initializes a new instance of the <see cref="AspNetCoreInstrumentation"/> class.
/// </summary>
/// <param name="tracer">Tracer to record traced with.</param>
/// <param name="options">Configuration options for ASP.NET Core instrumentation.</param>
public AspNetCoreInstrumentation(Tracer tracer, AspNetCoreInstrumentationOptions options)
public AspNetCoreInstrumentation(AspNetCoreInstrumentationOptions options)
{
this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber(new HttpInListener("Microsoft.AspNetCore", tracer, options), null);
this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber(new HttpInListener("Microsoft.AspNetCore", options), null);
this.diagnosticSourceSubscriber.Subscribe();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ internal class HttpInListener : ListenerHandler
private readonly bool hostingSupportsW3C = false;
private readonly AspNetCoreInstrumentationOptions options;

public HttpInListener(string name, Tracer tracer, AspNetCoreInstrumentationOptions options)
: base(name, tracer)
public HttpInListener(string name, AspNetCoreInstrumentationOptions options)
: base(name, null)
{
this.hostingSupportsW3C = typeof(HttpRequest).Assembly.GetName().Version.Major >= 3;
this.options = options ?? throw new ArgumentNullException(nameof(options));
Expand Down Expand Up @@ -70,7 +70,7 @@ public override void OnStartActivity(Activity activity, object payload)
{
// This requires to ignore the current activity and create a new one
// using the context extracted from w3ctraceprent header or
// using whatever the TextFormat offers.
// using the format TextFormat supports.
// TODO: actually implement code doing the above.

/*
Expand Down Expand Up @@ -109,15 +109,8 @@ public override void OnStartActivity(Activity activity, object payload)
public override void OnStopActivity(Activity activity, object payload)
{
const string EventNameSuffix = ".OnStopActivity";
var span = this.Tracer.CurrentSpan;

if (span == null || !span.Context.IsValid)
{
InstrumentationEventSource.Log.NullOrBlankSpan(nameof(HttpInListener) + EventNameSuffix);
return;
}

if (span.IsRecording)
if (activity.IsAllDataRequested)
{
if (!(this.stopContextFetcher.Fetch(payload) is HttpContext context))
{
Expand All @@ -126,31 +119,19 @@ public override void OnStopActivity(Activity activity, object payload)
}

var response = context.Response;
activity.AddTag(SpanAttributeConstants.HttpStatusCodeKey, response.StatusCode.ToString());

span.PutHttpStatusCode(response.StatusCode, response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase);

if (activity.IsAllDataRequested)
{
activity.AddTag("http.status_code", response.StatusCode.ToString());
}
Status status = SpanHelper.ResolveSpanStatusForHttpStatusCode((int)response.StatusCode);
activity.AddTag(SpanAttributeConstants.StatusCodeKey, SpanHelper.GetCachedCanonicalCodeString(status.CanonicalCode));
activity.AddTag(SpanAttributeConstants.StatusDescriptionKey, response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase);
}

span.End();
}

public override void OnCustom(string name, Activity activity, object payload)
{
if (name == "Microsoft.AspNetCore.Mvc.BeforeAction")
{
var span = this.Tracer.CurrentSpan;

if (span == null)
{
InstrumentationEventSource.Log.NullOrBlankSpan(name);
return;
}

if (span.IsRecording)
if (activity.IsAllDataRequested)
{
// See https://github.com/aspnet/Mvc/blob/2414db256f32a047770326d14d8b0e2afd49ba49/src/Microsoft.AspNetCore.Mvc.Core/MvcCoreDiagnosticSourceExtensions.cs#L36-L44
// Reflection accessing: ActionDescriptor.AttributeRouteInfo.Template
Expand All @@ -164,9 +145,8 @@ public override void OnCustom(string name, Activity activity, object payload)
if (!string.IsNullOrEmpty(template))
{
// override the span name that was previously set to the path part of URL.
span.UpdateName(template);

span.PutHttpRouteAttribute(template);
activity.DisplayName = template;
activity.AddTag(SpanAttributeConstants.HttpRouteKey, template);
}

// TODO: Should we get values from RouteData?
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// <copyright file="OpenTelemetryBuilderExtensions.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 System;
using OpenTelemetry.Instrumentation.AspNetCore;

namespace OpenTelemetry.Trace.Configuration
{
/// <summary>
/// Extension methods to simplify registering of asp.net core request instrumentation.
/// </summary>
public static class OpenTelemetryBuilderExtensions
{
/// <summary>
/// Enables the incoming requests automatic data collection for Asp.Net Core.
/// </summary>
/// <param name="builder"><see cref="OpenTelemetryBuilder"/> being configured.</param>
/// <param name="configureAspNetCoreInstrumentationOptions">ASP.NET Core Request configuration options.</param>
/// <returns>The instance of <see cref="OpenTelemetryBuilder"/> to chain the calls.</returns>
public static OpenTelemetryBuilder AddRequestInstrumentation(
this OpenTelemetryBuilder builder,
Action<AspNetCoreInstrumentationOptions> configureAspNetCoreInstrumentationOptions = null)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}

builder.AddActivitySource(string.Empty);
var aspnetCoreOptions = new AspNetCoreInstrumentationOptions();
configureAspNetCoreInstrumentationOptions?.Invoke(aspnetCoreOptions);

// TODO: decide who is responsible for dispose upon shutdown.
new AspNetCoreInstrumentation(aspnetCoreOptions);

return builder;
}
}
}

This file was deleted.

0 comments on commit f1e5108

Please sign in to comment.