/// <summary> /// Returns any rented resources for the <see cref="LoggerJsonMessageException"/> back to their parent pools. /// </summary> /// <param name="exception"><see cref="LoggerJsonMessageException"/>.</param> public static void Return(LoggerJsonMessageException exception) { Debug.Assert(exception != null); if (exception.InnerExceptions != null && s_ExceptionListPool.Count < 1024) { exception.InnerExceptions.Clear(); s_ExceptionListPool.Add(exception.InnerExceptions); exception.InnerExceptions = null; } }
/// <summary> /// Returns any rented resources for the <see cref="LoggerJsonMessage"/> back to their parent pools. /// </summary> /// <param name="message"><see cref="LoggerJsonMessage"/>.</param> public static void Return(LoggerJsonMessage message) { Debug.Assert(message != null); if (message.Scope != null && s_ScopeListPool.Count < 1024) { message.Scope.Clear(); s_ScopeListPool.Add(message.Scope); message.Scope = null; } if (message.Data != null && s_DataDictionaryPool.Count < 1024) { message.Data.Clear(); s_DataDictionaryPool.Add(message.Data); message.Data = null; } if (message.Exception != null) { LoggerJsonMessageException.Return(message.Exception); } }
/// <summary> /// Create a <see cref="LoggerJsonMessageException"/> instance from an <see cref="Exception"/> instance. /// </summary> /// <param name="exception">The exception to convert.</param> /// <returns>Created <see cref="LoggerJsonMessageException"/> instance.</returns> public static LoggerJsonMessageException FromException(Exception exception) { if (exception == null) { throw new ArgumentNullException(nameof(exception)); } LoggerJsonMessageException Exception = new LoggerJsonMessageException { ExceptionType = exception.GetType().Name, ErrorCode = $"0x{exception.HResult:X8}", Message = exception.Message }; if (!string.IsNullOrEmpty(exception.StackTrace)) { Exception.StackTrace = exception.StackTrace.Split('\r', '\n').Select(s => s.Trim()).Where(s => !string.IsNullOrEmpty(s)); } if (exception is AggregateException AggregateException) { Collection <LoggerJsonMessageException> Exceptions = new Collection <LoggerJsonMessageException>(); foreach (Exception ChildException in AggregateException.InnerExceptions) { Exceptions.Add(FromException(ChildException)); } Exception.InnerExceptions = Exceptions; } else if (exception.InnerException != null) { Exception.InnerExceptions = new[] { FromException(exception.InnerException) }; } return(Exception); }
/// <summary> /// Create a <see cref="LoggerJsonMessageException"/> instance from an <see cref="Exception"/> instance. /// </summary> /// <param name="exception">The exception to convert.</param> /// <returns>Created <see cref="LoggerJsonMessageException"/> instance.</returns> public static LoggerJsonMessageException FromException(Exception exception) { if (exception == null) { throw new ArgumentNullException(nameof(exception)); } LoggerJsonMessageException Exception = new LoggerJsonMessageException { ExceptionType = exception.GetType().Name, ErrorCode = $"0x{exception.HResult:X8}", Message = exception.Message }; Exception.StackTrace = exception.StackTrace; if (exception is AggregateException AggregateException) { List <LoggerJsonMessageException> Exceptions = RentExceptionList(); foreach (Exception ChildException in AggregateException.InnerExceptions) { Exceptions.Add(FromException(ChildException)); } Exception.InnerExceptions = Exceptions; } else if (exception.InnerException != null) { List <LoggerJsonMessageException> Exceptions = RentExceptionList(); Exceptions.Add(FromException(exception.InnerException)); Exception.InnerExceptions = Exceptions; } return(Exception); }
/// <summary> /// Create a <see cref="LoggerJsonMessage"/> instance from Logger data. /// </summary> /// <param name="categoryName">Category name associated with this entry.</param> /// <param name="scopeProvider"><see cref="IExternalScopeProvider"/>.</param> /// <param name="logLevel">Entry will be written on this level.</param> /// <param name="eventId">Id of the event.</param> /// <param name="state">The entry to be written. Can be also an object.</param> /// <param name="exception">The exception related to this entry.</param> /// <param name="formatter">Function to create a <see cref="string"/> message of the <paramref name="state"/> and <paramref name="exception"/>.</param> /// <typeparam name="TState">The type of the object to be written.</typeparam> /// <returns>Created <see cref="LoggerJsonMessage"/> instance.</returns> public static LoggerJsonMessage FromLoggerData <TState>( string categoryName, IExternalScopeProvider?scopeProvider, LogLevel logLevel, EventId eventId, TState state, Exception?exception, Func <TState, Exception?, string> formatter) { Debug.Assert(formatter != null); LoggerJsonMessage Message = new LoggerJsonMessage() { TimestampUtc = DateTime.UtcNow, ThreadId = Thread.CurrentThread.ManagedThreadId, EventId = eventId.Id != 0 ? eventId.Id : null, CategoryName = categoryName, LogLevel = logLevel switch { Microsoft.Extensions.Logging.LogLevel.Information => "Information", Microsoft.Extensions.Logging.LogLevel.Warning => "Warning", Microsoft.Extensions.Logging.LogLevel.Error => "Error", Microsoft.Extensions.Logging.LogLevel.Critical => "Critical", Microsoft.Extensions.Logging.LogLevel.Trace => "Trace", Microsoft.Extensions.Logging.LogLevel.Debug => "Debug", Microsoft.Extensions.Logging.LogLevel.None => "None", _ => throw new NotSupportedException($"LogLevel [{logLevel}] is not supported."), } }; scopeProvider?.ForEachScope(s_ParseScopeItem, Message); Message.GroupName = Message._Group?.GroupName; if (exception != null) { Message.Exception = LoggerJsonMessageException.FromException(exception); } if (state is FormattedLogValues formattedLogValues) { foreach (KeyValuePair <string, object?> Item in formattedLogValues) { AddStateItemToMessage(state, Message, Item); } } else if (state is IReadOnlyList <KeyValuePair <string, object?> > stateList) { for (int i = 0; i < stateList.Count; i++) { AddStateItemToMessage(state, Message, stateList[i]); } } else if (state is IEnumerable <KeyValuePair <string, object?> > stateValues) { foreach (KeyValuePair <string, object?> Item in stateValues) { AddStateItemToMessage(state, Message, Item); } } if (string.IsNullOrEmpty(Message.Content)) { string FormattedMessage = formatter(state, null); if (FormattedMessage != "[null]") { Message.Content = FormattedMessage; } } return(Message); }
/// <summary> /// Create a <see cref="LoggerJsonMessage"/> instance from Logger data. /// </summary> /// <param name="groupName">Group name associated with this entry.</param> /// <param name="categoryName">Category name associated with this entry.</param> /// <param name="scope">Scope data associated with this entry.</param> /// <param name="logLevel">Entry will be written on this level.</param> /// <param name="eventId">Id of the event.</param> /// <param name="state">The entry to be written. Can be also an object.</param> /// <param name="exception">The exception related to this entry.</param> /// <param name="formatter">Function to create a <see cref="string"/> message of the <paramref name="state"/> and <paramref name="exception"/>.</param> /// <typeparam name="TState">The type of the object to be written.</typeparam> /// <returns>Created <see cref="LoggerJsonMessage"/> instance.</returns> public static LoggerJsonMessage FromLoggerData <TState>( string?groupName, string categoryName, IEnumerable <object>?scope, LogLevel logLevel, EventId eventId, TState state, Exception?exception, Func <TState, Exception?, string> formatter) { if (formatter == null) { throw new ArgumentNullException(nameof(formatter)); } LoggerJsonMessage Message = new LoggerJsonMessage() { TimestampUtc = DateTime.UtcNow, ThreadId = Thread.CurrentThread.ManagedThreadId, EventId = eventId.Id != 0 ? (int?)eventId.Id : null, LogLevel = logLevel, GroupName = groupName, CategoryName = categoryName }; if (scope != null) { (Message.Data, Message.Scope) = ParseScope(scope); } if (exception != null) { Message.Exception = LoggerJsonMessageException.FromException(exception); } if (state is IEnumerable <KeyValuePair <string, object?> > StateValues) { foreach (KeyValuePair <string, object?> Item in StateValues) { if (Item.Key == "{OriginalFormat}") { // state should be a FormattedLogValues instance here, which formats when ToString is called. string FormattedMessage = state.ToString(); if (FormattedMessage != "[null]") { Message.Content = FormattedMessage; } continue; } if (Message.Data == null) { Message.Data = new Dictionary <string, object?>(); } if (Item.Key == "{Data}") { AddDataToMessage(Message.Data, Item.Value); continue; } Message.Data[Item.Key] = Item.Value; } } if (string.IsNullOrEmpty(Message.Content)) { string FormattedMessage = formatter(state, null); if (FormattedMessage != "[null]") { Message.Content = FormattedMessage; } } return(Message); }