Skip to content

Commit

Permalink
Use SocketsHttpHandler to improve performance in netcore applications…
Browse files Browse the repository at this point in the history
… by reusing connections
  • Loading branch information
Mauricio Dominguez committed Feb 4, 2020
1 parent 1fef073 commit 18698e5
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 18 deletions.
12 changes: 8 additions & 4 deletions src/Honeycomb.Serilog.Sink/Honeycomb.Serilog.Sink.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net461;netstandard2.0</TargetFrameworks>
<TargetFrameworks>net461;netcoreapp2.1;netcoreapp3.1</TargetFrameworks>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<Title>Honeycomb Serilog sink</Title>
<Authors>evilpilaf</Authors>
Expand All @@ -11,8 +11,12 @@
<Copyright>evilpilaf © $([System.DateTime]::Now.Year)</Copyright>
</PropertyGroup>

<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard2.0'">
<DefineConstants>NETCORE;NETSTANDARD;NETSTANDARD2_0</DefineConstants>
<PropertyGroup Condition=" '$(TargetFramework)' == 'netcoreapp2.1'">
<DefineConstants>NETCORE;NETCORE2_1</DefineConstants>
</PropertyGroup>

<PropertyGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.1'">
<DefineConstants>NETCORE;NETCORE3_1</DefineConstants>
</PropertyGroup>

<PropertyGroup Condition=" '$(TargetFramework)' == 'net461'">
Expand Down
58 changes: 44 additions & 14 deletions src/Honeycomb.Serilog.Sink/HoneycombSerilogSink.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,26 @@

using Honeycomb.Serilog.Sink.Formatters;

using Serilog.Debugging;
using Serilog.Events;
using Serilog.Sinks.PeriodicBatching;

namespace Honeycomb.Serilog.Sink
{
internal class HoneycombSerilogSink : PeriodicBatchingSink
{
#if NETCOREAPP
private static readonly SocketsHttpHandler _socketsHttpHandler = new SocketsHttpHandler { PooledConnectionLifetime = TimeSpan.FromMinutes(30) };
protected virtual HttpClient Client => BuildHttpClient();
#else
private static readonly Lazy<HttpClient> _clientBuilder = new Lazy<HttpClient>(BuildHttpClient);
protected virtual HttpClient Client => _clientBuilder.Value;
#endif
private static readonly Uri _honeycombApiUrl = new Uri("https://api.honeycomb.io/");

private readonly string _teamId;
private readonly string _apiKey;

private readonly Lazy<HttpClient> _clientBuilder = new Lazy<HttpClient>(BuildHttpClient);
protected virtual HttpClient Client => _clientBuilder.Value;
private readonly string _teamId;

/// <param name="teamId">The name of the team to submit the events to</param>
/// <param name="apiKey">The API key given in the Honeycomb ui</param>
Expand Down Expand Up @@ -48,34 +54,58 @@ protected override async Task EmitBatchAsync(IEnumerable<LogEvent> events)

private async Task SendBatchedEvents(string events)
{
var message = new HttpRequestMessage(HttpMethod.Post, $"/1/batch/{_teamId}")
var requestMessage = new HttpRequestMessage(HttpMethod.Post, $"/1/batch/{_teamId}")
{
Content = new StringContent(events, Encoding.UTF8, "application/json")
};
message.Headers.Add("X-Honeycomb-Team", _apiKey);
var result = await Client.SendAsync(message).ConfigureAwait(false);
var response = await result.Content.ReadAsStringAsync().ConfigureAwait(false);
requestMessage.Headers.Add("X-Honeycomb-Team", _apiKey);
var result = await SendRequest(requestMessage).ConfigureAwait(false);
if (!result.IsSuccessStatusCode)
{
using (Stream contentStream = await result.Content.ReadAsStreamAsync().ConfigureAwait(false))
using (var reader = new StreamReader(contentStream))
{
var response = await reader.ReadToEndAsync().ConfigureAwait(false);
SelfLog.WriteLine("Failure sending event to Honeycomb, received {statusCode} response with content {content}", result.StatusCode, response);
}
}
}

private async Task<HttpResponseMessage> SendRequest(HttpRequestMessage request)
{
#if NETCOREAPP
using (var client = Client)
{
return await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
}
#else
return await Client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
#endif
}

private static void BuildLogEvent(IEnumerable<LogEvent> logEvents, TextWriter payload)
{
payload.Write("[");
var eventSepparator = "";
var eventSeparator = "";
foreach (var evnt in logEvents)
{
payload.Write(eventSepparator);
eventSepparator = ",";
payload.Write(eventSeparator);
eventSeparator = ",";
RawJsonFormatter.FormatContent(evnt, payload);
}
payload.Write("]");
}

private static HttpClient BuildHttpClient()
{
var client = new HttpClient
{
BaseAddress = _honeycombApiUrl
};
HttpClient client;
#if NETCOREAPP
client = new HttpClient(_socketsHttpHandler, disposeHandler: false);
#else
client = new HttpClient();
#endif
client.BaseAddress = _honeycombApiUrl;

return client;
}
}
Expand Down

0 comments on commit 18698e5

Please sign in to comment.