2

Simple NCron service:

class Program
{
    static void Main(string[] args)
    {
        var schedService = new SchedulingService();
        schedService.At("* * * * *").Run<MyTask>(); // run every minute
        schedService.Start();

        Console.ReadLine();
    }
}

public class MyTask : NCron.ICronJob
{
    public void Execute()
    {
        Console.WriteLine("executing");
    }

    public void Initialize(NCron.CronContext context)
    {
    }

    public void Dispose()
    {
    }
}

Upon reaching the first minute but before executing MyTask, NCron seems to want to write to the Windows Event Log, and fails with

Unhandled Exception: System.Security.SecurityException: The source was not found, but some or all event logs could not be searched.  To create the source, you need permission to read all event logs to make sure that the new source name is unique.  Inaccessible logs: Security.
   at System.Diagnostics.EventLogInternal.FindSourceRegistration(String source, String machineName, Boolean readOnly, Boolean wantToCreate)
   at System.Diagnostics.EventLogInternal.SourceExists(String source, String machineName, Boolean wantToCreate)
   at System.Diagnostics.EventLogInternal.VerifyAndCreateSource(String sourceName, String currentMachineName)
   at System.Diagnostics.EventLogInternal.WriteEntry(String message, EventLogEntryType type, Int32 eventID, Int16 category, Byte[] rawData)
   at System.Diagnostics.EventLog.WriteEntry(String message, EventLogEntryType type)
   at NCron.ExceptionHelper.LogUnhandledException(Object exception)
   at NCron.Service.SchedulingService.WaitCallbackHandler(Object data)
   at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
   at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()
   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()`

What and why is NCron writing to the Event Log? This is the default behavior, so anyone using NCron must have dealt with this, I suppose, but I can't find any documentation or question/answers about the issue. I tried setting schedService.LogFactory = null;, which doesn't change anything.

Short of creating a custom log factory (which I don't want to do), or fiddling with the registry (which I really don't want to do, and sometimes can't on production machines), how can I fix this?

icktoofay
  • 126,289
  • 21
  • 250
  • 231
epalm
  • 4,283
  • 4
  • 43
  • 65

1 Answers1

1

If you don't want to write to the event log, you will need to provide an alternate logger and factory. As mentioned at the bottom of the https://code.google.com/p/ncron/wiki/Logging page, there's a log4net implementation available, of which the most recent version seems to reside at https://github.com/schourode/ncron/tree/master/src/NCron.Integration.log4net. If you don't want to use log4net, it would be quite trivial to write an alternate implementation.

If you are willing to allow NCron to write to the event log, you can avoid the runtime SecurityException by creating the target event log under an admin account before running the service. This would typically be done by including creation of the event log in your installer (assuming you have one), for example by using an EventLogInstaller.

Nicole Calinoiu
  • 20,843
  • 2
  • 44
  • 49
  • I find it disappointing and unfortunate that NCron doesn't work right out of the box. I'll review my options, thanks. – epalm Feb 01 '13 at 17:24
  • If you're not happy with its default behaviour, you could always submit a change request at https://code.google.com/p/ncron/issues/list. – Nicole Calinoiu Feb 01 '13 at 17:45
  • If your application is build around NCron's `Bootstrap.Init()` method, the event log installers are provided out of the box. Just run your EXE-file with `install` as the only command line parameter, and it will setup the application as a Windows service and create the event sources. – Jørn Schou-Rode Feb 05 '13 at 15:42
  • When I designed the logging framework in NCron, I considered having a default `NullLogger` that simply discarded all log messages. However, considering the non-UI nature of a scheduling application, this seemed like a crazy default, as all users would surely like some sort of logging. Windows' built in event logged thus seemed like a reasonable default. – Jørn Schou-Rode Feb 05 '13 at 15:48
  • Why is NCron writing any log messages at all? NCron (A) forces users to use a logging mechanism, and (B) automatically writes log messages. I don't think either of these things should be inflicted on users of a 3rd party library. In other words, I can write my own log messages to my own log, IF I want to. (Sorry for sounding so negative, NCron does everything else quite well, I've found.) – epalm Apr 12 '13 at 15:29