web-dev-qa-db-ja.com

.NET Windowsサービスでlog4netを動作させることができません

app.configlog4net.configを持つWindowsサービスがあります。

app.config

  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
  </configSections>
  <log4net configSource="log4net.config" />

log4net.config

<log4net>
  <appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
    <param name="File" value="D:\Projects\Integration\Interface Module\bin\Logs\MyFirstLogger.log"/>
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    <appendToFile value="true" />
    <rollingStyle value="Size" />
    <maxSizeRollBackups value="2" />
    <maximumFileSize value="1MB" />
    <staticLogFileName value="true" />
    <layout type="log4net.Layout.PatternLayout">
      <param name="ConversionPattern" value="%d [%t] %-5p %c %m%n"/>
    </layout>
  </appender>

  <root>
    <level value="ALL" />
    <appender-ref ref="LogFileAppender" />
  </root>
</log4net>

これもAssemblyInfo.csに追加しました:

[Assembly: log4net.Config.XmlConfigurator(Watch = true)]

そして、私のクラスの1つで、私は持っています:

private readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

そして

_log.Info(content);

allユーザーにLogsフォルダーへの完全なアクセス許可を与えました。

Binフォルダー(サービスの実行元)には、app.configlog4net.configの両方があります。

ただし、ログファイルは生成されません。どんな設定を見逃しましたか?

2014年3月4日に更新

私がやったように別個の構成ファイル(log4net.config)を使用している場合、ソリューションエクスプローラーでCopy to output directory設定をCopy alwaysに設定することを忘れないでください

34
Null Reference

設計によりLog4Netは

fail-stop、log4netは実行時に予期しない例外をスローしないため、アプリケーションがクラッシュする可能性があります

それで、何が問題を引き起こしているかを理解するのは非常に難しいです。

Log4netの内部デバッグを有効にするにはどうすればよいですか?

FROM FAQ- http://logging.Apache.org/log4net/release/faq.html

  • 内部デバッグは、アプリケーションの構成ファイル(log4net構成データがアプリケーションの構成ファイルに埋め込まれていない限り、log4net構成ファイルではない)に値を設定することでも有効にできます。 log4net.Internal.Debugアプリケーション設定は、値trueに設定する必要があります。例えば:
<?xml version="1.0" encoding="utf-8" ?> 
<configuration>
            <appSettings>
                <add key="log4net.Internal.Debug" value="true"/>
            </appSettings> 
</configuration>

この設定は起動時にすぐに読み取られ、すべての内部デバッグメッセージが発行されます。

  • 。 log4netの内部デバッグをプログラムで有効にするには、log4net.Util.LogLog.InternalDebuggingプロパティをtrueに設定する必要があります。明らかに、これがより早く設定されると、より多くのデバッグが生成されます。

だからここにlog4Net用に作成したカスタムクラスがあります-設定ファイルが非常に混乱していたため、このヘルパークラスを作成しました

  • アプリケーション全体で必要な数のアペンダーを開始できるため、あるdllが他のdllを呼び出すと、両方がアペンダーを開始でき、両方のアペンドが機能します。
  • また、アペンダーを閉じて(ファイルアペンダーの場合のように)メールとして送信することもできます。
Log4NetFileHelper log = new Log4NetFileHelper();
        log.Init(); //Initialize
        log.AddConsoleLogging(); //Add Console Logging
        log.AddFileLogging(Path.Combine(AssemblyDirectory, "BatchConsole.log")); 
        log.AddFileLogging(Path.Combine(AssemblyDirectory,"BatchConsole_error.log"),log4net.Core.Level.Error); 

このプロパティをTrueに設定してくださいlog4net.Util.LogLog.InternalDebugging = true;

public class Log4NetFileHelper
{
    private string  DEFAULT_LOG_FILENAME=string.Format("application_log_{0}.log",DateTime.Now.ToString("yyyyMMMdd_hhmm"));
    Logger root;
    public Log4NetFileHelper()
    {

    }

    public virtual void Init()
    {
        root = ((Hierarchy)LogManager.GetRepository()).Root;
        //root.AddAppender(GetConsoleAppender());
        //root.AddAppender(GetFileAppender(sFileName));
        root.Repository.Configured = true;
    }

    #region Public Helper Methods
    #region Console Logging
    public virtual void AddConsoleLogging()
    {
        ConsoleAppender C = GetConsoleAppender();
        AddConsoleLogging(C);
    }

    public virtual void AddConsoleLogging(ConsoleAppender C)
    {
        root.AddAppender(C);
    }
    #endregion

    #region File Logging
    public virtual FileAppender AddFileLogging()
    {
        return AddFileLogging(DEFAULT_LOG_FILENAME);
    }

    public virtual FileAppender AddFileLogging(string sFileFullPath)
    {
        return AddFileLogging(sFileFullPath, log4net.Core.Level.All);
    }

    public virtual FileAppender AddFileLogging(string sFileFullPath, log4net.Core.Level threshold)
    {
        return AddFileLogging(sFileFullPath, threshold,true);  
    }

