Skip to content

Commit

Permalink
Stopping activity as before, and using ticks timestamp to compute dur…
Browse files Browse the repository at this point in the history
…ation instead of activity durationCalculating the metrics duration on the metrics handler instead of stopping asp.net activity
  • Loading branch information
carlos-neto-maersk committed Nov 14, 2023
1 parent c630117 commit 28e4b18
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,7 @@ public static void StopAspNetActivity(TextMapPropagator textMapPropagator, Activ
var currentActivity = Activity.Current;
context.Items[ContextKey] = null;

// Make sure that the activity has a proper end time before onRequestStoppedCallback is called.
// Note that the activity must not be stopped before the callback is called.
if (aspNetActivity.Duration == TimeSpan.Zero)
{
aspNetActivity.SetEndTime(DateTime.UtcNow);
}
aspNetActivity.Stop();

try
{
Expand All @@ -149,7 +144,6 @@ public static void StopAspNetActivity(TextMapPropagator textMapPropagator, Activ
AspNetTelemetryEventSource.Log.CallbackException(aspNetActivity, "OnStopped", callbackEx);
}

aspNetActivity.Stop();
AspNetTelemetryEventSource.Log.ActivityStopped(aspNetActivity);

if (textMapPropagator is not TraceContextPropagator)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,30 +24,41 @@ namespace OpenTelemetry.Instrumentation.AspNet.Implementation;

internal sealed class HttpInMetricsListener : IDisposable
{
private static long syncStopwatchTicks;
private readonly Histogram<double> httpServerDuration;
private readonly AspNetMetricsInstrumentationOptions options;

public HttpInMetricsListener(Meter meter, AspNetMetricsInstrumentationOptions options)
{
this.httpServerDuration = meter.CreateHistogram<double>("http.server.duration", "ms", "Measures the duration of inbound HTTP requests.");
TelemetryHttpModule.Options.OnRequestStartedCallback += this.OnStartActivity;
TelemetryHttpModule.Options.OnRequestStoppedCallback += this.OnStopActivity;
this.options = options;
}

public void Dispose()
{
TelemetryHttpModule.Options.OnRequestStartedCallback -= this.OnStartActivity;
TelemetryHttpModule.Options.OnRequestStoppedCallback -= this.OnStopActivity;
}

private static long TimestampDifference()
{
return (long)((Stopwatch.GetTimestamp() - syncStopwatchTicks) * 10000000L /
(double)Stopwatch.Frequency);
}

private void OnStartActivity(Activity activity, HttpContext context)
{
syncStopwatchTicks = Stopwatch.GetTimestamp();
}

private void OnStopActivity(Activity activity, HttpContext context)
{
// TODO: This is just a minimal set of attributes. See the spec for additional attributes:
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/http-metrics.md#http-server
var tags = new TagList
{
{ SemanticConventions.AttributeHttpMethod, context.Request.HttpMethod },
{ SemanticConventions.AttributeHttpScheme, context.Request.Url.Scheme },
{ SemanticConventions.AttributeHttpStatusCode, context.Response.StatusCode },
};

if (this.options.Enrich is not null)
Expand All @@ -62,6 +73,16 @@ private void OnStopActivity(Activity activity, HttpContext context)
}
}

this.httpServerDuration.Record(activity.Duration.TotalMilliseconds, tags);
TimeSpan duration = activity.Duration;
if (duration == TimeSpan.Zero)
{
duration = activity.StartTimeUtc.AddTicks(TimestampDifference()) - activity.StartTimeUtc;
if (duration.Ticks <= 0)
{
duration = new TimeSpan(1);
}
}

this.httpServerDuration.Record(duration.TotalMilliseconds, tags);
}
}

0 comments on commit 28e4b18

Please sign in to comment.