-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Description
BACKGROUND: First, what is Session-based filtering.
EventSource has a multiple-reader model. Each reader is called a session and when sessions enable an EventSource the provide bitmask (keywords), and level (verbosity), which determine which events to give to the session. Importantly, you can have multiple sessions (readers) connected simultaneously and they should not interfere with one another (each gets the events they asked for and are unaware of the other sessions). Thus logically each session has the bitmask and verbosity for the EventSource associated with it and when an event is written, logically there is a loop over all sessions which writes the event to just those sessions that want it.
This all works well. The issue is when you have parameters for EventSource that is the problem. This is not a theoretical issue. Much of our instrumentation now is DiagnosticSource, and you turn on these events via a special EventSource. You specify exactly which DiagnosticSource events you want by using EventSource parameters. If you have more than two EventSources that want to listen to DiagnositicSource events, then you will have the issue I am about to describe.
The issue is that it is a PARTICULAR EventSource (e.g. DiagnosticSourceEventSource), that knows how to interpret the string, but the only mechanism it has to write will write to ALL sessions unconditionally. Thus for example if two sessions give filter parameters to DiagnosticSourceEventSource, turning on different events, then the second one 'win's and the first session does no get what it wants. 'Session based filtering fixes this so that each session gets the events it asked for and the two sessions do not interfere).
Fixing this is not actually trivial, because it requires a 'improved' contract between the EventSource base class and subclasses like DiagnosticSourceEventSource. The basic problem is that only the subclass knows how to interpret the arguments, but only the EventSource infrastructure has access to the list active sessions. Somehow we have to bring these together (in a way that does not make things complex for the current (common) case where you don't have sophisticated filtering).
Here is the proposed solution:
The strawman solution is
- Expose a small integer (can be used in index in an array), 'RequestingSessionId' on the EventCommandEventArgs.
- Expose a new method 'OnlyForSession(int sessionID), which logically sets a thread local variable so that the next write operation only targets that session (logically it is an another argument to the Write APIs, but there are so many option we don't really want to add that complexity. It gets logically reset back to 'all sessions' after that write on the thread.
Part of this work item would be to
- Fix DiangosticSourceEventSource would be session aware (Each DiagnosticSource tunnels to a specific session).
- Fix EventCounters to be session aware (This just means that the interval gets set to the minimum of all sessions (rather than currently the last set).