- PR -

ASP.NET上でのSystem.Diagnostics.Traceの使用について

1
投稿者投稿内容
のぶたけ
会議室デビュー日: 2002/04/03
投稿数: 3
投稿日時: 2004-03-02 19:40
はじめまして、もりいと申します。
他のスレッドをみても、該当する内容が見あたらなかったため、質問させていただきました。

現在、ASP.NET(C#)を用いた開発をしています。
このたび、独自の簡易ログクラスを作成することになり、System.Diagnostics.TraceクラスとTextWriterTraceListenerクラスを使ってファイルへのログ出力を試みたところ、下記のような例外が発生し、しばしばログの出力に失敗しています。(フラッシュに失敗して後に書き込みが実行されることもある)

プロセスはファイル "C:\Develop\dlg\logs\Trace_10.log" にアクセスできません。このファイルは別のプロセスが使用中です。
at System.IO.__Error.WinIOError(Int32 errorCode, String str)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, Boolean useAsync, String msgPath, Boolean bFromProxy)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access)
at LogTracer.InitializeTraceListener(String sectionName) in c:\develop\logging\logtracer.cs:line 81


上記の原因は、おそらく、インスタンスが生きている間は出力先ファイルを保持したままになってしまうため、排他制御がなされていると予測されますが。

エラーはASP.NETだけでなくコンソールアプリの場合でも同様のエラーが発生しています。コンソールやWinアプリの場合は、プログラム内でリスナーを追加するのではなく、アプリケーション構成ファイルに、listeners記述子でリスナーを記載して追加やれば、上記のエラーを発生させずに実行することができます。
ただ、ASP.NETのweb.configの場合は、Trace記述子はTraceContextクラスの情報しか設定
できない様子なので、難儀しております。

ASP.NET上でTraceクラスを使用して確実にログを出力する方法があれば、ご教授いただけないでしょうか?
とはいえ、特にTraceクラスにこだわっている訳ではなく、.NETネイティブである程度の機能があるので、それを利用してやりたいなと思っている程度です。他に有用な実装方法等があれば教えて頂ければ幸いです。


---アプリケーション記述子の設定例
<trace autoflush="true" indentsize="4">
<listeners>
<add name="myListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="c:\myListener.log" />
<remove type="Assembly text name, Version, Culture, PublicKeyToken"/>
</listeners>
</trace>


実装については、リファレンスに記載されているものと同様に以下のような記載をしており、ログクラスをSingletonでの実装をしています。


---ログクラス抜粋
public class LogTracer : IDisposable
{
protected static LogTracer logTracer = new LogTracer();
protected static TextWriterTraceListener traceListener;
protected static FileStream traceLog;

public LogTracer()
{
}
public static void InitializeTraceListener(string sectionName)
{
try
{
traceLog = new FileStream(logFile, FileMode.OpenOrCreate, FileAccess.Write);
traceListener = new TextWriterTraceListener(traceLog);

// Trace.Listenerコレクションに追加する
Trace.Listeners.Add(traceListener);

Trace.AutoFlush = true;
Trace.IndentSize = 4;
}
catch(Exception e)
{
Trace.WriteLine(e);
}
}
public void Dispose()
{
// TODO: LogTracer.Dispose 実装を追加します。
Trace.Listeners.Remove(traceListener);
traceListener.Close();
traceLog.Close();
}
}


_________________
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2004-03-02 20:23
とりあえず単純なのは、ファイル競合しても書き込めるトレースリスナを自分で作成することですかね。
ただ、書き込みでどういったことが起きて競合しているのかいまいち見えないんですけどね…
ASP.NETのプロセスリサイクルとかでタイミングが重なることがあるとか?

あと気になるのは、構成ファイルでリスナを追加したりよく分からない削除をしていたりと、何をやっているのか良く分からないところです。
LogTracer ってどういうときにどう使ってるんでしょうか?
なんか、触れずに使われないってパターンを想像してしまったり…
というか、このクラスは何のために作ってるんでしょう?

> ただ、ASP.NETのweb.configの場合は、Trace記述子はTraceContextクラスの情報しか設定できない様子なので、難儀しております。

これもよく意味が分からないんですよね…
のぶたけ
会議室デビュー日: 2002/04/03
投稿数: 3
投稿日時: 2004-03-02 22:51
わかりずらい記述だったようですね。ごめんなさい。

・使用用途
複数のWebアプリケーション上でデバッグログ情報(例外エラーやステップログ等)をファイルに出力するために使用しようと考えています。
System.Diagnostics.Traceクラスを使って、Assertも出力できればと考えました。

・競合原因
これはあまり予想がついていないです。ファイルのロックでの書き込みエラーを防ぐためにSingletonにしているはずのですが、クラスの廃棄タイミングと生成タイミングがかぶっているのであれば、それでも防ぎようがない気がしますね。

・web.configのTrace記述について
System.Diagnostics.Trace記述子をweb.configに書くと、listenersといった属性は無いと怒られてしまい設定できません。

個人的にも、アプリケーション構成ファイルの中でトレースの追加・削除をするのは、プログラムロジックが分散されることになるので好ましくない(むしろ後のメンテが大変になるため)と思いますが、状況としてきちんと調査しながら作り込んでやる時間が無いので、とりあえず例外を出さずに動くということを優先すると、アプリケーション構成ファイルにリスナーの指定を書いてしまうのもアリなのかなと思っています。
かめたろ
ぬし
会議室デビュー日: 2003/03/20
投稿数: 255
投稿日時: 2004-03-03 09:13
話からずれてしまうかもしれませんが、ログ出力クラスを作りたいというだけであれば、
%インストールディレクトリ%\Enterprise Samples\Duwamish 7.0 VB(またはCS)
にサンプルがあります。
サンプルとはいいつつも、LogやAssertのクラスはほとんど手直しせずに使えています。
のぶたけ
会議室デビュー日: 2002/04/03
投稿数: 3
投稿日時: 2004-03-03 20:39
かめたろさん

情報ありがとうございます。さっそく参照してみます。
Webサービスのサンプルと書いてあったので、今まで見逃していました。

1

スキルアップ/キャリアアップ(JOB@IT)