diff --git a/src/Helpers/MasterHelper.cs b/src/Helpers/MasterHelper.cs
index 7b6836b..3e65a44 100644
--- a/src/Helpers/MasterHelper.cs
+++ b/src/Helpers/MasterHelper.cs
@@ -152,5 +152,66 @@ namespace iFileProxy.Helpers
return null;
}
+ ///
+ /// 从HttpContext中提取调试信息
+ ///
+ public static async Task ExtractDebugInfo(HttpContext context)
+ {
+ var debugInfo = new HttpContextDebugInfo
+ {
+ RequestId = context.TraceIdentifier,
+ Path = context.Request.Path,
+ Method = context.Request.Method,
+ ClientIP = GetClientIPAddr(context),
+ UserAgent = context.Request.Headers.UserAgent.ToString(),
+ Host = context.Request.Host.ToString(),
+ ContentType = context.Request.ContentType ?? string.Empty,
+ ContentLength = context.Request.ContentLength,
+ IsHttps = context.Request.IsHttps,
+ Headers = context.Request.Headers.ToDictionary(
+ h => h.Key,
+ h => h.Value.ToArray(),
+ StringComparer.OrdinalIgnoreCase
+ ),
+ QueryParams = context.Request.Query.ToDictionary(
+ q => q.Key,
+ q => q.Value.ToArray(),
+ StringComparer.OrdinalIgnoreCase
+ ),
+ Cookies = context.Request.Cookies.ToDictionary(
+ c => c.Key,
+ c => c.Value,
+ StringComparer.OrdinalIgnoreCase
+ )
+ };
+
+ // 获取表单数据
+ if (context.Request.HasFormContentType)
+ {
+ var form = await context.Request.ReadFormAsync();
+ debugInfo.FormData = form.ToDictionary(
+ f => f.Key,
+ f => f.Value.ToArray(),
+ StringComparer.OrdinalIgnoreCase
+ );
+ }
+
+ // 获取请求体
+ if (context.Request.Body.CanRead)
+ {
+ context.Request.EnableBuffering();
+ using var reader = new StreamReader(
+ context.Request.Body,
+ encoding: System.Text.Encoding.UTF8,
+ detectEncodingFromByteOrderMarks: false,
+ leaveOpen: true
+ );
+ debugInfo.RequestBody = await reader.ReadToEndAsync();
+ context.Request.Body.Position = 0;
+ }
+
+ return debugInfo;
+ }
+
}
}
diff --git a/src/Middleware/ErrorHandlerMiddleware.cs b/src/Middleware/ErrorHandlerMiddleware.cs
index 080a4a0..997222a 100644
--- a/src/Middleware/ErrorHandlerMiddleware.cs
+++ b/src/Middleware/ErrorHandlerMiddleware.cs
@@ -31,7 +31,7 @@ namespace iFileProxy
if (context.Response.StatusCode == 404)
{
context.Response.ContentType = "application/json";
- await context.Response.WriteAsync(JsonSerializer.Serialize(new CommonRsp { Retcode = 404, Message = "this route not exists." }));
+ await context.Response.WriteAsync( JsonSerializer.Serialize(new CommonRsp { Retcode = 404, Message = "this route not exists." }));
}
}
@@ -44,7 +44,7 @@ namespace iFileProxy
private static Task HandleExceptionAsync(HttpContext context, Exception exception)
{
var code = HttpStatusCode.InternalServerError; // 500 if unexpected
- _logger.Error("Crash Data: {exception}",exception);
+ _logger.Error("Crash Data: {exception}\nContext: {context}", exception, JsonSerializer.Serialize (MasterHelper.ExtractDebugInfo(context)));
switch (exception)
{
diff --git a/src/Models/HttpContextDebugInfo.cs b/src/Models/HttpContextDebugInfo.cs
new file mode 100644
index 0000000..b9b0883
--- /dev/null
+++ b/src/Models/HttpContextDebugInfo.cs
@@ -0,0 +1,93 @@
+using System.Text.Json;
+
+namespace iFileProxy.Models
+{
+ public class HttpContextDebugInfo
+ {
+ ///
+ /// 请求ID
+ ///
+ public string RequestId { get; set; } = string.Empty;
+
+ ///
+ /// 请求路径
+ ///
+ public string Path { get; set; } = string.Empty;
+
+ ///
+ /// 请求方法
+ ///
+ public string Method { get; set; } = string.Empty;
+
+ ///
+ /// 客户端IP
+ ///
+ public string ClientIP { get; set; } = string.Empty;
+
+ ///
+ /// User-Agent
+ ///
+ public string UserAgent { get; set; } = string.Empty;
+
+ ///
+ /// 请求头信息
+ ///
+ public Dictionary Headers { get; set; } = [];
+
+ ///
+ /// 查询参数
+ ///
+ public Dictionary QueryParams { get; set; } = [];
+
+ ///
+ /// 表单数据
+ ///
+ public Dictionary FormData { get; set; } = [];
+
+ ///
+ /// Cookie信息
+ ///
+ public Dictionary Cookies { get; set; } = [];
+
+ ///
+ /// 请求体内容
+ ///
+ public string? RequestBody { get; set; }
+
+ ///
+ /// 请求时间
+ ///
+ public DateTime RequestTime { get; set; } = DateTime.Now;
+
+ ///
+ /// 服务器主机名
+ ///
+ public string Host { get; set; } = string.Empty;
+
+ ///
+ /// 请求内容类型
+ ///
+ public string ContentType { get; set; } = string.Empty;
+
+ ///
+ /// 内容长度
+ ///
+ public long? ContentLength { get; set; }
+
+ ///
+ /// 是否是HTTPS
+ ///
+ public bool IsHttps { get; set; }
+
+ ///
+ /// 转换为格式化的字符串
+ ///
+ public override string ToString()
+ {
+ return JsonSerializer.Serialize(this, new JsonSerializerOptions
+ {
+ WriteIndented = true
+ });
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/SerilogConfig.cs b/src/SerilogConfig.cs
index 0c2db33..89f5e4a 100644
--- a/src/SerilogConfig.cs
+++ b/src/SerilogConfig.cs
@@ -5,6 +5,7 @@
using System.Net;
using iFileProxy.Sinks;
using iFileProxy.Services;
+ using ZstdSharp.Unsafe;
public static class SerilogConfig
{