Beispiel #1
0
        public void Log <TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func <TState, Exception, string> formatter)
        {
            var    response = new StreamingMessage();
            string message  = formatter(state, exception);
            var    rpcLog   = new RpcLog
            {
                EventId     = eventId.ToString(),
                Exception   = exception.ToRpcException(),
                Category    = _category,
                LogCategory = WorkerMessage.IsSystemLog ? RpcLogCategory.System : RpcLogCategory.User,
                Level       = ToRpcLogLevel(logLevel),
                Message     = message
            };

            // Grab the invocation id from the current scope, if present.
            _scopeProvider.ForEachScope((scope, log) =>
            {
                if (scope is IEnumerable <KeyValuePair <string, object> > properties)
                {
                    foreach (KeyValuePair <string, object> pair in properties)
                    {
                        if (pair.Key == FunctionInvocationScope.FunctionInvocationIdKey)
                        {
                            log.InvocationId = pair.Value?.ToString();
                            break;
                        }
                    }
                }
            },
                                        rpcLog);

            response.RpcLog = rpcLog;

            _channelWriter.TryWrite(response);
        }
        public void Log <TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func <TState, Exception, string> formatter)
        {
            if (!IsEnabled(logLevel))
            {
                return;
            }

            if (formatter == null)
            {
                throw new ArgumentNullException(nameof(formatter));
            }

            var message = formatter(state, exception);

            if (string.IsNullOrEmpty(message))
            {
                return;
            }

            if (!String.IsNullOrWhiteSpace(_settings.PLogFileMessageTemplate))
            {
                message = string.Format(_settings.PLogFileMessageTemplate, message);
            }

            message = _name + Environment.NewLine + message;

            if (exception != null)
            {
                message += Environment.NewLine + Environment.NewLine + exception;
            }

            _externalScopeProvider?.ForEachScope <object>((scope, _) => message += Environment.NewLine + scope, null);

            logProvider.Value.WriteLog(message, logLevel, eventId.Id);
        }
Beispiel #3
0
        private static object[] GetScope(IExternalScopeProvider scopeProvider)
        {
            var scopes = new List <object>();

            scopeProvider.ForEachScope((scope, list) => list.Add(GetStateObject(scope)), scopes);
            return(scopes.Count > 0 ? scopes.ToArray() : null);
        }
        /// <inheritdoc />
        public void Log <TState>(
            LogLevel logLevel,
            EventId eventId,
            TState state,
            Exception exception,
            Func <TState, Exception, string> formatter)
        {
            if (!IsEnabled(logLevel))
            {
                return;
            }

            if (formatter == null)
            {
                throw new ArgumentNullException(nameof(formatter));
            }

            var message = formatter(state, exception);

            if (string.IsNullOrEmpty(message))
            {
                return;
            }

            message = _name + Environment.NewLine + message;

            if (exception != null)
            {
                message += Environment.NewLine + Environment.NewLine + exception;
            }

            _externalScopeProvider?.ForEachScope <object>((scope, _) => message += Environment.NewLine + scope, null);

            WriteMessage(message, GetEventLogEntryType(logLevel), eventId.Id);
        }
Beispiel #5
0
        public void Log <TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func <TState, Exception, string> formatter)
        {
            scopes.Clear();
            scopeProvider.ForEachScope((x, scopes) => scopes.Add(x), scopes);

            var message = formatter(state, exception);

            if (scopes.Count > 0)
            {
                message = $"[{string.Join(">", scopes)}] {message}";
            }

            switch (logLevel)
            {
            case LogLevel.Trace:
            case LogLevel.Debug:
            case LogLevel.Information:
                Debug.Log(message);
                break;

            case LogLevel.Warning:
                Debug.LogWarning(message);
                break;

            case LogLevel.Error:
            case LogLevel.Critical:
                Debug.LogError(message);
                break;
            }
        }
Beispiel #6
0
        public void ScopesAreNotCreatedInIScopeProviderWhenScopesAreDisabled()
        {
            var provider = new Mock <ILoggerProvider>();
            var logger   = new Mock <ILogger>();

            IExternalScopeProvider externalScopeProvider = null;

            provider.Setup(loggerProvider => loggerProvider.CreateLogger(It.IsAny <string>()))
            .Returns(logger.Object);
            provider.As <ISupportExternalScope>().Setup(scope => scope.SetScopeProvider(It.IsAny <IExternalScopeProvider>()))
            .Callback((IExternalScopeProvider scopeProvider) => externalScopeProvider = scopeProvider);

            var factory = TestLoggerBuilder.Create(
                builder => {
                builder.AddProvider(provider.Object);
                builder.Services.Configure <LoggerFilterOptions>(options => options.CaptureScopes = false);
            });

            var newLogger  = factory.CreateLogger("Logger");
            int scopeCount = 0;

            using (newLogger.BeginScope("Scope"))
            {
                externalScopeProvider.ForEachScope <object>((_, __) => scopeCount++, null);
            }

            provider.Verify(p => p.CreateLogger("Logger"), Times.Once);
            logger.Verify(l => l.BeginScope(It.IsAny <object>()), Times.Never);
            Assert.Equal(0, scopeCount);
        }
