C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[6]: イベントログを取得する際の処理時間について


(過去ログ 82 を表示中)

[トピック内 14 記事 (1 - 14 表示)]  << 0 >>

■48529 / inTopicNo.1)  イベントログを取得する際の処理時間について
  
□投稿者/ ゴボウ (1回)-(2010/04/08(Thu) 13:21:09)

分類:[VB.NET/VB2005 以降] 

VB.NET 2005
Windows XP Pro SP2

お世話になります。

以下のように、指定した時間以降のイベントログの内容を
データベースに保存しています。

============================================================================
Dim wevtLogs() As EventLog

        'IPアドレスセット
        wevtLogs = Diagnostics.EventLog.GetEventLogs("xxx.xxx.xxx.xxx")

        'EVENTLOGループ
        For Each wevtLog As EventLog In wevtLogs
            'ENTRYループ
            For Each wentry As EventLogEntry In wevtLog.Entries

                '指定された時間より過去のデータは何もしない
                If wentry.TimeWritten.ToString("yyyy/MM/dd HH:mm:ss") < "指定した時間" Then
                    Continue For
                End If

                'データベース保存

            Next wentry
        Next wevtLog
============================================================================

イベントログをループして、ログの更新時間が指定された時間以降の物を保存対象としているのですが、
この方法だとイベントログが何十万と膨大な量の場合、処理時間がかなり掛かります。

もし、処理時間があまり掛からない方法があるようでしたら、ご教授願えないでしょうか。
よろしくお願い致します。


引用返信 編集キー/
■48530 / inTopicNo.2)  Re[1]: イベントログを取得する際の処理時間について
□投稿者/ みきぬ (852回)-(2010/04/08(Thu) 13:38:05)
ぱっと見、気づいたのは2つ。

> '指定された時間より過去のデータは何もしない
> If wentry.TimeWritten.ToString("yyyy/MM/dd HH:mm:ss") < "指定した時間" Then

毎回 DateTime を ToString() するのは無駄なので、
"指定した時間" のほうを DateTime オブジェクトにして比較したほうがよい。
# 有意な差が出るかどうかわからないけど

> 'データベース保存

おそらく時間を一番使っているのはこの部分なので、見直してみてはどうかしら。

具体的には DB の種類や現状の処理内容にもよるだろうけど、
例えばもし毎回自動でコミットされていれば、1つのトランザクションに押し込んじゃうとか。
引用返信 編集キー/
■48531 / inTopicNo.3)  Re[1]: イベントログを取得する際の処理時間について
□投稿者/ はつね (1242回)-(2010/04/08(Thu) 13:40:21)
No48529 (ゴボウ さん) に返信
> 以下のように、指定した時間以降のイベントログの内容を
> データベースに保存しています。

最新から取得して指定時間になったらExit Forすればいいのでは?

引用返信 編集キー/
■48532 / inTopicNo.4)  Re[2]: イベントログを取得する際の処理時間について
□投稿者/ .SHO (1256回)-(2010/04/08(Thu) 13:44:19)

>> '指定された時間より過去のデータは何もしない
>> If wentry.TimeWritten.ToString("yyyy/MM/dd HH:mm:ss") < "指定した時間" Then
>
> 毎回 DateTime を ToString() するのは無駄なので、
> "指定した時間" のほうを DateTime オブジェクトにして比較したほうがよい。

さらに、ログの性質上(たぶん)時系列で記録されていると思うので
"指定した時間" まで検索したら、それ以降は比較せずに全て処理するように
2回のループに分けた方がよい。

引用返信 編集キー/
■48533 / inTopicNo.5)  Re[1]: イベントログを取得する際の処理時間について
□投稿者/ よねKEN (460回)-(2010/04/08(Thu) 13:45:16)
No48529 (ゴボウ さん) に返信
> '指定された時間より過去のデータは何もしない
> If wentry.TimeWritten.ToString("yyyy/MM/dd HH:mm:ss") < "指定した時間" Then

"指定した時間"というのは「yyyy/MM/dd HH:mm:ss」形式に加工された日付なんだと思いますが、

If wentry.TimeWritten < DataTime型の指定した時間 Then

