/
githubmirror
/
aspnetcore
Обзор
Документация
Войти
/
githubmirror
/
aspnetcore
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Shared/SignalR/WrappingLoggerFactory.cs
116 строк
3 KB
Brennan
Add rule to seal internal and private types (#41457)
05 май 2022, 19:26
Не верифицирован
05 май 2022, 19:26
3ea008c
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; namespace Microsoft.AspNetCore.SignalR.Tests; /// <summary> /// A logger factory that will prepend the current SignalR connection ID to the message. /// </summary> public class WrappingLoggerFactory : ILoggerFactory { private readonly ILoggerFactory _innerLoggerFactory; private readonly DummyProvider _provider; public WrappingLoggerFactory(ILoggerFactory innerLoggerFactory) { _innerLoggerFactory = innerLoggerFactory; _provider = new DummyProvider(); AddProvider(_provider); } public void Dispose() { _innerLoggerFactory.Dispose(); } public ILogger CreateLogger(string categoryName) { return new WrappingLogger(_provider, _innerLoggerFactory.CreateLogger(categoryName)); } public void AddProvider(ILoggerProvider provider) { _innerLoggerFactory.AddProvider(provider); } private sealed class DummyProvider : ILoggerProvider, ISupportExternalScope { public IExternalScopeProvider ScopeProvider { get; private set; } public void Dispose() { } public ILogger CreateLogger(string categoryName) { return NullLogger.Instance; } public void SetScopeProvider(IExternalScopeProvider scopeProvider) { ScopeProvider = scopeProvider; } } private sealed class WrappingLogger : ILogger { private readonly DummyProvider _provider; private readonly ILogger _logger; public WrappingLogger(DummyProvider provider, ILogger logger) { _provider = provider; _logger = logger; } public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter) { // Build the message outside of the formatter // Serilog doesn't appear to use the formatter and just writes the state var connectionId = GetConnectionId(); var sb = new StringBuilder(); if (connectionId != null) { sb.Append(connectionId + " - "); } sb.Append(formatter(state, exception)); var message = sb.ToString(); _logger.Log(logLevel, eventId, message, exception, (s, ex) => s); } public bool IsEnabled(LogLevel logLevel) { return _logger.IsEnabled(logLevel); } public IDisposable BeginScope<TState>(TState state) { return _logger.BeginScope(state); } private string GetConnectionId() { string connectionId = null; _provider.ScopeProvider?.ForEachScope<object>((scope, s) => { if (scope is IReadOnlyList<KeyValuePair<string, object>> logScope) { if (logScope.FirstOrDefault(kv => kv.Key == "TransportConnectionId" || kv.Key == "ClientConnectionId").Value is string id) { connectionId = id; } } }, null); return connectionId; } } }