Adds request logging to client

This commit is contained in:
Cyberboss
2018-08-14 09:57:51 -04:00
parent 1aaeb44972
commit 46b680cc32
5 changed files with 64 additions and 20 deletions
+19 -20
View File
@@ -1,5 +1,6 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
@@ -27,10 +28,15 @@ namespace Tgstation.Server.Client
}
/// <summary>
/// The <see cref="HttpClient"/> for the <see cref="IApiClient"/>
/// The <see cref="HttpClient"/> for the <see cref="ApiClient"/>
/// </summary>
readonly HttpClient httpClient;
/// <summary>
/// The <see cref="IRequestLogger"/>s used by the <see cref="ApiClient"/>
/// </summary>
readonly List<IRequestLogger> requestLoggers;
/// <summary>
/// Construct an <see cref="ApiClient"/>
/// </summary>
@@ -42,6 +48,7 @@ namespace Tgstation.Server.Client
Headers = apiHeaders ?? throw new ArgumentNullException(nameof(apiHeaders));
httpClient = new HttpClient();
requestLoggers = new List<IRequestLogger>();
}
/// <inheritdoc />
@@ -67,29 +74,18 @@ namespace Tgstation.Server.Client
var fullUri = new Uri(Url, route);
HttpContent content = null;
var message = new HttpRequestMessage(method, fullUri);
if (body != null)
content = new StringContent(JsonConvert.SerializeObject(body));
message.Content = new StringContent(JsonConvert.SerializeObject(body));
Task<HttpResponseMessage> task;
lock (this)
{
httpClient.DefaultRequestHeaders.Clear();
Headers.SetRequestHeaders(httpClient.DefaultRequestHeaders, instanceId);
Headers.SetRequestHeaders(message.Headers, instanceId);
if (method == HttpMethod.Get)
task = httpClient.GetAsync(route);
else if (method == HttpMethod.Put)
task = httpClient.PutAsync(fullUri, content, cancellationToken);
else if (method == HttpMethod.Post)
task = httpClient.PostAsync(fullUri, content, cancellationToken);
else if (method == HttpMethod.Delete)
task = httpClient.DeleteAsync(fullUri, cancellationToken);
else
throw new NotSupportedException();
}
await Task.WhenAll(requestLoggers.Select(x => x.LogRequest(message, cancellationToken))).ConfigureAwait(false);
var response = await task.ConfigureAwait(false);
var response = await httpClient.SendAsync(message, cancellationToken).ConfigureAwait(false);
await Task.WhenAll(requestLoggers.Select(x => x.LogResponse(response, cancellationToken))).ConfigureAwait(false);
var json = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
@@ -173,5 +169,8 @@ namespace Tgstation.Server.Client
/// <inheritdoc />
public Task<TResult> Create<TResult>(string route, long instanceId, CancellationToken cancellationToken) => RunRequest<TResult>(route, new object(), HttpMethod.Put, instanceId, cancellationToken);
/// <inheritdoc />
public void AddRequestLogger(IRequestLogger requestLogger) => requestLoggers.Add(requestLogger ?? throw new ArgumentNullException(nameof(requestLogger)));
}
}
@@ -16,6 +16,12 @@ namespace Tgstation.Server.Client
TimeSpan Timeout { get; set; }
/// <summary>
/// Adds a <paramref name="requestLogger"/> to the request pipeline
/// </summary>
/// <param name="requestLogger">The <see cref="IRequestLogger"/> to add</param>
void AddRequestLogger(IRequestLogger requestLogger);
Task<TResult> Create<TBody, TResult>(string route, TBody body, CancellationToken cancellationToken);
Task<TResult> Create<TResult>(string route, CancellationToken cancellationToken);
Task<TResult> Read<TResult>(string route, CancellationToken cancellationToken);
@@ -0,0 +1,29 @@
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace Tgstation.Server.Client
{
/// <summary>
/// For logging HTTP requests and responses
/// </summary>
public interface IRequestLogger
{
/// <summary>
/// Log a request
/// </summary>
/// <param name="requestMessage">The <see cref="HttpRequestMessage"/> representing the request</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param>
/// <returns>A <see cref="Task"/> representing the running operation</returns>
Task LogRequest(HttpRequestMessage requestMessage, CancellationToken cancellationToken);
/// <summary>
/// Log a response
/// </summary>
/// <param name="responseMessage">The <see cref="HttpResponseMessage"/> representing the request</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param>
/// <returns>A <see cref="Task"/> representing the running operation</returns>
Task LogResponse(HttpResponseMessage responseMessage, CancellationToken cancellationToken);
}
}
@@ -39,5 +39,11 @@ namespace Tgstation.Server.Client
/// The <see cref="System.Version"/> of the <see cref="IServerClient"/>
/// </summary>
Task<Version> Version(CancellationToken cancellationToken);
/// <summary>
/// Adds a <paramref name="requestLogger"/> to the request pipeline
/// </summary>
/// <param name="requestLogger">The <see cref="IRequestLogger"/> to add</param>
void AddRequestLogger(IRequestLogger requestLogger);
}
}
@@ -53,7 +53,11 @@ namespace Tgstation.Server.Client
/// <inheritdoc />
public void Dispose() => apiClient.Dispose();
/// <inheritdoc />
public Task<Version> Version(CancellationToken cancellationToken) => apiClient.Read<Version>(Routes.Root, cancellationToken);
/// <inheritdoc />
public void AddRequestLogger(IRequestLogger requestLogger) => apiClient.AddRequestLogger(requestLogger);
}
}