public ErrorLoggedEventArgs(ErrorLogEntry entry) { if (entry == null) throw new ArgumentNullException("entry"); _entry = entry; }
private void RenderError(HtmlTextWriter writer, ErrorLogEntry entry, Uri baseUrl) { Debug.Assert(writer != null); Debug.Assert(baseUrl != null); Debug.Assert(entry != null); Error error = entry.Error; writer.RenderBeginTag(HtmlTextWriterTag.Li); string errorType = ErrorDisplay.HumaneExceptionErrorType(error); if (errorType.Length > 0) { bool abbreviated = errorType.Length < error.Type.Length; if (abbreviated) { writer.AddAttribute(HtmlTextWriterAttribute.Title, error.Type); writer.RenderBeginTag(HtmlTextWriterTag.Span); } Server.HtmlEncode(errorType, writer); if (abbreviated) writer.RenderEndTag(/* span */); writer.Write(": "); } writer.AddAttribute(HtmlTextWriterAttribute.Href, baseUrl + "/detail?id=" + HttpUtility.UrlEncode(entry.Id)); writer.RenderBeginTag(HtmlTextWriterTag.A); Server.HtmlEncode(error.Message, writer); writer.RenderEndTag(/* a */); writer.RenderEndTag( /* li */); }
public void Add(ErrorLogEntry entry) { Debug.Assert(entry != null); Debug.AssertStringNotEmpty(entry.Id); Debug.Assert(this.Count <= _size); if (this.Count == _size) BaseRemoveAt(0); BaseAdd(entry.Id, entry); }
/// <summary> /// Logs an error to the application memory. /// </summary> /// <remarks> /// If the log is full then the oldest error entry is removed. /// </remarks> public override string Log(Error error) { if (error == null) throw new ArgumentNullException("error"); // // Make a copy of the error to log since the source is mutable. // Assign a new GUID and create an entry for the error. // error = (Error) ((ICloneable) error).Clone(); error.ApplicationName = this.ApplicationName; Guid newId = Guid.NewGuid(); ErrorLogEntry entry = new ErrorLogEntry(this, newId.ToString(), error); _lock.AcquireWriterLock(Timeout.Infinite); try { if (_entries == null) _entries = new EntryCollection(_size); _entries.Add(entry); } finally { _lock.ReleaseWriterLock(); } return newId.ToString(); }
/// <summary> /// Returns a page of errors from the application memory in /// descending order of logged time. /// </summary> public override int GetErrors(int pageIndex, int pageSize, IList errorEntryList) { if (pageIndex < 0) throw new ArgumentOutOfRangeException("pageIndex", pageIndex, null); if (pageSize < 0) throw new ArgumentOutOfRangeException("pageSize", pageSize, null); // // To minimize the time for which we hold the lock, we'll first // grab just references to the entries we need to return. Later, // we'll make copies and return those to the caller. Since Error // is mutable, we don't want to return direct references to our // internal versions since someone could change their state. // ErrorLogEntry[] selectedEntries = null; int totalCount; _lock.AcquireReaderLock(Timeout.Infinite); try { if (_entries == null) return 0; totalCount = _entries.Count; int startIndex = pageIndex * pageSize; int endIndex = Math.Min(startIndex + pageSize, totalCount); int count = Math.Max(0, endIndex - startIndex); if (count > 0) { selectedEntries = new ErrorLogEntry[count]; int sourceIndex = endIndex; int targetIndex = 0; while (sourceIndex > startIndex) selectedEntries[targetIndex++] = _entries[--sourceIndex]; } } finally { _lock.ReleaseReaderLock(); } if (errorEntryList != null && selectedEntries != null) { // // Return copies of fetched entries. If the Error class would // be immutable then this step wouldn't be necessary. // foreach (ErrorLogEntry entry in selectedEntries) { Error error = (Error)((ICloneable)entry.Error).Clone(); errorEntryList.Add(new ErrorLogEntry(this, entry.Id, error)); } } return totalCount; }
/// <summary> /// Logs an exception and its context to the error log. /// </summary> protected virtual void LogException(Exception e, HttpContext context) { if (e == null) throw new ArgumentNullException("e"); // // Fire an event to check if listeners want to filter out // logging of the uncaught exception. // ExceptionFilterEventArgs args = new ExceptionFilterEventArgs(e, context); OnFiltering(args); if (args.Dismissed) return; // // Log away... // ErrorLogEntry entry = null; try { Error error = new Error(e, context); ErrorLog log = GetErrorLog(context); string id = log.Log(error); entry = new ErrorLogEntry(log, id, error); } catch (Exception localException) { // // IMPORTANT! We swallow any exception raised during the // logging and send them out to the trace . The idea // here is that logging of exceptions by itself should not // be critical to the overall operation of the application. // The bad thing is that we catch ANY kind of exception, // even system ones and potentially let them slip by. // Trace.WriteLine(localException); } if (entry != null) OnLogged(new ErrorLoggedEventArgs(entry)); }
protected override void OnLoad(EventArgs e) { // // Retrieve the ID of the error to display and read it from // the store. // string errorId = Mask.NullString(this.Request.QueryString["id"]); if (errorId.Length == 0) return; _errorEntry = this.ErrorLog.GetError(errorId); // // Perhaps the error has been deleted from the store? Whatever // the reason, bail out silently. // if (_errorEntry == null) { Response.Status = HttpStatus.NotFound.ToString(); return; } // // Setup the title of the page. // this.PageTitle = string.Format("Error: {0} [{1}]", _errorEntry.Error.Type, _errorEntry.Id); base.OnLoad(e); }