0

EntLib 5 を使用してローリング フラット ファイルを作成しています。これは、ローリング フラット ファイル トレース リスナーを使用しませんが、コードにいくつかの変更を加えたフラット ファイル トレース リスナーを使用します。ローリング フラット ファイル トレース リスナーは、固有の設計に問題があるため使用されませんでした。このような要件には適合しません。

構成セクションは次のとおりです。

    <configuration>
    <configSections>
        <section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true"/>
        <sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
            <sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
                <section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
                <sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
                    <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>
                    <section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
                    <section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
                    <section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
                </sectionGroup>
            </sectionGroup>
        </sectionGroup>
    </configSections>
    <loggingConfiguration name="" tracingEnabled="true" defaultCategory="General">
  <listeners>
   <add name="Flat File Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
    listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
    fileName="./Logs/MyLog.log" formatter="Text Formatter" />
  </listeners>
  <formatters>
   <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
    template="Timestamp: {timestamp(local)}{newline}&#xA;Message: {message}{newline}&#xA;Category: {category}{newline}&#xA;Priority: {priority}{newline}&#xA;EventId: {eventid}{newline}&#xA;Severity: {severity}{newline}&#xA;Title:{title}{newline}&#xA;Machine: {localMachine}{newline}&#xA;App Domain: {localAppDomain}{newline}&#xA;ProcessId: {localProcessId}{newline}&#xA;Process Name: {localProcessName}{newline}&#xA;Thread Name: {threadName}{newline}&#xA;Win32 ThreadId:{win32ThreadId}{newline}&#xA;Extended Properties: {dictionary({key} - {value}{newline})}"
    name="Text Formatter" />
  </formatters>
  <categorySources>
   <add switchValue="All" name="General">
    <listeners>
     <add name="Flat File Trace Listener" />
    </listeners>
   </add>
  </categorySources>
  <specialSources>
   <allEvents switchValue="All" name="All Events" />
   <notProcessed switchValue="All" name="Unprocessed Category" />
   <errors switchValue="All" name="Logging Errors &amp; Warnings">
    <listeners>
     <add name="Flat File Trace Listener" />
    </listeners>
   </errors>
  </specialSources>
 </loggingConfiguration>
    <appSettings>
        <add key="LogFolder" value="./Logs"/>
        <add key="LogFileName" value="MyLog.log"/>
    </appSettings>
    <system.web>

次に、次のコードを使用して静的クラスを作成し、ログ プロセスを構成します。

public static class LoggingHelper {
private static string date = String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0:yyyyMMdd}", DateTime.Now);

public static void SetLogFile(string logFileFolder,string logFileName) {
    if (!string.IsNullOrEmpty(logFileName)) {
        string strfileName = logFileFolder + "/" + date + logFileName;
        LoggingHelper.SetTraceLogPath(strfileName, "FlatFile TraceListener", "General", "My Login System");
        LoggingHelper.WriteLogFile("General", "Log file path " + logFileFolder + "/" + logFileName, " My Login System");
    }
}  

public static void SetTraceLogPath(string logFile, string logFileName, string category, string message) {
    ConfigurationFileMap configFileMap = new ConfigurationFileMap();
    configFileMap.MachineConfigFilename = "Web.config";
    Configuration entLibConfig = WebConfigurationManager.OpenWebConfiguration("/ASP.NET_Logging");
    LoggingSettings loggingSettings = (LoggingSettings)entLibConfig.GetSection(LoggingSettings.SectionName);

    FlatFileTraceListenerData data = loggingSettings.TraceListeners.Get("Flat File Trace Listener") as FlatFileTraceListenerData;
    data.FileName = logFile;
    entLibConfig.Save();
    LogEntry objLog = new LogEntry();
    objLog.TimeStamp = System.DateTime.Now;
    objLog.Categories.Add(category);
    objLog.Message = message;
    objLog.Priority = 1;
    Logger.Write(objLog);

}

public static void WriteLogFile(string category, string msg, string title) {
    try {
        LogEntry le = new LogEntry();
        le.TimeStamp = System.DateTime.Now;
        le.Categories.Add(category);
        le.Severity = TraceEventType.Information;
        le.Priority = 1;
        le.Message = msg;
        le.Title = title;
        le.Priority = 1;
        Logger.Write(le);
    } catch (LoggingException ex) {
        LoggingHelper.WriteLogFile("General", "Error in writing log file " + ex.ToString(), "My Login System");
    }
}}

