有没有办法将 blazor 日志流式传输到客户端并在网页上实时显示?

Is there a way to stream blazor logs to the client and display them in real time on a web page?

我正在尝试弄清楚如何配置 Blazor 和 Serilog 以便能够呈现将在剃刀页面上显示日志输出的组件。我广泛搜索了一个专门使用 Blazor/Asp.Net Core 的示例,结果很短。

如果我的 Startup 中有以下内容:

   myServiceCollection.AddLogging(l =>
    {
        l.ClearProviders();
        l.AddConsole();
        l.SetMinimumLevel(LogLevel.Debug);
    });

然后在其他一些组件中我注入一个 ILogger 我将如何而不是登录到控制台,而是将日志重定向到我拥有的某些 <textarea><p>在有问题的剃须刀组件上?我基本上只想设置一个日志查看器页面或能够在任意组件上显示日志输出。

虽然我没有找到完全符合我要求的具体示例,但有大量 Blazor 聊天应用程序使用 SignalR 在用户之间进行实时聊天的示例。我的想法是我可以重新利用它,而不是在用户之间使用聊天应用程序,我只是在服务器和客户端之间“聊天”,其中消息是输出的日志行。这是最好的方法吗?

您可以创建自定义记录器。我设法让它与 tutorial chat-app

一起工作

Startup.cs

loggerFactory.AddProvider(
    new SignalRLoggerProvider(
        new SignalRLoggerConfiguration
        {
            HubContext = serviceProvider.GetService<IHubContext<BlazorChatSampleHub>>(),
            LogLevel = LogLevel.Information
        }));


public class SignalRLoggerProvider : ILoggerProvider
{
    private readonly SignalRLoggerConfiguration _config;
    private readonly ConcurrentDictionary<string, SignalRLogger> _loggers = new ConcurrentDictionary<string, SignalRLogger>();

    public SignalRLoggerProvider(SignalRLoggerConfiguration config)
    {
        _config = config;
    }

    public ILogger CreateLogger(string categoryName)
    {
        return _loggers.GetOrAdd(categoryName, name => new SignalRLogger(name, _config));
    }

    public void Dispose()
    {
        _loggers.Clear();
    }
}

public class SignalRLogger : ILogger
{
    private readonly string _name;
    private readonly SignalRLoggerConfiguration _config;
    public SignalRLogger(string name, SignalRLoggerConfiguration config)
    {
        _name = name;
        _config = config;
    }

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

    public bool IsEnabled(LogLevel logLevel)
    {
        return logLevel == _config.LogLevel;
    }

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

        if (_config.EventId == 0 || _config.EventId == eventId.Id)
        {
            this._config.HubContext?.Clients.Group(_config.GroupName).SendAsync("Broadcast", "LOGGER", $"{DateTimeOffset.UtcNow:T}-UTC : {formatter(state, exception)}");
        }
    }
}

Proof of concept