Beispiel #7
0
            private string GetScopeInformation()
            {
                var stringBuilder = new StringBuilder();

                scopeProvider.ForEachScope((scope, state) => state.Append(" => ").Append(scope), stringBuilder);
                return(stringBuilder.ToString());
            }
        private Dictionary <string, object> GetScopeInformation()
        {
            var scopeProperties = new Dictionary <string, object>();

            _scopeProvider.ForEachScope(AddScopeToProperties, scopeProperties);

            return(scopeProperties);
        }
Beispiel #9
0
        protected override void AppendLogScopeInfo(StringBuilder sb, IExternalScopeProvider scopeProvider)
        {
            scopeProvider.ForEachScope((scope, builder) =>
            {
                builder.Append(' ');

                AppendLogScope(builder, scope);
            }, sb);
        }
        /// <inheritdoc />
        public void Log <TState>(
            LogLevel logLevel,
            EventId eventId,
            TState state,
            Exception exception,
            Func <TState, Exception, string> formatter)
        {
            if (!IsEnabled(logLevel))
            {
                return;
            }

            if (formatter == null)
            {
                throw new ArgumentNullException(nameof(formatter));
            }

            string message = formatter(state, exception);

            if (string.IsNullOrEmpty(message))
            {
                return;
            }

            StringBuilder builder = new StringBuilder()
                                    .Append("Category: ")
                                    .AppendLine(_name)
                                    .Append("EventId: ")
                                    .Append(eventId.Id)
                                    .AppendLine();

            _externalScopeProvider?.ForEachScope((scope, sb) =>
            {
                if (scope is IEnumerable <KeyValuePair <string, object> > properties)
                {
                    foreach (KeyValuePair <string, object> pair in properties)
                    {
                        sb.Append(pair.Key).Append(": ").AppendLine(pair.Value?.ToString());
                    }
                }
                else if (scope != null)
                {
                    sb.AppendLine(scope.ToString());
                }
            },
                                                 builder);

            builder.AppendLine()
            .AppendLine(message);

            if (exception != null)
            {
                builder.AppendLine().AppendLine("Exception: ").Append(exception).AppendLine();
            }

            WriteMessage(builder.ToString(), GetEventLogEntryType(logLevel), EventLog.DefaultEventId ?? eventId.Id);
        }
Beispiel #11
0
        public void Log <TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func <TState, Exception, string> formatter)
        {
            lock (_jsonWriter)
            {
                _jsonWriter.WriteStartObject();
                if (!string.IsNullOrWhiteSpace(_options.TimestampFieldName))
                {
                    _jsonWriter.WriteString(_options.TimestampFieldName, DateTime.UtcNow);
                }

                if (!string.IsNullOrWhiteSpace(_options.MessageFieldName))
                {
                    _jsonWriter.WriteString(_options.MessageFieldName, formatter(state, exception));
                }

                if (!string.IsNullOrWhiteSpace(_options.LevelFieldName))
                {
                    _jsonWriter.WriteString(_options.LevelFieldName, GetLogLevelString(logLevel));
                }

                if (!string.IsNullOrWhiteSpace(_options.CategoryFieldName))
                {
                    _jsonWriter.WriteString(_options.CategoryFieldName, _categoryName);
                }

                if (!string.IsNullOrWhiteSpace(_options.EventIdFieldName))
                {
                    // This could really be just eventId.ToString() but this is to save on allocation
                    if (eventId.Name != default)
                    {
                        _jsonWriter.WriteString(_options.EventIdFieldName, eventId.Name);
                    }
                    else if (eventId.Id != default)
                    {
                        _jsonWriter.WriteNumber(_options.EventIdFieldName, eventId.Id);
                    }
                }

                if (!string.IsNullOrWhiteSpace(_options.ExceptionFieldName) && exception != default)
                {
                    _jsonWriter.WriteString(_options.ExceptionFieldName, exception.ToString());
                }

                WriteFormattedLogValues(state, _jsonWriter);

                _scopeProvider?.ForEachScope(WriteFormattedLogValues, _jsonWriter);

                _jsonWriter.WriteEndObject();
                _jsonWriter.Flush();
                _jsonWriter.Reset();

                _options.Stream.Write(NewLine, 0, NewLine.Length);
            }
        }
