0

私はさまざまなドメインコントローラーのイベントログを照会しています。しばらくしてから照会を続ける必要があります。

以下は、クエリに使用しているコードです。

public static void FindAllLog(string machineName)
        {
            //EventLog log = new EventLog("", "");
            //log.
            EventLog[] remoteEventLogs;
            // Gets logs on the local computer, gives remote computer name to get the logs on the remote computer.
            remoteEventLogs = EventLog.GetEventLogs(machineName);
            Console.WriteLine("Number of logs on computer: " + remoteEventLogs.Length);

            for (int i = 0; i < remoteEventLogs.Length; i++)
            {
                Console.WriteLine("Log : " + remoteEventLogs[i].Log);
                ReadEventLog(machineName, remoteEventLogs[i].Log, DateTime.Now.AddDays(-30));
                //ReadAppEventLog(machineName, remoteEventLogs[i].Log);                
            }
        }

public static void ReadEventLog(string machine, string logType,DateTime fromDate)
        {
            EventLog ev = new EventLog(logType, machine);
            var entry = (from EventLogEntry e in ev.Entries
                         where e.TimeGenerated >= fromDate
                         orderby e.TimeGenerated
                         select e);//.LastOrDefault();
            foreach (EventLogEntry CurrentEntry in entry)
            {
                Console.WriteLine("Event ID : " + CurrentEntry.EventID);
                Console.WriteLine("Event Source : " + CurrentEntry.Source);
                Console.WriteLine("Event TimeGenerated : " + CurrentEntry.TimeGenerated);
                Console.WriteLine("Event TimeWritten : " + CurrentEntry.TimeWritten);
                Console.WriteLine("Event MachineName : " + CurrentEntry.MachineName);
                Console.WriteLine("Entry Type : " + CurrentEntry.EntryType.ToString());
                Console.WriteLine("Message :  " + CurrentEntry.Message + "\n");
                Console.WriteLine("-----------------------------------------");
            }
        }

ドメインコントローラーに初めてクエリを実行するときは、過去30日間のログを読み取る必要があります。それ以外の場合は、最後に離れたときの最新のログを読みます。クエリを実行するのに非常に時間がかかりますか?WMIを試してみましたが、同じ問題が何度も発生し、「無効なクエリエラー」が発生することがありますか?これを改善する方法は?このタスクを実行するために提案するモデルはありますか?ここでは、ドメインコントローラーごとにマルチスレッドを実行していますか?

ありがとう

4

2 に答える 2

2

この質問に答えるために。イベントログの読み取りのすべてのスタイルを試しました。

EventLog クラスを使用した .NET2.0 アプローチを使用し、次に EventLogQuery と EventLogReader クラスを使用した .NET3.0 アプローチを使用して読み取り、最後に WMI アプローチを試しました。

時間に基づいて、または 5 分ごとにタイム スライスでイベント ログを読み取る必要があります。

皆さんは、WMI が他の .NETx アプローチよりもはるかに高速にデータを取得し、より多くのフィールドを取得し、OS の依存関係やファイアウォールの問題がないことを知って驚かれることでしょう。

しかし、他の 2 つのアプローチには短所があります。

これを共有したかっただけです。

ありがとう

于 2012-07-18T07:14:02.843 に答える
1

EventLog から読み取るときは、LINQ を避けます。これを試して:

// Store indices of last accessed EventLogEntries in Dictionary {logType, lastIndex}
private static readonly Dictionary<string, int> _lastIndices = new Dictionary<string, int>();

public static void FindAllLog(string machineName)
{
    //EventLog log = new EventLog("", "");
    //log.
    EventLog[] remoteEventLogs;
    // Gets logs on the local computer, gives remote computer name to get the logs on the remote computer.
    remoteEventLogs = EventLog.GetEventLogs(machineName);
    Console.WriteLine("Number of logs on computer: " + remoteEventLogs.Length);

    for (int i = 0; i < remoteEventLogs.Length; i++)
    {
        Console.WriteLine("Log : " + remoteEventLogs[i].Log);
        ReadEventLog(machineName, remoteEventLogs[i].Log, DateTime.Now.AddDays(-30));
        //ReadAppEventLog(machineName, remoteEventLogs[i].Log);                
    }
}

public static void ReadEventLog(string machine, string logType, DateTime fromDate)
{
    int lastIndex;
    EventLog ev = new EventLog(logType, machine);
    IList<EventLogEntry> entries = new List<EventLogEntry>();

    if (_lastIndices.ContainsKey(logType))
        lastIndex = _lastIndices[logType];
    else {
        lastIndex = 0;
        _lastIndices.Add(logType, 0);
    }

    // Try to avoid LINQ because it uses Enumerator and Loops EVERYTIME trough all items.
    // Start Looping from top of the list and break if Entry has Index less than lastIndex or
    // if Entry has TimeWritten less than fromDate
    for (var i = ev.Entries.Count - 1; ev.Entries[i].Index > lastIndex && ev.Entries[i].TimeWritten > fromDate; i--)
        entries.Add(ev.Entries[i]);

    if (entries.Count > 0) // Set lastIndex for corresponding logType
        _lastIndices[logType] = entries.Max(e => e.Index);

    foreach (EventLogEntry CurrentEntry in entry.OrderBy(e => e.TimeWritten))
    {
        Console.WriteLine("Event ID : " + CurrentEntry.EventID);
        Console.WriteLine("Event Source : " + CurrentEntry.Source);
        Console.WriteLine("Event TimeGenerated : " + CurrentEntry.TimeGenerated);
        Console.WriteLine("Event TimeWritten : " + CurrentEntry.TimeWritten);
        Console.WriteLine("Event MachineName : " + CurrentEntry.MachineName);
        Console.WriteLine("Entry Type : " + CurrentEntry.EntryType.ToString());
        Console.WriteLine("Message :  " + CurrentEntry.Message + "\n");
        Console.WriteLine("-----------------------------------------");
    }
}

ここでは TimeWritten プロパティを使用しました。これは、TimeGenerated よりも信頼性が高いためです。TimeGenerated は順不同である可能性がありますが、TimeWritten はインデックスと同様に常に昇順です。これが役立つことを願っています。

于 2013-09-25T09:03:09.020 に答える