Skip to content

Commit

Permalink
Add additional tags to ASP.NET Core metrics (#3247)
Browse files Browse the repository at this point in the history
  • Loading branch information
vishweshbankwar committed May 6, 2022
1 parent 95500ff commit ee19d70
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 6 deletions.
3 changes: 3 additions & 0 deletions src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## Unreleased

* Added additional metric dimensions.
([3247](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3247))

* Removes net5.0 target as .NET 5.0 is going out
of support. The package keeps netstandard2.1 target, so it
can still be used with .NET5.0 apps.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
using System.Diagnostics;
using System.Diagnostics.Metrics;
using Microsoft.AspNetCore.Http;
#if NETCOREAPP
using Microsoft.AspNetCore.Routing;
#endif
using OpenTelemetry.Trace;

namespace OpenTelemetry.Instrumentation.AspNetCore.Implementation
Expand Down Expand Up @@ -51,16 +54,60 @@ public override void OnStopActivity(Activity activity, object payload)
return;
}

string host;

if (context.Request.Host.Port is null or 80 or 443)
{
host = context.Request.Host.Host;
}
else
{
host = context.Request.Host.Host + ":" + context.Request.Host.Port;
}

TagList tags;

// We need following directive as
// RouteEndpoint is not available in netstandard2.0 and netstandard2.1
#if NETCOREAPP
var target = (context.GetEndpoint() as RouteEndpoint)?.RoutePattern.RawText;

// 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
if (!string.IsNullOrEmpty(target))
{
tags = new TagList
{
{ SemanticConventions.AttributeHttpFlavor, context.Request.Protocol },
{ SemanticConventions.AttributeHttpScheme, context.Request.Scheme },
{ SemanticConventions.AttributeHttpMethod, context.Request.Method },
{ SemanticConventions.AttributeHttpHost, host },
{ SemanticConventions.AttributeHttpTarget, target },
{ SemanticConventions.AttributeHttpStatusCode, context.Response.StatusCode.ToString() },
};
}
else
{
tags = new TagList
{
{ SemanticConventions.AttributeHttpFlavor, context.Request.Protocol },
{ SemanticConventions.AttributeHttpScheme, context.Request.Scheme },
{ SemanticConventions.AttributeHttpMethod, context.Request.Method },
{ SemanticConventions.AttributeHttpHost, host },
{ SemanticConventions.AttributeHttpStatusCode, context.Response.StatusCode.ToString() },
};
}
#else
tags = new TagList
{
{ SemanticConventions.AttributeHttpMethod, context.Request.Method },
{ SemanticConventions.AttributeHttpScheme, context.Request.Scheme },
{ SemanticConventions.AttributeHttpStatusCode, context.Response.StatusCode },
{ SemanticConventions.AttributeHttpFlavor, context.Request.Protocol },
{ SemanticConventions.AttributeHttpScheme, context.Request.Scheme },
{ SemanticConventions.AttributeHttpMethod, context.Request.Method },
{ SemanticConventions.AttributeHttpHost, host },
{ SemanticConventions.AttributeHttpStatusCode, context.Response.StatusCode.ToString() },
};

#endif
this.httpServerDuration.Record(activity.Duration.TotalMilliseconds, tags);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,17 @@ public async Task RequestMetricIsCaptured()

var method = new KeyValuePair<string, object>(SemanticConventions.AttributeHttpMethod, "GET");
var scheme = new KeyValuePair<string, object>(SemanticConventions.AttributeHttpScheme, "http");
var statusCode = new KeyValuePair<string, object>(SemanticConventions.AttributeHttpStatusCode, 200);
var statusCode = new KeyValuePair<string, object>(SemanticConventions.AttributeHttpStatusCode, "200");
var flavor = new KeyValuePair<string, object>(SemanticConventions.AttributeHttpFlavor, "HTTP/1.1");
var host = new KeyValuePair<string, object>(SemanticConventions.AttributeHttpHost, "localhost");
var target = new KeyValuePair<string, object>(SemanticConventions.AttributeHttpTarget, "api/Values");
Assert.Contains(method, attributes);
Assert.Contains(scheme, attributes);
Assert.Contains(statusCode, attributes);
Assert.Contains(flavor, attributes);
Assert.Equal(4, attributes.Length);
Assert.Contains(host, attributes);
Assert.Contains(target, attributes);
Assert.Equal(6, attributes.Length);
}

public void Dispose()
Expand Down

0 comments on commit ee19d70

Please sign in to comment.