簡體   English   中英

什么是事件ID管理的最佳實踐?

[英]What are best practices for event id management?

我正在試圖弄清楚如何管理我的事件ID。 到目前為止,我已經手動將每個事件id放在每個方法中,並按順序編號的方法中的每個步驟。 這不允許我有效地過濾事件日志中的事件。 為了在事件日志中使用過濾器,似乎每個記錄的事件都必須具有自己的唯一ID。

我可以將它們全部存儲在一個表中,並將描述鏈接到它們,但隨后我的代碼執行,我正在記錄“魔術”毫無意義的事件代碼。

我進行了谷歌搜索,但我似乎對用於解決此問題的正確關鍵字感到茫然。

提前致謝

像Ben的建議一樣,它可能值得使用一個間接級別 - 但不是使用int代碼,我會使用實際的枚舉,所以Ben的例子:

public enum EventId
{
    [Format("Building command object from {0}.")]
    BuildingCommandObject = 1,
    [Format("Command object build successfully.")]
    CommandObjectBuilt = 2,
    [Format("Connecting to {0}.")]
    ConnectingToDatabase = 3,
    [Format("Executing command against database {0}.")]
    ExecutingCommand = 4,
    [Format("Command executed successfully.")]
    CommandExecuted = 5,
    [Format("Disconnecting from {0}.")]
    DisconnectingFromDatabase = 6,
    [Format("Connection terminated")]
    Disconnected = 7
}

或者(以更面向對象的方式)使用“智能枚舉”模式):

public class LogEvent
{
    public static readonly LogEvent BuildingCommandObject = new LogEvent(1,
         "Building command object from {0}");
    // etc

    private readonly int id;
    private readonly string format;

    // Add the description if you want
    private LogEvent(int id, string format)
    {
        this.id = id;
        this.format = format;
    }

    public void Log(params object[] data)
    {
        string message = string.Format(format, data);
        // Do the logging here
    }
}

然后你可以打電話:

LogEvent.BuildingCommandObject.Log("stuff");

通過一些工作,您可以以安全的方式公開它,使用具有不同接口的不同日志事件,以便在每個參數的數量方面使其安全(在編譯時)。 事實上,我確信你可以使用接口和私有嵌套類來做到這一點,但是凌晨4點,我太累了,不能寫出來atm :)

首先想到 - 我還沒有完全想到這一點,但這似乎是一個合理的可能性:

public class LogEvent
{
    /* This is the event code you reference from your code 
     * so you're not working with magic numbers.  It will work
     * much like an enum */
    public string Code; 

    /* This is the event id that's published to the event log
     * to allow simple filtering for specific events */
    public int Id; 

    /* This is a predefined string format that allows insertion
     * of variables so you can have a descriptive text template. */
    public string DisplayFormat;

    /* A constructor to allow you to add items to a collection in
     * a single line of code */
    public LogEvent(int id, string code, string displayFormat)
    {
        Code = code;
        Id = id;
        DisplayFormat = displayFormat;
    }
    public LogEvent(int id, string code)
        : this(id, code, null)
    {
    }
    public LogEvent()
    {
    }
}

然后,您可以擁有一個事件管理器類,它包裝您的事件列表,提供根據您傳遞的參數查詢列表的方法 - 例如:

public class EventManager
{
    private List<LogEvent> _eventList;
    public LogEvent this[string eventCode]
    {
        get
        {
            return _eventList.Where(i => i.Code.Equals(eventCode)).SingleOrDefault();
        }
    }
    public LogEvent this[int id]
    {
        get
        {
            return _eventList.Where(i => i.Id.Equals(id)).SingleOrDefault();
        }
    }
    public void AddRange(params LogEvent[] logEvents)
    {
        Array.ForEach(logEvents, AddEvent);
    }
    public void Add(int id, string code)
    {
        AddEvent(new LogEvent(id, code));
    }
    public void Add(int id, string code, string displayFormat)
    {
        AddEvent(new LogEvent(id, code, displayFormat));
    }
    public void Add(LogEvent logEvent)
    {
        _events.Add(logEvent);
    }
    public void Remove(int id)
    {
        _eventList.Remove(_eventList.Where(i => i.id.Equals(id)).SingleOrDefault());
    }
    public void Remove(string code)
    {
        _eventList.Remove(_eventList.Where(i => i.Code.Equals(code)).SingleOrDefault());
    }
    public void Remove(LogEvent logEvent)
    {
        _eventList.Remove(logEvent);
    }
}

這樣可以簡化事件定義的管理,可以為每個TraceSource獨立管理。

var Events = new EventManager();
Events.AddRange(
    new LogEvent(1, "BuildingCommandObject", "Building command object from {0}."),
    new LogEvent(2, "CommandObjectBuilt", "Command object built successfully."),
    new LogEvent(3, "ConnectingToDatabase", "Connecting to {0}."),
    new LogEvent(4, "ExecutingCommand", "Executing command against database {0}".),
    new LogEvent(5, "CommandExecuted", "Command executed succesfully."),
    new LogEvent(6, "DisconnectingFromDatabase", "Disconnecting from {0}."),
    new LogEvent(7, "Disconnected", "Connection terminated.")
)

您可以使用您指定的有意義的標識符訪問事件:

var evt = Events["ConnectingToDatabase"];
TraceSource.TraceEvent(TraceEventType.Information, evt.Id, evt.DisplayFormat, otherParams);

要么

var evt = Events[1024];
Console.WriteLine("Id: {1}{0}Code: {2}{0}DisplayFormat{3}", 
    Environment.NewLine, evt.Id, evt.Code, evt.DisplayFormat);

這可能會簡化您的事件管理,您不再通過幻數來調用您的事件,在一個地方管理您的所有事件很簡單 - 您的EventManager類,您仍然可以通過它需要的神奇數字過濾您的事件日志過濾。

我知道這是一個老問題,但也許您正在尋找一種方法來做這樣的事情,您可以將自定義事件ID用於不同目的,並在代碼中的適當位置調用它們:

public class ErrorLog
{
    //Notifications
    public const int NOTIFY_ALPHA = 2000;
    public const int NOTIFY_BETA = 2001;
    public const int NOTIFY_GAMMA = 2002;

    public static string[] errMessage = 
        {"Critical Error.",           //2000
         "File not found.",          //2001
         "Unknown Event Action Encountered - "     //2002
        };

    public static string GetErrMsg(int errNum)
    {
        return (errMessage[errNum-2000]);
    }

    private static bool ErrorRoutine(int eventLogId)
    {
        try
        {
            string eventAppName = "My Application";
            string eventLogName = "My Apps Events";
            string msgStr = GetErrMsg(eventLogId);  // gets the message associated with the ID from the constant you passed in

            if (!EventLog.SourceExists(eventAppName))
                EventLog.CreateEventSource(eventAppName, eventLogName);

            EventLog.WriteEntry(eventAppName, msgStr, EventLogEntryType.Error, eventLogId);

            return true;
        }
        catch (Exception)
        {
            return false;
        }
    }
}

當你拋出異常時,你會像這樣調用這個類:

ErrorLog.ErrorRoutine(ErrorLog.NOTIFY_ALPHA);

就最佳實踐而言,我認為如果將自己的類中的所有錯誤處理作為自定義(或更多,例如,當綁定警告和信息時EventLogEntryTypes或其他信息比固定消息給出的話) )比這一個。 擁有個人ID,您可以查看他們的消息,這樣可以讓您的生活更輕松,同時嘗試解決要呼叫的消息,何時以及在何處。

暫無
暫無

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

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