の方が、ToStringメソッドの呼び出しが丸々なくなるので、比較が速くなります。
(VBでは検証してませんが、C#で類似のコードで試してみた限りでは(C#なので細々とコードは違いますが)、
私の環境で100万件でだいたいDateTime型で比較する場合→60ms、ToStringで変換してから文字列で比較する場合→6000ms)でした。

トータルで6秒程度の差なので微々たるものですが・・・

> 処理時間がかなり掛かります。

どの処理がどの程度掛かっているのか計測してください。

> もし、処理時間があまり掛からない方法があるようでしたら、ご教授願えないでしょうか。

たぶん「'データベース保存」と書いて省略するところが大半じゃないかと思うので、
現在の情報からではこれくらいしかアドバイスは無理だと思います。

引用返信 編集キー/
■48536 / inTopicNo.6)  Re[2]: イベントログを取得する際の処理時間について
□投稿者/ ゴボウ (2回)-(2010/04/08(Thu) 14:31:12)
とりあえず余計なものを取っ払って計測してみましたが、
イベント件数約10万件で、4分掛かりました。

データベース保存処理が無しでもこの処理時間なので、
根本的な部分で問題がありそうです・・・

============================================================================
Dim wevtLogs() As EventLog

'IPアドレスセット
wevtLogs = Diagnostics.EventLog.GetEventLogs("xxx.xxx.xxx.xxx")

'EVENTLOGループ
For Each wevtLog As EventLog In wevtLogs
'ENTRYループ
For Each wentry As EventLogEntry In wevtLog.Entries

Next wentry
Next wevtLog
============================================================================

>最新から取得して指定時間になったらExit Forすればいいのでは?
はつねさんのやり方が一番処理が早いと思いますが、更新時間でソートする方法はあるのでしょうか?
引用返信 編集キー/
■48538 / inTopicNo.7)  Re[3]: イベントログを取得する際の処理時間について
□投稿者/ よねKEN (462回)-(2010/04/08(Thu) 14:51:50)
No48536 (ゴボウ さん) に返信
> >最新から取得して指定時間になったらExit Forすればいいのでは?
> はつねさんのやり方が一番処理が早いと思いますが、更新時間でソートする方法はあるのでしょうか?

ソートしたら結局全要素にアクセスしているのでおそらく速くはならないのでは?

はつねさんがおっしゃっているのは最新から取得する、なので、
wevtLog.Entriesから逆順に取り出したら?という意味じゃないですか?。
(foreachではなくfor文で末尾からカウントを減らしていくループにすればOKです)

ただ、逆順に取り出する方法が、ゴボウさんの開発するものの仕様にマッチする方法かどうかは、
.SHOさんがおっしゃっている

> さらに、ログの性質上(たぶん)時系列で記録されていると思うので

この法則が保証されているかどうかにかかっていると思います。
これが保証されていないとゴボウさんのおっしゃるように「更新時間でソート」を行ってからでないと
はつねさんのアイデアも.SHOさんのアイデアも適用できませんね。

--
ところで
> wevtLogs = Diagnostics.EventLog.GetEventLogs("xxx.xxx.xxx.xxx")

この部分のコードの実行時間はどの程度かかっているのでしょうか?
仮にここが大半の時間を締めている場合はこのメソッドを使わない方法の検討から
模索する必要がでてくるので、この点は先に明らかにしておいた方がよいでしょう。
引用返信 編集キー/
■48545 / inTopicNo.8)  Re[4]: イベントログを取得する際の処理時間について
□投稿者/ .SHO (1259回)-(2010/04/08(Thu) 15:28:08)
>>wevtLogs = Diagnostics.EventLog.GetEventLogs("xxx.xxx.xxx.xxx")
>
> この部分のコードの実行時間はどの程度かかっているのでしょうか?

ここがネックっぽいですね。

IPアドレスを指定しているってことは、ネットワーク経由で
数10万件のレコードを取得しているわけですよね。

4分を長いとみるかは難しいところですが、ネットワークの状態によっては
それぐらいかかるかも知れないですね。
引用返信 編集キー/
■48546 / inTopicNo.9)  Re[4]: イベントログを取得する際の処理時間について
□投稿者/ ゴボウ (3回)-(2010/04/08(Thu) 15:30:46)
> wevtLogs = Diagnostics.EventLog.GetEventLogs("xxx.xxx.xxx.xxx")
>この部分のコードの実行時間はどの程度かかっているのでしょうか?
この部分の処理時間は1秒も掛かりませんでした。

