Search code examples
traceetw

Moving from file-based tracing session to real time session


I need to log trace events during boot so I configure an AutoLogger with all the required providers. But when my service/process starts I want to switch to real-time mode so that the file doesn't explode. I'm using TraceEvent and I can't figure out how to do this move correctly and atomically.

The first thing I tried:

const int timeToWait = 5000;

using (var tes = new TraceEventSession("TEMPSESSIONNAME", @"c:\temp\TEMPSESSIONNAME.etl") { StopOnDispose = false })
{
    tes.EnableProvider(ProviderExtensions.ProviderName<MicrosoftWindowsKernelProcess>());
    Thread.Sleep(timeToWait);
}

using (var tes = new TraceEventSession("TEMPSESSIONNAME", TraceEventSessionOptions.Attach))
{
    Thread.Sleep(timeToWait);
    tes.SetFileName(null);
    Thread.Sleep(timeToWait);

    Console.WriteLine("Done");
}

Here I wanted to make that I can transfer the session to real-time mode. But instead, the file I got contained events from a 15s period instead of just 10s. The same happens if I use new TraceEventSession("TEMPSESSIONNAME", @"c:\temp\TEMPSESSIONNAME.etl", TraceEventSessionOptions.Create) instead.

It seems that the following will cause the file to stop being written to:

using (var tes = new TraceEventSession("TEMPSESSIONNAME"))
{
    tes.EnableProvider(ProviderExtensions.ProviderName<MicrosoftWindowsKernelProcess>());
    Thread.Sleep(timeToWait);
}

But here I must reenable all the providers and according to the documentation "if the session already existed it is closed and reopened (thus orphans are cleaned up on next use)". I don't understand the last part about orphans. Obviously some events might occur in the time between closing, opening and subscribing on the events. Does this mean I will lose these events or will I get the later?

I also found the following in the documentation of the library:

In real time mode, events are buffered and there is at least a second or so delay (typically 3 sec) between the firing of the event and the reception by the session (to allow events to be delivered in efficient clumps of many events)

Does this make the above code alright (well, unless the improbable happens and for some reason my thread is delayed for more than a second between creating the real-time session and starting processing the events)?

I could close the session and create a new different one but then I think I'd miss some events. Or I could open a new session and then close the file-based one but then I might get duplicate events.

I couldn't find online any examples of moving from a file-based trace to a real-time trace.


Solution

  • I managed to contact the author of TraceEvent and this is the answer I got:

    Re the exception of the 'auto-closing and restarting' feature, it is really questions about the OS (TraceEvent simply calls the underlying OS API). Just FYI, the deal about orphans is that it is EASY for your process to exit but leave a session going. This MAY be what you want, but often it is not, and so to make the common case 'just work' if you do Create (which is the default), it will close a session if it already existed (since you asked for a new one).

    Experimentation of course is the touchstone of 'truth' but I would frankly expecting unusual combinations to just work is generally NOT true.

    My recommendation is to keep it simple. You need to open a new session and close the original one. Yes, you will end up with duplicates, but you CAN filter them out (after all they are IDENTICAL timestamps).

    The other possibility is use SetFileName in its intended way (from one file to another). This certainly solves your problem of file size growth, and often is a good way to deal with other scenarios (after all you can start up you processing and start deleting files even as new files are being generated).