SetLogFile は Application_Start メソッドで呼び出され、次のように Global.aspx ページです。

void Application_Start(object sender, EventArgs e) 
{
    // Code that runs on application startup
    LoggingHelper.SetLogFile(ConfigurationSettings.AppSettings["LogFolder"].Trim     (),      ConfigurationSettings.AppSettings["LogFileName"].Trim());
    LoggingHelper.WriteLogFile("General", "*** Application_Start ***", "");
}

次に、次のように、ログが必要な場所で WriteLogFile メソッドを呼び出します。

protected void btn_Page2_Click(object sender, EventArgs e) {
    LoggingHelper.WriteLogFile("General", "btn_Page2_Click on Default.aspx", "");

    Response.Redirect("SecongPage.aspx");

}

これは問題なく動作しますが、小さな問題です。初めて Web ページにアクセスすると、Logfilename.log 形式のログ ファイルは作成されず、MyLog.log または Web.config で指定された名前が作成され、ログ ファイルは指定されたフォルダーの外に作成されます。ケース「ログ」、初めて。後続の要求の場合、構成されたフォルダーに目的のファイル名で目的のファイルが作成されます。このパターンは毎日繰り返されます。最初のリクエストの翌日、ログは昨日のファイルに書き込まれ、次のリクエスト以降、今日の日付の新しいファイルが作成され、すべてのログ メッセージがそのファイルに書き込まれます。

これが発生する原因となっているコードで何をしましたか?

WinForms アプリケーションに問題なくログインするために、上記のコードを少し変更して使用します。

Web サイトは現在 IIS にデプロイされていません。これは進行中の作業であるため、VS 2008 の組み込み開発サーバーを使用しています。もう 1 つの懸念事項は、コードが起動時に少なくとも 1 回は Web.config を更新しようとすることです。これがそれについての方法であるかどうかわかりません!

これは 2 つのページを持つ非常に単純なサンプルです。最初のページには、クリックすると 2 番目のページに移動するボタンがあります。ログ ファイルを毎日実装しようとしていますが、EntLib に付属のローリング フラット ファイルは、その日の必要な日付で毎日ファイルを作成しないため、要件に適合しません。

よろしく。

4

1 に答える 1

0

長い間探した後。これが私が思いついたものです。アイデアは、ビルド内のローリング フラット ファイルの代わりに FlatFile Trace リスナーを使用することです。

免責事項: 私の同僚の 1 人がこのコードを持っていましたが、どこから入手したか覚えていません。

私はその所有者ではないため、この回答に投票しないでください。それにもかかわらず、同様の実装を探している人を助けるためにここにいます

これは EntLib 4 を使用しますが、EntLib 5 でも使用できます。

ここに私の Web.config からのロギング部分があります:

<loggingConfiguration name="Logging Application Block" tracingEnabled="true"
defaultCategory="User" logWarningsWhenNoCategoriesMatch="true">
<listeners>
  <add fileName="trace.log" header="----------------------------------------"
    footer="----------------------------------------" formatter=""
    listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
    traceOutputOptions="None" filter="All" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
    name="FlatFile TraceListener" />
  <add fileName="MyLoggingSystem.log" header="" footer="" formatter="Text Formatter"
    listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
    traceOutputOptions="None" filter="All" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
    name="MyLoggingApp FlatFile TraceListener " />
  <add listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.WmiTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
    traceOutputOptions="None" filter="All" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.WmiTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
    name="WMI TraceListener" />
</listeners>
<formatters>
  <add template="[{timestamp}]  [{category}] {message}" type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
    name="Text Formatter" />
</formatters>
<categorySources>
  <add switchValue="All" name="Developer">
    <listeners>
      <add name="FlatFile TraceListener" />
    </listeners>
  </add>
  <add switchValue="All" name="General" />
  <add switchValue="All" name="Instrumentation">
    <listeners>
      <add name="WMI TraceListener" />
    </listeners>
  </add>
  <add switchValue="All" name="EskoLoggingApp">
    <listeners>
      <add name="MyLogging FlatFile TraceListener " />
    </listeners>
  </add>
  <add switchValue="All" name="User">
    <listeners>
      <add name="FlatFile TraceListener" />
    </listeners>
  </add>
