修复 生产者端的 请求日志无法读取request问题
This commit is contained in:
parent
bbad3da13a
commit
d49550807b
|
|
@ -54,10 +54,25 @@ namespace Learn.VideoAnalysis.API.Expand
|
|||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <exception cref="CustomException"></exception>
|
||||
public void ExecutingFileCached(ActionExecutingContext context)
|
||||
public void ExecutingCached(ActionExecutingContext context)
|
||||
{
|
||||
//特殊处理:ResultIgnore,不进行返回结果包装,原样输出
|
||||
var endpoint = context.HttpContext.GetEndpoint();
|
||||
var request = context.HttpContext.Request;
|
||||
// 1. 只有非 GET 请求且不是文件上传时才读取 Body
|
||||
if (!request.Method.Equals("GET", StringComparison.OrdinalIgnoreCase)
|
||||
&& !request.HasFormContentType)
|
||||
{
|
||||
// 确保从头开始读
|
||||
request.Body.Position = 0;
|
||||
// 使用 leaveOpen: true 防止 StreamReader 关闭底层的 Request.Body
|
||||
using (var reader = new System.IO.StreamReader(request.Body, System.Text.Encoding.UTF8, detectEncodingFromByteOrderMarks: false, bufferSize: 1024, leaveOpen: true))
|
||||
{
|
||||
var body = reader.ReadToEnd();
|
||||
context.HttpContext.Items["RequestBodyRaw"] = body;
|
||||
request.Body.Position = 0;
|
||||
}
|
||||
}
|
||||
// 直接返回原始结果,不封装
|
||||
if (endpoint?.Metadata.GetMetadata<HttpLogEnable>() == null) return;
|
||||
if (context.HttpContext.Request.HasFormContentType &&
|
||||
|
|
@ -74,6 +89,8 @@ namespace Learn.VideoAnalysis.API.Expand
|
|||
}).ToArray();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 执行接口前400 处理
|
||||
|
|
@ -149,54 +166,32 @@ namespace Learn.VideoAnalysis.API.Expand
|
|||
/// <returns></returns>
|
||||
public async Task AddHttpLogAsync(HttpContext context, BaseReturn<object>? result = null, Exception? e = null)
|
||||
{
|
||||
//特殊处理:ResultIgnore,不进行返回结果包装,原样输出
|
||||
var endpoint = context.GetEndpoint();
|
||||
// 所有请求都记录
|
||||
//if (endpoint?.Metadata.GetMetadata<HttpLogEnable>() == null&& e is null) return;
|
||||
|
||||
string request = null;
|
||||
var logId = Yitter.IdGenerator.YitIdHelper.NextId();
|
||||
if (!context.Request.Method.Equals("GET", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
context.Request.EnableBuffering();
|
||||
//记录请求参数
|
||||
if (context.Request.Body.CanSeek)
|
||||
var fileArr = context.Items.ContainsKey("FileCached") ? context.Items["FileCached"] as (IFormFile file, MemoryStream stream)[] : null;
|
||||
if (context.Request.HasFormContentType && fileArr != null)
|
||||
{
|
||||
try
|
||||
string uploadsFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "UploadLogs", logId.ToString());
|
||||
if (!Directory.Exists(uploadsFolder))
|
||||
Directory.CreateDirectory(uploadsFolder);
|
||||
foreach (var fileInfo in fileArr)
|
||||
{
|
||||
var fileArr = context.Items.ContainsKey("FileCached") ? context.Items["FileCached"] as (IFormFile file, MemoryStream stream)[] : null;
|
||||
if (context.Request.HasFormContentType && fileArr != null)
|
||||
{
|
||||
// 设置保存目录(例如:项目根目录下的Uploads文件夹)
|
||||
string uploadsFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "UploadLogs", logId.ToString());
|
||||
// 创建目录(如果不存在)
|
||||
if (!Directory.Exists(uploadsFolder))
|
||||
Directory.CreateDirectory(uploadsFolder);
|
||||
foreach (var fileInfo in fileArr)
|
||||
{
|
||||
// 生成安全文件名(防止路径遍历攻击)
|
||||
string uniqueFileName = Guid.NewGuid().ToString().Substring(0, 5) + "_" + Path.GetFileName(fileInfo.file.FileName);
|
||||
// 保存文件
|
||||
using var stream = new FileStream(Path.Combine(uploadsFolder, uniqueFileName), FileMode.Create, FileAccess.Write);
|
||||
fileInfo.stream.Position = 0;
|
||||
await fileInfo.stream.CopyToAsync(stream);
|
||||
fileInfo.stream.Dispose();
|
||||
}
|
||||
request = $"请求体包含{context.Request.Form.Files.Count()}个文件 目录 {uploadsFolder}";
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Request.Body.Position = 0;
|
||||
using var sr = new System.IO.StreamReader(context.Request.Body);
|
||||
request = await sr.ReadToEndAsync();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
request = "处理请求入参时发生了错误 \r\n" + ex.ToString() + "\r\n 原有请求数据 " + request;
|
||||
string uniqueFileName = Guid.NewGuid().ToString().Substring(0, 5) + "_" + Path.GetFileName(fileInfo.file.FileName);
|
||||
using var stream = new FileStream(Path.Combine(uploadsFolder, uniqueFileName), FileMode.Create, FileAccess.Write);
|
||||
fileInfo.stream.Position = 0;
|
||||
await fileInfo.stream.CopyToAsync(stream);
|
||||
fileInfo.stream.Dispose();
|
||||
}
|
||||
request = $"请求体包含{context.Request.Form.Files.Count()}个文件 目录 {uploadsFolder}";
|
||||
}
|
||||
|
||||
}
|
||||
if (context.Items.ContainsKey("RequestBodyRaw"))
|
||||
{
|
||||
request = context.Items["RequestBodyRaw"] as string;
|
||||
}
|
||||
//写入队列
|
||||
await DbScoped.Sugar.CopyNew()
|
||||
.Insertable<HttpLog>(new HttpLog
|
||||
|
|
@ -205,7 +200,7 @@ namespace Learn.VideoAnalysis.API.Expand
|
|||
Url = context.Request.Path + context.Request.QueryString,
|
||||
Method = context.Request.Method,
|
||||
Request = request,
|
||||
IP = $"{context.Connection?.RemoteIpAddress?.ToString()}",
|
||||
IP = GetClientIp(context),
|
||||
ResponseCode = result?.Code ?? -1,
|
||||
Response = (result != null ? JsonSerializer.Serialize(result) : null) ,
|
||||
Authorization = context.Request.Headers.ContainsKey("Authorization")
|
||||
|
|
@ -218,21 +213,31 @@ namespace Learn.VideoAnalysis.API.Expand
|
|||
}).ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
private string GetClientIp(HttpContext context)
|
||||
{
|
||||
var headers = context.Request.Headers;
|
||||
var ip = headers["X-Forwarded-For"].FirstOrDefault();
|
||||
if (!string.IsNullOrWhiteSpace(ip))
|
||||
{
|
||||
ip = ip.Split(',', StringSplitOptions.RemoveEmptyEntries).FirstOrDefault()?.Trim();
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(ip))
|
||||
{
|
||||
ip = headers["X-Real-IP"].FirstOrDefault();
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(ip) && context.Connection.RemoteIpAddress != null)
|
||||
{
|
||||
ip = context.Connection.RemoteIpAddress.ToString();
|
||||
}
|
||||
return ip ?? string.Empty;
|
||||
}
|
||||
|
||||
public override async void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
// 过期的
|
||||
//if (context.HttpContext.GetEndpoint()?
|
||||
// .Metadata.GetMetadata<IAllowAnonymous>() is null)
|
||||
//{
|
||||
// context.Result = new UnauthorizedResult();
|
||||
// return;
|
||||
//}
|
||||
|
||||
|
||||
Executing400(context);
|
||||
ExecutingFileCached(context);
|
||||
base.OnActionExecuting(context);
|
||||
ExecutingCached(context);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -248,6 +253,9 @@ namespace Learn.VideoAnalysis.API.Expand
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"{DateTime.Now}=>接口规范出现异常");
|
||||
Console.WriteLine(ex.Message);
|
||||
Console.WriteLine(ex.StackTrace);
|
||||
}
|
||||
|
||||
base.OnActionExecuted(context);
|
||||
|
|
|
|||
|
|
@ -106,8 +106,6 @@ namespace Learn.VideoAnalysis
|
|||
AppCommon.Services = app.Services;
|
||||
app.UseMiddleware<BasicAuthMiddleware>("Swagger");
|
||||
// Configure the HTTP request pipeline.
|
||||
//开启redis队列服务
|
||||
_ = app.Services.GetRequiredService<RedisInit>();
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI();
|
||||
app.UseExceptionHandler("/Error");
|
||||
|
|
@ -133,7 +131,12 @@ namespace Learn.VideoAnalysis
|
|||
app.UseCorsExpand();
|
||||
app.UseSqlSugarExpand();
|
||||
app.UseCoravelExpand();
|
||||
app.UseServiceSystem();
|
||||
app.UseServiceSystem(() =>
|
||||
{
|
||||
//开启redis队列服务
|
||||
_ = AppCommon.Services.GetRequiredService<RedisInit>();
|
||||
|
||||
});
|
||||
|
||||
app.Run();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using VideoAnalysisCore.Common;
|
||||
using VideoAnalysisCore.Common;
|
||||
using System.Text.Json;
|
||||
using VideoAnalysisCore.Model;
|
||||
using System.Text;
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ namespace VideoAnalysisCore.Common
|
|||
public static string FrameName = "frame_";
|
||||
|
||||
/// <summary>
|
||||
/// 删除 AI分析任务的缓存文件
|
||||
/// 删除 AI分析任务视频/PPT的缓存文件
|
||||
/// </summary>
|
||||
/// <param name="taskId"></param>
|
||||
/// <returns></returns>
|
||||
|
|
@ -144,6 +144,32 @@ namespace VideoAnalysisCore.Common
|
|||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除 AI分析任务的缓存文件
|
||||
/// </summary>
|
||||
/// <param name="taskId"></param>
|
||||
/// <returns></returns>
|
||||
public static async Task<bool> DeleteTaskAllFileAsync(long? taskId, RedisManager redisManager)
|
||||
{
|
||||
if (taskId is null || taskId == 0) return false;
|
||||
var path = taskId.ToString().LocalPath();
|
||||
if (!string.IsNullOrEmpty(path) && Directory.Exists(path))
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.Delete(path, true);
|
||||
await redisManager.AddTaskLog(taskId, $"已清理所有缓存文件: {taskId}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await redisManager.AddTaskLog(taskId, $"删除缓存文件 {taskId} 时出错: {ex.Message}");
|
||||
}
|
||||
}
|
||||
else
|
||||
await redisManager.AddTaskLog(taskId, $"未识别到任务缓存: {path}");
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 对象转化为JSON字符串
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -42,7 +42,9 @@ namespace VideoAnalysisCore.Common
|
|||
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!context.Request.Method.Equals("GET", StringComparison.OrdinalIgnoreCase)
|
||||
&& !context.Request.HasFormContentType)
|
||||
context.Request.EnableBuffering();
|
||||
await _next(context);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ namespace VideoAnalysisCore.Common.Expand
|
|||
/// 系统服务
|
||||
/// </summary>
|
||||
/// <param name="app1"></param>
|
||||
public static void UseServiceSystem(this IHost app1)
|
||||
public static void UseServiceSystem(this IHost app1,Action? action=null)
|
||||
{
|
||||
var app = app1.Services;
|
||||
// 注册启动后的回调
|
||||
|
|
@ -46,7 +46,10 @@ namespace VideoAnalysisCore.Common.Expand
|
|||
.Replace("+", "127.0.0.1");
|
||||
var uri = new Uri(normalizedAddress);
|
||||
int port = uri.Port; // 这里的 port 就是你要的数字 (int)
|
||||
OpenBrowser($"http://localhost:{uri.Port}/ui/index.html");
|
||||
if (OperatingSystem.IsWindows())
|
||||
OpenBrowser($"http://localhost:{uri.Port}/ui/index.html");
|
||||
if(action != null)
|
||||
action();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -414,7 +414,9 @@ namespace VideoAnalysisCore.Common
|
|||
}).ExecuteCommandAsync();
|
||||
try
|
||||
{
|
||||
await ExpandFunction.DeleteTaskFileAsync(tId, this);
|
||||
//await ExpandFunction.DeleteTaskFileAsync(tId, this);
|
||||
|
||||
await ExpandFunction.DeleteTaskAllFileAsync(tId, this);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
|
@ -429,6 +431,7 @@ namespace VideoAnalysisCore.Common
|
|||
/// </summary>
|
||||
public async Task InitChannel()
|
||||
{
|
||||
Thread.Sleep(1000);
|
||||
if (Redis is null) throw new Exception("redis未初始化");
|
||||
//处理之前程序结束前未能执行完的情况
|
||||
var oldTaskCount = Redis.LLen(RedisExpandKey.IDTask);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ namespace VideoAnalysisCore.Controllers
|
|||
/// <summary>
|
||||
/// 通用接口
|
||||
/// </summary>
|
||||
[Authorize(AuthenticationSchemes = Authentication.vdAdmin)]
|
||||
[Route("api/[controller]")]
|
||||
public class PublicController : ControllerBase
|
||||
{
|
||||
|
|
|
|||
|
|
@ -31,12 +31,12 @@ namespace VideoAnalysisCore.Job
|
|||
this.videotaskDB = videotaskDB;
|
||||
this.redisManager = redisManager;
|
||||
}
|
||||
public void DeleteTaskAllCaches()
|
||||
public async Task DeleteTaskAllCachesAsync()
|
||||
{
|
||||
|
||||
var startTime = -5;
|
||||
var startTime = -2;
|
||||
var timeSpan = startTime - 999;
|
||||
// 计算 6 天前已完成任务缓存
|
||||
// 计算 {startTime} 天前已完成任务缓存
|
||||
DateTime twoDaysAgo = DateTime.Now.AddDays(startTime);
|
||||
DateTime endDaysAgo = DateTime.Now.AddDays(timeSpan);
|
||||
|
||||
|
|
@ -54,21 +54,7 @@ namespace VideoAnalysisCore.Job
|
|||
|
||||
// 遍历查询结果,删除缓存文件
|
||||
foreach (var taskId in completedTasks)
|
||||
{
|
||||
var path = taskId.ToString().LocalPath();
|
||||
if (!string.IsNullOrEmpty(path) && Directory.Exists(path))
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.Delete(path, true);
|
||||
Console.WriteLine($"已删除缓存文件: {taskId}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"删除缓存文件 {taskId} 时出错: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
await ExpandFunction.DeleteTaskAllFileAsync(taskId, redisManager);
|
||||
}
|
||||
public async void DeleteTaskVideoCaches()
|
||||
{
|
||||
|
|
@ -105,7 +91,7 @@ namespace VideoAnalysisCore.Job
|
|||
{
|
||||
Console.WriteLine($"{DateTime.Now} 执行=>{this.GetType().FullName}");
|
||||
DeleteTaskVideoCaches();
|
||||
DeleteTaskAllCaches();
|
||||
DeleteTaskAllCachesAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue