System.Diagnostics.XmlWriterTraceListener を使用してローカル ファイルにログを記録しようとしています。まず、ソースを作成し、それに新しい XmlWriterTraceListener を追加します。次のようにします。
public class Logger
{
const string LOG_ERR_FMT = "<message><![CDATA[{0}]]></message>{2}";
TraceSource tSource = new TraceSource(
"MyApp",
SourceLevels.Verbose | SourceLevels.ActivityTracing
);
public Logger() {
tSource.Listeners.Add(
new XmlWriterTraceListener("C:\\app_path\\app_tracelog.svclog", "LocalListener")
);
}
public static Logger defLogger = new Logger();
public static Logger Default {
get {return defLogger; }
set { if (value != null) defLogger = value; }
}
public void LogError(string msg, string extraXmlData) {
tSource.TraceEvent(TraceEventType.Error, 0, LOG_ERR_FMT, logMsg, extraXmlData);
}
}
上記のサンプルでは、ログ形式を簡略化しました。実際のLogError
メソッドはException
オブジェクトを受け取り、それに関する xml シリアル化されたデータをメッセージに挿入しますが、ここで私の問題が何であるかを示す必要はありません。
とにかく、私のアプリの他の部分は、次のような単純な行で「app_tracelog.svclog」ファイルにエラーを記録できるようになりました...
Logger.Default.LogError(
"Error parsing response from web service \"someservice.com\".",
"<RequestBody><![CDATA[" + responseBody + "]]></RequestBody>"
);
app_tracelog.svclog を開くまでは問題ありません。まず、Microsoft Service Trace Viewer で開こうとすると、プログラムが空のように動作し、「ファイルから読み込まれたトレースがありません」というメッセージが表示されます。
次に、古き良き Notepad++ でファイルを開くと、アプリが DID INDEED ログに記録されていることがわかります。すべてを選択して、XmlTools に整形するように指示すると、ツールは、XML にエラーがあるため、それを行うことができないと教えてくれます。
それで、手動でフォーマットを開始します。ログに記録した実際のアプリケーション メッセージに到達するまで、最初はすべてうまくいきます。ここで、この STUPID @#$ クラスが、ブラケットなどをエンコードされた XML/HTML エンティティに置き換えることで、ネストされたすべての XML を台無しにしてしまっていることがわかりました。
すべての「<」が「<」になり、すべての「>」が「>」になったなど...したがって、ログメッセージは次のようになります。
<message><![CDATA[Error parsing response from web service "someservice.com".]]></message><RequestBody...
次のようになります。
<message><![CDATA[Error parsing response from web service "someservice.com".]]></message><RequestBody...
したがって、大きな問題は次のとおりです。ログに記録するときに、XmlWriterTraceListener に強制的にメッセージを破棄させないようにするにはどうすればよいでしょうか。特殊な XML 文字を入力すると、自分が何をしているのかが分かります。--または- ローカルの XML ファイルにログを記録する別のリスナー クラスはありますか?