Skip to content

Commit

Permalink
allow sending custom data with the requesttelemetry
Browse files Browse the repository at this point in the history
  • Loading branch information
lefoulkrod committed Jan 25, 2017
1 parent a7cba77 commit 12f677d
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 7 deletions.
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ApplicationInsights.OwinExtensions.Tests.Utils;
Expand Down Expand Up @@ -178,6 +179,62 @@ public async Task Can_Pass_Request_Details_For_Filtering()

}

[Fact]
public async Task Should_Add_Properties_To_Request_Telemetry_Context_When_They_Are_Provided()
{
// given
var channel = new MockTelemetryChannel();

var request = Mock.Of<IOwinRequest>(r =>
r.Method == "GET" &&
r.Path == new PathString("/path") &&
r.Uri == new Uri("http://google.com/path")
);

var response = Mock.Of<IOwinResponse>(r => r.StatusCode == 200);

var context = new MockOwinContextBuilder()
.WithRequest(request)
.WithResponse(response)
.Build();

var configuration = new TelemetryConfigurationBuilder()
.WithChannel(channel)
.Build();


var sut = new OperationIdContextMiddleware(
new HttpRequestTrackingMiddleware(
new NoopMiddleware(), configuration, getContextProperties: (req, res) => new[]
{
new KeyValuePair<string, string>("key1", "val1"),
new KeyValuePair<string, string>("key2", "val2"),
}),
new OperationIdContextMiddlewareConfiguration());

// when
await sut.Invoke(context);

// then
channel.SentTelemetries.Count.Should().Be(1);

var telemetry = channel.SentTelemetries.First() as RequestTelemetry;
telemetry.Should().NotBeNull();

telemetry.HttpMethod.Should().Be("GET");
telemetry.Name.Should().Be("GET /path");
telemetry.Context.Operation.Name.Should().Be("GET /path");
telemetry.Id.Should().NotBeNullOrEmpty();
telemetry.Success.Should().BeTrue();
telemetry.Url.Should().Be(new Uri("http://google.com/path"));
telemetry.StartTime.Date.Should().Be(DateTimeOffset.Now.Date);
telemetry.Context.Properties.Should().Contain(new[]
{
new KeyValuePair<string, string>("key1", "val1"),
new KeyValuePair<string, string>("key2", "val2"),
});
}

[Theory]
[InlineData(200, true )]
[InlineData(201, true )]
Expand Down
6 changes: 4 additions & 2 deletions src/ApplicationInsights.OwinExtensions/AppBuilderExtension.cs
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.Owin;
using Owin;
Expand All @@ -10,10 +11,11 @@ public static class AppBuilderExtension
public static IAppBuilder UseApplicationInsights(this IAppBuilder builder,
OperationIdContextMiddlewareConfiguration middlewareConfiguration = null,
TelemetryConfiguration telemetryConfiguration = null,
Func<IOwinRequest, IOwinResponse, bool> shouldTraceRequest = null)
Func<IOwinRequest, IOwinResponse, bool> shouldTraceRequest = null,
Func<IOwinRequest, IOwinResponse, KeyValuePair<string,string>[]> getContextProperties = null)
{
builder.Use<OperationIdContextMiddleware>(middlewareConfiguration);
builder.Use<HttpRequestTrackingMiddleware>(telemetryConfiguration, shouldTraceRequest);
builder.Use<HttpRequestTrackingMiddleware>(telemetryConfiguration, shouldTraceRequest, getContextProperties);

return builder;
}
Expand Down
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using Microsoft.ApplicationInsights;
Expand All @@ -11,11 +12,17 @@ namespace ApplicationInsights.OwinExtensions
public class HttpRequestTrackingMiddleware : OwinMiddleware
{
private readonly Func<IOwinRequest, IOwinResponse, bool> _shouldTraceRequest;
private readonly Func<IOwinRequest, IOwinResponse, KeyValuePair<string, string>[]> _getContextProperties;
private readonly TelemetryClient _client;

public HttpRequestTrackingMiddleware(OwinMiddleware next, TelemetryConfiguration configuration = null, Func<IOwinRequest, IOwinResponse, bool> shouldTraceRequest = null) : base(next)
public HttpRequestTrackingMiddleware(
OwinMiddleware next,
TelemetryConfiguration configuration = null,
Func<IOwinRequest, IOwinResponse, bool> shouldTraceRequest = null,
Func<IOwinRequest, IOwinResponse, KeyValuePair<string,string>[]> getContextProperties = null) : base(next)
{
_shouldTraceRequest = shouldTraceRequest;
_getContextProperties = getContextProperties;
_client = configuration != null ? new TelemetryClient(configuration) : new TelemetryClient();
}

Expand All @@ -37,18 +44,31 @@ public override async Task Invoke(IOwinContext context)
{
stopWatch.Stop();
if (ShouldTraceRequest(context))
TraceRequest(method, path, uri, context.Response.StatusCode, requestStartDate, stopWatch.Elapsed);
{
var contextProperties = GetContextProperties(context);
TraceRequest(method, path, uri, context.Response.StatusCode, requestStartDate, stopWatch.Elapsed, contextProperties);
}

}
}

private KeyValuePair<string,string>[] GetContextProperties(IOwinContext context)
{
if (_getContextProperties == null)
{
return new KeyValuePair<string, string>[0];
}
return _getContextProperties(context.Request, context.Response);
}

private bool ShouldTraceRequest(IOwinContext context)
{
if (_shouldTraceRequest == null)
return true;
return _shouldTraceRequest(context.Request, context.Response);
}

private void TraceRequest(string method, string path, Uri uri, int responseCode, DateTimeOffset requestStartDate, TimeSpan duration)
private void TraceRequest(string method, string path, Uri uri, int responseCode, DateTimeOffset requestStartDate, TimeSpan duration, KeyValuePair<string, string>[] contextProperties)
{
var name = $"{method} {path}";

Expand All @@ -63,9 +83,11 @@ private void TraceRequest(string method, string path, Uri uri, int responseCode,
HttpMethod = method,
Url = uri
};

telemetry.Context.Operation.Name = name;

foreach (var kvp in contextProperties)
{
telemetry.Context.Properties.Add(kvp);
}
_client.TrackRequest(telemetry);
}
}
Expand Down

0 comments on commit 12f677d

Please sign in to comment.