Beispiel #12
0
        public void CaptureScopesIsReadFromConfiguration()
        {
            var provider = new Mock <ILoggerProvider>();
            var logger   = new Mock <ILogger>();
            var json     = @"{ ""CaptureScopes"": ""false"" }";

            var config = TestConfiguration.Create(() => json);
            IExternalScopeProvider externalScopeProvider = null;

            provider.Setup(loggerProvider => loggerProvider.CreateLogger(It.IsAny <string>()))
            .Returns(logger.Object);
            provider.As <ISupportExternalScope>().Setup(scope => scope.SetScopeProvider(It.IsAny <IExternalScopeProvider>()))
            .Callback((IExternalScopeProvider scopeProvider) => externalScopeProvider = scopeProvider);

            var factory = TestLoggerBuilder.Create(
                builder => {
                builder.AddProvider(provider.Object);
                builder.AddConfiguration(config);
            });

            var newLogger  = factory.CreateLogger("Logger");
            int scopeCount = 0;

            using (newLogger.BeginScope("Scope"))
            {
                externalScopeProvider.ForEachScope <object>((_, __) => scopeCount++, null);
                Assert.Equal(0, scopeCount);
            }

            json = @"{ ""CaptureScopes"": ""true"" }";
            config.Reload();

            scopeCount = 0;
            using (newLogger.BeginScope("Scope"))
            {
                externalScopeProvider.ForEachScope <object>((_, __) => scopeCount++, null);
                Assert.Equal(1, scopeCount);
            }
        }
Beispiel #13
0
        public void Log <TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func <TState, Exception, string> formatter)
        {
            var entry = new LogEntry
            {
                level   = logLevel,
                scopes  = new List <object>(),
                message = formatter(state, exception)
            };

            scopeProvider.ForEachScope((scope, scopes) => scopes.Add(scope), entry.scopes);

            entries.Add(entry);
        }
Beispiel #14
0
        private void GetScopeInformation(StringBuilder stringBuilder)
        {
            if (_scopeProvider != null)
            {
                _scopeProvider.ForEachScope((scope, sb) =>
                {
                    var empty = sb.Length == 0;
#if NETCOREAPP
                    var message = scope?.ToString().Replace("\n", string.Empty, StringComparison.OrdinalIgnoreCase) ?? "";
#else
                    var message = scope?.ToString().Replace("\n", string.Empty) ?? "";
#endif
                    sb.Append(empty ? "=> " : " => ").Append(message);
                }, stringBuilder);
            }
        }
        public static IDictionary <string, object> GetScopeDictionary(this IExternalScopeProvider scopeProvider)
        {
            var dictionary = new Dictionary <string, object>();

            scopeProvider.ForEachScope((scope, d) =>
            {
                if (scope is IEnumerable <KeyValuePair <string, object> > kvps)
                {
                    foreach (var kvp in kvps)
                    {
                        d[kvp.Key] = kvp.Value;
                    }
                }
            }, dictionary);

            return(dictionary);
        }
Beispiel #16
0
            public void Log <TState>(LogLevel logLevel, EventId eventId, TState state, Exception?exception, Func <TState, Exception?, string> formatter)
            {
                ICollection <object>?Scopes = null;

                _ScopeProvider.ForEachScope(
                    (scope, state) =>
                {
                    if (Scopes == null)
                    {
                        Scopes = new Collection <object>();
                    }
                    Scopes.Add(scope);
                },
                    state);

                Message = LoggerJsonMessage.FromLoggerData(null, "Category", Scopes, logLevel, eventId, state, exception, formatter);
            }
            private bool TryAppendScopes(StringBuilder sb)
            {
                var scopes = false;

                _scopes?.ForEachScope((callback, state) =>
                {
                    if (!scopes)
                    {
                        state.Append(Spacer);
                        scopes = true;
                    }

                    state.Append(ScopeDelimiter);
                    state.Append(callback);
                }, sb);
                return(scopes);
            }
Beispiel #18
0
        public static IDictionary <string, object> GetScopeDictionaryOrNull(this IExternalScopeProvider scopeProvider)
        {
            IDictionary <string, object> result = null;

            scopeProvider.ForEachScope((scope, _) =>
            {
                if (scope is IEnumerable <KeyValuePair <string, object> > kvps)
                {
                    result = result ?? new Dictionary <string, object>(16, StringComparer.OrdinalIgnoreCase);

                    foreach (var kvp in kvps)
                    {
                        result[kvp.Key] = kvp.Value;
                    }
                }
            }, (object)null);

            return(result);
        }
