app.config
とlog4net.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.config
とlog4net.config
の両方があります。
ただし、ログファイルは生成されません。どんな設定を見逃しましたか?
2014年3月4日に更新
私がやったように別個の構成ファイル(log4net.config)を使用している場合、ソリューションエクスプローラーでCopy to output directory
設定をCopy always
に設定することを忘れないでください
設計によりLog4Netは
fail-stop、log4netは実行時に予期しない例外をスローしないため、アプリケーションがクラッシュする可能性があります
それで、何が問題を引き起こしているかを理解するのは非常に難しいです。
Log4netの内部デバッグを有効にするにはどうすればよいですか?
FROM FAQ- http://logging.Apache.org/log4net/release/faq.html
<?xml version="1.0" encoding="utf-8" ?> <configuration> <appSettings> <add key="log4net.Internal.Debug" value="true"/> </appSettings> </configuration>
この設定は起動時にすぐに読み取られ、すべての内部デバッグメッセージが発行されます。
だからここにlog4Net用に作成したカスタムクラスがあります-設定ファイルが非常に混乱していたため、このヘルパークラスを作成しました
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)
{
}
}
プロセスが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")));
ここに私のために働く設定があります。
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#クラスライブラリプロジェクトにこのセットアップがあり、他のすべてのプロジェクトはこのプロジェクト参照を使用して例外をログに記録します。
チェックして再チェックした後... :-)
必要なのは、ロガーを作成する前にXmlConfigurator.Configure();
を呼び出すことです(一度だけ)。
喜んでお手伝いします、
Ofir
別の構成ファイルを作成し、log4netに関連するものをそのファイルに配置する場合は、AssemblyInfo.csの代わりに[Assembly: log4net.Config.XmlConfigurator(ConfigFile = @"...\log4net.config", Watch = true)]
を使用する必要があります
[Assembly: log4net.Config.XmlConfigurator(Watch = true)]
それ以外の場合は、<log4net> ... </log4net>
App.config内の構成の一部
「すべてのユーザー」がログディレクトリへの完全な権限を持っていると言うとき、これにはサービスアカウントが含まれますか?
LocalService、NetworkService、LocalSystemなどに権限があることを確認します(サービスが実行されているコンテキストによって異なります)。
また、サービスをアプリケーションとして実行するハーネスがあると仮定すると、ユーザーとして実行しているときにロギングは機能しますか?
アプリケーションとして正常に動作しない場合は、log4netの設定に問題があります(他の回答が対処しようとしました)。
これらのいくつかが明らかである場合は申し訳ありませんが、これらは私がチェックするものです:
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には何も必要ありません。
自分でデバッグできるように、アプリケーションをアップロードしてください。
いくつかを確認することをお勧めします:
ファイルパスのすべての「\」を「\」に置き換えます
すべてのlog4net構成をアプリケーションの構成ファイルに埋め込みます。
log4netデバッグを有効にします( こちらを参照 )
別の構成を試してください。インターネット上のどこかのサンプル設定を取得するだけです。
念のため、すべてのユーザーにログディレクトリへの最大のアクセス許可を付与します。
サービスをアンインストールして再インストールしてください。
log4netは、アクティブユーザーの権限で実行されます。アクティブなユーザーが、指定されたテキストファイルを作成/変更/削除する権限を持っていることを確認してください。
log4net.config用に別のファイルがある場合。次のプロパティを設定しました:
出力ディレクトリにコピー=常にコピー
上記のスレッドの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());
}
システムログインを使用するWindowsサービスは、存在するすべてのディレクトリにアクセスできません。そのため、「C:\ Users\Public\AppData」にログインしてみてください。これは私のために働いた
AssemblyInfo.csでコードに小さな問題があることがわかりました。
コードを次のように置き換えます。[アセンブリ:log4net.Config.XmlConfigurator(ConfigFile = "{{folder_path}}\log4net.config")]
{{folder_path}}はlog4net.configのパスです