    public virtual FileAppender AddFileLogging(string sFileFullPath, log4net.Core.Level threshold, bool bAppendfile)
    {
        FileAppender appender = GetFileAppender(sFileFullPath, threshold , bAppendfile);
        root.AddAppender(appender);
        return appender;
    }

    public virtual SmtpAppender AddSMTPLogging(string smtpHost, string From, string To, string CC, string subject, log4net.Core.Level threshhold)
    {
        SmtpAppender appender = GetSMTPAppender(smtpHost, From, To, CC, subject, threshhold);
         root.AddAppender(appender);
         return appender;
    }

    #endregion


    public log4net.Appender.IAppender GetLogAppender(string AppenderName)
    {
        AppenderCollection ac = ((log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root.Appenders;

        foreach(log4net.Appender.IAppender appender in ac){
            if (appender.Name == AppenderName)
            {
                return appender;
            }
        }

        return null;
    }

    public void CloseAppender(string AppenderName)
    {
        log4net.Appender.IAppender appender = GetLogAppender(AppenderName);
        CloseAppender(appender);
    }

    private void CloseAppender(log4net.Appender.IAppender appender)
    {
        appender.Close();
    }

    #endregion

    #region Private Methods

    private SmtpAppender GetSMTPAppender(string smtpHost, string From, string To, string CC, string subject, log4net.Core.Level threshhold)
    {
        SmtpAppender lAppender = new SmtpAppender();
        lAppender.Cc = CC;
        lAppender.To = To;
        lAppender.From = From;
        lAppender.SmtpHost = smtpHost;
        lAppender.Subject = subject;
        lAppender.BufferSize = 512;
        lAppender.Lossy = false;
        lAppender.Layout = new
        log4net.Layout.PatternLayout("%date{dd-MM-yyyy HH:mm:ss,fff} %5level [%2thread] %message (%logger{1}:%line)%n");
        lAppender.Threshold = threshhold;
        lAppender.ActivateOptions();
        return lAppender;
    }

    private ConsoleAppender GetConsoleAppender()
    {
        ConsoleAppender lAppender = new ConsoleAppender();
        lAppender.Name = "Console";
        lAppender.Layout = new 
        log4net.Layout.PatternLayout(" %message %n");
        lAppender.Threshold = log4net.Core.Level.All;
        lAppender.ActivateOptions();
        return lAppender;
    } 
    /// <summary>
    /// DETAILED Logging 
    /// log4net.Layout.PatternLayout("%date{dd-MM-yyyy HH:mm:ss,fff} %5level [%2thread] %message (%logger{1}:%line)%n");
    ///  
    /// </summary>
    /// <param name="sFileName"></param>
    /// <param name="threshhold"></param>
    /// <returns></returns>
    private FileAppender GetFileAppender(string sFileName , log4net.Core.Level threshhold ,bool bFileAppend)
    {
        FileAppender lAppender = new FileAppender();
        lAppender.Name = sFileName;
        lAppender.AppendToFile = bFileAppend;
        lAppender.File = sFileName;
        lAppender.Layout = new 
        log4net.Layout.PatternLayout("%date{dd-MM-yyyy HH:mm:ss,fff} %5level [%2thread] %message (%logger{1}:%line)%n");
        lAppender.Threshold = threshhold;
        lAppender.ActivateOptions();
        return lAppender;
    }

    //private FileAppender GetFileAppender(string sFileName)
    //{
    //    return GetFileAppender(sFileName, log4net.Core.Level.All,true);
    //}

    #endregion

    private void  ConfigureLog(string sFileName)
    {


    }
}
23
dekdev

プロセスがWindowsサービスとして実行される場合、Environment.CurrentDirectoryは「C:\ Windows\system32」になることに注意してください。

したがって、*。exeの横にlog4net構成ファイル(log4net.config)を配置すると、次のコードを使用してlog4netを構成できます。

var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
XmlConfigurator.Configure(new FileInfo(Path.Combine(assemblyFolder, "log4net.config")));
21
YantingChen

ここに私のために働く設定があります。

AssemblyInfo.cs

[Assembly: log4net.Config.XmlConfigurator(ConfigFile = "Log4net.config", Watch = true)]

Log4net.Config

<?xml version="1.0" encoding="utf-8" ?>
<log4net>
    <appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender,log4net">
            <param name="File" value="C:\TEMP\Logs.txt"/>
            <lockingModel type="log4net.Appender.FileAppender+MinimalLock,log4net" />
            <appendToFile value="true" />
            <rollingStyle value="Size" />
            <maxSizeRollBackups value="2" />
            <maximumFileSize value="1MB" />
            <staticLogFileName value="true" />
        <layout type="log4net.Layout.PatternLayout,log4net">
            <param name="ConversionPattern" value="%d [%t] %-5p %c %m%n"/>
        </layout>
    </appender>
    <root>
         <level value="ALL" />
         <appender-ref ref="LogFileAppender" />
    </root>
</log4net>

C#コード

private static readonly log4net.ILog Logger = log4net.LogManager.GetLogger(typeof(class_name));

C#クラスライブラリプロジェクトにこのセットアップがあり、他のすべてのプロジェクトはこのプロジェクト参照を使用して例外をログに記録します。

11
Deeptechtons

チェックして再チェックした後... :-)

必要なのは、ロガーを作成する前にXmlConfigurator.Configure();を呼び出すことです(一度だけ)。

喜んでお手伝いします、

Ofir

9
Ofir

別の構成ファイルを作成し、log4netに関連するものをそのファイルに配置する場合は、AssemblyInfo.csの代わりに[Assembly: log4net.Config.XmlConfigurator(ConfigFile = @"...\log4net.config", Watch = true)]を使用する必要があります

[Assembly: log4net.Config.XmlConfigurator(Watch = true)]

それ以外の場合は、<log4net> ... </log4net>App.config内の構成の一部

5
Alpay

「すべてのユーザー」がログディレクトリへの完全な権限を持っていると言うとき、これにはサービスアカウントが含まれますか?

LocalService、NetworkService、LocalSystemなどに権限があることを確認します(サービスが実行されているコンテキストによって異なります)。

また、サービスをアプリケーションとして実行するハーネスがあると仮定すると、ユーザーとして実行しているときにロギングは機能しますか?

アプリケーションとして正常に動作しない場合は、log4netの設定に問題があります(他の回答が対処しようとしました)。

3
l33tmike

これらのいくつかが明らかである場合は申し訳ありませんが、これらは私がチェックするものです:

