Created
June 21, 2015 16:09
-
-
Save dibble-james/82595999d950fdfa0c71 to your computer and use it in GitHub Desktop.
Rollbar Middleware example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using System.Security.Claims; | |
using System.Threading.Tasks; | |
using Microsoft.AspNet.Builder; | |
using Microsoft.AspNet.Http; | |
using Microsoft.Framework.Runtime; | |
using RollbarSharp; | |
using RollbarSharp.Serialization; | |
public class RollbarMiddleware | |
{ | |
private readonly Lazy<RollbarClient> _rollbar; | |
private readonly RequestDelegate _next; | |
private readonly string _accessToken; | |
private readonly string _environment; | |
public RollbarMiddleware(RequestDelegate next, string accessToken, string environment) | |
{ | |
this._rollbar = new Lazy<RollbarClient>(BuildClient); | |
this._next = next; | |
this._accessToken = accessToken; | |
this._environment = environment; | |
} | |
public async Task Invoke(HttpContext context) | |
{ | |
try | |
{ | |
await _next(context); | |
} | |
catch(Exception ex) | |
{ | |
Task.WaitAll(this._rollbar.Value.SendException(ex, null, "error", async dm => await this.AddDetails(dm, context))); | |
throw; | |
} | |
} | |
private RollbarClient BuildClient() | |
{ | |
var client = new RollbarClient(this._accessToken); | |
client.Configuration.Environment = this._environment; | |
return client; | |
} | |
private async Task AddDetails(DataModel model, HttpContext context) | |
{ | |
var request = this.AddRequestDetails(context.Request); | |
model.Server = this.AddServerDetails(context); | |
model.Person = this.AddPersonDetails(context.User); | |
model.Request = await request; | |
} | |
private async Task<RequestModel> AddRequestDetails(HttpRequest request) | |
{ | |
var m = new RequestModel | |
{ | |
Url = string.Concat(request.Scheme, "://", request.Host, request.Path), | |
Method = request.Method, | |
Headers = request.Headers.Keys.Select( | |
k => new KeyValuePair<string, string>(k, request.Headers.Get(k))).ToDictionary(kvp => kvp.Key, kvp => kvp.Value) | |
}; | |
// TODO: Add session | |
if(request.QueryString.HasValue) | |
{ | |
var rawQueryString = request.QueryString.Value.TrimStart('?'); | |
var queryStringParameters = | |
rawQueryString.Split('&').Select(qs => new KeyValuePair<string, string>(qs.Split('=').First(), qs.Split('=').Last())); | |
m.QueryStringParameters = queryStringParameters.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); | |
} | |
try | |
{ | |
m.PostParameters = | |
request.Form.Keys.Select( | |
k => new KeyValuePair<string, string>(k, request.Form.Get(k))).ToDictionary(kvp => kvp.Key, kvp => kvp.Value); | |
} | |
catch(InvalidOperationException) | |
{ | |
// Swallow IOE. ASP.Net throws this is no form exists. | |
} | |
m.PostParameters.Add("Body", await new StreamReader(request.Body).ReadToEndAsync()); | |
m.UserIp = request.HttpContext.GetFeature<IHttpConnectionFeature>()?.RemoteIpAddress.ToString(); | |
return m; | |
} | |
private ServerModel AddServerDetails(HttpContext context) | |
{ | |
var m = new ServerModel | |
{ | |
Host = context.Request.Host.Value, | |
Machine = Environment.MachineName, | |
Software = Environment.OSVersion.ToString(), | |
Root = (context.ApplicationServices.GetService(typeof(IApplicationEnvironment)) as IApplicationEnvironment)?.ApplicationBasePath | |
}; | |
return m; | |
} | |
private PersonModel AddPersonDetails(ClaimsPrincipal user) | |
{ | |
if(user == null) | |
{ | |
return new PersonModel(); | |
} | |
return new PersonModel { Id = user.Identity.Name, Username = user.Identity.Name }; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment