Skip to content

Commit

Permalink
[Instrumenation.AspNet] File scoped namespace (open-telemetry#581)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kielek authored Aug 12, 2022
1 parent 097e25a commit d9e91a7
Show file tree
Hide file tree
Showing 20 changed files with 1,668 additions and 1,688 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -19,104 +19,103 @@
using System.Diagnostics.Tracing;
using OpenTelemetry.Internal;

namespace OpenTelemetry.Instrumentation.AspNet
namespace OpenTelemetry.Instrumentation.AspNet;

/// <summary>
/// ETW EventSource tracing class.
/// </summary>
[EventSource(Name = "OpenTelemetry-Instrumentation-AspNet-Telemetry", Guid = "1de158cc-f7ce-4293-bd19-2358c93c8186")]
internal sealed class AspNetTelemetryEventSource : EventSource
{
/// <summary>
/// ETW EventSource tracing class.
/// Instance of the PlatformEventSource class.
/// </summary>
[EventSource(Name = "OpenTelemetry-Instrumentation-AspNet-Telemetry", Guid = "1de158cc-f7ce-4293-bd19-2358c93c8186")]
internal sealed class AspNetTelemetryEventSource : EventSource
{
/// <summary>
/// Instance of the PlatformEventSource class.
/// </summary>
public static readonly AspNetTelemetryEventSource Log = new();
public static readonly AspNetTelemetryEventSource Log = new();

[NonEvent]
public void ActivityStarted(Activity activity)
[NonEvent]
public void ActivityStarted(Activity activity)
{
if (this.IsEnabled(EventLevel.Verbose, EventKeywords.All))
{
if (this.IsEnabled(EventLevel.Verbose, EventKeywords.All))
{
this.ActivityStarted(activity?.Id);
}
this.ActivityStarted(activity?.Id);
}
}

[NonEvent]
public void ActivityStopped(Activity activity)
[NonEvent]
public void ActivityStopped(Activity activity)
{
if (this.IsEnabled(EventLevel.Verbose, EventKeywords.All))
{
if (this.IsEnabled(EventLevel.Verbose, EventKeywords.All))
{
this.ActivityStopped(activity?.Id);
}
this.ActivityStopped(activity?.Id);
}
}

[NonEvent]
public void ActivityRestored(Activity activity)
[NonEvent]
public void ActivityRestored(Activity activity)
{
if (this.IsEnabled(EventLevel.Informational, EventKeywords.All))
{
if (this.IsEnabled(EventLevel.Informational, EventKeywords.All))
{
this.ActivityRestored(activity?.Id);
}
this.ActivityRestored(activity?.Id);
}
}

[NonEvent]
public void ActivityException(Activity activity, Exception ex)
[NonEvent]
public void ActivityException(Activity activity, Exception ex)
{
if (this.IsEnabled(EventLevel.Error, EventKeywords.All))
{
if (this.IsEnabled(EventLevel.Error, EventKeywords.All))
{
this.ActivityException(activity?.Id, ex.ToInvariantString());
}
this.ActivityException(activity?.Id, ex.ToInvariantString());
}
}

[NonEvent]
public void CallbackException(Activity activity, string eventName, Exception ex)
[NonEvent]
public void CallbackException(Activity activity, string eventName, Exception ex)
{
if (this.IsEnabled(EventLevel.Error, EventKeywords.All))
{
if (this.IsEnabled(EventLevel.Error, EventKeywords.All))
{
this.CallbackException(activity?.Id, eventName, ex.ToInvariantString());
}
this.CallbackException(activity?.Id, eventName, ex.ToInvariantString());
}
}

[Event(1, Message = "Callback='{0}'", Level = EventLevel.Verbose)]
public void TraceCallback(string callback)
{
this.WriteEvent(1, callback);
}
[Event(1, Message = "Callback='{0}'", Level = EventLevel.Verbose)]
public void TraceCallback(string callback)
{
this.WriteEvent(1, callback);
}

[Event(2, Message = "Activity started, Id='{0}'", Level = EventLevel.Verbose)]
public void ActivityStarted(string id)
{
this.WriteEvent(2, id);
}
[Event(2, Message = "Activity started, Id='{0}'", Level = EventLevel.Verbose)]
public void ActivityStarted(string id)
{
this.WriteEvent(2, id);
}

[Event(3, Message = "Activity stopped, Id='{0}'", Level = EventLevel.Verbose)]
public void ActivityStopped(string id)
{
this.WriteEvent(3, id);
}
[Event(3, Message = "Activity stopped, Id='{0}'", Level = EventLevel.Verbose)]
public void ActivityStopped(string id)
{
this.WriteEvent(3, id);
}

[Event(4, Message = "Activity restored, Id='{0}'", Level = EventLevel.Informational)]
public void ActivityRestored(string id)
{
this.WriteEvent(4, id);
}
[Event(4, Message = "Activity restored, Id='{0}'", Level = EventLevel.Informational)]
public void ActivityRestored(string id)
{
this.WriteEvent(4, id);
}

[Event(5, Message = "Failed to invoke OnExecuteRequestStep, Error='{0}'", Level = EventLevel.Error)]
public void OnExecuteRequestStepInvocationError(string error)
{
this.WriteEvent(5, error);
}
[Event(5, Message = "Failed to invoke OnExecuteRequestStep, Error='{0}'", Level = EventLevel.Error)]
public void OnExecuteRequestStepInvocationError(string error)
{
this.WriteEvent(5, error);
}

[Event(6, Message = "Activity exception, Id='{0}': {1}", Level = EventLevel.Error)]
public void ActivityException(string id, string ex)
{
this.WriteEvent(6, id, ex);
}
[Event(6, Message = "Activity exception, Id='{0}': {1}", Level = EventLevel.Error)]
public void ActivityException(string id, string ex)
{
this.WriteEvent(6, id, ex);
}

[Event(7, Message = "Callback exception, Id='{0}', Name='{1}': {2}", Level = EventLevel.Error)]
public void CallbackException(string id, string eventName, string ex)
{
this.WriteEvent(7, id, eventName, ex);
}
[Event(7, Message = "Callback exception, Id='{0}', Name='{1}': {2}", Level = EventLevel.Error)]
public void CallbackException(string id, string eventName, string ex)
{
this.WriteEvent(7, id, eventName, ex);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,129 +19,128 @@
using System.Reflection;
using System.Web;

namespace OpenTelemetry.Instrumentation.AspNet
namespace OpenTelemetry.Instrumentation.AspNet;

/// <summary>
/// Http Module sets ambient state using Activity API from DiagnosticsSource package.
/// </summary>
public class TelemetryHttpModule : IHttpModule
{
/// <summary>
/// Http Module sets ambient state using Activity API from DiagnosticsSource package.
/// OpenTelemetry.Instrumentation.AspNet <see cref="ActivitySource"/> name.
/// </summary>
public class TelemetryHttpModule : IHttpModule
{
/// <summary>
/// OpenTelemetry.Instrumentation.AspNet <see cref="ActivitySource"/> name.
/// </summary>
public const string AspNetSourceName = "OpenTelemetry.Instrumentation.AspNet.Telemetry";
public const string AspNetSourceName = "OpenTelemetry.Instrumentation.AspNet.Telemetry";

/// <summary>
/// <see cref="Activity.OperationName"/> for OpenTelemetry.Instrumentation.AspNet created <see cref="Activity"/> objects.
/// </summary>
public const string AspNetActivityName = "Microsoft.AspNet.HttpReqIn";
/// <summary>
/// <see cref="Activity.OperationName"/> for OpenTelemetry.Instrumentation.AspNet created <see cref="Activity"/> objects.
/// </summary>
public const string AspNetActivityName = "Microsoft.AspNet.HttpReqIn";

// ServerVariable set only on rewritten HttpContext by URL Rewrite module.
private const string URLRewriteRewrittenRequest = "IIS_WasUrlRewritten";
// ServerVariable set only on rewritten HttpContext by URL Rewrite module.
private const string URLRewriteRewrittenRequest = "IIS_WasUrlRewritten";

// ServerVariable set on every request if URL module is registered in HttpModule pipeline.
private const string URLRewriteModuleVersion = "IIS_UrlRewriteModule";
// ServerVariable set on every request if URL module is registered in HttpModule pipeline.
private const string URLRewriteModuleVersion = "IIS_UrlRewriteModule";

private static readonly MethodInfo OnExecuteRequestStepMethodInfo = typeof(HttpApplication).GetMethod("OnExecuteRequestStep");
private static readonly MethodInfo OnExecuteRequestStepMethodInfo = typeof(HttpApplication).GetMethod("OnExecuteRequestStep");

/// <summary>
/// Gets the <see cref="TelemetryHttpModuleOptions"/> applied to requests processed by the handler.
/// </summary>
public static TelemetryHttpModuleOptions Options { get; } = new TelemetryHttpModuleOptions();
/// <summary>
/// Gets the <see cref="TelemetryHttpModuleOptions"/> applied to requests processed by the handler.
/// </summary>
public static TelemetryHttpModuleOptions Options { get; } = new TelemetryHttpModuleOptions();

/// <inheritdoc />
public void Dispose()
{
}
/// <inheritdoc />
public void Dispose()
{
}

/// <inheritdoc />
public void Init(HttpApplication context)
{
context.BeginRequest += this.Application_BeginRequest;
context.EndRequest += this.Application_EndRequest;
context.Error += this.Application_Error;
/// <inheritdoc />
public void Init(HttpApplication context)
{
context.BeginRequest += this.Application_BeginRequest;
context.EndRequest += this.Application_EndRequest;
context.Error += this.Application_Error;

if (HttpRuntime.UsingIntegratedPipeline && OnExecuteRequestStepMethodInfo != null)
if (HttpRuntime.UsingIntegratedPipeline && OnExecuteRequestStepMethodInfo != null)
{
// OnExecuteRequestStep is availabile starting with 4.7.1
try
{
OnExecuteRequestStepMethodInfo.Invoke(context, new object[] { (Action<HttpContextBase, Action>)this.OnExecuteRequestStep });
}
catch (Exception e)
{
// OnExecuteRequestStep is availabile starting with 4.7.1
try
{
OnExecuteRequestStepMethodInfo.Invoke(context, new object[] { (Action<HttpContextBase, Action>)this.OnExecuteRequestStep });
}
catch (Exception e)
{
AspNetTelemetryEventSource.Log.OnExecuteRequestStepInvocationError(e.Message);
}
AspNetTelemetryEventSource.Log.OnExecuteRequestStepInvocationError(e.Message);
}
}
}

private void Application_BeginRequest(object sender, EventArgs e)
private void Application_BeginRequest(object sender, EventArgs e)
{
AspNetTelemetryEventSource.Log.TraceCallback("Application_BeginRequest");
ActivityHelper.StartAspNetActivity(Options.TextMapPropagator, ((HttpApplication)sender).Context, Options.OnRequestStartedCallback);
}

private void OnExecuteRequestStep(HttpContextBase context, Action step)
{
// Called only on 4.7.1+ runtimes

if (context.CurrentNotification == RequestNotification.ExecuteRequestHandler && !context.IsPostNotification)
{
AspNetTelemetryEventSource.Log.TraceCallback("Application_BeginRequest");
ActivityHelper.StartAspNetActivity(Options.TextMapPropagator, ((HttpApplication)sender).Context, Options.OnRequestStartedCallback);
ActivityHelper.RestoreContextIfNeeded(context.ApplicationInstance.Context);
}

private void OnExecuteRequestStep(HttpContextBase context, Action step)
{
// Called only on 4.7.1+ runtimes
step();
}

if (context.CurrentNotification == RequestNotification.ExecuteRequestHandler && !context.IsPostNotification)
{
ActivityHelper.RestoreContextIfNeeded(context.ApplicationInstance.Context);
}
private void Application_EndRequest(object sender, EventArgs e)
{
AspNetTelemetryEventSource.Log.TraceCallback("Application_EndRequest");
bool trackActivity = true;

step();
}
var context = ((HttpApplication)sender).Context;

private void Application_EndRequest(object sender, EventArgs e)
if (!ActivityHelper.HasStarted(context, out Activity aspNetActivity))
{
AspNetTelemetryEventSource.Log.TraceCallback("Application_EndRequest");
bool trackActivity = true;

var context = ((HttpApplication)sender).Context;

if (!ActivityHelper.HasStarted(context, out Activity aspNetActivity))
// Rewrite: In case of rewrite, a new request context is created, called the child request, and it goes through the entire IIS/ASP.NET integrated pipeline.
// The child request can be mapped to any of the handlers configured in IIS, and it's execution is no different than it would be if it was received via the HTTP stack.
// The parent request jumps ahead in the pipeline to the end request notification, and waits for the child request to complete.
// When the child request completes, the parent request executes the end request notifications and completes itself.
// Do not create activity for parent request. Parent request has IIS_UrlRewriteModule ServerVariable with success response code.
// Child request contains an additional ServerVariable named - IIS_WasUrlRewritten.
// Track failed response activity: Different modules in the pipeline has ability to end the response. For example, authentication module could set HTTP 401 in OnBeginRequest and end the response.
if (context.Request.ServerVariables != null && context.Request.ServerVariables[URLRewriteRewrittenRequest] == null && context.Request.ServerVariables[URLRewriteModuleVersion] != null && context.Response.StatusCode == 200)
{
// Rewrite: In case of rewrite, a new request context is created, called the child request, and it goes through the entire IIS/ASP.NET integrated pipeline.
// The child request can be mapped to any of the handlers configured in IIS, and it's execution is no different than it would be if it was received via the HTTP stack.
// The parent request jumps ahead in the pipeline to the end request notification, and waits for the child request to complete.
// When the child request completes, the parent request executes the end request notifications and completes itself.
// Do not create activity for parent request. Parent request has IIS_UrlRewriteModule ServerVariable with success response code.
// Child request contains an additional ServerVariable named - IIS_WasUrlRewritten.
// Track failed response activity: Different modules in the pipeline has ability to end the response. For example, authentication module could set HTTP 401 in OnBeginRequest and end the response.
if (context.Request.ServerVariables != null && context.Request.ServerVariables[URLRewriteRewrittenRequest] == null && context.Request.ServerVariables[URLRewriteModuleVersion] != null && context.Response.StatusCode == 200)
{
trackActivity = false;
}
else
{
// Activity has never been started
aspNetActivity = ActivityHelper.StartAspNetActivity(Options.TextMapPropagator, context, Options.OnRequestStartedCallback);
}
trackActivity = false;
}

if (trackActivity)
else
{
ActivityHelper.StopAspNetActivity(Options.TextMapPropagator, aspNetActivity, context, Options.OnRequestStoppedCallback);
// Activity has never been started
aspNetActivity = ActivityHelper.StartAspNetActivity(Options.TextMapPropagator, context, Options.OnRequestStartedCallback);
}
}

private void Application_Error(object sender, EventArgs e)
if (trackActivity)
{
AspNetTelemetryEventSource.Log.TraceCallback("Application_Error");
ActivityHelper.StopAspNetActivity(Options.TextMapPropagator, aspNetActivity, context, Options.OnRequestStoppedCallback);
}
}

var context = ((HttpApplication)sender).Context;
private void Application_Error(object sender, EventArgs e)
{
AspNetTelemetryEventSource.Log.TraceCallback("Application_Error");

var exception = context.Error;
if (exception != null)
{
if (!ActivityHelper.HasStarted(context, out Activity aspNetActivity))
{
aspNetActivity = ActivityHelper.StartAspNetActivity(Options.TextMapPropagator, context, Options.OnRequestStartedCallback);
}
var context = ((HttpApplication)sender).Context;

ActivityHelper.WriteActivityException(aspNetActivity, context, exception, Options.OnExceptionCallback);
var exception = context.Error;
if (exception != null)
{
if (!ActivityHelper.HasStarted(context, out Activity aspNetActivity))
{
aspNetActivity = ActivityHelper.StartAspNetActivity(Options.TextMapPropagator, context, Options.OnRequestStartedCallback);
}

ActivityHelper.WriteActivityException(aspNetActivity, context, exception, Options.OnExceptionCallback);
}
}
}
Loading

0 comments on commit d9e91a7

Please sign in to comment.