2

I created an EventSource (WebApiEventSource) in my ASP.NET WebApi application (to is as ITraceWriter-implementation):

[EventSource(Name = "WebApi")]
public class WebApiEventSource : EventSource
{
    public static readonly WebApiEventSource Log = new WebApiEventSource();

    [Event(1)]
    public void Event(string url, string message)
    {
        WriteEvent(1, url, message);
    }
}

I checked that EventSource's methods are called during runtime without errors.

Then I run PerfView and checked in its log that it can see my provider (EventSource):

Parsing Spec *WebApi Enabling Provider:*WebApi Level:Critical Keywords:0x0 Options:None Values: Guid:fc7bbb67-1b01-557b-5e0e-c1c4e40b6a24

Then I run 'collect' with filter "*WebApi", execute some action in my app and stop it.

But there're no any events from my provider in etl file! Section "Events" doesn't even contain the name of my provider.

What did I miss?

UPDATED: I found the reason, see my answer below.

Shrike
  • 9,218
  • 7
  • 68
  • 105

1 Answers1

3

It turns out that the reason why events are missing is pretty subtle. For the simplicity I didn't provide all my code, just part which I thought is important - the method where I'm calling EventSource.WriteEvent.

It's interesting that if an EventSource-implementation class contains ANY other method where EventSource.WriteEvent is being called with the same id then you won't see ANY events from this EventSource. It's unbelievable but it is.

So my class had one more method with WriteEvent call which I didn't use:

[EventSource(Name = "WebApi")]
public class WebApiEventSource : EventSource
{
    public static readonly WebApiEventSource Log = new WebApiEventSource();

    public void Event(string url, string message)
    {
        WriteEvent(1, url, message);
    }

    public void Event2(string url, string message)
    {
        WriteEvent(1, url, message);
    }
}

After that I removed my additional method (Event2) I did see my events in PerfView log!

NOTE: And applying EventAttribute is totally optional indeed.

Another reason I found is that that method which calls WriteEvent should not have arguments which are not strings.

Shrike
  • 9,218
  • 7
  • 68
  • 105
  • If I understand it correctly you should have Event2 use id=2 for WriteEvent like so: WriteEvent( 2, url, message ). This because id is the unique 64 bit identifier that differs Event from Event2 under the WebApi (your event source name) umbrella. I might be wrong, someone please correct me if so. – LosManos Jan 21 '14 at 20:31
  • Note that if you're using `Microsoft.Diagnostics.Tracing.EventSource` from NuGet, you can also include the Microsoft EventRegister Tool which adds a build target which checks for some (not all) of these gotchas. – Benjol Feb 11 '16 at 10:05
  • Consider using an enum to declare the event id uniquely and use method annotation, e.g.: `[Event(eventId: (int)AdapterEventIds.LegacyTraceInformational, Level = EventLevel.Informational)] private void LegacyTraceInformational(string sourceId, string correlationCode, ...) { this.WriteEvent(eventId: (int)AdapterEventIds.LegacyTraceInformational, sourceId: sourceId, correlationCode: correlationCode, ...); } public enum AdapterEventIds { LegacyTraceInformational = 1, LegacyTraceVerbose = 2, ...` `code in backticks` – David Burg May 02 '18 at 19:02