单个界面中的 ServiceStack 日志记录和 SSE?

ServiceStack logging and SSE in a single interface?

所以,我们的项目最近开始在 ServiceStack 中使用服务器发送的事件。我们的项目还使用 log4net 提供程序使用 log4net 进行登录。现在我已经使用 SSE 完成了几个组件,我想知道是否还有其他人在想我在这里...

我通常使用 'DEBUG' 级别的 log4net 来获得真正的聊天 'debug' 体验。当我在开发服务器上时,或者当我试图查明问题的根源时……我会将日志记录级别更改为 'DEBUG' 然后去镇上。虽然我不会 运行 在更高的环境中使用 'DEBUG' - 我发现相同级别的信息是我可能有兴趣发送给客户的。我在一个服务中有一些 long-运行ning 进程,它通过 SSE 与网络仪表板通信以报告更新。我发现我通常会记录到 'DEBUG' 的信息类型是 通常 我想发送到我的仪表板的信息。正如您随后想象的那样,我的代码开始看起来像这样,并且在许多方面:

var msg = $"Processed {count} records.";
MessageLog.Debug(msg);
ServerEvents.NotifyChannel(channelName, selector, msg);

看到这个让我想创建一个瘦包装器,以便通过一次调用将消息发送到日志、SSE 或两者。目前ServiceStack中是否存在这种设置?我意识到它是高级别的,还有一些细节需要解决(日志记录级别、通道和选择器值),但我必须相信有一些方法可以简化它。

没有任何内置的东西,有几种方法可以实现它,我的首选是使用采用 ILog 的扩展方法,例如:

public static void NotifyChannel(this IServerEvents server, 
    string channel, string selector, object message, ILog log)
{
    if (log.IsDebugEnabled)
        log.Debug(message);

    server.NotifyChannel(channel, selector, message);
}

或者您可以创建一个适配器 IServerEvents class,您可以将其注册为单独的依赖项,例如:

container.Register(c => 
    new LoggingServerEvents(c.Resolve<IServerEvents>()));

记录并委托 API 对 IServerEvents 依赖项的调用,例如:

class LoggingServerEvents : IServerEvents
{
    private static ILog Log = LogManager.GetLogger(typeof(LoggingServerEvents));

    private IServerEvents sse;
    public LoggingServerEvents(IServerEvents sse) => this.sse = sse;

    public void NotifyChannel(string channel, string selector, object message)
    {
        if (Log.IsDebugEnabled)
            Log.Debug(message);

        sse.NotifyChannel(channelName, selector, message);
    }

    //...
}

当您希望消息也被记录时,您可以像普通依赖项一样在您的服务中引用它,您可以使用它来代替 ServerEvents,例如:

public class MyServices : Service
{
    public LoggingServerEvents LoggingServerEvents { get; set; }

    public object Any(MyRequest request)
    {
        //ServerEvents.NotifyChannel(channelName, selector, msg);
        LoggingServerEvents.NotifyChannel(channelName, selector, msg);
    }
}