</categorySources>
<specialSources>
  <allEvents switchValue="All" name="All Events" />
  <notProcessed switchValue="All" name="Unprocessed Category" />
  <errors switchValue="All" name="Logging Errors &amp; Warnings">
    <listeners>
      <add name="FlatFile TraceListener" />
    </listeners>
  </errors>
</specialSources>
</loggingConfiguration>

ファイルを保存するためのファイル名とフォルダーの 2 つのセクションがあります。

<appSettings>
    <add key="LogFolder" value="./Logs" />
    <add key="LogFileName" value="MyLoginSystem" />
</appSettings>

次のようなクラスを作成します。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Logging.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Logging;
using System.Diagnostics;
using System.Globalization;
using Microsoft.Practices.EnterpriseLibrary.Logging.Formatters;
using Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners;
using Microsoft.Practices.EnterpriseLibrary.Logging.Filters;

/// <summary>
/// Summary description for Utility
/// </summary>
public static class Utility {
    /// <summary>
    /// Instance for log writer 
    /// </summary> 
    private static LogWriter writer;

    /// <summary>
    /// Instance for log writer 
    /// </summary> 
    private static LogWriter wmiWriter;

    /// <summary>
    /// Instance for log writer 
    /// </summary> 
    private static LogWriter eskoLoggingWriter;

    /// <summary>
    /// Intialize the Trace listners without using app.config file
    /// </summary>
    /// <param name="fileName">log file name</param>
    public static void Initialize(string fileName) {
        CreateLogWriterFromCode(fileName);
    }


    /// <summary>
    /// Log User Messages
    /// </summary>
    /// <param name="message">Message text</param>
    /// <param name="prior">Logger Priority</param>
    /// <param name="traceType">Trave event type</param>
    public static void LogUserMessage(string message, int prior, System.Diagnostics.TraceEventType traceType) {
        LogEntry(message, "User", prior, traceType);
    }

    /// <summary>
    /// Any type of Log Entry 
    /// </summary>
    /// <param name="message">Message text</param>
    /// <param name="category">Logger category</param>
    /// <param name="prior">Priory logger </param>
    /// <param name="traceType">Trace event type</param>
    public static void LogEntry(string message, string category, int prior, System.Diagnostics.TraceEventType traceType) {
        try {
            LogEntry log = null;
            log = new LogEntry();
            log.Message = message;
            log.Categories.Add(category);
            log.Severity = traceType;
            log.Priority = prior;
            log.TimeStamp = DateTime.Now;
            if (writer != null) {
                writer.Write(log);
            } else {
                eskoLoggingWriter.Write(log);
            }
            // wmiWriter.Write(log);
        } catch (LoggingException ex) {
            LogEntry(ex.Message, "Developer", prior, traceType);
        }
    }

    /// <summary>
    /// Log Developer Messages 
    /// </summary>
    /// <param name="message">Message text</param>
    /// <param name="prior">Logger priority</param>
    /// <param name="traceType">Trace event type</param>
    public static void LogDeveloperMessage(string message, int prior, System.Diagnostics.TraceEventType traceType) {
        LogEntry(message, "Developer", prior, traceType);
    }

    /// <summary>
    /// Close splash screen
    /// </summary>
    public static void ExitSplash() {
        Logger.Reset();
    }

    /// <summary>
    /// Disposing log write instance
    /// </summary>
    public static void Dispose() {
        if (writer != null) {
            writer = null;
        }
    }

