Merge pull request #3017 from sbwalker/dev

added logging to ServiceBase to capture HTTP errors
This commit is contained in:
Shaun Walker 2023-07-13 07:40:55 -04:00 committed by GitHub
commit 367a825955
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 55 additions and 17 deletions

View File

@ -37,7 +37,7 @@
</div> </div>
</div> </div>
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="category" HelpText="The categories that were affected" ResourceKey="Category">Category: </Label> <Label Class="col-sm-3" For="category" HelpText="The fully qualified type type that was affected" ResourceKey="Category">Type Name: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<input id="category" class="form-control" @bind="@_category" readonly /> <input id="category" class="form-control" @bind="@_category" readonly />
</div> </div>

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<root> <root>
<!-- <!--
Microsoft ResX Schema Microsoft ResX Schema
@ -136,7 +136,7 @@
<value>The function that was performed</value> <value>The function that was performed</value>
</data> </data>
<data name="Category.HelpText" xml:space="preserve"> <data name="Category.HelpText" xml:space="preserve">
<value>The categories that were affected</value> <value>The fully qualified type type that was affected</value>
</data> </data>
<data name="Page.HelpText" xml:space="preserve"> <data name="Page.HelpText" xml:space="preserve">
<value>The page that was affected</value> <value>The page that was affected</value>
@ -178,7 +178,7 @@
<value>Function: </value> <value>Function: </value>
</data> </data>
<data name="Category.Text" xml:space="preserve"> <data name="Category.Text" xml:space="preserve">
<value>Category: </value> <value>Type Name: </value>
</data> </data>
<data name="Page.Text" xml:space="preserve"> <data name="Page.Text" xml:space="preserve">
<value>Page: </value> <value>Page: </value>

View File

