【发布时间】:2016-08-25 05:45:41
【问题描述】:
我有一个启动较小程序或任务的程序,现在我希望每个任务都动态记录到自己的文件名,最好使用任务名称。
我已经挖掘了一下,似乎有一个漂亮的%property 可以与 Log4Net 一起使用。所以我试过了。但似乎 Log4Net 在初始化后并没有对此进行更改。
我写了一个小测试程序来玩。 我宁愿只构建一次 windsor 容器,但是 Log4Net 不会被“重新初始化”,而是创建一个新的日志文件。所以现在我必须在开始任务之前构建容器,以确保我在日志文件中获得正确的文件名。
有谁知道在运行时是否有更好/更智能的方法来更改日志的文件名?
这是我的测试代码:
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
【问题讨论】: