Skip to content

[API Proposal]: make payload types in System.Net.Http.DiagnosticsHandler to be public #82910

Description

@xakep139

Background and motivation

Currently all folks who want to listen to HttpClient events with DiagnosticListener, need to use reflection to get request/response data from a payload. Here's an example of a class used to get these properties in OpenTelemetry repo: PropertyFetcher
This applies to both .NET Core/.NET 5+ and .NET Framework (HttpHandlerDiagnosticListener and System.Net.Http.Desktop listeners respectively).

API Proposal

To improve both user experience and performance, these types can be made public:

For .NET Framework, anonymous types used for payload can be also done as regular public types:

API Usage

var observer = new HttpClientDiagnosticListener();
using var listenerSubscription = DiagnosticListener.AllListeners.Subscribe(observer);

// ...

class HttpClientDiagnosticListener : IObserver<DiagnosticListener>, IObserver<KeyValuePair<string, object?>>, IDisposable
{
    private IDisposable? _listenerSubscription;

    public void Dispose() => _listenerSubscription?.Dispose();

    public void OnCompleted() => /* ... */;

    public void OnError(Exception error) => /* ... */;

    public void OnNext(DiagnosticListener listener)
    {
        if (listener.Name == "HttpHandlerDiagnosticListener")
        {
            _listenerSubscription?.Dispose();
            _listenerSubscription = listener.Subscribe(this);
        }
    }

    public void OnNext(KeyValuePair<string, object?> @event)
    {
        // NB: No reflection here, we just cast payload:
        switch (@event.Key)
        {
            case "System.Net.Http.Request":
                if (@event.Value is RequestData request)
                {
                    // ...
                }
                break;

            case "System.Net.Http.Response":
                if (@event.Value is ResponseData response)
                {
                    // ...
                }
                break;

            case "System.Net.Http.Exception":
                if (@event.Value is RequestData request)
                {
                    // ...
                }
                break;
        }
    }
}

Alternative Designs

No response

Risks

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions