小さなプログラムやタスクを起動するプログラムがあり、今度はタスクの名前を使用して動的に自分のファイル名に動的にログを記録したい。 少し掘り下げましたが、Log4Netで使用できるのは、%property
という素晴らしいものがあるようです。だから私はそれを試みた。しかし、Log4Netは、初期化された後、これに対してピックアップの変更がないようです。実行時にlog4netのファイル名を変更する
私は周りに遊ぶために少しテストプログラムを書いた。 ウィンザーコンテナを一度しかビルドしたくないのですが、Log4Netは "再初期化"されず、新しいログファイルが作成されます。だから今私は、ログファイルに正しいファイル名を取得することを確認するタスクを開始する前に、コンテナを構築する必要があります。
実行中にログのファイル名を変更する方が良いか賢明な方法があれば、誰にも分かりますか?ここで
は私のtestcodeです:使用
public class Program
{
static void Main(string[] args)
{
GlobalContext.Properties["LogName"] = "default";
XmlConfigurator.ConfigureAndWatch(new FileInfo("log4net.config"));
while (true)
{
Console.WriteLine();
Console.Write("> ");
string cmd = (Console.ReadLine() ?? string.Empty);
if (string.IsNullOrWhiteSpace(cmd)) continue;
if (cmd.ToLower() == "exit") Environment.Exit(0);
ExecuteTask(Regex.Split(cmd, @"\s+"));
}
}
private static void ExecuteTask(string[] args)
{
//This changes the filename Log4Net logs to, but Log4Net only picks it up if I rebuild my container
GlobalContext.Properties["LogName"] = args[0];
//This should only be run once. No real need to build the container before each run, except to reinitialize Log4Net
var container = BuildContainer();
try
{
var task = container.Resolve<ITask>(args[0]);
task.DoLog();
}
catch (Exception)
{
// This doesn't work as expected, Log4Net logs to the file specified outside of the trycatch
GlobalContext.Properties["LogName"] = "default";
var logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
logger.Info("Could not find "+args[0]);
}
}
private static WindsorContainer BuildContainer()
{
Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
var container = new WindsorContainer();
container.Install(
FromAssembly.This());
return container;
}
}
public interface ITask
{
void DoLog();
}
public class TwoTask : ITask
{
private readonly ILogger _logger;
public TwoTask(ILogger logger)
{
_logger = logger;
}
public void DoLog()
{
_logger.Info("Hello!");
}
}
public class OneTask : ITask
{
private readonly ILogger _logger;
public OneTask(ILogger logger)
{
_logger = logger;
}
public void DoLog()
{
_logger.Info("Hello!");
}
}
public class Installer : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Classes.FromThisAssembly()
.BasedOn(typeof(ITask))
.Configure(c => c.LifeStyle.Transient.Named(c.Implementation.Name)));
container.AddFacility<LoggingFacility>(f => f.UseLog4Net("log4net.config"));
}
}
Nugets: Castle.Core、Castle.Core-log4netの、Castle.LoggingFacility、Castle.Windsor
あなたが本当にやったすべてが 'ThreadContext'の代わりに使用' GlobalContext'されますこれはまだ動作しません - ファイル名は設定時に設定されます。プロパティの値は必要なだけ変更できますが、効果はありません。 – stuartd