簡體   English   中英

Log4Net 自定義 AdoNetAppender 緩沖區問題

[英]Log4Net Custom AdoNetAppender Buffer Issue

我正在使用log4net ,並且我從AdoNetAppender創建了自己的附加程序。 我的 appender 只是實現了一種緩沖區,它允許在一個日志中對相同的事件進行分組(對於數千個相同的錯誤,我將在數據庫中只有一行)。

這是易於理解的代碼(我的附加程序有一個 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()
                                );
    }
}

緩沖區和計數部分進展順利。 我的問題是我丟失了最后 5 個日志,因為在程序結束時緩沖區沒有被刷新。 unSendEvent 緩沖區已滿,但從未在數據庫中刷新,因為不再有新日志將“推送”到 db 舊日志中。

有什么解決辦法嗎? 我嘗試使用 Flush() 方法但沒有成功。

Smtp appender 有一個有損參數。 如果它未設置為 false,則不能保證您獲得所有日志記錄消息。 聽起來這可能是你的問題? 我使用了一個配置文件,所以這一行在我的 appender 定義中。

<lossy value="false" />

我可以想到幾種方法來處理這個問題。 第一個是將緩沖區大小更改為 1(現在為 5)。 這將確保所有條目都被立即寫入。 但是,這可能並不理想。 如果是這種情況,我能想到的一種解決方法是將五個虛擬日志消息放入緩沖區。 這將清除真實事件,而您的虛擬事件將被丟棄。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM