Last active
August 16, 2017 01:17
-
-
Save nickalbrecht/8f0c8f8cf82906049eb1e266f81e6f59 to your computer and use it in GitHub Desktop.
StackExchange.Exceptional - Custom Error List
This file contains 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
Sample of some files I whipped up to try and demonstrate how to provide a | |
custom RazorPage to list errors recorded in StackExchange's Exceptional |
This file contains 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
public class ErrorsController : Controller | |
{ | |
//The stock handler. Still needed to get the default CSS and JS used for Exceptional | |
public async Task Exceptions() => await StackExchange.Exceptional.ExceptionalMiddleware.HandleRequestAsync(HttpContext); | |
} |
This file contains 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
@{ | |
bool InlineCSS = false; | |
bool IncludeJS = true; | |
var store = Settings.Current.DefaultStore; | |
} | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>@ViewBag.PageTitle</title> | |
@if (InlineCSS) | |
{ | |
<style> | |
@Resources.BundleCss.Content | |
</style> | |
} | |
else | |
{ | |
<link rel="stylesheet" type="text/css" href="/errors/exceptions/@(KnownRoutes.Css)" integrity="[email protected](Resources.BundleCss.Sha512)" crossorigin="anonymous" /> | |
} | |
@foreach (var css in Settings.Current.Render.CSSIncludes) | |
{ | |
<link rel="stylesheet" type="text/css" href="@css" /> | |
} | |
<script>var baseUrl = "";</script> | |
@if(false) | |
{ | |
<script> | |
var Exception = ""; //error.WriteDetailedJson | |
</script> | |
} | |
@if (IncludeJS) | |
{ | |
<script src="/errors/exceptions/@(KnownRoutes.Js)[email protected]" integrity="[email protected](@Resources.BundleJs.Sha512)" crossorigin="anonymous"></script> | |
} | |
@foreach (var js in Settings.Current.Render.JSIncludes) | |
{ | |
<script src="@js"></script> | |
} | |
</head> | |
<body> | |
<div class="wrapper"> | |
<header class="@(store.InFailureMode ? "failure": null)">Exceptions Log: @(Settings.Current.ApplicationName ?? "[Application Name]")</header> | |
<main> | |
@RenderBody() | |
</main> | |
<div class="bottom"></div> | |
</div> | |
<footer> | |
<div class="version-info">Exceptional X.X.X.X <br />@store.Name</div> | |
<div class="server-time">Server time is @DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ")</div> | |
</footer> | |
</body> | |
</html> |
This file contains 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 StackExchange.Exceptional | |
@using StackExchange.Exceptional.Internal | |
@inject Microsoft.Extensions.Options.IOptions<Settings> settings | |
@inject Microsoft.AspNetCore.Hosting.IHostingEnvironment hostingEnvironment | |
@inject Microsoft.Extensions.Logging.ILoggerFactory loggerFactory |
This file contains 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
@page "exceptional" | |
@{ | |
var store = Settings.Current.DefaultStore; | |
var errors = (await store.GetAllAsync()).OrderByDescending(e => e.LastLogDate ?? e.CreationDate).ToList(); | |
ViewBag.PageTitle = "Error Log"; | |
Layout = "_Layout"; | |
} | |
@if (store.InFailureMode) | |
{ | |
<div class="failure-mode"> | |
<svg viewBox="0 0 1792 1792"><path d="M1024 1375v-190q0-14-9.5-23.5t-22.5-9.5h-192q-13 0-22.5 9.5t-9.5 23.5v190q0 14 9.5 23.5t22.5 9.5h192q13 0 22.5-9.5t9.5-23.5zm-2-374l18-459q0-12-10-19-13-11-24-11h-220q-11 0-24 11-10 7-10 21l17 457q0 10 10 16.5t24 6.5h185q14 0 23.5-6.5t10.5-16.5zm-14-934l768 1408q35 63-2 126-17 29-46.5 46t-63.5 17h-1536q-34 0-63.5-17t-46.5-46q-37-63-2-126l768-1408q17-31 47-49t65-18 65 18 47 49z" /></svg> | |
Error log is in failure mode, @store.WriteQueue.Count queued to log. | |
@if (store.LastRetryException != null) | |
{ | |
<div>Last Logging Exception: @store.LastRetryException.Message <a href="#" class="js-show-details">view details</a></div> | |
<pre class="stack dark details"> | |
<code> | |
@Utils.StackTrace.HtmlPrettify(store.LastRetryException.Message + "\n" + store.LastRetryException.StackTrace) | |
</code> | |
</pre> | |
} | |
</div> | |
} | |
@if (errors.Count == 0) | |
{ | |
<div> | |
<h1>No errors yet, yay!</h1> | |
<div>There are no active errors in the log.</div> | |
</div> | |
} | |
else | |
{ | |
var last = errors.FirstOrDefault(); | |
<h1> | |
<span class="js-error-count">@errors.Count Error@(errors.Count > 1 ? "s" : null)</span> | |
<span class="sub">(last: @last.CreationDate.ToRelativeTime())</span> | |
</h1> | |
<table class="js-error-list hover alt-rows error-list"> | |
<thead> | |
<tr> | |
<th></th> | |
<th>Type</th> | |
<th>Error</th> | |
<th>Url</th> | |
<th>Remote IP</th> | |
<th>Time</th> | |
<th>Site</th> | |
<th>Server</th> | |
</tr> | |
</thead> | |
<tbody> | |
@foreach (var error in errors) | |
{ | |
<tr data-id="" class="error @(error.IsProtected ? "js-protected": null)"> | |
<td> | |
<a href="#" class="js-delete-link" title="Delete this error"><svg class='icon x' viewBox='0 0 1792 1792'><path d='M1490 1322q0 40-28 68l-136 136q-28 28-68 28t-68-28l-294-294-294 294q-28 28-68 28t-68-28l-136-136q-28-28-28-68t28-68l294-294-294-294q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 294 294-294q28-28 68-28t68 28l136 136q28 28 28 68t-28 68l-294 294 294 294q28 28 28 68z' /></svg></a> | |
@if (!error.IsProtected) | |
{ | |
<a href="#" class="js-protect-link" title="Protect this error"><svg class='icon lock' viewBox='0 0 1792 1792'><path d='M640 768h512v-192q0-106-75-181t-181-75-181 75-75 181v192zm832 96v576q0 40-28 68t-68 28h-960q-40 0-68-28t-28-68v-576q0-40 28-68t68-28h32v-192q0-184 132-316t316-132 316 132 132 316v192h32q40 0 68 28t28 68z' /></svg></a> | |
} | |
else | |
{ | |
<span title="This error is protected"><svg class='icon lock' viewBox='0 0 1792 1792'><path d='M640 768h512v-192q0-106-75-181t-181-75-181 75-75 181v192zm832 96v576q0 40-28 68t-68 28h-960q-40 0-68-28t-28-68v-576q0-40 28-68t68-28h32v-192q0-184 132-316t316-132 316 132 132 316v192h32q40 0 68 28t28 68z' /></svg></span> | |
} | |
</td> | |
<td title="@error.Type">@error.Type.ToShortTypeName()</td> | |
<td class="wrap"> | |
<a href="/errors/exceptions/@(KnownRoutes.Info)?guid=@(error.GUID)">@error.Message</a> @if (error.DuplicateCount > 1) { <span class="duplicate-count" title="number of similar errors occurring close to this error">(@error.DuplicateCount)</span>} | |
</td> | |
<td>@if (error.Url.HasValue()) { <span title="@(error.Host)@(error.Url))">@error.Url.TruncateWithEllipsis(40)</span> }</td> | |
<td>@error.IPAddress</td> | |
<td title="@((error.LastLogDate ?? error.CreationDate).ToUniversalTime().ToString("u"))">@((error.LastLogDate ?? error.CreationDate).ToRelativeTime())</td> | |
<td>@error.Host</td> | |
<td>@error.MachineName</td> | |
</tr> | |
} | |
</tbody> | |
</table> | |
} | |
@if(errors.Any(x=>x.IsProtected)) | |
{ | |
<div class="page-actions"> | |
<a class="js-clear-all" href="#">Clear all non-protected errors</a> | |
</div> | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment