I am working on a windows service and that service has five different jobs which runs at the same time as there is a scheduler which uses Quarts.Net and TopShelf library for scheduling these jobs at a specific time interval. The problem is with logging with each job, log4Net library is being used for logging each job to a separate file and there is a proper configuration for each logger in app.config file but still at run time logging is not done on correct log file, when all jobs running simultaneously. Below is the code sample for these jobs:
factory = new StdSchedulerFactory();
scheduler = factory.GetScheduler();
scheduler.JobFactory = new LoggerEnabledJobFactory() { AppLogger = LogManager.GetLogger("Job1") }; // in case of another job it will be "Job2"
scheduler.ListenerManager.AddJobListener(new JobListener() { Name = "Job1Listener" });
IJobDetail jobDetails = JobBuilder.Create<ServiceJob1>().SetJobData(map).Build();
ITrigger trigger = TriggerBuilder.Create()
.WithSimpleSchedule(x =>
x.WithIntervalInSeconds(interval)
.RepeatForever().WithMisfireHandlingInstructionIgnoreMisfires()
)
.StartNow()
.WithIdentity("Job1TriggerGroup")
.Build();
scheduler.ScheduleJob(jobDetails, trigger);
scheduler.Start();
Below is custom JobFactory code: (which was already there in code)
public interface IloggerEnabledJob : IJob
{
ILog AppLogger{ get; set; }
}
public class LoggerEnabledJobFactory : IJobFactory
{
public ILog AppLogger { get; set; }
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
var job = Activator.CreateInstance(bundle.JobDetail.JobType);
((IloggerEnabledJob)job).AppLogger = AppLogger ;
return (IJob)job;
}
public void ReturnJob(IJob job)
{
}
}
Below is the "ServiceJob1" class code:
public class ServiceJob1 : IloggerEnabledJob
{
public ILog AppLogger { get; set; }
public void Execute(IJobExecutionContext context)
{
try
{
// do something
}
catch (Exception ex)
{
Logger.Log(AppLogger, Logger.LogType.Error, "Exception : " + ex);
}
}
}
App.config :
<log4net>
<root>
<level value="INFO"/>
<appender-ref ref="Job1FileAppender"/>
<appender-ref ref="Job2FileAppender"/>
</root>
<appender name="Job1FileAppender" type="log4net.Appender.RollingFileAppender">
<file type="log4net.Util.PatternString">
<conversionPattern value="\Logs\Job1\Job1_Log_%date{yyyy.MM.dd.HH.mm.ss}-%processid.txt"/>
</file>
<filter type="log4net.Filter.LoggerMatchFilter">
<loggerToMatch value="Job1"/>
</filter>
<filter type="log4net.Filter.DenyAllFilter"/>
<appendToFile value="true"/>
<rollingStyle value="Size"/>
<maxSizeRollBackups value="10"/>
<maximumFileSize value="25MB"/>
<staticLogFileName value="true"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline"/>
</layout>
</appender>
<appender name="Job2FileAppender" type="log4net.Appender.RollingFileAppender">
<file type="log4net.Util.PatternString">
<conversionPattern value="\Logs\Job2\Job2_Log_%date{yyyy.MM.dd.HH.mm.ss}-%processid.txt"/>
</file>
<filter type="log4net.Filter.LoggerMatchFilter">
<loggerToMatch value="Job2"/>
</filter>
<filter type="log4net.Filter.DenyAllFilter"/>
<appendToFile value="true"/>
<rollingStyle value="Size"/>
<maxSizeRollBackups value="10"/>
<maximumFileSize value="25MB"/>
<staticLogFileName value="true"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline"/>
</layout>
</appender>
<logger name="Job1" additivity="true">
<level value="ALL" />
<appender-ref ref="Job1FileAppender" />
</logger>
<logger name="Job2" additivity="true">
<level value="ALL" />
<appender-ref ref="Job2FileAppender" />
</logger>
</log4net>
I need to log Job1 and Job2 logs to their respective log file even if all five jobs running simultaneously. Any help/suggestions would be appreciated!