Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only enable events/counters if there are listeners available #928

Merged
merged 3 commits into from
Apr 21, 2021

Conversation

MihaZupan
Copy link
Member

Replacement for #915, description is NOT the same

Removed the AddProxyTelemetryListener, AddHttpTelemetryListener, ... extension methods as they don't provide any benefit over just AddTelemetryListeners after this change.

The listeners no longer fetch consumers per request (GetServices) - instead they get the consumers injected in the constructor. This means the core listeners only respect singleton consumers.

If needed, we can expose wrappers/helpers that add scoped consumer lifetimes.

Added an abstract EventListenerService class as a base of all listeners.
It abstracts away the synchronization around enabling the EventSource based on parameters from the constructor.

The listener implementations now only enable the necessary EventSources with the needed parameters. We will only enable events if a telemetry consumer is present & only enable event counters if a metrics consumer is present. Previously we would always enable events & metrics, even if only metrics were being used.

EventSource & EventSourceListener have a weird interaction where the OnEventSourceCreated may be called from the base constructor. That means parameters passed to the listener constructor can't control what happens in OnEventSourceCreated.
To work around that, the EventSourceName is taken from a property implemented by derived types instead of being a ctor argument.
Since only the ctor can decide on whether we need events/metrics, we delay calling EnableEvents until the ctor runs and inspects the service collection.
We avoid returning from OnEventSourceCreated before enabling the EventSource so that the first event isn't dropped.

A side-effect of the change to use singleton consumers is that this library now works with non-proxy scenarios out-of-the-box. For example, a user can register an IHttpProxyTelemetryConsumer and they will observe all Http events from HttpClients even outside the AspNetCore pipeline (as we are no longer bound by the HttpContext scope).

I added default interface implementations for all I*TelemetryConsumer methods. This makes it much easier to implement consumers that don't care about ALL the events - a user only overrides events they are interested in.

Metrics sample will be updated later as it targets a NuGet package.

@MihaZupan
Copy link
Member Author

Compared to #915:

  • The synchonization logic is the same
  • Singleton consumers are injected into listener ctors - we don't inspect the IServiceCollection
    • As a side-effect, this enables the consumption library to be used in non-proxy scenarios
    • Big perf boost over calling GetServices for every event

Copy link
Member

@Tratcher Tratcher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We avoid returning from OnEventSourceCreated before enabling the EventSource so that the first event isn't dropped.

Not a fan of the complexity needed for this part.

@Tratcher
Copy link
Member

We avoid returning from OnEventSourceCreated before enabling the EventSource so that the first event isn't dropped.

Without this check how likely are we to miss events, and how important are those events? The initialization happens once when starting the app, right?

@MihaZupan
Copy link
Member Author

Now that we are avoiding dotnet/runtime#51227/dotnet/runtime#51429, we should be okay with the minimal level of synchronization.

I removed the ThreadStatic/MRE logic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants