feat(exception): 优化异常中间件的日志记录功能
- 添加了对 Swap Trade 编辑请求的特殊处理逻辑 - 实现了针对掉期交易的诊断功能,包括 JSON 解析和验证 - 添加了专门用于检测无效利率的诊断方法 - 优化了异常日志的输出格式和内容 - 集成了缓冲区管理和流位置重置功能 - 增强了错误信息的详细程度和可读性
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using System.Buffers;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace YLErp.Web.App
|
||||
{
|
||||
@@ -17,6 +19,11 @@ namespace YLErp.Web.App
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
if (IsSwapTradeEditRequest(context.Request))
|
||||
{
|
||||
context.Request.EnableBuffering();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await _next.Invoke(context);
|
||||
@@ -41,9 +48,17 @@ namespace YLErp.Web.App
|
||||
|
||||
if (serviceExpcetion == null || serviceExpcetion.IsFaultError)
|
||||
{
|
||||
var result = await request.BodyReader.ReadAsync();
|
||||
var reqBody = ConvertBufferToString(result.Buffer);
|
||||
LogFactory.GetLogger(context.Request.Path.Value).Error(serviceExpcetion ?? exception, $"[query]:{request.QueryString.Value};[body]:{reqBody}");
|
||||
if (IsSwapTradeEditRequest(request))
|
||||
{
|
||||
var diagnostic = await GetSwapIntervalDiagnosticAsync(request);
|
||||
LogFactory.GetLogger(context.Request.Path.Value).Error(serviceExpcetion ?? exception, $"[query]:{request.QueryString.Value};{diagnostic}");
|
||||
}
|
||||
else
|
||||
{
|
||||
var result = await request.BodyReader.ReadAsync();
|
||||
var reqBody = ConvertBufferToString(result.Buffer);
|
||||
LogFactory.GetLogger(context.Request.Path.Value).Error(serviceExpcetion ?? exception, $"[query]:{request.QueryString.Value};[body]:{reqBody}");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -78,6 +93,106 @@ namespace YLErp.Web.App
|
||||
return System.Text.Encoding.UTF8.GetString(span);
|
||||
}
|
||||
|
||||
private static bool IsSwapTradeEditRequest(HttpRequest request)
|
||||
{
|
||||
return string.Equals(request.Path.Value, "/swaptrade2/tradeEditJson", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
private static async Task<string> GetSwapIntervalDiagnosticAsync(HttpRequest request)
|
||||
{
|
||||
if (!request.Body.CanSeek)
|
||||
{
|
||||
return "[swap-interval-diagnostic]:request-body-unavailable";
|
||||
}
|
||||
|
||||
request.Body.Position = 0;
|
||||
using var reader = new StreamReader(request.Body, Encoding.UTF8, false, 1024, leaveOpen: true);
|
||||
var requestBody = await reader.ReadToEndAsync();
|
||||
request.Body.Position = 0;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(requestBody))
|
||||
{
|
||||
return "[swap-interval-diagnostic]:request-body-empty";
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
using var document = JsonDocument.Parse(requestBody);
|
||||
if (!document.RootElement.TryGetProperty("swap_positions", out var positions) || positions.ValueKind != JsonValueKind.Array)
|
||||
{
|
||||
return "[swap-interval-diagnostic]:swap_positions-missing";
|
||||
}
|
||||
|
||||
var invalidRates = new List<string>();
|
||||
var positionIndex = 0;
|
||||
foreach (var position in positions.EnumerateArray())
|
||||
{
|
||||
var positionId = position.TryGetProperty("id", out var id) ? id.ToString() : "missing";
|
||||
AddInvalidRateDiagnostics(position, "SwapIntervalList", false, positionIndex, positionId, invalidRates);
|
||||
AddInvalidRateDiagnostics(position, "InterestSwapInterval", true, positionIndex, positionId, invalidRates);
|
||||
if (position.TryGetProperty("Obervation", out var observation))
|
||||
{
|
||||
AddInvalidRateDiagnostics(observation, "Obervation.ObservationInterval", true, positionIndex, positionId, invalidRates);
|
||||
}
|
||||
if (invalidRates.Count >= 10)
|
||||
{
|
||||
break;
|
||||
}
|
||||
positionIndex++;
|
||||
}
|
||||
|
||||
return invalidRates.Count == 0
|
||||
? "[swap-interval-diagnostic]:no-invalid-rate-in-payload"
|
||||
: $"[swap-interval-diagnostic]:{string.Join(";", invalidRates)}";
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
return "[swap-interval-diagnostic]:request-json-invalid";
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddInvalidRateDiagnostics(JsonElement position, string source, bool serializedJson, int positionIndex, string positionId, List<string> invalidRates)
|
||||
{
|
||||
if (!position.TryGetProperty(source, out var intervals))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (serializedJson)
|
||||
{
|
||||
if (intervals.ValueKind != JsonValueKind.String)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
using var document = JsonDocument.Parse(intervals.GetString());
|
||||
intervals = document.RootElement.Clone();
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
invalidRates.Add($"positionIndex={positionIndex},positionId={positionId},source={source},interval-json-invalid");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (intervals.ValueKind != JsonValueKind.Array)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var intervalIndex = 0;
|
||||
foreach (var interval in intervals.EnumerateArray())
|
||||
{
|
||||
if ((!interval.TryGetProperty("Rate", out var rate) || rate.ValueKind == JsonValueKind.Null) && invalidRates.Count < 10)
|
||||
{
|
||||
invalidRates.Add($"positionIndex={positionIndex},positionId={positionId},source={source},intervalIndex={intervalIndex},rate={(rate.ValueKind == JsonValueKind.Null ? "null" : "missing")}");
|
||||
}
|
||||
intervalIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetInnerExceptionMessage(Exception ex)
|
||||
{
|
||||
var exceptionStr = ex.Message;
|
||||
@@ -89,4 +204,4 @@ namespace YLErp.Web.App
|
||||
return exceptionStr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user