Пример #1
0
        protected override void OnLoad(EventArgs e)
        {
            //
            // Retrieve the ID of the error to display and read it from
            // the store.
            //

            string errorId = StringEtc.MaskNull(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)
                return;

            //
            // Setup the title of the page.
            //

            this.Title = string.Format("Error: {0} [{1}]", _errorEntry.Error.Type, _errorEntry.Id);

            base.OnLoad(e);
        }
Пример #2
0
            public void Add(Guid id, 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);
            }
Пример #3
0
        protected override void Render(HtmlTextWriter writer)
        {
            if (writer == null)
            {
                throw new ArgumentNullException("writer");
            }

            //
            // Retrieve the ID of the error to display and read it from
            // the log.
            //

            string errorId = StringEtc.MaskNull(this.Request.QueryString["id"]);

            if (errorId.Length == 0)
            {
                return;
            }

            ErrorLogEntry errorEntry = this.ErrorLog.GetError(errorId);

            if (errorEntry == null)
            {
                return;
            }

            //
            // If we have a host (ASP.NET) formatted HTML message
            // for the error then just stream it out as our response.
            //

            if (errorEntry.Error.WebHostHtmlMessage.Length != 0)
            {
                writer.Write(errorEntry.Error.WebHostHtmlMessage);
            }
        }
Пример #4
0
        /// <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");
            }

            if (pageSize < 0)
            {
                throw new ArgumentOutOfRangeException("pageSite");
            }

            //
            // 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;
            int             totalCount;

            _lock.AcquireReaderLock(Timeout.Infinite);

            try
            {
                if (_entries == null)
                {
                    return(0);
                }

                int lastIndex = Math.Max(0, _entries.Count - (pageIndex * pageSize)) - 1;
                selectedEntries = new ErrorLogEntry[lastIndex + 1];

                int sourceIndex = lastIndex;
                int targetIndex = 0;

                while (sourceIndex >= 0)
                {
                    selectedEntries[targetIndex++] = _entries[sourceIndex--];
                }

                totalCount = _entries.Count;
            }
            finally
            {
                _lock.ReleaseReaderLock();
            }

            //
            // 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);
        }
Пример #5
0
        private void RenderErrors(HtmlTextWriter writer)
        {
            Debug.Assert(writer != null);

            //
            // Create a table to display error information in each row.
            //

            Table table = new Table();

            table.ID          = "ErrorLog";
            table.CellSpacing = 0;

            //
            // Create the table row for headings.
            //

            TableRow headRow = new TableRow();

            headRow.Cells.Add(FormatCell(new TableHeaderCell(), "Host", "host-col"));
            headRow.Cells.Add(FormatCell(new TableHeaderCell(), "Code", "code-col"));
            headRow.Cells.Add(FormatCell(new TableHeaderCell(), "Type", "type-col"));
            headRow.Cells.Add(FormatCell(new TableHeaderCell(), "Error", "error-col"));
            headRow.Cells.Add(FormatCell(new TableHeaderCell(), "User", "user-col"));
            headRow.Cells.Add(FormatCell(new TableHeaderCell(), "Date", "date-col"));
            headRow.Cells.Add(FormatCell(new TableHeaderCell(), "Time", "time-col"));

            table.Rows.Add(headRow);

            //
            // Generate a table body row for each error.
            //

            for (int errorIndex = 0; errorIndex < _errorEntryList.Count; errorIndex++)
            {
                ErrorLogEntry errorEntry = (ErrorLogEntry)_errorEntryList[errorIndex];
                Error         error      = errorEntry.Error;

                TableRow bodyRow = new TableRow();
                bodyRow.CssClass = errorIndex % 2 == 0 ? "even-row" : "odd-row";

                //
                // Format host and status code cells.
                //

                bodyRow.Cells.Add(FormatCell(new TableCell(), error.HostName, "host-col"));
                bodyRow.Cells.Add(FormatCell(new TableCell(), error.StatusCode.ToString(), "code-col"));
                bodyRow.Cells.Add(FormatCell(new TableCell(), GetSimpleErrorType(error), "type-col", error.Type));

                //
                // Format the message cell, which contains the message
                // text and a details link pointing to the page where
                // all error details can be viewed.
                //

                TableCell messageCell = new TableCell();
                messageCell.CssClass = "error-col";

                Label messageLabel = new Label();
                messageLabel.Text = this.Server.HtmlEncode(error.Message);

                HyperLink detailsLink = new HyperLink();
                detailsLink.NavigateUrl = this.Request.Path + "/detail?id=" + errorEntry.Id;
                detailsLink.Text        = "[Details]";

                messageCell.Controls.Add(messageLabel);
                messageCell.Controls.Add(new LiteralControl(" "));
                messageCell.Controls.Add(detailsLink);

                bodyRow.Cells.Add(messageCell);

                //
                // Format the user, date and time cells.
                //

                bodyRow.Cells.Add(FormatCell(new TableCell(), error.User, "user-col"));
                bodyRow.Cells.Add(FormatCell(new TableCell(), error.Time.ToShortDateString(), "date-col",
                                             error.Time.ToLongDateString()));
                bodyRow.Cells.Add(FormatCell(new TableCell(), error.Time.ToLongTimeString(), "time-col"));

                //
                // Finally, add the row to the table.
                //

                table.Rows.Add(bodyRow);
            }

            table.RenderControl(writer);
        }
