Semantic logging of Process and Thread

Topics: Semantic Logging Application Block
Sep 4, 2013 at 5:52 PM
I am trying to understand using SLAB out of process.
If I understand correctly, ETW is being used as the delivery mechanism.
It seems to me, though, that some of the basic information included in ETW messages is not exposed by SLAB - specifically Process name and Thread Id. Two pieces of information I think are very valuable, especially if "centralizing" logging to a DB.
I found this post that suggests this data should be added as parameters to the EventSource method: http://entlib.codeplex.com/discussions/445111

But:
a) Why should I incur the cost of these parameters when the information is already captured by ETW?
b) Failing a method to capture the ETW information into my messages, how do I implement my EventSource to hide this from the developer? In other words, how can I implement my EventSource methods so that some subset of information may be uniformly added (transparently) to each and every WriteEvent? Especially when EventSourceAnalyzer will complain if the method parameter count does not match the message parameters?

Thank you!
Editor
Sep 6, 2013 at 6:01 AM
Why should I incur the cost of these parameters when the information is already captured by ETW?

I think the question you are asking is why Process Name and Thread Id parameters are not included in SLAB. It appears that ETW has about 30 pieces of information that could have been included while SLAB has much less (about 10) so I'm going to guess that the intent was to simplify the "interface". As to why those were not included, I can't say -- perhaps someone on the team will comment.

Failing a method to capture the ETW information into my messages, how do I implement my EventSource to hide this from the developer?

The way to do this is to have two methods: one public but decorated with NonEventAttribute and another private but decorated with EventAttribute. Here's an example:
    public class AppEventSource : EventSource
    {
        private static readonly Lazy<AppEventSource> Instance =
            new Lazy<AppEventSource>(() => new AppEventSource());

        private string processName;

        private AppEventSource()
        {
            processName = Process.GetCurrentProcess().ProcessName;
        }

        public static AppEventSource Log
        {
            get { return Instance.Value; }
        }

        [NonEvent]
        public void Initializing()
        {
            Initializing(processName, Thread.CurrentThread.ManagedThreadId);
        }

        [Event(1, Level = EventLevel.Verbose)]
        private void Initializing(string processName, int threadId)
        {
            if (IsEnabled())
            {
                WriteEvent(1, processName, threadId);
            }
        }
    }

Now developers only see the the Initializing() method with no arguments but the manifest is created based on Initializing(string processName, int threadId). The AppEventSource would be used like this:
    // Setup in process logging probably at application startup
    ObservableEventListener listener = new ObservableEventListener();

    listener.EnableEvents(AppEventSource.Log, System.Diagnostics.Tracing.EventLevel.Verbose);
    listener.LogToConsole(new EventTextFormatter(), new DefaultConsoleColorMapper());

    // Developer can only call Initializing()
    AppEventSource.Log.Initializing();

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Mar 17 at 8:39 PM
You should vote on this work item on the SLAB project sight here.
https://slab.codeplex.com/workitem/38