Beispiel #19
0
        public void Log <TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func <TState, Exception, string> formatter)
        {
            var previousColor = Console.ForegroundColor;

            Console.ForegroundColor = _consoleColor;

            Console.WriteLine();
            Console.WriteLine("------------------------------------------");
            Console.WriteLine($"Category:  {_category}");
            Console.WriteLine($"Level:     {logLevel}");
            Console.WriteLine($"Formatter: {formatter(state, exception)}");
            Console.WriteLine("State:");

            // Require state to be key/value pairs. Otherwise, ignore.
            if (state is IEnumerable <KeyValuePair <string, object> > stateKvps)
            {
                foreach (var kvp in stateKvps)
                {
                    Console.WriteLine($"  {kvp.Key}: {kvp.Value}");
                }
            }

            if (_scopeProvider != null)
            {
                Console.WriteLine("Scope:");
                {
                    _scopeProvider.ForEachScope <object>((s, _) =>
                    {
                        if (s is IEnumerable <KeyValuePair <string, object> > kvps)
                        {
                            foreach (var kvp in kvps.Where(p => p.Key != "{OriginalFormat}"))
                            {
                                Console.WriteLine($"  {kvp.Key}: {kvp.Value}");
                            }
                        }
                    }, null);
                }
            }

            Console.ForegroundColor = previousColor;
        }
        public void Log <TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func <TState, Exception, string> formatter)
        {
            var stringBuilder = new StringBuilder();

            stringBuilder.AppendFormat(_format, logLevel, eventId, formatter(state, exception));
            _scopeProvider?.ForEachScope((obj, sb) =>
            {
                if (obj is IEnumerable <KeyValuePair <string, object> > properties)
                {
                    foreach (var pair in properties)
                    {
                        sb.Append(pair.Key).Append(": ").AppendLine(pair.Value?.ToString());
                    }
                }
                else if (obj != null)
                {
                    sb.AppendLine(obj.ToString());
                }
            }, stringBuilder);
            _testOutputHelper.WriteLine(stringBuilder.ToString());
        }
Beispiel #21
0
        public void Log <TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func <TState, Exception, string> formatter)
        {
            if (!IsEnabled(logLevel))
            {
                return;
            }

            IDictionary <string, string> properties = new Dictionary <string, string>()
            {
                { "EventId", eventId.ToString() }
            };

            // gather info about scope(s), if any
            if (scopeProvider != null)
            {
                scopeProvider.ForEachScope((value, loggingProps) =>
                {
                    if (value is string)
                    {
                        properties["ScopeValue"] = value.ToString();
                    }
                    else if (value is IEnumerable <KeyValuePair <string, object> > props)
                    {
                        foreach (KeyValuePair <string, object> pair in props)
                        {
                            properties[pair.Key] = pair.Value.ToString();
                        }
                    }
                }, state);
            }

            string message = $"[{category}] {formatter(state, exception)}";

            client.TrackTrace(message, logLevel.ToSeverity(), properties);
            if (null != exception)
            {
                client.TrackException(exception, properties);
            }
        }
Beispiel #22
0
        private void WriteMessage(LogLevel logLevel, EventId eventId, string message, Exception exception)
        {
            WebLogEntry entry = new WebLogEntry
            {
                Level     = logLevel,
                Date      = DateTime.UtcNow,
                Category  = _category,
                EventId   = eventId,
                Exception = exception,
                Message   = message
            };

            if (_scopeProvider != null)
            {
                entry.Scopes = new List <object>();
                _scopeProvider.ForEachScope(
                    (s, scopes) => scopes.Add(s),
                    entry.Scopes
                    );
            }

            _loggerProcessor.EnqueueEntry(entry);
        }
        protected virtual void AppendLogScopeInfo(StringBuilder sb, IExternalScopeProvider scopeProvider)
        {
            var initialLength = sb.Length;

            scopeProvider.ForEachScope((scope, state) =>
            {
                var(builder, length) = state;

                var first = length == builder.Length;
                if (!first)
                {
                    builder.Append(' ');
                }

                AppendLogScope(builder, scope);
            }, (sb, initialLength));

            if (sb.Length > initialLength)
            {
                sb.Insert(initialLength, _messagePadding);
                sb.AppendLine();
            }
        }
