dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.27k stars 4.73k forks source link

Is it okay if I replace the current DebugProvider used by System.Diagnostics.Debug in my .NET Core application? #82758

Closed chenxinyanc closed 1 year ago

chenxinyanc commented 1 year ago

We're working on an ASP.NET 6 application running on a certain cluster. Sometimes in our debugging process, we'd like to deploy the application in DEBUG profile to our dev cluster and try it out. We send HTTP requests and check out the telemetry sent from the application.

We have a lot of Debug.Assert calls in our app. If there is any assertion failure, Environment.FailFast will eventually get invoked, emitting the stack trace in Console and in Windows Application event logs.

This poses some inconvenience for us, and we are looking for some solution so that we can figure out what has happend without RDP to the VMSS or relaying the event logs. I found that Environment.FailFast is invoked from DebugProvider. After taking a look at the following function, I think I can just replace the current DebugProvider so that it can emit some telemetry, (synchronously) flush it, before eventually failfast.

https://github.com/dotnet/runtime/blob/967250cc86b4c613015066b47b882e7424fdb590/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Debug.cs#L18-L27

However, while Debug.SetProvider is a public method in System.Private.CoreLib, this method is not forwarded to System.Runtime ref assembly.

Thus I'm not sure

  1. whether this method is intended to be called by non-NET-SDK code,
  2. whether there is any way to inherit from DebugProvider and to access Debug.SetProvider without reflection / emit,
  3. whether there can be anything I need to pay attention to, if I want to add some custom logic when the assertion fails (e.g., to emit some additional telemetry.) a. such as, I think I'd better prevent this function from getting reentered from my custom logic, and b. something like I'd better remove such code in RELEASE profile.
ghost commented 1 year ago

Tagging subscribers to this area: @tommcdon See info in area-owners.md if you want to be subscribed.

Issue Details
We're working on an ASP.NET 6 application running on a certain cluster. Sometimes in our debugging process, we'd like to deploy the application in DEBUG profile to our dev cluster and try it out. We send HTTP requests and check out the telemetry sent from the application. We have a lot of `Debug.Assert` calls in our app. If there is any assertion failure, [`Environment.FailFast`](https://learn.microsoft.com/en-us/dotnet/api/system.environment.failfast?view=net-7.0) will eventually get invoked, emitting the stack trace in Console and in Windows Application event logs. This poses some inconvenience for us, and we are looking for some solution so that we can figure out what has happend without RDP to the VMSS or relaying the event logs. I found that `Environment.FailFast` is invoked from `DebugProvider`. After taking a look at the following function, I think I can just replace the current `DebugProvider` so that *it can emit some telemetry, (synchronously) flush it, before eventually failfast*. https://github.com/dotnet/runtime/blob/967250cc86b4c613015066b47b882e7424fdb590/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Debug.cs#L18-L27 However, while `Debug.SetProvider` is a public method in `System.Private.CoreLib`, this method is not forwarded to `System.Runtime` ref assembly. Thus I'm not sure 1. whether this method is intended to be called by non-NET-SDK code, 2. whether there is any way to inherit from `DebugProvider` and to access `Debug.SetProvider` without reflection / emit, 3. whether there can be anything I need to pay attention to, if I want to add some custom logic when the assertion fails (e.g., to emit some additional telemetry.) a. such as, I think I'd better prevent this function from getting reentered from my custom logic, and b. something like I'd better remove such code in RELEASE profile.
Author: chenxinyanc
Assignees: -
Labels: `area-Diagnostics-coreclr`, `untriaged`
Milestone: -
jkotas commented 1 year ago

This method is not meant to be called by non-.NET Runtime code.

Have you looked into registering your own TraceListener? It should allow you to do what you are looking for.

chenxinyanc commented 1 year ago

Thans for pointing that out! I've neglected there is a SetDebugProvider call when I access the Trace.Listeners collection.

https://github.com/dotnet/runtime/blob/967250cc86b4c613015066b47b882e7424fdb590/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceInternal.cs#L69

Then I suppose I'll implement a custom trace listener that