Serilog 事件速率限制以及有关实际发生的限制的通知

发布于 2025-01-10 08:15:07 字数 2311 浏览 3 评论 0原文

我限制了 Serilog 记录器中注册的所有接收器的事件:任何接收器每分钟只允许发出 5 个事件。

我需要在所有实际发生节流的接收器中记录(Serilog 事件),否则我不知道确切的最大值是否。每分钟已记录允许数量的事件或更多事件已被限制。

我使用自己的节流方法,类似于“官方”PoC。我创建了一个 ILogEventFilter,并在其 IsEnabled 方法中检查事件的当前速率,并希望将“发生限制”事件直接写入所有接收器(否则,例如,如果我通过记录器写入此事件,我就会陷入无休止的递归):

public class EventFilter : ILogEventFilter
{
    public bool IsEnabled(LogEvent logEvent)
    {
        var enabled = ThrottledInvoker<string>.Invoke( // internally counts the calls, the method signature is simplified for the sake of this code sample
                            () => // method to call if throttling takes place
                            {
                                // send additional events/records into the sinks about throttling
                                
                                var throttlingInfoEvent = new LogEvent(
                                    logEvent.Timestamp,
                                    logEvent.Level,
                                    null,
                                    MessageTemplate.Empty,
                                    new[] {
                                        new LogEventProperty("CustomMessage", new ScalarValue("Too many events of this kind.")),
                                    });
                                
                                // TODO: how to write to registered sinks?
                                sink1.Emit(throttlingInfoEvent);
                                sink2.Emit(throttlingInfoEvent);
                                // ...
                                // sinkN.Emit(throttlingInfoEvent);
                            },
                            TimeSpan.FromMinutes(1), // time period
                            5); // max. allowed event count per time period
        return enabled;
    }
}

我没有找到 Logger.Sinks 属性或类似的东西。我知道我可以使用反射(GitHub 上的问题)来获取私有 我的记录器聚合接收器的 _sinks 字段,但是有味道。

我可以在将过滤器传递给 LoggerConfiguration.Filter.With() 方法之前对其进行初始化,并将所有接收器作为过滤器的构造函数参数传递。但是记录器和接收器是由我无权访问的应用程序的另一个组件配置的。

有没有正确/官方的方式来做我想做的事?

I throttle events for all sinks registered in a Serilog logger: only 5 events per minute are allowed to be emitted by any sink.

I need a record (a Serilog event) in all the sinks that the throttling actually took place, otherwise I don't know if the exact max. allowed amount of events has been logged per minute or more events have been throttled.

I use my own throttle approach similar to the "official" PoC. I create an ILogEventFilter, and in its IsEnabled method I check the current rate of the events and want to write my "throttling happened" event to all the sinks directly (otherwise, e.g. if I write this event via the logger, I'm in endless recursion):

public class EventFilter : ILogEventFilter
{
    public bool IsEnabled(LogEvent logEvent)
    {
        var enabled = ThrottledInvoker<string>.Invoke( // internally counts the calls, the method signature is simplified for the sake of this code sample
                            () => // method to call if throttling takes place
                            {
                                // send additional events/records into the sinks about throttling
                                
                                var throttlingInfoEvent = new LogEvent(
                                    logEvent.Timestamp,
                                    logEvent.Level,
                                    null,
                                    MessageTemplate.Empty,
                                    new[] {
                                        new LogEventProperty("CustomMessage", new ScalarValue("Too many events of this kind.")),
                                    });
                                
                                // TODO: how to write to registered sinks?
                                sink1.Emit(throttlingInfoEvent);
                                sink2.Emit(throttlingInfoEvent);
                                // ...
                                // sinkN.Emit(throttlingInfoEvent);
                            },
                            TimeSpan.FromMinutes(1), // time period
                            5); // max. allowed event count per time period
        return enabled;
    }
}

I have found no Logger.Sinks property or anything alike. I understand that I can use reflection (issue on GitHub) to get private _sinks fields of my logger's aggregated sinks, but that smells.

I could initialize my filter before passing it to LoggerConfiguration.Filter.With() method, and pass all the sinks as my filter's constructor arguments. But the logger and sinks are configured by another component of the application which I don't have access to.

Is there a right/official way to do what I want?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文