とりあえずログが時系列順に登録されていると仮定して
以下のように修正しました。これによって、処理時間も大幅に短縮できました。

============================================================================
        Dim wevtLogs() As EventLog
        Dim wentry As EventLogEntry

        'IPアドレスセット
        wevtLogs = Diagnostics.EventLog.GetEventLogs("xxx.xxx.xxx.xxx")

        'EVENTLOGループ
        For Each wevtLog As EventLog In wevtLogs
            'ENTRYループ
            For i As Integer = wevtLog.Entries.Count - 1 To 0 Step -1
                wentry = wevtLog.Entries(i)

                '前回チェック時間より以前のデータは取得しない
                If wentry.TimeWritten < "指定した時間" Then
                    Exit For
                End If

                'データベース保存

            Next i
        Next wevtLog
============================================================================

ログの登録順に関しては、この後も色々調べてみます。
ありがとうございました。

解決済み
引用返信 編集キー/
■48547 / inTopicNo.10)  Re[3]: イベントログを取得する際の処理時間について
□投稿者/ はつね (1243回)-(2010/04/08(Thu) 15:35:50)
No48536 (ゴボウ さん) に返信
> >最新から取得して指定時間になったらExit Forすればいいのでは?
> はつねさんのやり方が一番処理が早いと思いますが、更新時間でソートする方法はあるのでしょうか?

ReadEventLog-APIでEVENTLOG_BACKWARDS_READ指定で読み込むとか?

http://nienie.com/~masapico/api_ReadEventLog.html
引用返信 編集キー/
■48549 / inTopicNo.11)  Re[5]: イベントログを取得する際の処理時間について
□投稿者/ .SHO (1260回)-(2010/04/08(Thu) 15:48:17)
No48546 (ゴボウ さん) に返信

> ログの登録順に関しては、この後も色々調べてみます。

↓この部分を実行した場合と、しない場合の結果を比較すればいいですね。

>                 '前回チェック時間より以前のデータは取得しない
>                 If wentry.TimeWritten < "指定した時間" Then
>                     Exit For
>                 End If

まぁ、たまたま時系列になってただけかも知れないので
完全な証明にはなりませんが。。。




引用返信 編集キー/
■48551 / inTopicNo.12)  Re[4]: イベントログを取得する際の処理時間について
□投稿者/ なちゃ (419回)-(2010/04/08(Thu) 16:15:49)
実はLogParserとかうまく使えたりして…

引用返信 編集キー/
■48581 / inTopicNo.13)  Re[5]: イベントログを取得する際の処理時間について
□投稿者/ ゴボウ (4回)-(2010/04/08(Thu) 22:07:55)
すいません、解決済みにするのを忘れてました・・・

皆様、本当にありがとうございます!!
解決済み
引用返信 編集キー/
■48591 / inTopicNo.14)  Re[6]: イベントログを取得する際の処理時間について
□投稿者/ よねKEN (464回)-(2010/04/09(Fri) 09:25:23)
No48581 (ゴボウ さん) に返信
> すいません、解決済みにするのを忘れてました・・・

ゴボウさんはちゃんと「解決済み」にされていましたよ。
その後、解決済みがはずれているのは、以降の返信する人も明示的に
”解決済み”にチェックしないといけないこの掲示板の仕様ですので、
あやまらなくても大丈夫ですよ。

--
ところで、1点だけ本題と関係ないところで気になっっていた箇所があったので補足しておきます。
EventLogクラスについてはまったく詳しくないのですが、今回ヘルプを調べていて、
TimeWrittenプロパティに以下のような記述がありました。

EventLogEntry.TimeWritten プロパティ
http://msdn.microsoft.com/ja-jp/library/system.diagnostics.eventlogentry.timewritten(VS.80).aspx

> このメンバは、イベント情報がイベント ログに書き込まれた時間を保持します。
> これは、イベントが生成された時間とは異なる場合があります。
> 書き込み時間については、TimeGenerated プロパティのトピックを参照してください。

指定した時間と比較するのは、TimeGeneratedプロパティじゃなくていいのかなと気になりました。
#その辺はすでに把握した上でTimeWrittenプロパティを使ってます、ということならこの投稿は無視してください。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -