// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
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
{
///
/// A logger factory that will prepend the current SignalR connection ID to the message.
///
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 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 class WrappingLogger : ILogger
{
private readonly DummyProvider _provider;
private readonly ILogger _logger;
public WrappingLogger(DummyProvider provider, ILogger logger)
{
_provider = provider;
_logger = logger;
}
public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func 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 state)
{
return _logger.BeginScope(state);
}
private string GetConnectionId()
{
string connectionId = null;
_provider.ScopeProvider?.ForEachScope