Files
caliverse_server/BrokerApiServer/Common/ResultLoggingMiddleware.cs
2025-05-01 07:23:28 +09:00

68 lines
2.1 KiB
C#

namespace BrokerApiServer;
using ServerCore;
public class ResultLoggingMiddleware : IMiddleware
{
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
var path = context.Request.Path.Value;
if (Const.ExcludeLogPaths.Any(excludeLogPath => path?.Contains(excludeLogPath) ?? false))
{
await next(context);
return;
}
// 요청 로깅
var trace_id = context.TraceIdentifier;
var request_body = await readRequestBody(context.Request);
Log.getLogger()
.Info($"Request trace_id {trace_id} method {context.Request.Method} path {path}, req {request_body}");
// 응답 로깅을 위해 응답 본문을 캡처
var original_body_stream = context.Response.Body;
using var response_body_stream = new MemoryStream();
context.Response.Body = response_body_stream;
// 다음 미들웨어로 요청 전달
await next(context);
// 200 OK 응답 로깅 - 에러인 경우 에러 필터에서 처리
var response_body = await readResponseBody(context.Response);
var response =
$"trace_id {trace_id} status {context.Response.StatusCode}, path {path}, res {response_body}, req {request_body} ";
if (context.Response.StatusCode == StatusCodes.Status200OK)
{
// 불필요한 로그를 남기지 않은 healthcheck, swagger 제외
if (Const.ExcludeLogPaths.Any(excludeLogPath => path?.Contains(excludeLogPath) ?? false))
{
return;
}
Log.getLogger().info($"Response {response}");
}
else
{
Log.getLogger().error($"Response {response}");
}
// 응답 본문을 원래 스트림으로 복사
await response_body_stream.CopyToAsync(original_body_stream);
}
private async Task<string> readRequestBody(HttpRequest request)
{
request.EnableBuffering();
var body = await new StreamReader(request.Body).ReadToEndAsync();
request.Body.Position = 0;
return body;
}
private async Task<string> readResponseBody(HttpResponse response)
{
response.Body.Seek(0, SeekOrigin.Begin);
var body = await new StreamReader(response.Body).ReadToEndAsync();
response.Body.Seek(0, SeekOrigin.Begin);
return body;
}
}