Пример #6
0
            public void Add(Guid id, 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);
            }
Пример #7
0
        /// <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 void 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(newId, entry);
            }
            finally
            {
                _lock.ReleaseWriterLock();
            }
        }
Пример #8
0
        /// <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");

            if (pageSize < 0)
                throw new ArgumentOutOfRangeException("pageSite");

            //
            // 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;
            int totalCount;

            _lock.AcquireReaderLock(Timeout.Infinite);

            try
            {
                if (_entries == null)
                {
                    return 0;
                }

                int lastIndex = Math.Max(0, _entries.Count - (pageIndex * pageSize)) - 1;
                selectedEntries = new ErrorLogEntry[lastIndex + 1];

                int sourceIndex = lastIndex;
                int targetIndex = 0;

                while (sourceIndex >= 0)
                {
                    selectedEntries[targetIndex++] = _entries[sourceIndex--];
                }

                totalCount = _entries.Count;
            }
            finally
            {
                _lock.ReleaseReaderLock();
            }

            //
            // 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;
        }
Пример #9
0
        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/xml";

            //
            // Get the last set of errors for this application.
            //

            const int pageSize       = 15;
            ArrayList errorEntryList = new ArrayList(pageSize);

            ErrorLog.Default.GetErrors(0, pageSize, errorEntryList);

            //
            // We'll be emitting RSS vesion 0.91.
            //

            RichSiteSummary rss = new RichSiteSummary();

            rss.version = "0.91";

            //
            // Set up the RSS channel.
            //

            Channel channel = new Channel();

            channel.title       = "Error log of " + ErrorLog.Default.ApplicationName + " on " + Environment.MachineName;
            channel.description = "Log of recent errors";
            channel.language    = "en";
            channel.link        = context.Request.Url.GetLeftPart(UriPartial.Authority) +
                                  context.Request.ServerVariables["URL"];

            rss.channel = channel;

            //
            // For each error, build a simple channel item. Only the title,
            // description, link and pubDate fields are populated.
            //

            channel.item = new Item[errorEntryList.Count];

            for (int index = 0; index < errorEntryList.Count; index++)
            {
                ErrorLogEntry errorEntry = (ErrorLogEntry)errorEntryList[index];
                Error         error      = errorEntry.Error;

                Item item = new Item();

                item.title       = error.Message;
                item.description = "An error of type " + error.Type + " occurred. " + error.Message;
                item.link        = channel.link + "/detail?id=" + errorEntry.Id;
                item.pubDate     = error.Time.ToUniversalTime().ToString("r");

                channel.item[index] = item;
            }

            //
            // Stream out the RSS XML.
            //

            XmlSerializer serializer = new XmlSerializer(typeof(RichSiteSummary));

            serializer.Serialize(context.Response.Output, rss);
        }