代码之家  ›  专栏  ›  技术社区  ›  BobTheBuilder

事件id管理的最佳实践是什么?

  •  16
  • BobTheBuilder  · 技术社区  · 17 年前

    我正试图弄清楚如何管理我的事件ID。到目前为止,我一直在手动地将每个事件id放入每个方法中,方法中的每个步骤都按顺序编号。这不允许我有效地过滤事件日志中的事件。为了在事件日志中使用过滤器,似乎每个记录的事件都必须有自己的唯一id。

    我可以将它们全部存储在一个表中,并将描述链接到它们,但当我的代码执行时,我正在记录“神奇的”无意义的事件代码。

    我在谷歌上搜索了一下,但我似乎不知道该用什么样的关键词才能找到问题的症结所在。

    提前谢谢

    3 回复  |  直到 17 年前
        1
  •  11
  •   Jon Skeet    17 年前

    像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");
    

    只要你做点工作 也许

        2
  •  7
  •   BenAlabaster    14 年前

    第一个想法——我还没有完全想清楚这一点,但这似乎是一个合理的可能性:

    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);
        }
    }
    

    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);
    

        3
  •  0
  •   vapcguy    11 年前

    我知道这是一个老生常谈的问题,但也许您正在寻找一种类似的方法,在这种方法中,您将自定义事件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);
    

    推荐文章