我有一個啓動較小程序或任務的程序,現在我希望每個任務都動態地記錄到它們自己的文件名,最好使用任務名稱。 我已經挖掘了一點,似乎有一個漂亮的%property
事情,你可以使用Log4Net。所以我試了一下。但似乎Log4Net在初始化之後沒有爲此獲取更改。運行時更改log4net文件名
我寫了一個小測試程序來玩。 我寧願只構建windsor容器一次,但是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