    /// <summary>
    /// Creating log writer programatically 
    /// </summary>
    /// <param name="fileName">Full path of log file</param>
    static private void CreateLogWriterFromCode(string fileName) {
        if (writer != null) {
            writer = null;
        }
        //// The formatter is responsible for the look of the message. Notice the tokens: {timestamp}, {newline}, {message}, {category}
        TextFormatter formatter = new TextFormatter
            ("[{timestamp}]" + "[{category}]" + "{message}{newline}");

        //// Log messages to a log file. Use the formatter mentioned above specified.

        FlatFileTraceListener logFileListener = new FlatFileTraceListener(fileName, "", "", formatter);
        //// My collection of TraceListeners. 
        LogSource mainLogSource =
            new LogSource("FlatFile TraceListener", SourceLevels.All);
        mainLogSource.Listeners.Add(logFileListener);

        //// Assigning a non-existant LogSource for Logging Application Block 
        //// Specials Sources I don't care about.Used to say "don't log".
        LogSource nonExistantLogSource = new LogSource("Empty");

        //// I want all messages with a category of "User" or "Developer" to get distributed
        //// to all TraceListeners in my mainLogSource.
        IDictionary<string, LogSource> traceSources =
                      new Dictionary<string, LogSource>();
        traceSources.Add("User", mainLogSource);
        traceSources.Add("Developer", mainLogSource);

        // Let's glue it all together.
        // No filters at this time.
        // I won't log a couple of the Special
        // Sources: All Events and Events not
        // using "Error" or "Debug" categories.
        writer = new LogWriter(new ILogFilter[0],
                        traceSources,
                        nonExistantLogSource,
                        nonExistantLogSource,
                        mainLogSource,
                        "ALL",
                        false,
                        true);

    }

    /// <summary>
    /// Creating log writer programatically 
    /// </summary>
    static public void CreateLogWriterFromCode(string folder, string fileName) {
        if (eskoLoggingWriter == null) {
            //// The formatter is responsible for the look of the message. Notice the tokens: {timestamp}, {newline}, {message}, {category}
            TextFormatter formatter = new TextFormatter
                ("[{timestamp}]" + "[{category}]" + "{message}{newline}");

            //// Log messages to a log file. Use the formatter mentioned above specified.

            string date = String.Format("{0:yyyyMMdd}", DateTime.Now);
            FlatFileTraceListener logFileListener = new FlatFileTraceListener(folder + "/" + fileName + "_" + date + ".log", "", "", formatter);
            WmiTraceListener wmiListener = new WmiTraceListener();
            //// My collection of TraceListeners. 
            LogSource mainLogSource =
                new LogSource("FlatFile TraceListener", SourceLevels.All);
            LogSource wmiMainLogSource = new LogSource("WmiTraceListener", SourceLevels.All);
            mainLogSource.Listeners.Add(logFileListener);
            wmiMainLogSource.Listeners.Add(wmiListener);

            //// Assigning a non-existant LogSource for Logging Application Block 
            //// Specials Sources I don't care about.Used to say "don't log".
            LogSource nonExistantLogSource = new LogSource("Empty");

            //// I want all messages with a category of "User" or "Developer" to get distributed
            //// to all TraceListeners in my mainLogSource.
            IDictionary<string, LogSource> traceSources =
                          new Dictionary<string, LogSource>();
            traceSources.Add("User", mainLogSource);
            traceSources.Add("Developer", mainLogSource);

            IDictionary<string, LogSource> wmiTraceSources =
                                     new Dictionary<string, LogSource>();
            wmiTraceSources.Add("Instrumentation", wmiMainLogSource);

            // Let's glue it all together.
            // No filters at this time.
            // I won't log a couple of the Special
            // Sources: All Events and Events not
            // using "Error" or "Debug" categories.
            eskoLoggingWriter = new LogWriter(new ILogFilter[0],
                            traceSources,
                            nonExistantLogSource,
                            nonExistantLogSource,
                            mainLogSource,
                            "ALL",
                            false,
                            true);

            wmiWriter = new LogWriter(new ILogFilter[0],
                           wmiTraceSources,
                           nonExistantLogSource,
                           nonExistantLogSource,
                           wmiMainLogSource,
                           "All",
                           true,
                           true);
        }
    }
}

Global.asax で、これらの行を Application_Start に追加します。

void Application_Start(object sender, EventArgs e) {
        // Code that runs on application startup
        Utility.CreateLogWriterFromCode(ConfigurationSettings.AppSettings["LogFolder"].Trim(), ConfigurationSettings.AppSettings["LogFileName"].Trim());
        Utility.LogUserMessage("******** Application_Start Event My Login application started   ******", 1, System.Diagnostics.TraceEventType.Information);
}

メッセージをログに記録したい場所はどこでも、使用します

Utility.LogUserMessage

EntLib 5 を使用する場合は、Utility クラスに小さな変更を加える必要がある場合があります。それは些細なことです。

これで、その日の正しいデータを含む日単位のログ ファイルが作成されました。最初に Utility クラスを書いた匿名の人にもう一度感謝します。お役に立てれば。

よろしく。

于 2012-05-15T07:21:30.743 に答える