Skip to content

Fix Client Diagnostics following upgrade to DiagnosticSource 5.0.0 #5326

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

Merged
merged 1 commit into from
Feb 17, 2021

Conversation

russcam
Copy link
Contributor

@russcam russcam commented Feb 17, 2021

Relates: elastic/apm-agent-dotnet#1094

This commit fixes a rather pernicious bug with Diagnostics from the clients,
following the upgrade to System.Diagnostics.DiagnosticSource 5.0.0.

Diagnostic and Diagnostic<TState, TStateEnd> derived from
System.Diagnostics.Activity, implementing IDisposable to make them
nicer to work with. In System.Diagnostics.DiagnosticSource 5.0.0, Activity now
implements IDisposable, so the impl was updated to override Dispose(bool).

A problem arises from now deriving from Activity in that for an activity that is not finished,
Dispose() calls Stop() which in turn will notify the ActivitySource that it has stopped
and sets Activity.Current to the parent Activity (null if there's no parent). Now,
when calling into overridden Dispose(bool), the DiagnosticSource is notified that
the Activity has stopped, allowing for listeners to take action. If a listener is getting
the Activity through Activity.Current as Elastic APM's integration does however,
Activity.Current no longer represents the Activity that has stopped, but its parent, with
no nice way to reference the stopped Activity.

This commit removes deriving from Activity and introduces a private field
in which to hold an Activity that is started, and ended on Dispose. Starting
and stopping the activity sets the start and end times, respectively.

Relates: elastic/apm-agent-dotnet#1094

This commit fixes a rather pernicious bug with Diagnostics from the clients,
following the upgrade to System.Diagnostics.DiagnosticSource 5.0.0.

`Diagnostic` and `Diagnostic<TState, TStateEnd>` derived from
System.Diagnostics.Activity, implementing IDisposable to make them
nicer to work with. In System.Diagnostics.DiagnosticSource 5.0.0, Activity now
implements IDisposable, so the impl was updated to override `Dispose(bool)`.

A problem arises from now deriving from Activity in that for an activity that is not finished,
`Dispose()` calls `Stop()` which in turn will notify the ActivitySource that it has stopped
**and** sets `Activity.Current` to the parent Activity (null if there's no parent). Now,
when calling into overridden `Dispose(bool)`, the DiagnosticSource is notified that
the `Activity` has stopped, allowing for listeners to take action. If a listener is getting
the Activity through `Activity.Current` as Elastic APM's integration does however,
`Activity.Current` no longer represents the Activity that has stopped, but its parent, with
no nice way to reference the stopped Activity.

This commit removes deriving from `Activity` and introduces a private field
in which to hold an Activity that is started, and ended on Dispose. Starting
and stopping the activity sets the start and end times, respectively.
Copy link
Contributor

@stevejgordon stevejgordon left a comment

Choose a reason for hiding this comment

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

Thanks, Russ! That's an annoying bug! This looks good, but I think the dispose pattern could be tweaked on this?

Copy link
Contributor

@stevejgordon stevejgordon left a comment

Choose a reason for hiding this comment

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

LGTM!

@stevejgordon stevejgordon merged commit de2174d into 7.x Feb 17, 2021
@stevejgordon stevejgordon deleted the fix/activity-diagnostics branch February 17, 2021 09:24
github-actions bot pushed a commit that referenced this pull request Feb 17, 2021
…5326)

Relates: elastic/apm-agent-dotnet#1094

This commit fixes a rather pernicious bug with Diagnostics from the clients,
following the upgrade to System.Diagnostics.DiagnosticSource 5.0.0.

`Diagnostic` and `Diagnostic<TState, TStateEnd>` derived from
System.Diagnostics.Activity, implementing IDisposable to make them
nicer to work with. In System.Diagnostics.DiagnosticSource 5.0.0, Activity now
implements IDisposable, so the impl was updated to override `Dispose(bool)`.

A problem arises from now deriving from Activity in that for an activity that is not finished,
`Dispose()` calls `Stop()` which in turn will notify the ActivitySource that it has stopped
**and** sets `Activity.Current` to the parent Activity (null if there's no parent). Now,
when calling into overridden `Dispose(bool)`, the DiagnosticSource is notified that
the `Activity` has stopped, allowing for listeners to take action. If a listener is getting
the Activity through `Activity.Current` as Elastic APM's integration does however,
`Activity.Current` no longer represents the Activity that has stopped, but its parent, with
no nice way to reference the stopped Activity.

This commit removes deriving from `Activity` and introduces a private field
in which to hold an Activity that is started, and ended on Dispose. Starting
and stopping the activity sets the start and end times, respectively.
stevejgordon pushed a commit that referenced this pull request Feb 17, 2021
…5326) (#5327)

Relates: elastic/apm-agent-dotnet#1094

This commit fixes a rather pernicious bug with Diagnostics from the clients,
following the upgrade to System.Diagnostics.DiagnosticSource 5.0.0.

`Diagnostic` and `Diagnostic<TState, TStateEnd>` derived from
System.Diagnostics.Activity, implementing IDisposable to make them
nicer to work with. In System.Diagnostics.DiagnosticSource 5.0.0, Activity now
implements IDisposable, so the impl was updated to override `Dispose(bool)`.

A problem arises from now deriving from Activity in that for an activity that is not finished,
`Dispose()` calls `Stop()` which in turn will notify the ActivitySource that it has stopped
**and** sets `Activity.Current` to the parent Activity (null if there's no parent). Now,
when calling into overridden `Dispose(bool)`, the DiagnosticSource is notified that
the `Activity` has stopped, allowing for listeners to take action. If a listener is getting
the Activity through `Activity.Current` as Elastic APM's integration does however,
`Activity.Current` no longer represents the Activity that has stopped, but its parent, with
no nice way to reference the stopped Activity.

This commit removes deriving from `Activity` and introduces a private field
in which to hold an Activity that is started, and ended on Dispose. Starting
and stopping the activity sets the start and end times, respectively.

Co-authored-by: Russ Cam <russ.cam@elastic.co>
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