Search code examples
c#etwetw-eventsourceperfview

How to define names hierarchy in ETW EventSource?


In my project I use System.Diagnostics.Tracing.EventSource like this:

namespace kafka4net.Tracing
{
    [EventSource(Name = "kafka4net")]
    public class ConnectionTrace : EventSource
    {
        public static ConnectionTrace Log = new ConnectionTrace();

        public void Connecting(string host, int port)
        {
            Log.WriteEvent(1, host, port);
        }

        public void Connected(string host, int port)
        {
            Log.WriteEvent(2, host, port);
        }
    }
}

I use PerfView with dynamic provider feature by defining "*kafka4net" in "Additional Providers" field. This resolves provider by its name. Works just fine. With one exception. Events I see are of kafka4net/Connecting whereas I would like to see kafka4net/ConnectionTrace/Connecting.

Generally speaking, I want event to be product/subsystem/event. I can see some system components have this structure, for example "Microsoft-Windows-DotNETRuntime/GC/Start".

I tried to put [EventSource(Name = "kafka4net-Connection")], but than I can not use it as dynamic event in PerfView because I would have to enumerate all my subsystems like "kafka4net-Connection, kafka4net-Fetcher", etc. And this is no go.

EventSource has Name property which can be top-level "product" and function name is used as lowest-level in the event name hierarchy. How do I stick in a middle element "subsystem" in event name hierarchy?


Solution

  • this can't be done because ProviderName/Event/OpCode is the convention to show Events in PerfView.

    Microsoft-Windows-DotNETRuntime/GC/Start also follows this. Microsoft-Windows-DotNETRuntime is the provider, GC is the Event and Start is the OpCode.

    You can use Tasks to get a better output:

    public class Tasks
    {
        public const EventTask Connect = (EventTask)0x1;
    }
    
    [EventSource(Name = "kafka4net")]
    public sealed class ConnectionTrace : EventSource
    {
        public static ConnectionTrace Log = new ConnectionTrace();
    
        [Event(1, Task = Tasks.Connect, Opcode = EventOpcode.Start)]
        public void Connecting(string host, int port)
        {
            if (Log.IsEnabled())
            {
                Log.WriteEvent(1, host, port);
            }
        }
    
        [Event(2, Task = Tasks.Connect, Opcode = EventOpcode.Stop)]
        public void Connected(string host, int port)
        {
            if (Log.IsEnabled())
            {
                Log.WriteEvent(2, host, port);
            }
        }
    }
    

    Here you have a better output in PerfView:

    enter image description here