private ErrorLogEntry LoadErrorLogEntry(string path) { for (var i = 0; i < 5; i++) { try { using var reader = XmlReader.Create(path, new XmlReaderSettings() { CheckCharacters = false }); if (!reader.IsStartElement("error")) { return(null); } var id = reader.GetAttribute("errorId"); var error = ErrorXml.Decode(reader); return(new ErrorLogEntry(this, id, error)); } catch (IOException) { //ignored Task.Delay(500).GetAwaiter().GetResult(); } } throw new IOException(""); }
/// <summary> /// Returns the specified error from the filesystem, or throws an exception if it does not exist. /// </summary> public override ErrorLogEntry GetError(string id) { try { id = new Guid(id).ToString(); // validate GUID } catch (FormatException e) { throw new ArgumentException(e.Message, id, e); } var file = new DirectoryInfo(LogPath).GetFiles($"error-*-{id}.xml") .FirstOrDefault(); if (file == null) { return(null); } if (!IsUserFile(file.Attributes)) { return(null); } using var reader = XmlReader.Create(file.FullName); return(new ErrorLogEntry(this, id, ErrorXml.Decode(reader))); }
private void ErrorsXmlToList(XmlReader reader, ICollection <ErrorLogEntry> errorEntryList) { Debug.Assert(reader != null); if (errorEntryList != null) { while (reader.IsStartElement("error")) { string id = reader.GetAttribute("errorId"); Error error = ErrorXml.Decode(reader); errorEntryList.Add(new ErrorLogEntry(this, id, error)); } } }
private ErrorLogEntry LoadErrorLogEntry(string path) { using (var reader = XmlReader.Create(path)) { if (!reader.IsStartElement("error")) { return(null); } var id = reader.GetAttribute("errorId"); var error = ErrorXml.Decode(reader); return(new ErrorLogEntry(this, id, error)); } }
public static void ProcessRequest(HttpContext context, ErrorLog errorLog) { var response = context.Response; response.ContentType = "application/xml"; // // Retrieve the ID of the requested error and read it from // the store. // var errorId = context.Request.Query["id"].FirstOrDefault(); if (string.IsNullOrEmpty(errorId)) { throw new ApplicationException("Missing error identifier specification."); } var entry = errorLog.GetError(errorId); // // Perhaps the error has been deleted from the store? Whatever // the reason, pretend it does not exist. // if (entry == null) { context.Response.StatusCode = 404; } // // Stream out the error as formatted XML. // var settings = new XmlWriterSettings(); settings.Indent = true; settings.NewLineOnAttributes = true; settings.CheckCharacters = false; var writer = XmlWriter.Create(response.Body, settings); writer.WriteStartDocument(); writer.WriteStartElement("error"); ErrorXml.Encode(entry.Error, writer); writer.WriteEndElement(/* error */); writer.WriteEndDocument(); writer.Flush(); }
/// <summary> /// Logs an error to the database. /// </summary> /// <remarks> /// Logs an error as a single XML file stored in a folder. XML files are named with a /// sortable date and a unique identifier. Currently the XML files are stored indefinately. /// As they are stored as files, they may be managed using standard scheduled jobs. /// </remarks> public override string Log(Error error) { var logPath = LogPath; if (!Directory.Exists(logPath)) { Directory.CreateDirectory(logPath); } var errorId = Guid.NewGuid().ToString(); var timeStamp = (error.Time > DateTime.MinValue ? error.Time : DateTime.Now); var fileName = string.Format(CultureInfo.InvariantCulture, @"error-{0:yyyy-MM-ddHHmmssZ}-{1}.xml", /* 0 */ timeStamp.ToUniversalTime(), /* 1 */ errorId); var path = Path.Combine(logPath, fileName); try { using (var writer = new XmlTextWriter(path, Encoding.UTF8)) { writer.Formatting = Formatting.Indented; writer.WriteStartElement("error"); writer.WriteAttributeString("errorId", errorId); ErrorXml.Encode(error, writer); writer.WriteEndElement(); writer.Flush(); } } catch (IOException) { // If an IOException is thrown during writing the file, // it means that we will have an either empty or // partially written XML file on disk. In both cases, // the file won't be valid and would cause an error in // the UI. File.Delete(path); throw; } return(errorId); }
/// <summary> /// Returns the specified error from the database, or null /// if it does not exist. /// </summary> public override ErrorLogEntry GetError(string id) { if (id == null) { throw new ArgumentNullException("id"); } if (id.Length == 0) { throw new ArgumentException(null, "id"); } Guid errorGuid; try { errorGuid = new Guid(id); } catch (FormatException e) { throw new ArgumentException(e.Message, "id", e); } string errorXml; using (SqlConnection connection = new SqlConnection(this.ConnectionString)) using (SqlCommand command = Commands.GetErrorXml(this.ApplicationName, errorGuid)) { command.Connection = connection; connection.Open(); errorXml = (string)command.ExecuteScalar(); } if (errorXml == null) { return(null); } Error error = ErrorXml.DecodeString(errorXml); return(new ErrorLogEntry(this, id, error)); }
/// <summary> /// Returns the specified error from the database, or null /// if it does not exist. /// </summary> public override ErrorLogEntry GetError(string id) { if (id == null) { throw new ArgumentNullException("id"); } if (id.Length == 0) { throw new ArgumentException(null, "id"); } string errorXml = string.Empty; var connections = new List <string>(); if (this.ConnectionString.Contains(",")) { foreach (var connection in this.ConnectionString.Split(',')) { connections.Add(connection); } } var redisManager = connections.Count() == 0 ? new RedisManagerPool(this.ConnectionString) : new RedisManagerPool(connections); using (var client = redisManager.GetClient()) { Guid errorGuid = new Guid(id); var redis = client.As <RedisObject>(); var redisObject = redis.GetById(errorGuid); if (redisObject != null) { errorXml = redisObject.AllXml; } } if (errorXml == null) { return(null); } Error error = ErrorXml.DecodeString(errorXml); return(new ErrorLogEntry(this, id, error)); }
/// <summary> /// Logs an error to the database. /// </summary> /// <remarks> /// Use the stored procedure called by this implementation to set a /// policy on how long errors are kept in the log. The default /// implementation stores all errors for an indefinite time. /// </remarks> public override string Log(Error error) { if (error == null) { throw new ArgumentNullException("error"); } string errorXml = ErrorXml.EncodeString(error); Guid id = Guid.NewGuid(); var connections = new List <string>(); if (this.ConnectionString.Contains(",")) { foreach (var connection in this.ConnectionString.Split(',')) { connections.Add(connection); } } var redisManager = connections.Count() == 0 ? new RedisManagerPool(this.ConnectionString) : new RedisManagerPool(connections); using (var client = redisManager.GetClient()) { var redis = client.As <RedisObject>(); var redisObject = new RedisObject() { AllXml = errorXml, Application = this.ApplicationName, ErrorId = id, Host = error.HostName, Message = error.Message, Source = error.Source, StatusCode = error.StatusCode, TimeUtc = error.Time.ToUniversalTime(), Type = error.Type, User = error.User, Id = id }; redis.AddToRecentsList(redisObject); redis.Store(redisObject); } return(id.ToString()); }
/// <summary> /// Logs an error to the database. /// </summary> /// <remarks> /// Use the stored procedure called by this implementation to set a /// policy on how long errors are kept in the log. The default /// implementation stores all errors for an indefinite time. /// </remarks> public override string Log(Error error) { if (error == null) { throw new ArgumentNullException("error"); } string errorXml = ErrorXml.EncodeString(error); Guid id = Guid.NewGuid(); using (SqlConnection connection = new SqlConnection(this.ConnectionString)) using (SqlCommand command = Commands.LogError( id, this.ApplicationName, error.HostName, error.Type, error.Source, error.Message, error.User, error.StatusCode, error.Time.ToUniversalTime(), errorXml)) { command.Connection = connection; connection.Open(); command.ExecuteNonQuery(); return(id.ToString()); } }
/// <summary> /// Returns a page of errors from the databse in descending order /// of logged time. /// </summary> public override int GetErrors(int pageIndex, int pageSize, ICollection <ErrorLogEntry> errorEntryList) { if (pageIndex < 0) { throw new ArgumentOutOfRangeException("pageIndex", pageIndex, null); } if (pageSize < 0) { throw new ArgumentOutOfRangeException("pageSize", pageSize, null); } var connections = new List <string>(); if (this.ConnectionString.Contains(",")) { foreach (var connection in this.ConnectionString.Split(',')) { connections.Add(connection); } } var redisManager = connections.Count() == 0 ? new RedisManagerPool(this.ConnectionString) : new RedisManagerPool(connections); using (var client = redisManager.GetClient()) { var redis = client.As <RedisObject>(); var index = pageIndex - 1; var objects = redis.GetLatestFromRecentsList(1, pageSize); foreach (var redisError in objects) { errorEntryList.Add(new ErrorLogEntry(this, redisError.ErrorId.ToString(), ErrorXml.DecodeString(redisError.AllXml))); } var total = client.As <RedisObject>().GetAll().Count(); return(total); } }