Skip to content

Instantly share code, notes, and snippets.

@chagretes
Created January 14, 2020 18:34
Show Gist options
  • Save chagretes/30eb5cb3d93d6a2d844c8efb3b0d1cb4 to your computer and use it in GitHub Desktop.
Save chagretes/30eb5cb3d93d6a2d844c8efb3b0d1cb4 to your computer and use it in GitHub Desktop.
using System;
using System.Threading.Tasks;
using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.AspNetCore.Http;
using Proposta.API.Utils;
using Proposta.Shared.Interfaces;
namespace Proposta.API
{
public class ApplicationInsightsMiddleware
{
private readonly RequestDelegate next;
private TelemetryClient telemetryClient;
private ITelemetryLogClient logClient;
public ApplicationInsightsMiddleware(RequestDelegate next, TelemetryClient telemetryClient, ITelemetryLogClient logClient)
{
this.telemetryClient = telemetryClient;
this.next = next;
this.logClient = logClient;
}
public async Task InvokeAsync(HttpContext context)
{
// Let's create and start RequestTelemetry.
var requestTelemetry = new RequestTelemetry
{
Name = $"{context.Request.Method} {context.Request.Path}"
};
// If there is a Request-Id received from the upstream service, set the telemetry context accordingly.
if (context.Request.Headers.ContainsKey("Request-Id"))
{
var requestId = context.Request.Headers["Request-Id"];
// Get the operation ID from the Request-Id (if you follow the HTTP Protocol for Correlation).
requestTelemetry.Context.Operation.Id = GetOperationId(requestId);
requestTelemetry.Context.Operation.ParentId = requestId;
}
if (context.Request.Headers.ContainsKey("idUsuario"))
{
var user = context.Request.Headers["idUsuario"];
// Get the operation ID from the Request-Id (if you follow the HTTP Protocol for Correlation).
requestTelemetry.Context.User.Id = user;
}
requestTelemetry.Properties.Add("query", context.Request.QueryString.ToString());
// StartOperation is a helper method that allows correlation of
// current operations with nested operations/telemetry
// and initializes start time and duration on telemetry items.
var operation = telemetryClient.StartOperation(requestTelemetry);
// Process the request.
try
{
await next.Invoke(context);
}
catch (Exception e)
{
await PropostaExceptionHandler.HandleException(context, logClient, e);
requestTelemetry.Success = false;;
}
finally
{
// Update status code and success as appropriate.
if (context.Response != null)
{
requestTelemetry.ResponseCode = context.Response.StatusCode.ToString();
requestTelemetry.Success = context.Response.StatusCode >= 200 && context.Response.StatusCode <= 299;
}
else
{
requestTelemetry.Success = false;
}
// Now it's time to stop the operation (and track telemetry).
telemetryClient.StopOperation(operation);
}
}
public static string GetOperationId(string id)
{
// Returns the root ID from the '|' to the first '.' if any.
int rootEnd = id.IndexOf('.');
if (rootEnd < 0)
rootEnd = id.Length;
int rootStart = id[0] == '|' ? 1 : 0;
return id.Substring(rootStart, rootEnd - rootStart);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment