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

Default-Keyword not working #20

Closed mjeanrichard closed 10 years ago

mjeanrichard commented 10 years ago

Hi,

I tried using your example with PerfView (capturing *ILog) and the following console application:

    public class Program
    {
        private static void Main(string[] args)
        {
            var log = EventSourceImplementer.GetEventSourceAs<ILog>();

            log.SomethingIsStarting("hello");
            log.SomethingIsFinishing("goodbye");
        }
    }

    [EventSourceImplementation()]
    public interface ILog
    {
        void SomethingIsStarting(string message);
        void SomethingIsFinishing(string message);
    }

The only thing being captured by PerfView is the Event ILog/ManifestData with the manifest. If I add AutoKeywords = true to the EventSourceImplementation-Attribute I can capture all events as expected.

Is this behaviour by design?

Thanks for your help! Best regards Meinrad

jonwagner commented 10 years ago

Keywords are a little bit of a mess in ETW. It doesn't make complete sense to me. I think I need to add a wiki page just for that.

When you create a listener, you have the option of enabling keyword filters.

As far as I know, there is no way to create a filter that has both types of events. I think you have to leave the filter blank to disable filtering.

In my example, I think I said to set the keyword filter to -1, but that would ignore the None events. It also explains why enabling AutoKeywords fixed your problem. You probably should leave the keyword filter blank.

Let me know if this explains it for you, and I'll update the wiki.

mjeanrichard commented 10 years ago

Thanks for your help, but unfortunately it does no explain our problem.

If I write a conventional (without the Proxy) EventSource and specify no keywords in the Event-Attribute all Events are captured (with no keyword filter applied).

If I use the Proxy and specify AutoKeywords=false no events are captured even with the Keyword Filter set to 0 (or -1).

After further inspection of the EventSource code I found a possible explanation:

If you implement a Event in your Proxy, do you use the IsEnabled overload with the two parameters? If so, if there are no Keywords specified do you use None for the keywords parameter? That would explain why there are no events produced.

mjeanrichard commented 10 years ago

If I have a "conventional" EventSource as follows:

    [EventSource()]
    public class Log2 : EventSource
    {
        public static Log2 Log = new Log2();

        [Event(100)]
        public void SomethingIsStarting(string message)
        {
            if (IsEnabled(EventLevel.Informational, (EventKeywords)(-1))) WriteEvent(100, message);
        }

        [Event(101)]
        public void SomethingIsFinishing(string message)
        {
            if (IsEnabled(EventLevel.Informational, EventKeywords.None)) WriteEvent(101, message);
        }
    }

The SomethingIsStarting Event is captured if there is no Keyword-Filter specified. But the second Event (SomethingIsFinishing) is never captured.

jonwagner commented 10 years ago

Yes, that's exactly it. I'll try to find some time to play with PerfView again and see if I have a better answer.

sashaozz commented 10 years ago

Hi, I don't use PerfView and its filters but in the .NET code I can enable events twice - once for events with keywords and once for events without any keyword. So for ESP interface

[EventSourceImplementation(Name = "name", Keywords = typeof(Keywords))]
public interface IWebApplicationEvents
{

        [Event(1, Level = EventLevel.Verbose)]
        void Event1();

        [Event(2, Level = EventLevel.Verbose, Keywords = EventKeywords.None)]
        void Event2();

        [Event(3, Level = EventLevel.Verbose, Keywords = Keywords.Keyword1)]
        void Event3();
}

if i will call

listener.EnableEvents(WebApplicationEvents.LogEventSource, level);
listener.EnableEvents(WebApplicationEvents.LogEventSource, level,(EventKeywords)(-1));

all the events would be logged. AutoKeywords of ESP is false in this case.

Hope it helps

jonwagner commented 10 years ago

This is the code in EventSource that causes the issue:

if ((this.m_matchAnyKeyword != EventKeywords.None) && ((keywords & this.m_matchAnyKeyword) == EventKeywords.None))
{
    return false;
}

In other words, once you filter by keywords, anything with a keyword of None will be skipped.

To be safe, I'm updating the call to IsEnabled so that it passes in -1 if there are no keywords. It should do no harm.

jonwagner commented 10 years ago

This should be fixed in v3.0.1. Available in NuGet now.

Please check it out and close this issue if it's fixed.

mjeanrichard commented 10 years ago

Thank you for the fast fix! Everything works great now.