  • Log4net.configファイルのプロパティに[出力にコピー]が[常にコピー]に設定されていることを確認し、binディレクトリ内のファイルを確認して確認します。

  • また、AssemblyInfo.csプロパティに関連するlog4netドキュメントからも注意してください。

属性を使用すると、アプリケーションの構成の読み込み元を定義するためのより明確な方法になります。ただし、属性は純粋に受動的であることに注意してください。それらは情報のみです。したがって、構成属性を使用する場合は、log4netを呼び出して属性を読み取れるようにする必要があります。 LogManager.GetLoggerを単純に呼び出すと、呼び出し元のアセンブリの属性が読み取られて処理されます。 したがって、アプリケーションの起動時、および外部アセンブリがロードされて呼び出される前に、できるだけ早くロギング呼び出しを行うことが不可欠です

  • トラブルシューティングを行うには、アセンブリレベルプロパティから明示的な構成呼び出しに切り替えてみてください。

    XmlConfigurator.Configure();

    十分なはずです。

  • 私は常にlog4net.configを完全な設定ファイルにします

     <?xml version = "1.0" encoding = "utf-8"?> 
     <configuration> 
     <configSections> 
     <section name = "log4net" 
     type = "log4net.Config.Log4NetConfigurationSectionHandler、log4net" />
     </ configSections> 
     <log4net> 
     ... 
     </ log4net> 
     </ configuration> 
    

Configファイルがlog4net.configである限り、log4netに関連するapp.configには何も必要ありません。

3
SteveM

自分でデバッグできるように、アプリケーションをアップロードしてください。

いくつかを確認することをお勧めします:

  1. ファイルパスのすべての「\」を「\」に置き換えます

  2. すべてのlog4net構成をアプリケーションの構成ファイルに埋め込みます。

  3. log4netデバッグを有効にします( こちらを参照

  4. 別の構成を試してください。インターネット上のどこかのサンプル設定を取得するだけです。

  5. 念のため、すべてのユーザーにログディレクトリへの最大のアクセス許可を付与します。

  6. サービスをアンインストールして再インストールしてください。

1
Uri Abramson

log4netは、アクティブユーザーの権限で実行されます。アクティブなユーザーが、指定されたテキストファイルを作成/変更/削除する権限を持っていることを確認してください。

1
user2373845

log4net.config用に別のファイルがある場合。次のプロパティを設定しました:

出力ディレクトリにコピー=常にコピー

0
shawtza

上記のスレッドのYanting Chenからのコメントの続き-以下のコードを使用すると、Windowsスケジューラでアプリを実行したときに、log4netによってすべての構成メッセージが記録される内容を見つけることができます。特にコマンド画面が表示されないサービスまたはスケジューラで実行している場合、誰かがlog4netの洞察を得るのに役立ちます。

  private static void InstanceLogger()
    {
        if (logger == null)
            logger = LogManager.GetLogger(typeof(Utility));

        // Code to troubleshoot Log4Net issues through Event log viewer
        StringBuilder sb = new StringBuilder();

        foreach (log4net.Util.LogLog m in logger.Logger.Repository.ConfigurationMessages)
        {
            sb.AppendLine(m.Message);
        }

        throw new Exception("String messages: " + sb.ToString());

    }
0
Phantom

システムログインを使用するWindowsサービスは、存在するすべてのディレクトリにアクセスできません。そのため、「C:\ Users\Public\AppData」にログインしてみてください。これは私のために働いた

0

AssemblyInfo.csでコードに小さな問題があることがわかりました。

コードを次のように置き換えます。[アセンブリ:log4net.Config.XmlConfigurator(ConfigFile = "{{folder_path}}\log4net.config")]

{{folder_path}}はlog4net.configのパスです

0
Essie