protected override void Append(LoggingEvent loggingEvent) { try { Guid Id = Guid.NewGuid(); // if exception is of type BusinessException, use the Correlation ID as the row key for the log entry if (loggingEvent.ExceptionObject != null && loggingEvent.ExceptionObject.GetType().IsAssignableFrom(typeof(BusinessException))) { Id = ((BusinessException)loggingEvent.ExceptionObject).CorrelationID; } AzureLogEntry logEntry = new AzureLogEntry(DateTime.Now, Id) { Logger = loggingEvent.LoggerName, Timestamp = loggingEvent.TimeStamp, Message = loggingEvent.RenderedMessage, Level = loggingEvent.Level.Name, Source = loggingEvent.LocationInformation.FullInfo, User = loggingEvent.UserName }; Exception exception = loggingEvent.ExceptionObject as LogException ?? new LogException(loggingEvent.RenderedMessage); logEntry.ErrorXml = ErrorXml.EncodeString(new Error(exception)); _ctx.Log(logEntry); } catch (Exception e) { ErrorHandler.Error(string.Format("{0}: Could not write log entry to {1}: {2}", GetType().AssemblyQualifiedName, storageTableName, e.Message)); } }
public override string Log(Error error) { var errorXml = ErrorXml.EncodeString(error); var id = Guid.NewGuid(); var token = Task.Run(() => GetAccessToken()).Result; if (string.IsNullOrWhiteSpace(token) && !httpContext.User.Identity.IsAuthenticated) { throw new SecurityException("Unauthenticated user"); } var innerException = error.Exception as ApiException; if (innerException != null && innerException.ErrorData != null) { Task.Run(() => apiClient.ErrorLog.Create(token, new ErrorData(Guid.NewGuid(), ApplicationName, error.HostName, error.Type, innerException.Source, innerException.ErrorData.ExceptionMessage, error.User, (int)innerException.StatusCode, error.Time.ToUniversalTime(), GetApiErrorAsXml(innerException.ErrorData)))); } var errorData = new ErrorData(id, ApplicationName, error.HostName, error.Type, error.Source, error.Message, error.User, error.StatusCode, error.Time.ToUniversalTime(), errorXml); Task.Run(() => apiClient.ErrorLog.Create(token, errorData)); return(id.ToString()); }
public override int GetErrors(int pageIndex, int pageSize, ICollection <ErrorLogEntry> errorEntryCollection) { if (pageIndex < 0) { var paramName = nameof(pageIndex); var message = $"Argument {paramName} can't have negative value!"; LoggerExtensions.LogError($"Error in RedisErrorLog: {message}"); throw new ArgumentOutOfRangeException(paramName, pageIndex, message); } if (pageSize < 0) { var paramName = nameof(pageSize); var message = $"Argument {paramName} has negative value."; LoggerExtensions.LogError($"Error in RedisErrorLog: {message}"); throw new ArgumentOutOfRangeException(paramName, pageSize, message); } if (errorEntryCollection == null) { errorEntryCollection = new List <ErrorLogEntry>(); } var allLoggedErrors = _redisClient.GetValues(GetRedisKey("*")); var loggedErrors = allLoggedErrors.ToArray(); foreach (var eachLog in loggedErrors.Skip(pageSize * pageIndex).Take(pageSize)) { var error = ErrorXml.DecodeString(eachLog.Info); errorEntryCollection.Add(new ErrorLogEntry(this, eachLog.Id.ToString(), error)); } return(loggedErrors.Count()); }
public ErrorEntity(Error error) : base() { PartitionKey = TableErrorLog.TableName; RowKey = (DateTime.MaxValue.Ticks - DateTime.UtcNow.Ticks).ToString("d19"); this.SerializedError = ErrorXml.EncodeString(error); }
public override ErrorLogEntry GetError(string id) { if (string.IsNullOrEmpty(id)) { throw new ArgumentNullException(nameof(id)); } Guid errorId; if (!Guid.TryParse(id, out errorId)) { throw new ArgumentException("Could not parse id as guid", nameof(id)); } var dbElmahErrors = dataModel.ElmahErrors.Where(x => x.Id == errorId); if (ApplicationName != "*") { dbElmahErrors = dbElmahErrors.Where(x => x.Application == ApplicationName); } var dbElmahError = dbElmahErrors.SingleOrDefault(); if (dbElmahError == null) { return(null); } var error = ErrorXml.DecodeString(dbElmahError.AllXml); return(new ErrorLogEntry(this, id, error)); }
private static ErrorData CreateErrorDataFromXml(Guid id, string xml) { var error = ErrorXml.DecodeString(xml); return(new ErrorData(id, error.ApplicationName, error.HostName, error.Type, error.Source, error.Message, error.User, error.StatusCode, error.Time, xml)); }
public override string Log(Error error) { if (error == null) { throw new ArgumentNullException(nameof(error)); } var errorXml = ErrorXml.EncodeString(error); using (var scope = DataAccessScope.CreateReadCommitted()) { var dbElmahError = dataModel.ElmahErrors.Create(); dbElmahError.Application = ApplicationName; dbElmahError.Host = error.HostName; dbElmahError.Type = error.Type; dbElmahError.Source = error.Source; dbElmahError.Message = error.Message; dbElmahError.User = error.User; dbElmahError.StatusCode = error.StatusCode; dbElmahError.TimeUtc = error.Time; dbElmahError.AllXml = errorXml; scope.Complete(); return(dbElmahError.Id.ToString()); } }
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); } if (errorEntryList == null) { throw new ArgumentNullException("errorEntryList"); } var blobContainer = GetBlobContainer(); var blobs = blobContainer.ListBlobs() .OfType <CloudBlockBlob>() .Skip(pageIndex * pageSize) .Take(pageSize); var count = 0; foreach (var blob in blobs) { count++; using (var blobStream = blob.OpenRead()) using (var reader = new XmlTextReader(blobStream)) { var error = ErrorXml.Decode(reader); errorEntryList.Add(new ErrorLogEntry(this, blob.Name, error)); } } return(count); }
/// <summary> /// Logs an error /// </summary> /// <param name="error">the error data</param> /// <returns>the new ErrorId created in the table</returns> 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 = CommandsWithApplicationId.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()); } } }
public override string Log(Error error) { string errorId = Guid.NewGuid().ToString(); DateTime time = (error.Time > DateTime.MinValue) ? error.Time : DateTime.Now; string fileName = string.Format(CultureInfo.InvariantCulture, "error-{0:yyyy-MM-ddHHmmssZ}-{1}.xml", new object[] { time.ToUniversalTime(), errorId }); var blobContainer = GetBlobContainer(); var blob = blobContainer.GetBlobReference(fileName); using (var memory = new MemoryStream()) { using (XmlTextWriter writer = new XmlTextWriter(memory, Encoding.UTF8)) { writer.Formatting = Formatting.Indented; writer.WriteStartElement("error"); writer.WriteAttributeString("errorId", errorId); ErrorXml.Encode(error, writer); writer.WriteEndElement(); writer.Flush(); memory.Position = 0; blob.UploadFromStream(memory); } } return(errorId); }
public override string Log(Error error) { AssertTableExists(); var allXml = ErrorXml.EncodeString(error); var id = Guid.NewGuid(); var entity = new ErrorEntity { ErrorId = id, Application = ApplicationName, Host = error.HostName, Type = error.Type, Source = error.Source, Message = error.Message, User = error.User, StatusCode = error.StatusCode, TimeUtc = error.Time.ToUniversalTime(), AllXml = allXml }; using (var context = new DynamoDBContext(_client)) { context.Save(entity, new DynamoDBOperationConfig { OverrideTableName = TableName }); } return(id.ToString()); }
public override string Log(Error error) { Guid Id = Guid.NewGuid(); // if exception is of type BusinessException, use the Correlation ID as the row key for the log entry if (error.Exception != null && error.Exception.GetType().IsAssignableFrom(typeof(BusinessException))) { Id = ((BusinessException)error.Exception).CorrelationID; } AzureLogEntry entity = new AzureLogEntry(error.Time, Id) { Host = error.HostName, Type = error.Type, ErrorXml = ErrorXml.EncodeString(error), Message = error.Message, Code = error.StatusCode, User = error.User, Source = error.Source, Logger = "Elmah" }; _ctx.AddObject(storageTableName, entity); _ctx.SaveChanges(); return(entity.ID.ToString()); }
public override string Log(Error error) { try { var elmahError = new ExceptionLog() { Error = ErrorXml.EncodeString(error), //ApplicationName = error.ApplicationName, //Cookies = error.Cookies, Detail = error.Detail, //Exception = error.Exception, //Form = error.Form, //HostName = error.HostName, LocalDateTime = LanguageManager.ToLocalDateTime(error.Time.ToUniversalTime()), Time = error.Time.ToUniversalTime(), Message = error.Message, //QueryString = error.QueryString, //ServerVariables = error.ServerVariables, Source = error.Source, StatusCode = error.StatusCode, Type = error.Type, User = error.User, WebHostHtmlMessage = error.WebHostHtmlMessage, IsDebugMode = Settings.IsDebugMode, IsMobileMode = Settings.IsMobileMode }; AddedLogDictionary.TryAdd(Guid.NewGuid().ToString(), elmahError); } catch (Exception ex) { LogException(ex.ToString()); } return("1"); }
public void CanGetError() { // Arrange var fixture = new Fixture(); var id = fixture.Create <string>(); var applicationName = fixture.Create <string>(); var error = new Error(new HttpException()); var errorXml = ErrorXml.EncodeString(error); var elasticClientMock = new Mock <IElasticClient>(); elasticClientMock .Setup(x => x.Get <ErrorDocument>(id)) .Returns(new ErrorDocument { ErrorXml = errorXml }); var errorLog = new ElasticSearchErrorLog(elasticClientMock.Object) { ApplicationName = applicationName, }; // Act var elmahError = errorLog.GetError(id); // Assert Assert.That(elmahError != null); Assert.That(elmahError.Id, Is.EqualTo(id)); Assert.That(elmahError.Error != null); Assert.That(elmahError.Error.ApplicationName, Is.EqualTo(applicationName)); }
void ITableEntity.ReadEntity(IDictionary <string, EntityProperty> properties, Microsoft.WindowsAzure.Storage.OperationContext operationContext) { // This can occasionally fail because someone didn't finish creating the entity yet. EntityProperty value; if (properties.TryGetValue("SerializedError", out value)) { Error = ErrorXml.DecodeString(value.StringValue); } else { Error = new Error { ApplicationName = "TableErrorLog", StatusCode = 999, HostName = Environment.MachineName, Time = DateTime.UtcNow, Type = typeof(Exception).FullName, Detail = "Error Log Entry is Corrupted/Missing in Table Store" }; return; } if (properties.TryGetValue("Detail", out value)) { Error.Detail = value.StringValue; } if (properties.TryGetValue("WebHostHtmlMessage", out value)) { Error.WebHostHtmlMessage = value.StringValue; } }
/// <summary> /// Returns a page of errors from the database 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); } // Skip is not allowed, so we will take extra records and then discard ones that weren't requested. // This obviously has a performance hit, but since users are usually looking at the latest ones, this may be OK for most scenarios. var partitionKey = AzureHelper.EncodeAzureKey(ApplicationName); var tableQuery = _cloudTable.CreateQuery <ElmahEntity>() .Where(e => e.PartitionKey == partitionKey) .Take((pageIndex + 1) * pageSize); var errorEntities = _cloudTable .ExecuteQuery(tableQuery as TableQuery <ElmahEntity>) .Skip(pageIndex * pageSize); foreach (var errorEntity in errorEntities) { var error = ErrorXml.DecodeString(errorEntity.AllXml); errorEntryList.Add(new ErrorLogEntry(this, errorEntity.RowKey, error)); } // Azure Table Storage cannot return the total number of records, // so if the max number of errors are displayed, // we will report an extra element to indicate to the user that more records may exist return(errorEntryList.Count == pageSize ? (pageIndex + 1) * pageSize + 1 : pageIndex *pageSize + errorEntryList.Count); }
public string Html() { try { var path = Path.Combine(_rootPathProvider.GetRootPath(), "App_Data/Elmah"); var info = new DirectoryInfo(path); var logs = info.GetFiles("*.xml") .OrderByDescending(f => f.CreationTime) .Select(f => { using (var xmlReader = XmlReader.Create(new StreamReader(f.FullName))) { var error = ErrorXml.Decode(xmlReader); return($"\n--- {f.Name}\n{XmlErrorToString(error)}"); } }) .Take(20); return($"<pre>{string.Join("\n", logs)}</pre>"); } catch (Exception ex) { ErrorSignal.FromCurrentContext().Raise(ex); return($"<pre>{ex.Message}</pre>"); } }
/// <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"); } var elmahEntity = new ElmahEntity(ApplicationName) { AllXml = ErrorXml.EncodeString(error), ApplicationName = ApplicationName, HostName = error.HostName, Message = error.Message, Source = error.Source, StatusCode = error.StatusCode, Type = error.Type, User = error.User, }; var tableOperation = TableOperation.Insert(elmahEntity); _cloudTable.Execute(tableOperation); return(elmahEntity.RowKey); }
public override int GetErrors(int errorIndex, int pageSize, ICollection <ErrorLogEntry> errorEntryList) { if (errorIndex < 0) { throw new ArgumentOutOfRangeException("errorIndex", errorIndex, null); } if (pageSize < 0) { throw new ArgumentOutOfRangeException("pageSize", pageSize, null); } using (var connection = new MySqlConnection(ConnectionString)) { connection.Open(); using (var command = CommandExtension.GetErrorsXml(ApplicationName, errorIndex, pageSize)) { command.Connection = connection; using (var reader = command.ExecuteReader()) { while (reader.Read()) { var id = reader.GetGuid(0); var xml = reader.GetString(1); var error = ErrorXml.DecodeString(xml); errorEntryList.Add(new ErrorLogEntry(this, id.ToString(), error)); } } } return(this.GetTotalErrorsXml(connection)); } }
/// <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 = Error.GetErrorXml(errorGuid, this.ApplicationName); if (errorXml == null) { return(null); } var error = ErrorXml.DecodeString(errorXml); return(new ErrorLogEntry(this, id, error)); }
public override int GetErrors(int pageIndex, int pageSize, IList errorEntryList) { var result = _elasticClient.Search <ErrorDocument>(x => x .Query(q => q .Term("applicationName.raw", ApplicationName) ) .Skip(pageSize * pageIndex) .Take(pageSize) .Sort(s => s .Descending(d => d.Time) ) ) .VerifySuccessfulResponse(); //var debug = result.GetRequestString(); foreach (var errorDocHit in result.Hits) { var error = ErrorXml.DecodeString(errorDocHit.Source.ErrorXml); error.ApplicationName = ApplicationName; errorEntryList.Add(new ErrorLogEntry(this, errorDocHit.Id, error)); } return((int)result.Total); }
public override ErrorLogEntry GetError(string id) { if (id == null) { throw new ArgumentNullException(nameof(id)); } AssertTableExists(); Guid key; if (!Guid.TryParse(id, out key)) { throw new ArgumentException($"Invalid id '{id}'", nameof(id)); } using (var context = new DynamoDBContext(_client)) { var entity = context.Load <ErrorEntity>(key, new DynamoDBOperationConfig { OverrideTableName = TableName }); var error = ErrorXml.DecodeString(entity.AllXml); return(new ErrorLogEntry(this, id, error)); } }
public override string Log(Error error) { var indexResponse = _elasticClient.Index (new IndexRequest <ErrorDocument>(new ErrorDocument { ApplicationName = ApplicationName, ErrorXml = ErrorXml.EncodeString(error), Detail = error.Detail, HostName = error.HostName, Message = error.Message, Source = error.Source, StatusCode = error.StatusCode, Time = error.Time, Type = error.Type, User = error.User, WebHostHtmlMessage = error.WebHostHtmlMessage, CustomerName = CustomerName, EnvironmentName = EnvironmentName, ServerVariables = ConvertToKeyValue(error.ServerVariables) })); indexResponse.VerifySuccessfulResponse(); return(indexResponse.Id); }
private static Error GetElmahError(string errorXml) { if (!string.IsNullOrEmpty(errorXml)) { return(ErrorXml.DecodeString(errorXml)); } return(new Error(new Exception("Unknown error format."))); }
public void GetErrors() { // Arrange var fixture = new Fixture(); var id1 = fixture.Create <string>(); var id2 = fixture.Create <string>(); var applicationName = fixture.Create <string>(); var error1 = new Error(new Exception("error1")); var error2 = new Error(new Exception("error2")); var errorXml1 = ErrorXml.EncodeString(error1); var errorXml2 = ErrorXml.EncodeString(error2); var errorDoc1 = new ErrorDocument { ErrorXml = errorXml1 }; var errorDoc2 = new ErrorDocument { ErrorXml = errorXml2 }; var queryResponse = new Mock <ISearchResponse <ErrorDocument> >(); queryResponse.Setup(x => x.Total).Returns(2); queryResponse.Setup(x => x.Hits).Returns(() => { var mockHit1 = new Mock <IHit <ErrorDocument> >(); mockHit1.Setup(x => x.Id).Returns(id1); mockHit1.Setup(x => x.Source).Returns(errorDoc1); var mockHit2 = new Mock <IHit <ErrorDocument> >(); mockHit2.Setup(x => x.Id).Returns(id2); mockHit2.Setup(x => x.Source).Returns(errorDoc2); return(new[] { mockHit1.Object, mockHit2.Object }); }); queryResponse.Setup(x => x.IsValid).Returns(true); _elasticClientMock .Setup(x => x.Search(It.IsAny <Func <SearchDescriptor <ErrorDocument>, ISearchRequest> >())) .Returns(queryResponse.Object); var errorLog = new ElasticSearchErrorLog(_elasticClientMock.Object, new Hashtable()) { ApplicationName = applicationName }; // Act var result = new ArrayList(); var count = errorLog.GetErrors(0, int.MaxValue, result); // Assert Assert.That(count, Is.EqualTo(2)); Assert.That(result.Count, Is.EqualTo(2)); }
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); } var blobContainer = GetBlobContainer(); var blobs = blobContainer.ListBlobs(); if (blobs.Count() < 1) { return(0); } int count = 0; string[] keys = new string[blobs.Count()]; foreach (var blob in blobs) { keys[count++] = blob.Uri.ToString(); } Array.Sort(keys, 0, count, Comparer.DefaultInvariant); Array.Reverse(keys, 0, count); if (errorEntryList != null) { int firstIndex = pageIndex * pageSize; int lastIndex = (firstIndex + pageSize < count) ? firstIndex + pageSize : count; for (int i = firstIndex; i < lastIndex; i++) { var blob = blobContainer.GetBlobReference(keys[i]); using (var stream = new MemoryStream()) { blob.DownloadToStream(stream); stream.Position = 0; using (XmlTextReader reader = new XmlTextReader(stream)) { while (reader.IsStartElement("error")) { string attribute = reader.GetAttribute("errorId"); Error error = ErrorXml.Decode(reader); errorEntryList.Add(new ErrorLogEntry(this, attribute, error)); } } } } } return(count); }
public override int GetErrors(int pageIndex, int pageSize, IList errorEntryList) { AssertTableExists(); var max = pageSize * (pageIndex + 1); Dictionary <string, AttributeValue> lastEvaluatedKey = null; var errors = new List <ErrorLogEntry>(max); // have to start at the beginning and go through up to the current page, this means it will perform worse as we go through more pages // usually, we are just looking at the first few pages so ¯\_(ツ)_/¯ // low level scanning http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LowLevelDotNetScanning.html#LowLevelDotNetScanningOptions do { var request = new QueryRequest(TableName) { KeyConditionExpression = "Application = :v_appl", ExpressionAttributeValues = new Dictionary <string, AttributeValue> { { ":v_appl", new AttributeValue(ApplicationName) } }, IndexName = "Application-TimeUtc-index", ScanIndexForward = false, Limit = max, Select = Select.ALL_PROJECTED_ATTRIBUTES }; if (lastEvaluatedKey != null) { request.ExclusiveStartKey = lastEvaluatedKey; } var response = _client.Query(request); errors.AddRange(from item in response.Items let errorXml = item["AllXml"].S let errorId = item["ErrorId"].S let error = ErrorXml.DecodeString(errorXml) select new ErrorLogEntry(this, errorId, error)); lastEvaluatedKey = response.LastEvaluatedKey; } while (lastEvaluatedKey != null && lastEvaluatedKey.Count > 0 && errors.Count < max); var numberToSkip = pageIndex * pageSize; errors = errors.Skip(numberToSkip).Take(pageSize).ToList(); errors.ForEach(err => errorEntryList.Add(err)); // get total count of items in the table. // This value is stale (updates every six hours) but will do the job in most cases // the other alternative would be to do another scan of the entire index with a Select.COUNT var total = _client.DescribeTable(new DescribeTableRequest(TableName)).Table.ItemCount; return(Convert.ToInt32(Math.Max(errorEntryList.Count, total))); }
public override ErrorLogEntry GetError(string id) { var document = _elasticClient.Get <ErrorDocument>(id); var error = ErrorXml.DecodeString(document.ErrorXml); error.ApplicationName = ApplicationName; var result = new ErrorLogEntry(this, id, error); return(result); }
public override ErrorLogEntry GetError(string id) { var errorDoc = _elasticClient.Get <ErrorDocument>(id).VerifySuccessfulResponse(); var error = ErrorXml.DecodeString(errorDoc.Source.ErrorXml); error.ApplicationName = ApplicationName; var result = new ErrorLogEntry(this, id, error); return(result); }
public override int GetErrors(int pageIndex, int pageSize, IList errorEntryList) { var count = 0; foreach (var error in CloudStorageAccount.Parse(connectionString).CreateCloudTableClient().GetDataServiceContext().CreateQuery <ErrorEntity>("elmaherrors").Where(e => e.PartitionKey == string.Empty).AsTableServiceQuery().Take((pageIndex + 1) * pageSize).ToList().Skip(pageIndex * pageSize)) { errorEntryList.Add(new ErrorLogEntry(this, error.RowKey, ErrorXml.DecodeString(error.SerializedError))); count += 1; } return(count); }