jonwagner / EventSourceProxy

EventSourceProxy (ESP) is the easiest way to add scalable Event Tracing for Windows (ETW) logging to your .NET program
Other
97 stars 20 forks source link

Usage with SLAB #18

Closed codethug closed 10 years ago

codethug commented 10 years ago

I'm using EventSourceProxy, and it's emitting events, which I can view in PerfView. However, I'm having trouble getting it to work with the Semantic Logging Application Block. Let's look at two EventSources I created:

[EventSource(Name = "Client-SMS-EventSource2")]
public class SmsEventSource2 : EventSource
{
    private static SmsEventSource2 _Log;
    public static SmsEventSource2 Log
    {
        get
        {
            if (_Log == null)
            {
                _Log = new SmsEventSource2();
            }
            return _Log;
        }
    }

    [Event(201, Version = 1, Level = EventLevel.LogAlways)]
    public void EmailSignatureNotSet(string username)
    {
        WriteEvent(201, username);
    }
}

[EventSource(Name = "Client-SMS-EventSource3")]
public abstract class SmsEventSource3 : EventSource
{
    private static SmsEventSource3 _Log;
    public static SmsEventSource3 Log
    {
        get
        {
            if (_Log == null)
            {
                _Log = EventSourceImplementer.GetEventSourceAs<SmsEventSource3>();
            }
            return _Log;
        }
    }

    [Event(201, Version = 1, Level = EventLevel.LogAlways)]
    public abstract void EmailSignatureNotSet(string username);
}

SmsEventSource2 is a standard EventSource that calls WriteEvent directly. SmsEventSource3 uses EventSourceProxy. I have code that calls these logging methods, and they both make events appear when I monitor with Perfview.

That's working great.

The problem comes when I try to use SLAB to log to SQLServer. Here is how I have it set up:

public class InProcessSlabManagement
{
    private static ObservableEventListener listener = new ObservableEventListener();
    private static EventSource eventSource;
    private static SinkSubscription<SqlDatabaseSink> sqlSink;

    public static void StartInProcTracing(EventSource source, string instanceName, string connectionString)
    {
        if (eventSource != null) { throw new InvalidOperationException("Started in proc tracing twice!"); }
        eventSource = source;
        JsonEventTextFormatter formatter = new JsonEventTextFormatter(EventTextFormatting.Indented);

        listener.EnableEvents(SmsEventSource2.Log, EventLevel.Verbose);
        listener.EnableEvents(SmsEventSource3.Log, EventLevel.Verbose);
        sqlSink = listener.LogToSqlDatabase(instanceName, connectionString);
    }

    public static void StopInProcTracing()
    {
        sqlSink.Sink.FlushAsync();
        if (eventSource == null) return;
        listener.DisableEvents(eventSource);
        listener.Dispose();
        eventSource.Dispose();
    }
}

The events from SmsEventSource2 are making it to the SQL Server, but not the ones from SmsEventSource3. Any thoughts on what I'm doing wrong?

My only guess is that I'm calling EnableEvents and passing in something that shows up as the type of my abstract class (SmsEventSource2) instead of the actual class (SmsEventSource2_Implemented), but I'm not really sure how else to do this.

jonwagner commented 10 years ago

There seems to be an issue with keywords. ESP automatically implements keywords for your events, but it seems that the listener is filtering it out.

For now, try this:

        listener.EnableEvents(SmsEventSource3.Log, EventLevel.Verbose, (EventKeywords)(-1));

And I'll put in a fix for it.

jonwagner commented 10 years ago

sigh

When you call EventListener.EnableEvents with no keywords, it only enables events with Keyword=None. When you call EventListener.EnableEvents WITH keywords (even -1), it only enables events WITH keywords.

That makes no sense to me. I'm sure there's a reason.

I'd like ESP to work exactly like a native implementation, so I'm going to turn off AutoKeywords by default. You'll be able to turn it on with the EventSourceImplementation attribute, or by a global flag (so people don't have to change too much existing code).

I'll also have to bump the version to 3.0 to signal to people that it's a breaking change.

jonwagner commented 10 years ago

Ok, I put v3.0 in nuget.

I'm actually glad that I made this change. I knew something wasn't quite right with keywords, but now it all lines up with the default implementation, so future issues won't be my problem. :)

codethug commented 10 years ago

Thanks, Jon! And thanks for updating NuGet.