@ -3,9 +3,10 @@ using System.Collections.Generic;
using System.Net; using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Net.Http.Json; using System.Net.Http.Json;
using System.Reflection.Metadata.Ecma335; using System.Text.Json;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Oqtane.Enums;
using Oqtane.Models; using Oqtane.Models;
using Oqtane.Shared; using Oqtane.Shared;
@ -106,7 +107,7 @@ namespace Oqtane.Services
protected async Task GetAsync(string uri) protected async Task GetAsync(string uri)
{ {
var response = await GetHttpClient().GetAsync(uri); var response = await GetHttpClient().GetAsync(uri);
CheckResponse(response, uri); await CheckResponse(response, uri);
} }
protected async Task<string> GetStringAsync(string uri) protected async Task<string> GetStringAsync(string uri)
@ -140,7 +141,7 @@ namespace Oqtane.Services
protected async Task<T> GetJsonAsync<T>(string uri) protected async Task<T> GetJsonAsync<T>(string uri)
{ {
var response = await GetHttpClient().GetAsync(uri, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None); var response = await GetHttpClient().GetAsync(uri, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None);
if (CheckResponse(response, uri) && ValidateJsonContent(response.Content)) if (await CheckResponse(response, uri) && ValidateJsonContent(response.Content))
{ {
return await response.Content.ReadFromJsonAsync<T>(); return await response.Content.ReadFromJsonAsync<T>();
} }
@ -151,7 +152,7 @@ namespace Oqtane.Services
protected async Task PutAsync(string uri) protected async Task PutAsync(string uri)
{ {
var response = await GetHttpClient().PutAsync(uri, null); var response = await GetHttpClient().PutAsync(uri, null);
CheckResponse(response, uri); await CheckResponse(response, uri);
} }
protected async Task<T> PutJsonAsync<T>(string uri, T value) protected async Task<T> PutJsonAsync<T>(string uri, T value)
@ -162,7 +163,7 @@ namespace Oqtane.Services
protected async Task<TResult> PutJsonAsync<TValue, TResult>(string uri, TValue value) protected async Task<TResult> PutJsonAsync<TValue, TResult>(string uri, TValue value)
{ {
var response = await GetHttpClient().PutAsJsonAsync(uri, value); var response = await GetHttpClient().PutAsJsonAsync(uri, value);
if (CheckResponse(response, uri) && ValidateJsonContent(response.Content)) if (await CheckResponse(response, uri) && ValidateJsonContent(response.Content))
{ {
var result = await response.Content.ReadFromJsonAsync<TResult>(); var result = await response.Content.ReadFromJsonAsync<TResult>();
return result; return result;
@ -173,7 +174,7 @@ namespace Oqtane.Services
protected async Task PostAsync(string uri) protected async Task PostAsync(string uri)
{ {
var response = await GetHttpClient().PostAsync(uri, null); var response = await GetHttpClient().PostAsync(uri, null);
CheckResponse(response, uri); await CheckResponse(response, uri);
} }
protected async Task<T> PostJsonAsync<T>(string uri, T value) protected async Task<T> PostJsonAsync<T>(string uri, T value)
@ -184,7 +185,7 @@ namespace Oqtane.Services
protected async Task<TResult> PostJsonAsync<TValue, TResult>(string uri, TValue value) protected async Task<TResult> PostJsonAsync<TValue, TResult>(string uri, TValue value)
{ {
var response = await GetHttpClient().PostAsJsonAsync(uri, value); var response = await GetHttpClient().PostAsJsonAsync(uri, value);
if (CheckResponse(response, uri) && ValidateJsonContent(response.Content)) if (await CheckResponse(response, uri) && ValidateJsonContent(response.Content))
{ {
var result = await response.Content.ReadFromJsonAsync<TResult>(); var result = await response.Content.ReadFromJsonAsync<TResult>();
return result; return result;
@ -196,21 +197,20 @@ namespace Oqtane.Services
protected async Task DeleteAsync(string uri) protected async Task DeleteAsync(string uri)
{ {
var response = await GetHttpClient().DeleteAsync(uri); var response = await GetHttpClient().DeleteAsync(uri);
CheckResponse(response, uri); await CheckResponse(response, uri);
} }
private bool CheckResponse(HttpResponseMessage response, string uri) private async Task<bool> CheckResponse(HttpResponseMessage response, string uri)
{ {
if (!response.RequestMessage.RequestUri.AbsolutePath.Contains("/api/")) if (uri.Contains("/api/") && !response.RequestMessage.RequestUri.AbsolutePath.Contains("/api/"))
{ {
Console.WriteLine($"Request: {uri} Not Mapped To A Controller Method"); await Log(uri, response.RequestMessage.Method.ToString(), "Request {Uri} Not Mapped To A Controller Method", uri);
return false; return false;
} }
if (response.IsSuccessStatusCode) return true; if (response.IsSuccessStatusCode) return true;
if (response.StatusCode != HttpStatusCode.NoContent && response.StatusCode != HttpStatusCode.NotFound) if (response.StatusCode != HttpStatusCode.NoContent && response.StatusCode != HttpStatusCode.NotFound)
{ {
Console.WriteLine($"Request: {response.RequestMessage.RequestUri}"); await Log(uri, response.RequestMessage.Method.ToString(), "Request {Uri} Failed With Status {StatusCode} - {ReasonPhrase}", uri, response.StatusCode, response.ReasonPhrase);
Console.WriteLine($"Response status: {response.StatusCode} {response.ReasonPhrase}");
} }
return false; return false;
} }
@ -221,6 +221,44 @@ namespace Oqtane.Services
return mediaType != null && mediaType.Equals("application/json", StringComparison.OrdinalIgnoreCase); return mediaType != null && mediaType.Equals("application/json", StringComparison.OrdinalIgnoreCase);
} }
private async Task Log(string uri, string method, string message, params object[] args)
{
if (_siteState.Alias != null)
{
var log = new Log();
log.SiteId = _siteState.Alias.SiteId;
log.PageId = null;
log.ModuleId = null;
log.UserId = null;
log.Url = uri;
log.Category = GetType().AssemblyQualifiedName;
log.Feature = Utilities.GetTypeNameLastSegment(log.Category, 0);
switch (method)
{
case "GET":
log.Function = LogFunction.Read.ToString();
break;
case "POST":
log.Function = LogFunction.Create.ToString();
break;
case "PUT":
log.Function = LogFunction.Update.ToString();
break;
case "DELETE":
log.Function = LogFunction.Delete.ToString();
break;
default:
log.Function = LogFunction.Other.ToString();
break;
}
log.Level = LogLevel.Error.ToString();
log.Message = message;
log.MessageTemplate = "";
log.Properties = JsonSerializer.Serialize(args);
await PostJsonAsync(CreateApiUrl("Log"), log);
}
}
//[Obsolete("This constructor is obsolete. Use ServiceBase(HttpClient client, SiteState siteState) : base(http, siteState) {} instead.", false)] //[Obsolete("This constructor is obsolete. Use ServiceBase(HttpClient client, SiteState siteState) : base(http, siteState) {} instead.", false)]
// This constructor is obsolete. Use ServiceBase(HttpClient client, SiteState siteState) : base(http, siteState) {} instead. // This constructor is obsolete. Use ServiceBase(HttpClient client, SiteState siteState) : base(http, siteState) {} instead.
protected ServiceBase(HttpClient client) protected ServiceBase(HttpClient client)