如何注册自定义 ILogger 以便记录所有未处理的异常

3
请查看GitHub上的Log unhandled exceptions to custom logger。显然,在Preview 2版本中,Blazor通过Console.WriteLine记录未处理的异常。这将在Preview 3版本中更改为使用ILogger。
此处所述,Blazor使用配置的ILogger实例记录所有未处理的异常。但是我无法使其正常工作。在网上搜索时,我发现了使用ILoggerProvider或ILoggerFactory的网站,使我感到困惑。
我需要配置哪些服务以记录未处理的异常?
更新: 我想添加第二个非控制台记录器,但我不能使第二个记录器正常工作。来自Blazor的内置控制台日志记录器正常工作。
更新2: 以下是我尝试过的所有内容。没有一项起作用并将Unhandled exceptions发送到MyLogger(在某些情况下,我转发了所有其他消息到MyLogger)。
我尝试注册记录器:
public static void ConfigureServices(IServiceCollection services)  {
    services.AddSingleton<ILogger, MyLogger>();
    services.AddSingleton(ServiceDescriptor.Singleton(typeof(ILogger<>), typeof(MyLogger<>)));

我尝试注册提供者:

services.AddSingleton(ServiceDescriptor.Singleton<ILoggerProvider, MyLoggerProvider>());
services.TryAddEnumerable(ServiceDescriptor.Singleton<ILoggerProvider, MyLoggerProvider>());
services.AddSingleton<ILoggerProvider, MyLoggerProvider>();

我试图使用现有的ILoggerFactory注册提供程序:

host.Services.GetService<ILoggerFactory>().AddProvider(new MyLoggerProvider());

我尝试注册我的MyLoggerFactory:

services.AddSingleton<ILoggerFactory, MyLoggerFactory>();

我的ILogger实现:

public class MyLogger : ILogger
{
    public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
    {
        Debug.WriteLine($"MyLogger.exception='{exception}'");
    }

    public bool IsEnabled(LogLevel logLevel)
    {
        return true;
    }

    public IDisposable BeginScope<TState>(TState state)
    {
        return new EmptyDisposable();
    }

    internal class EmptyDisposable : IDisposable 
    {
        public void Dispose()
        {
        }
    }
}

public class MyLogger<T> : ILogger<T>
{
    public void Log<TState>(
        LogLevel logLevel,
        EventId eventId,
        TState state,
        Exception exception,
        Func<TState, Exception, string> formatter)
    {
        Debug.WriteLine($"MyLogger<generic>.exception='{exception}'");
    }

    public bool IsEnabled(LogLevel logLevel)
    {
        return true;
    }

    public IDisposable BeginScope<TState>(TState state)
    {
        return new MyLogger.EmptyDisposable();
    }
}

我的ILoggerProvider实现

public class MyLoggerProvider: ILoggerProvider
{
    public void Dispose()
    {

    }

    public ILogger CreateLogger(string categoryName)
    {
        Debug.WriteLine($"MyLoggerProvider.categoryName='{categoryName}'");
        return new MyLogger();
    }
}

我的ILoggerFactory实现

public class MyLoggerFactory : ILoggerFactory
{
    public MyLoggerFactory()
    {
        Debug.WriteLine($"MyLoggerFactory.ctor");
    }

    public void Dispose()
    {
    }

    public ILogger CreateLogger(string categoryName)
    {
        Debug.WriteLine($"MyLoggerFactory.categoryName='{categoryName}'");
        return new MyLogger();
    }

    public void AddProvider(ILoggerProvider provider)
    {
        Debug.WriteLine($"MyLoggerFactory.AddProvider");
    }
}

所以我从来没有使用过Blazer,但我快速查看了文档。我想我有点不确定你在问什么。您是否在说Blazer无法捕获未处理的异常?还是说Blazer不能捕获自己未处理的异常?或者您是否要添加第二个非控制台记录器,但无法使该第二个记录器正常工作? (如果这是问题,那么配置了控制台记录器的Blazer是否正常工作?) - Frank Merrow
1
@FrankMerrow 我想添加第二个非控制台日志记录器,但我无法让第二个工作。Blazor 内置的控制台日志记录器可以正常工作。 - Thomas
你能否展示一下你目前尝试过的内容吗?请将其添加到上面的问题中。 - Frank Merrow
1
@FrankMerrow 我已经更新了问题,并附上了我尝试过的所有内容。 - Thomas
不要使用 不要使用“host.Services.GetService<ILoggerFactory>().AddProvider(new MyLoggerProvider());” 我认为你可能想要使用a) “host.Services.AddProvider(new MyLoggerProvider());”来注册工厂,或者b) “host.Services.GetService<ILoggerFactory>();”来获取一个日志记录器工厂实例。 - Dudeman3000
1个回答

1
测试代码可以让您了解如何注册日志记录器。 https://github.com/dotnet/aspnetcore/pull/19606/files#diff-106bbead18cff2ed036495cc7c9dbdd1
builder.Services.AddSingleton<ILoggerFactory>(services =>
{
    var originalLogger = (ILoggerFactory)Activator.CreateInstance(
         originalLoggerDescriptor.ImplementationType,
         new object[] { services });
    return new PrependMessageLoggerFactory("Custom logger", originalLogger);
});

简而言之:
builder.Services.AddSingleton<ILoggerFactory>(services => new MyLoggerFactory());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接