首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NLog限制在设定时间内记录相同错误的次数

NLog限制在设定时间内记录相同错误的次数
EN

Stack Overflow用户
提问于 2013-03-06 02:05:47
回答 2查看 2.1K关注 0票数 3

我们使用NLog在发生“严重”错误时发送电子邮件消息。它可能会经常发生,在某些情况下会生成太多的消息。

有没有办法让NLog限制它在设定的时间段内针对某个特定或任何错误发送的消息数量?

在log4net或其他流行的日志库中有没有类似的机制?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-03-07 23:50:50

你可以在这里看到我对类似的log4net问题的回答:

log4net - any filter for logging only the Nth message?

在回答中,我提出了一个自定义log4net过滤器实现,它允许在可配置的时间段内限制重复的消息。

对于NLog,最简单的方法可能是编写一个自定义包装器target。自定义包装器目标实现将检查传入的日志记录消息,如果当前消息与最近的消息不同(或者可能已经过了一定时间),则进行转发。然后,您可以使用这个自定义包装器包装任何现有的Target。

请注意,我实际上还没有编写包装器目标,否则我将尝试提供更多信息。

票数 3
EN

Stack Overflow用户

发布于 2014-11-05 17:09:26

配置文件更改:

代码语言:javascript
复制
 <target name="SystemErrorLog" xsi:type="TokenTimeThrottler" EntryExpirationPeriodSec="300">
    <target xsi:type="AsyncWrapper" queueLimit="5000" overflowAction="Discard">
      <target xsi:type="Mail" ... />
    </target>   </target>

目标类:

代码语言:javascript
复制
[Target("TokenTimeThrottler", IsCompound = true)]
public class ThrottlingLogTarget : CompoundTargetBase
{
    private ITokenTimeThrottler _tokenTimeThrottler;

    public ThrottlingLogTarget()
        : this(new Target[0])
    {
    }

    public ThrottlingLogTarget(params Target[] targets)
        : base(targets)
    {
    }

    [Required]
    public int EntryExpirationPeriodSec { get; set; }

    protected override void InitializeTarget()
    {
        base.InitializeTarget();

        _tokenTimeThrottler = new TokenTimeThrottler(EntryExpirationPeriodSec > 0 ? EntryExpirationPeriodSec : 0);
    }

    protected override void Write(AsyncLogEventInfo logEvent)
    {
        if (this.Targets.Count == 0)
        {
            logEvent.Continuation(null);
            return;
        }

        var token = string.Format("{0},{1},{2}", logEvent.LogEvent.LoggerName, logEvent.LogEvent.Level, logEvent.LogEvent.FormattedMessage);

        if (_tokenTimeThrottler.CheckAllow(token))
        {
            foreach (var target in Targets)
            {
                target.WriteAsyncLogEvent(logEvent);
            }
        }
    }
}


public class TokenTimeThrottler : ITokenTimeThrottler
{
    private readonly ConcurrentDictionary<string, DateTime> _entriesLastTimes;
    private readonly int _expirationPeriodSec;

    public TokenTimeThrottler(int entryExpirationPeriodSec)
    {
        _entriesLastTimes = new ConcurrentDictionary<string, DateTime>();

        _expirationPeriodSec = entryExpirationPeriodSec;
    }

    public bool CheckAllow(string token)
    {
        DateTime lastLoggedTime;

        if (_entriesLastTimes.TryGetValue(token, out lastLoggedTime))
        {
            DateTime? updatedTime = null;

            if (lastLoggedTime.AddSeconds(_expirationPeriodSec) < DateTime.Now)
            {
                updatedTime = DateTime.Now;
            }

            _entriesLastTimes.AddOrUpdate(token, k => updatedTime ?? lastLoggedTime,
                                            (k, v) => updatedTime ?? v);

            return updatedTime.HasValue;
        }

        _entriesLastTimes.AddOrUpdate(token, k => DateTime.Now, (k, v) => v);

        return true;
    }
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15230962

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档