4

記事 ( http://www.daveoncsharp.com/2009/09/create-a-logger-using-the-trace-listener-in- csharp/ ) で、System.Diagnostics と App.config を使用して Trace メソッド経由でログを記録する方法について説明しました。クラスと App.config の両方を正常に実装できましたが、ログ ファイルの値/場所 (initializeData 内) を動的に割り当てることができるようにしたいのですが、その方法がわかりません。 . ご提案がありましたら、お気軽に投稿してください。

App.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.diagnostics>
    <trace autoflush="true" indentsize="4">
      <listeners>
        <add name="myListener" 
             type="System.Diagnostics.TextWriterTraceListener" 
             initializeData="fileSizeThreshold=512, fileSizeUnit=kilobytes, 
             fileAgeThreshold=1, fileAgeUnit=months, fileNameTemplate='{0}\MyApp-{1:MMM-yy}.log'"/>
        <remove name="Default" />
      </listeners>
    </trace>
  </system.diagnostics>
</configuration>

ロガー クラス:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;


namespace MyCurrentProject
{
    class Logger
    {
        public void Error(string module, string message)
        {
            WriteEntry(message, "ERROR:", module);
        }

        public void Error(Exception ex, string module)
        {
            WriteEntry(ex.Message, "ERROR:", module);
        }

        public void Warning(string module, string message)
        {
            WriteEntry(message, "WARNING:", module);
        }

        public void Info(string module, string message)
        {
            WriteEntry(message, "INFO:", module);
        }

        private void WriteEntry(string message, string type, string module)
        {
            Trace.WriteLine(
                    string.Format("{0} {1} [{2}] {3}",
                                  DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                                  type,
                                  module,
                                  message));
        }
    }
}

RE:明確でなくて申し訳ありません...明確にするために、ログ ファイル出力が保存されるファイル パスを動的に設定する必要があります。%AppData% 内の場所に保存するパスが必要です。構成で発生した問題は、「initializeData」の値を設定すると、その値を変更または動的に設定/リセットする方法が見つからないことでした。正直なところ...現時点では、機能してログファイルの場所を管理できるソリューションが欲しいだけです。

4

2 に答える 2

6

次に示すのは、Systems.Diagnostics を使用した実際の例です。これには、非基本クラス ライブラリに比べて 2 つの利点があります。これは (大規模な組織では) 常に許可され、常に利用可能であり、開発者が基本クラス ライブラリに精通している限り、保守開発者の次のバッチはそれを聞いているでしょう。

using System.Diagnostics;

namespace DynamicTraceLog
{
    class Program
    {
        static void Main(string[] args)
        {
            //Use TraceSource, not Trace, they are easier to turn off
            TraceSource trace = new TraceSource("app");
            //SourceSwitches allow you to turn the tracing on and off.
            SourceSwitch level =new SourceSwitch("app");
            //I assume you want to be dynamic, so probalby some user input would be here:
            if(args.Length>0 && args[0]=="Off")
                level.Level= SourceLevels.Off;
            else
                level.Level = SourceLevels.Verbose;
            trace.Switch = level;
            //remove default listner to improve performance
            trace.Listeners.Clear();
            //Listeners implement IDisposable
            using (TextWriterTraceListener file = new TextWriterTraceListener("log.txt"))
            using (ConsoleTraceListener console = new ConsoleTraceListener())
            {
                //The file will likely be in /bin/Debug/log.txt
                trace.Listeners.Add(file);
                //So you can see the results in screen
                trace.Listeners.Add(console);
                //Now trace, the console trace appears immediately.
                trace.TraceInformation("Hello world");
                //File buffers, it flushes on Dispose or when you say so.
                file.Flush();
            }
            System.Console.ReadKey();
        }
    }
}

Re: 出力をフォーマットする方法 Systems.Diagnostics クラスを使用して、テンプレート化されたトレース フォーマット/出力を実装するトレース リスナーについては、次の 2 つのいずれかを試してください : http://essentialdiagnostics.codeplex.com またはhttp://ukadcdiagnostics.codeplex.com/診断では、標準トークンの特定の書式設定や出力は提供されません。

于 2012-10-11T00:54:15.907 に答える
1

これに反対票が投じられる可能性があることはわかっていますが、牧場から少し離れて、ツールボックスとは別のツールを使用することをお勧めします。Log4Netは、非常に強力で簡潔なロギング フレームワークです。たとえば、以下はそれを使用するコンソール アプリケーションであり、ご覧のように完全に機能します。

using Com.Foo;

// Import log4net classes.
using log4net;
using log4net.Config;

public class MyApp 
{
    // Define a static logger variable so that it references the
    // Logger instance named "MyApp".
    private static readonly ILog log = LogManager.GetLogger(typeof(MyApp));

    static void Main(string[] args) 
    {
        // Set up a simple configuration that logs on the console.
        BasicConfigurator.Configure();

        log.Info("Entering application.");
        Bar bar = new Bar();
        bar.DoIt();
        log.Info("Exiting application.");
    }
}

しかし、あなたが使いたいとほのめかしているように、構成ファイルでそれをやりたかったとしましょう。まあ、それはかなり簡単です!以下は、App.config同じことを達成するために配置する構成です。

<log4net>
    <!-- A1 is set to be a ConsoleAppender -->
    <appender name="A1" type="log4net.Appender.ConsoleAppender">

        <!-- A1 uses PatternLayout -->
        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%-4timestamp [%thread] %-5level %logger %ndc - %message%newline" />
        </layout>
    </appender>

    <!-- Set root logger level to DEBUG and its only appender to A1 -->
    <root>
        <level value="DEBUG" />
        <appender-ref ref="A1" />
    </root>
</log4net>

次に、その構成を次のように使用できます。

using Com.Foo;

// Import log4net classes.
using log4net;
using log4net.Config;

public class MyApp 
{
    private static readonly ILog log = LogManager.GetLogger(typeof(MyApp));

    static void Main(string[] args) 
    {
        // BasicConfigurator replaced with XmlConfigurator.
        XmlConfigurator.Configure(new System.IO.FileInfo(args[0]));

        log.Info("Entering application.");
        Bar bar = new Bar();
        bar.DoIt();
        log.Info("Exiting application.");
    }
}

そして、パターンに不意を突かれないようにしてください。これは、メッセージにある程度の一貫性を持たせるために、上記のコーディング内容を構成しているだけです。ただし、ログに記録する必要があるのは、パターンにプラグインする必要がある情報だけであり、パターンはカプセル化されるため、非常に簡単です。


これは Log4Net の速習コースですが、私が本当にお勧めしている理由は、上記の 2 つの例では、コンソールにログを記録していることがわかりますが、可能性のあるロガーは無数にあるためです。次のリストを見てください。

log4net.Appender.AdoNetAppender : 準備済みステートメントまたはストアド プロシージャを使用して、ログ イベントをデータベースに書き込みます。

log4net.Appender.AnsiColorTerminalAppender : 色で強調表示されたロギング イベントを ANSI ターミナル ウィンドウに書き込みます。

log4net.Appender.AspNetTraceAppender : ログ イベントを ASP トレース コンテキストに書き込みます。これらは、ASP ページの最後または ASP トレース ページに表示できます。

log4net.Appender.ColoredConsoleAppender : 色で強調表示されたログ イベントをアプリケーションの Windows コンソールに書き込みます。

log4net.Appender.ConsoleAppender : ロギング イベントをアプリケーションのコンソールに書き込みます。イベントは、標準の our ストリームまたは標準のエラー ストリームのいずれかに送られます。

log4net.Appender.DebugAppender : ログ イベントを .NET システムに書き込みます。

log4net.Appender.EventLogAppender : ログ イベントを Windows イベント ログに書き込みます。

log4net.Appender.FileAppender : ログ イベントをファイル システム内のファイルに書き込みます。

log4net.Appender.LocalSyslogAppender : ロギング イベントをローカル syslog サービスに書き込みます (UNIX のみ)。

log4net.Appender.MemoryAppender : ロギング イベントをメモリ内バッファに格納します。

log4net.Appender.NetSendAppender : ログ イベントを Windows Messenger サービスに書き込みます。これらのメッセージは、ユーザー端末のダイアログに表示されます。

log4net.Appender.OutputDebugStringAppender : ロギング イベントをデバッガーに書き込みます。アプリケーションにデバッガーがない場合は、システム デバッガーが文字列を表示します。アプリケーションにデバッガーがなく、システム デバッガーがアクティブでない場合、メッセージは無視されます。

log4net.Appender.RemoteSyslogAppender : UDP ネットワークを使用して、ログ イベントをリモート syslog サービスに書き込みます。

log4net.Appender.RemotingAppender : .NET リモート処理を使用してログ イベントをリモート処理シンクに書き込みます。

log4net.Appender.RollingFileAppender : ログ イベントをファイル システム内のファイルに書き込みます。RollingFileAppender は、日付またはファイル サイズの制約に基づいて複数のファイルにログを記録するように構成できます。

log4net.Appender.SmtpAppender : ロギング イベントを電子メール アドレスに送信します。

log4net.Appender.SmtpPickupDirAppender : ロギング イベントを電子メール アドレスに送信しますが、SMTP 経由で直接送信するのではなく、構成可能なディレクトリに電子メールを書き込みます。

log4net.Appender.TelnetAppender : クライアントは Telnet 経由で接続してログ イベントを受信します。

log4net.Appender.TraceAppender : ログ イベントを .NET トレース システムに書き込みます。

log4net.Appender.UdpAppender : UdpClient を使用して、ロギング イベントをコネクションレス UDP データグラムとしてリモート ホストまたはマルチキャスト グループに送信します。


ご覧のとおり、非常に有能な OOB です。この投稿がお役に立てば幸いです。

于 2012-10-10T01:43:38.317 に答える