Beispiel #24
0
        /// <inheritdoc />
        public void Log <TState>(LogLevel logLevel, EventId eventId, TState state, Exception?exception, Func <TState, Exception?, string> formatter)
        {
            if (!IsEnabled(logLevel))
            {
                return;
            }

            if (formatter == null)
            {
                throw new ArgumentNullException(nameof(formatter));
            }

            var message = formatter(state, exception);

            if (string.IsNullOrEmpty(message))
            {
                return;
            }

            var sb = new StringBuilder();

            sb.Append($"{DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss.fffff", DateTimeFormatInfo.InvariantInfo)} {CorrelationIdLogger.GetLogLevel(logLevel)}: {message} [{_name}]");

            if ((_includeLoggingScopesInOutput.HasValue && _includeLoggingScopesInOutput.Value) || (!_includeLoggingScopesInOutput.HasValue && TestSetUp.IncludeLoggingScopesInOutput))
            {
                _scopeProvider?.ForEachScope <object>((scope, _) => CorrelationIdLogger.ScopeWriter(sb, scope), null !);
            }

            if (exception != null)
            {
                sb.AppendLine();
                sb.Append(exception);
            }

            TestContext.Out.WriteLine(sb.ToString());
        }
 public void Log <TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func <TState, Exception, string> formatter)
 {
     LogText.Add(formatter(state, exception));
     _scopeProvider.ForEachScope((scope, builder) => builder.Add(scope.ToString()), LogText);
 }
        public void Log <TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func <TState, Exception, string> formatter)
        {
            var level = logLevel.ToSerilogLevel();

            if (!_logger.IsEnabled(level))
            {
                return;
            }

            var    logger          = _logger;
            string messageTemplate = null;

            var properties = new List <LogEventProperty>();

            if (state is IEnumerable <KeyValuePair <string, object> > structure)
            {
                foreach (var property in structure)
                {
                    if (string.Equals(property.Key, SerilogLoggerProvider._originalFormatPropertyName, StringComparison.OrdinalIgnoreCase) && property.Value is string value)
                    {
                        messageTemplate = value;
                    }
                    else if (property.Key.StartsWith("@", StringComparison.Ordinal))
                    {
                        if (logger.BindProperty(property.Key.Substring(1), property.Value, destructureObjects: true, out var destructured))
                        {
                            properties.Add(destructured);
                        }
                    }
                    else
                    {
                        if (logger.BindProperty(property.Key, property.Value, destructureObjects: false, out var bound))
                        {
                            properties.Add(bound);
                        }
                    }
                }

                var stateType     = state.GetType();
                var stateTypeInfo = stateType.GetTypeInfo();
                // Imperfect, but at least eliminates `1 names
                if (messageTemplate == null && !stateTypeInfo.IsGenericType)
                {
                    messageTemplate = "{" + stateType.Name + ":l}";
                    if (logger.BindProperty(stateType.Name, AsLoggableValue(state, formatter), destructureObjects: false, out var stateTypeProperty))
                    {
                        properties.Add(stateTypeProperty);
                    }
                }
            }

            if (messageTemplate == null)
            {
                string propertyName = null;
                if (state != null)
                {
                    propertyName    = "State";
                    messageTemplate = "{State:l}";
                }
                else if (formatter != null)
                {
                    propertyName    = "Message";
                    messageTemplate = "{Message:l}";
                }

                if (propertyName != null && logger.BindProperty(propertyName, AsLoggableValue(state, formatter), false, out var property))
                {
                    properties.Add(property);
                }
            }

            if (eventId.Id != 0 || eventId.Name != null)
            {
                properties.Add(CreateEventIdProperty(eventId));
            }

            var parsedTemplate = _messageTemplateParser.Parse(messageTemplate ?? "");
            var logEvent       = new LogEvent(DateTimeOffset.Now, level, exception, parsedTemplate, properties);

            if (!(_externalScopeProvider is null))
            {
                var stringBuilder = new StringBuilder();
                _externalScopeProvider.ForEachScope(
                    (activeScope, builder) =>
                {
                    if (activeScope is IReadOnlyCollection <KeyValuePair <string, object> > activeScopeDictionary)
                    {
                        foreach (KeyValuePair <string, object> item in activeScopeDictionary)
                        {
                            logEvent.AddPropertyIfAbsent(new LogEventProperty(item.Key, new ScalarValue(Convert.ToString(item.Value, CultureInfo.InvariantCulture))));
                        }
                    }
                    else
                    {
                        builder.Append(" => ").Append(activeScope);
                    }
                },
                    stringBuilder);
            }

            logger.Write(logEvent);
        }
Beispiel #27
0
        /// <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);
        }
 public void ForEachScope <TState>(Action <object, TState> callback, TState state)
 {
     _scopeProvider.ForEachScope(callback, state);
 }