문제

이벤트 ID를 관리하는 방법을 알아 내려고 노력하고 있습니다. 이 시점까지 나는 각 방법에 각 단계에 각 단계에 각 단계에 각 단계를 순차적으로 번호를 매기는 메소드에 넣었습니다. 이를 통해 이벤트 로그에서 이벤트를 효과적으로 필터링 할 수 없습니다. 이벤트 로그에서 필터를 사용하려면 모든 로그인 이벤트에 고유 한 ID가 있어야합니다.

나는 그것들을 그들과 연결된 설명과 함께 테이블에 모두 저장할 수 있었지만 내 코드가 실행되면 "Magic"무의미한 이벤트 코드를 기록하고 있습니다.

Google 검색을 수행했지만이 문제의 맨 아래로 이동하는 데 사용할 올바른 키워드와 관련하여 손실 된 것으로 보입니다.

미리 감사드립니다

도움이 되었습니까?

해결책

첫 번째 생각 - 나는 아직 이것을 완전히 생각하지 않았지만 합리적인 가능성처럼 보입니다.

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

이것은 아마도 이벤트 관리를 단순화 할 것입니다. 더 이상 마법 번호로 이벤트를 호출하지 않으며, 한 곳에서 모든 이벤트를 관리하는 것이 간단합니다. 이벤트 관리자 클래스 및 필요한 마법 번호로 이벤트 로그를 필터링 할 수 있습니다. 필터.

다른 팁

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

약간의 일로 5월 서로 다른 로그 이벤트가 다른 인터페이스를 갖는 다른 로그 이벤트와 함께 안전한 방식으로이를 노출시킬 수있어 각 매개 변수의 측면에서 안전 할 수 있습니다 (컴파일 타임). 사실 나는 당신이 인터페이스와 개인 중첩 클래스를 사용하여 할 수 있다고 확신하지만, 오전 4시이고 너무 피곤해서 ATM을 작성하기에는 너무 피곤합니다 :)

나는 이것이 오래된 질문이라는 것을 알고 있지만 아마도 당신은 다른 목적으로 사용자 정의 이벤트 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);

모범 사례가 진행되는 한, 커스텀 (또는 경고 및 정보에 묶는 것과 같은 등장하는 것)이 제공되는 것보다 더 많은 오류 처리를하는 것이 좋습니다. ) 이것보다. 개별 ID를 사용하면 이와 같은 메시지를 찾아 볼 수 있으면 전화 할 메시지, 언제 어디서나 어디서 전화 할 메시지를 정리하려고 할 때 인생이 더 쉬워집니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top