All Projects → ghuntley → HttpClientDiagnostics

ghuntley / HttpClientDiagnostics

Licence: MIT license
HttpClientDiagnostics is a cross platform, portable class library that provides tracing/logging telemetry to Microsoft.Net.HttpClient. In the spirit of "applications decide the logging framework, libraries should play nice" this package does not require any external dependencies or abstractions like Common.Logging

Programming Languages

C#
18002 projects
powershell
5483 projects

Icon

HttpClientDiagnostics Build status

HttpClientDiagnostics is a cross platform, portable class library that provides tracing/logging telemetry of Microsoft.Net.HttpClient requests. In the spirit of "applications decide the logging framework, libraries should play nice" this package does not require any external dependencies or abstractions like Common.Logging. Logging all happens automatically, behind the scenes, without you needing to know how or care how to wire this up thanks to the amazing LibLog. It’s like magic! Its the future.

Supported Platforms

  • .NET 4.5
  • Mono
  • Xamarin.iOS
  • Xamarin.Android
  • Xamarin.Mac
  • UWP

Installation

Installation is done via NuGet:

Install-Package HttpClientDiagnostics

Usage

HttpClient client = new HttpClient(new HttpClientDiagnosticsHandler(new HttpClientHandler()));
HttpResponseMessage response = await client.GetStringAsync("https://api.duckduckgo.com/?q=apple&format=json");

Which will automatically yield in your application logs:

2016-05-04 18:45:19.291 +10:00 [Debug] Request: Method: GET, RequestUri: 'https://api.duckduckgo.com/?q=apple&format=json', Version: 1.1, Content: <null>, Headers:
{
}
2016-05-04 18:45:21.264 +10:00 [Debug] Response: StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
  Connection: keep-alive
  Strict-Transport-Security: max-age=0
  X-DuckDuckGo-Locale: en_US
  Cache-Control: max-age=1
  Date: Wed, 04 May 2016 08:45:21 GMT
  Server: nginx
  Content-Length: 23528
  Content-Type: application/x-javascript
  Expires: Wed, 04 May 2016 08:45:22 GMT
}
2016-05-04 18:45:21.681 +10:00 [Debug] Response Content: {"Result":"<a href=\"https://duckduckgo.com/Apple\">Apple</a>A deciduous tree in the rose family best known for its sweet, pomaceous fruit, the apple.}
2016-05-04 18:45:22.074 +10:00 [Debug] Response elapsed time: 2750 ms
2016-05-04 18:45:22.077 +10:00 [Debug] Total elapsed time: 2788 ms

Advanced Usage

The constructor of HttpClientDiagnosticsHandler can take another HttpMessageHandler which provides you with a way to chain multiple handlers together. A common scenario would be using Refit to automatically convert interface definitions into REST clients and integrating with ModernHttpClient for performance improvements, Fusillade for auto-deduplication of requests/request limiting/request prioritization and then finally your own custom handler that handles REST API authentication, authorization/security in a single and central place.

public interface IDuckDuckGoApi
{
    [Get("/?q={query}&format=json")]
    IObservable<DuckDuckGoSearchResult> Search(string query);
}

public class DuckDuckGoApiService : IDuckDuckGoApiService
{
    public const string ApiBaseAddress = "https://api.duckduckgo.com";

    private readonly Lazy<IDuckDuckGoApi> _background;
    private readonly Lazy<IDuckDuckGoApi> _speculative;
    private readonly Lazy<IDuckDuckGoApi> _userInitiated;

    public DuckDuckGoApiService(string apiBaseAddress = null, bool enableDiagnostics = false)
    {
        Func<HttpMessageHandler, IDuckDuckGoApi> createClient = innerHandler =>
        {
            HttpMessageHandler handler;

            if (enableDiagnostics)
            {
                handler = new HttpClientDiagnosticsHandler(innerHandler);
            }
            else
            {
                handler = innerHandler;
            }

            var client = new HttpClient(handler))
            {
                BaseAddress = new Uri(apiBaseAddress ?? ApiBaseAddress)
            };

            return RestService.For<IDuckDuckGoApi>(client);
        };

        _background = new Lazy<IDuckDuckGoApi>(() => createClient(
            new RateLimitedHttpMessageHandler(new NativeMessageHandler(), Priority.Background)));

        _userInitiated = new Lazy<IDuckDuckGoApi>(() => createClient(
            new RateLimitedHttpMessageHandler(new NativeMessageHandler(), Priority.UserInitiated)));

        _speculative = new Lazy<IDuckDuckGoApi>(() => createClient(
            new RateLimitedHttpMessageHandler(new NativeMessageHandler(), Priority.Speculative)));
    }

    public IDuckDuckGoApi Background => _background.Value;
    public IDuckDuckGoApi Speculative => _speculative.Value;
    public IDuckDuckGoApi UserInitiated => _userInitiated.Value;
}

With thanks to

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].