有没有一种方法可以将blazor日志流式传输到客户端并在网页上实时显示它们?

时间:2020-10-30 19:41:43

标签: c# asp.net-core signalr blazor

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

如果我的启动中包含以下内容:

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

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

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

1 个答案:

答案 0 :(得分:0)

您可以创建一个自定义记录器。我设法使它与此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