I'm trying to pass my logger to a Logging Aspect that I've created with PostSharp. I have one logger per job run (because I need to send each job's logs to different folders), each job runs in different threads using BackgroundWorker. This is the code that I have:
[Serializable]
public class LogExecutionTimeAttribute : OnMethodBoundaryAspect
{
[NonSerialized]
public static Func<ILog> GetLogger;
private string methodName;
public override void CompileTimeInitialize(MethodBase method, AspectInfo aspectInfo)
{
this.methodName = method.Name;
}
public override void OnEntry(MethodExecutionArgs args)
{
args.MethodExecutionTag = Stopwatch.StartNew();
base.OnEntry(args);
}
public override void OnExit(MethodExecutionArgs args)
{
Stopwatch sw = (Stopwatch)args.MethodExecutionTag;
sw.Stop();
var logger = GetLogger();
logger.DebugFormat(
"{0} executed in {1} seconds.",
this.methodName,
sw.ElapsedMilliseconds / 1000.0);
base.OnExit(args);
}
}
Each thread would do:
var log = CreateLoggerForJobId(jobId);
LogExecutionTimeAttribute.GetLogger = () => log;
I'm doubtful about the Func<ILog> GetLogger
being static - How will it work when called from multiple threads? My manual tests seem to suggest that this is working, but I'm not sure if this is thread safe. I am also not sure if using NonSerialized
attribute on GetLogger
helps.
Entire working code is here:
https://gist.github.com/rnarayana/5518327f9c7c94f8c2fde4ae7fee7733