简体   繁体   English

Log4Net 自定义 AdoNetAppender 缓冲区问题

[英]Log4Net Custom AdoNetAppender Buffer Issue

I am using log4net and I have created my own appender from the AdoNetAppender .我正在使用log4net ,并且我从AdoNetAppender创建了自己的附加程序。 My appender just implements a kind of a buffer which permits grouping identical events in one log (for thousands of identical errors, I will only have one line in the database).我的 appender 只是实现了一种缓冲区,它允许在一个日志中对相同的事件进行分组(对于数千个相同的错误,我将在数据库中只有一行)。

Here is the code for easy comprehension (my appender has a buffersize = 1):这是易于理解的代码(我的附加程序有一个 buffersize = 1):

class CustomAdoNetAppender : AdoNetAppender
{
    //My Custom Buffer
    private static List<LoggingEvent> unSendEvents = new List<LoggingEvent>();
    private int customBufferSize = 5;
    private double interval = 100;
    private static DateTime lastSendTime = DateTime.Now;

    protected override void SendBuffer(log4net.Core.LoggingEvent[] events)
    {
        LoggingEvent loggingEvent = events[0];
        LoggingEvent l = unSendEvents.Find(delegate(LoggingEvent logg) { return GetKey(logg).Equals(GetKey(loggingEvent), StringComparison.OrdinalIgnoreCase); });
        //If the events already exist in the custom buffer (unSendEvents) containing the 5 last events
        if (l != null)
        {
            //Iterate the count property
            try
            {
                l.Properties["Count"] = (int)l.Properties["Count"] + 1;
            }
            catch
            {
                l.Properties["Count"] = 1;
            }
        }

        //Else
        else
        {
            //If the custom buffer (unSendEvents) contains 5 events
            if (unSendEvents.Count() == customBufferSize)
            {
                //Persist the older event
                base.SendBuffer(new LoggingEvent[] { unSendEvents.ElementAt(0) });
                //Delete it from the buffer
                unSendEvents.RemoveAt(0);
            }
            //Set count properties to 1
            loggingEvent.Properties["Count"] = 1;
            //Add the event to the pre-buffer 
            unSendEvents.Add(loggingEvent);
        }

        //If timer is over
        TimeSpan timeElapsed = loggingEvent.TimeStamp - lastSendTime;
        if (timeElapsed.TotalSeconds > interval)
        {
            //Persist all events contained in the unSendEvents buffer
            base.SendBuffer(unSendEvents.ToArray());
            //Update send time
            lastSendTime = unSendEvents.ElementAt(unSendEvents.Count() - 1).TimeStamp;
            //Flush the buffer
            unSendEvents.Clear();
        }
    }

    /// <summary>
    /// Function to build a key (aggregation of important properties of a logging event) to facilitate comparison.
    /// </summary>
    /// <param name="logg">The loggign event to get the key.</param>
    /// <returns>Formatted string representing the log event key.</returns>
    private string GetKey(LoggingEvent logg)
    {
        return string.Format("{0}|{1}|{2}|{3}", logg.Properties["ErrorCode"] == null ? string.Empty : logg.Properties["ErrorCode"].ToString()
                                , logg.Level.ToString()
                                , logg.LoggerName
                                , logg.MessageObject.ToString()
                                );
    }
}

The buffer and count part is going well.缓冲区和计数部分进展顺利。 My issue is that I am losing the 5 last logs because the buffer is not flushed at the end of the program.我的问题是我丢失了最后 5 个日志,因为在程序结束时缓冲区没有被刷新。 The unSendEvent buffer is full but never flushed in the database because no more new logs are going to "push" in the db older logs. unSendEvent 缓冲区已满,但从未在数据库中刷新,因为不再有新日志将“推送”到 db 旧日志中。

Is there any solution for me?有什么解决办法吗? I have tried to use the Flush() method but with no success.我尝试使用 Flush() 方法但没有成功。

The Smtp appender has a lossy parameter. Smtp appender 有一个有损参数。 If it's not set to false, you aren't guaranteed to get all of the logging messages.如果它未设置为 false,则不能保证您获得所有日志记录消息。 Sounds like that might be your problem perhaps?听起来这可能是你的问题? I use a config file, so this line is in my appender definition.我使用了一个配置文件,所以这一行在我的 appender 定义中。

<lossy value="false" />

There are a couple ways I can think of to handle this.我可以想到几种方法来处理这个问题。 The first is to change your buffer size to one (it is at 5 right now).第一个是将缓冲区大小更改为 1(现在为 5)。 That would ensure that all entries get written right away.这将确保所有条目都被立即写入。 However, this might not be ideal.但是,这可能并不理想。 If that is the case, one work-around I can think of is to put five dummy log messages into your buffer.如果是这种情况,我能想到的一种解决方法是将五个虚拟日志消息放入缓冲区。 That will flush out the real ones and your dummy events will be the ones that get dropped.这将清除真实事件,而您的虚拟事件将被丢弃。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM