Skip to content

Commit

Permalink
Code cleanup
Browse files Browse the repository at this point in the history
Process query args in fewer steps
  • Loading branch information
mike-ward committed Feb 25, 2014
1 parent c1be6aa commit 11c9502
Show file tree
Hide file tree
Showing 7 changed files with 277 additions and 297 deletions.
2 changes: 1 addition & 1 deletion Src/Nancy.Elmah.Asp.Net.Example/Bootstrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ public class Bootstrapper : DefaultNancyBootstrapper
protected override void ApplicationStartup(TinyIoc.TinyIoCContainer container, Nancy.Bootstrapper.IPipelines pipelines)
{
base.ApplicationStartup(container, pipelines);
Elmahlogging.Enable(pipelines, "/admin/elmah", new string[0], new HttpStatusCode[]{HttpStatusCode.NotFound});
Elmahlogging.Enable(pipelines, "/admin/elmah", new string[0], new []{HttpStatusCode.NotFound});
}
}
}
29 changes: 13 additions & 16 deletions Src/Nancy.Elmah.Asp.Net.Example/DefaultModule.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Nancy.Elmah.Asp.Net.Example
{
public class DefaultModule : NancyModule
{
public DefaultModule()
{
Get["/"] = _ => Response.AsText("<html><body><h1>Nancy.Elmah</h1><p>the Elmah interface is avilable <a href=\"/admin/elmah\">here</a></p><br/><img src=\"/exception\" alt=\"this image is broken on purpose\"/></body></html>").WithContentType("text/html;charset=UTF-8");

Get["/exception"] = _ => { throw new Exception("this is just an example exception"); };
}
}
using System;

namespace Nancy.Elmah.Asp.Net.Example
{
public class DefaultModule : NancyModule
{
public DefaultModule()
{
Get["/"] = _ => Response.AsText("<html><body><h1>Nancy.Elmah</h1><p>the Elmah interface is avilable <a href=\"/admin/elmah\">here</a></p><br/><img src=\"/exception\" alt=\"this image is broken on purpose\"/></body></html>").WithContentType("text/html;charset=UTF-8");

Get["/exception"] = _ => { throw new Exception("this is just an example exception"); };
}
}
}
278 changes: 136 additions & 142 deletions Src/Nancy.Elmah/Elmahlogging.cs
Original file line number Diff line number Diff line change
@@ -1,142 +1,136 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Elmah;
using Nancy.Bootstrapper;
using Nancy.Security;
using ErrorSignal = Elmah.ErrorSignal;

namespace Nancy.Elmah
{
/// <summary>
///
/// </summary>
public class Elmahlogging : NancyModule
{
private static string _elmahPath = string.Empty;
private static string[] _requiredClaims = new string[0];
private static HttpStatusCode[] _loggedHttpStatusCodes;

/// <summary>
/// Enables Elmah logging of application exceptions and errors.
/// Using this enabled will catch and log exceptions only.
/// The Elmah admin interface at the path defined by <param name="elmahModuleBasePath">elmahModuleBasePath</param> will be public and visible to anybody
/// </summary>
/// <param name="pipelines"></param>
/// <param name="elmahModuleBasePath"></param>
public static void Enable(IPipelines pipelines, string elmahModuleBasePath)
{
_loggedHttpStatusCodes = new HttpStatusCode[0];
_requiredClaims = new string[0];
_elmahPath = elmahModuleBasePath;
pipelines.OnError.AddItemToEndOfPipeline(LogError);
pipelines.AfterRequest.AddItemToEndOfPipeline(LogHttpStatusCode);
}

/// <summary>
/// Enables Elmah logging of application exceptions and errors.
/// Using this enabled will catch and log exceptions only.
/// The Elmah admin interface at the path defined by <param name="elmahModuleBasePath">elmahModuleBasePath</param> will be visible to users that has the claims specified by <param name="requiredClaims">requiredClaims</param>
/// </summary>
/// <param name="pipelines"></param>
/// <param name="elmahModuleBasePath"></param>
/// <param name="requiredClaims"></param>
public static void Enable(IPipelines pipelines, string elmahModuleBasePath, IEnumerable<string> requiredClaims)
{
_loggedHttpStatusCodes = new HttpStatusCode[0];
_requiredClaims = requiredClaims.ToArray();
_elmahPath = elmahModuleBasePath;
pipelines.OnError.AddItemToEndOfPipeline(LogError);
pipelines.AfterRequest.AddItemToEndOfPipeline(LogHttpStatusCode);
}

/// <summary>
/// Enables Elmah logging of application exceptions and errors.
/// Using this enabled will catch and log exceptions and HttpStatusCodes defined by <param name="loggedHttpStatusCodes">loggedHttpStatusCodes</param>.
/// The Elmah admin interface at the path defined by <param name="elmahModuleBasePath">elmahModuleBasePath</param> will be visible to users that has the claims specified by <param name="requiredClaims">requiredClaims</param>.
/// </summary>
/// <param name="pipelines"></param>
/// <param name="elmahModuleBasePath"></param>
/// <param name="requiredClaims"></param>
/// <param name="loggedHttpStatusCodes"></param>
public static void Enable(IPipelines pipelines, string elmahModuleBasePath, IEnumerable<string> requiredClaims, IEnumerable<HttpStatusCode> loggedHttpStatusCodes)
{
_loggedHttpStatusCodes = loggedHttpStatusCodes.ToArray();
_requiredClaims = requiredClaims.ToArray();
_elmahPath = elmahModuleBasePath;
pipelines.OnError.AddItemToEndOfPipeline(LogError);
pipelines.AfterRequest.AddItemToEndOfPipeline(LogHttpStatusCode);
}

public static void LogHttpStatusCode(NancyContext context)
{
if(context == null || context.Response == null)
return;

if (!_loggedHttpStatusCodes.Contains(context.Response.StatusCode))
return;

var url = context.Request == null ? string.Empty : context.Request.Url.ToString();
var statusCode = context.Response == null ? string.Empty : context.Response.StatusCode.ToString();
var nancyModuleName = context.NegotiationContext == null ? string.Empty : context.NegotiationContext.ModuleName;
var nancyModulePath = context.NegotiationContext == null ? string.Empty : context.NegotiationContext.ModulePath;
var user = context.CurrentUser == null ? string.Empty : context.CurrentUser.UserName;

var message = string.Format("url: {0}, statuscode: {1}, user: {2}, moduleName: {3}, modulePath: {4}", url, statusCode, user, nancyModuleName, nancyModulePath);

var exception = new HttpException((int) context.Response.StatusCode, message);

LogError(context, exception);
}

public static Response LogError(NancyContext context, Exception exception)
{
ErrorSignal.FromCurrentContext().Raise(exception);
return null;
}

public Elmahlogging() : base(_elmahPath)
{
if (_requiredClaims.Length>0)
this.RequiresClaims(_requiredClaims);

if(!string.IsNullOrEmpty(_elmahPath))
{
Get["/"] = args =>
{
switch((string)Request.Query.get.Value)
{
case "stylesheet":
return Response.AsElmahEmbeddedResource("ErrorLog.css", "text/css").WithContentType("text/css;charset=UTF-8");
case "about":
return Response.AsElmahEmbeddedPage("AboutPage");
case "detail":
return Response.AsElmahEmbeddedPage("ErrorDetailPage");
case "xml":
return Response.AsElmahEmbeddedPage("ErrorXmlHandler").WithContentType("text/xml;charset=UTF-8");
case "json":
return Response.AsElmahEmbeddedPage("ErrorJsonHandler").WithContentType("application/json;charset=UTF-8");
case "digestrss":
return Response.AsElmahEmbeddedPage("ErrorDigestRssHandler").WithContentType("application/rss+xml;charset=UTF-8");
case "rss":
return Response.AsElmahEmbeddedPage("ErrorRssHandler").WithContentType("application/rss+xml;charset=UTF-8");
case "download":
return Response.AsElmahEmbeddedPage("ErrorLogDownloadHandler").WithContentType("application/rss+xml;charset=UTF-8");
default:
return Response.AsElmahEmbeddedPage("ErrorLogPage");
}
};

Get["/{resource}"] = args =>
{
var q = (Request.Query as DynamicDictionary).Keys.ToDictionary(key => key.Replace("?", ""), key => (string)(Request.Query as DynamicDictionary)[key]);
q["get"] = (string) args.resource;
var queryString = "?"+string.Join("&", q.Select(kv => string.Format("{0}={1}", kv.Key, kv.Value)));
return Response.AsRedirect(_elmahPath +"/"+ queryString);
};
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Elmah;
using Nancy.Bootstrapper;
using Nancy.Security;

namespace Nancy.Elmah
{
public class Elmahlogging : NancyModule
{
private static string _elmahPath = string.Empty;
private static string[] _requiredClaims = new string[0];
private static HttpStatusCode[] _loggedHttpStatusCodes;

/// <summary>
/// Enables Elmah logging of application exceptions and errors.
/// Using this enabled will catch and log exceptions only.
/// The Elmah admin interface at the path defined by <param name="elmahModuleBasePath">elmahModuleBasePath</param>
/// will be public and visible to anybody
/// </summary>
/// <param name="pipelines"></param>
/// <param name="elmahModuleBasePath"></param>
public static void Enable(IPipelines pipelines, string elmahModuleBasePath)
{
_loggedHttpStatusCodes = new HttpStatusCode[0];
_requiredClaims = new string[0];
_elmahPath = elmahModuleBasePath;
pipelines.OnError.AddItemToEndOfPipeline(LogError);
pipelines.AfterRequest.AddItemToEndOfPipeline(LogHttpStatusCode);
}

/// <summary>
/// Enables Elmah logging of application exceptions and errors.
/// Using this enabled will catch and log exceptions only.
/// The Elmah admin interface at the path defined by <param name="elmahModuleBasePath">elmahModuleBasePath</param>
/// will be visible to users that has the claims specified by <param name="requiredClaims">requiredClaims</param>
/// </summary>
/// <param name="pipelines"></param>
/// <param name="elmahModuleBasePath"></param>
/// <param name="requiredClaims"></param>
public static void Enable(IPipelines pipelines, string elmahModuleBasePath, IEnumerable<string> requiredClaims)
{
_loggedHttpStatusCodes = new HttpStatusCode[0];
_requiredClaims = requiredClaims.ToArray();
_elmahPath = elmahModuleBasePath;
pipelines.OnError.AddItemToEndOfPipeline(LogError);
pipelines.AfterRequest.AddItemToEndOfPipeline(LogHttpStatusCode);
}

/// <summary>
/// Enables Elmah logging of application exceptions and errors.
/// Using this enabled will catch and log exceptions and HttpStatusCodes defined by <param name="loggedHttpStatusCodes">loggedHttpStatusCodes</param>.
/// The Elmah admin interface at the path defined by <param name="elmahModuleBasePath">elmahModuleBasePath</param>
/// will be visible to users that has the claims specified by <param name="requiredClaims">requiredClaims</param>.
/// </summary>
/// <param name="pipelines"></param>
/// <param name="elmahModuleBasePath"></param>
/// <param name="requiredClaims"></param>
/// <param name="loggedHttpStatusCodes"></param>
public static void Enable(IPipelines pipelines, string elmahModuleBasePath, IEnumerable<string> requiredClaims, IEnumerable<HttpStatusCode> loggedHttpStatusCodes)
{
_loggedHttpStatusCodes = loggedHttpStatusCodes.ToArray();
_requiredClaims = requiredClaims.ToArray();
_elmahPath = elmahModuleBasePath;
pipelines.OnError.AddItemToEndOfPipeline(LogError);
pipelines.AfterRequest.AddItemToEndOfPipeline(LogHttpStatusCode);
}

public static void LogHttpStatusCode(NancyContext context)
{
if (context == null || context.Response == null) return;
if (_loggedHttpStatusCodes.Contains(context.Response.StatusCode) == false) return;

var url = context.Request == null ? string.Empty : context.Request.Url.ToString();
var statusCode = context.Response == null ? string.Empty : context.Response.StatusCode.ToString();
var nancyModuleName = context.NegotiationContext == null ? string.Empty : context.NegotiationContext.ModuleName;
var nancyModulePath = context.NegotiationContext == null ? string.Empty : context.NegotiationContext.ModulePath;
var user = context.CurrentUser == null ? string.Empty : context.CurrentUser.UserName;

var message = string.Format("url: {0}, statuscode: {1}, user: {2}, moduleName: {3}, modulePath: {4}",
url, statusCode, user, nancyModuleName, nancyModulePath);

var exception = new HttpException((int)context.Response.StatusCode, message);
LogError(context, exception);
}

public static Response LogError(NancyContext context, Exception exception)
{
ErrorSignal.FromCurrentContext().Raise(exception);
return null;
}

public Elmahlogging() : base(_elmahPath)
{
if (_requiredClaims.Length > 0) this.RequiresClaims(_requiredClaims);

if (!string.IsNullOrEmpty(_elmahPath))
{
Get["/"] = args =>
{
switch ((string)Request.Query.get.Value)
{
case "stylesheet":
return Response.AsElmahEmbeddedResource("ErrorLog.css", "text/css").WithContentType("text/css;charset=UTF-8");
case "about":
return Response.AsElmahEmbeddedPage("AboutPage");
case "detail":
return Response.AsElmahEmbeddedPage("ErrorDetailPage");
case "xml":
return Response.AsElmahEmbeddedPage("ErrorXmlHandler").WithContentType("text/xml;charset=UTF-8");
case "json":
return Response.AsElmahEmbeddedPage("ErrorJsonHandler").WithContentType("application/json;charset=UTF-8");
case "digestrss":
return Response.AsElmahEmbeddedPage("ErrorDigestRssHandler").WithContentType("application/rss+xml;charset=UTF-8");
case "rss":
return Response.AsElmahEmbeddedPage("ErrorRssHandler").WithContentType("application/rss+xml;charset=UTF-8");
case "download":
return Response.AsElmahEmbeddedPage("ErrorLogDownloadHandler").WithContentType("application/rss+xml;charset=UTF-8");
default:
return Response.AsElmahEmbeddedPage("ErrorLogPage");
}
};

Get["/{resource}"] = args =>
{
var query = Request.Query as IDictionary<string, object>;
query["get"] = (string)args.resource;
var queryString = string.Join("&", query.Select(kv => string.Format("{0}={1}", kv.Key.Replace("?", ""), kv.Value)));
return Response.AsRedirect(_elmahPath + "/?" + queryString);
};
}
}
}
}
Loading

0 comments on commit 11c9502

Please sign in to comment.