请求日志: 响应行显示字节长度 [ N bytes ] 并换行输出响应体

This commit is contained in:
2026-08-18 02:50:04 +08:00
parent 8a5c34756b
commit 3b252e08d5
2 changed files with 40 additions and 34 deletions
+12 -12
View File
@@ -1,19 +1,19 @@
version = 0
[requires]
soulsoft_web_http = {version = "1.0.20260528"}
soulsoft_extensions_options_configuration = {version = "1.0.20260528"}
soulsoft_web_http = {version = "1.0.20260528"}
soulsoft_web_routing = {version = "1.0.20260528"}
soulsoft_extensions_logging_configuration = {version = "1.0.20260528"}
soulsoft_extensions_configuration = {version = "1.0.20260528"}
soulsoft_serialization = {version = "1.0.20260528"}
soulsoft_extensions_injection = {version = "1.0.20260528"}
soulsoft_identity_claims = {version = "1.0.20260528"}
soulsoft_extensions_options = {version = "1.0.20260528"}
redis = {version = "1.0.20260627"}
soulsoft_web_hosting = {version = "1.0.20260528"}
soulsoft_web_mvc = {version = "1.0.20260528"}
soulsoft_web_cors = {version = "1.0.20260528"}
soulsoft_extensions_logging_console = {version = "1.0.20260528"}
soulsoft_extensions_logging = {version = "1.0.20260528"}
soulsoft_web_hosting = {version = "1.0.20260528"}
soulsoft_identity_claims = {version = "1.0.20260528"}
redis = {version = "1.0.20260627"}
soulsoft_extensions_hosting = {version = "1.0.20260528"}
soulsoft_serialization = {version = "1.0.20260528"}
soulsoft_web_mvc = {version = "1.0.20260528"}
soulsoft_extensions_logging_configuration = {version = "1.0.20260528"}
soulsoft_extensions_logging_console = {version = "1.0.20260528"}
soulsoft_extensions_configuration = {version = "1.0.20260528"}
soulsoft_web_cors = {version = "1.0.20260528"}
soulsoft_extensions_options = {version = "1.0.20260528"}
soulsoft_extensions_injection = {version = "1.0.20260528"}
+27 -21
View File
@@ -24,7 +24,9 @@ import simapi.helpers.*
* - 捕获下游异常并记录,随后重抛(对齐 C# ExceptionDispatchInfo + edi.Throw
* - 响应体:soulsoft HttpResponse.body 只读且不可读回(read 抛 UnsupportedException),
* 无法像 C# 那样用 MemoryStream 替换捕获;改为在各统一写出入口
* SimApiResponseWriter)缓存响应文本,此处直接读取。ShowFullResponse=false 时截断到 200 字符(对齐 C#)
* SimApiResponseWriter)缓存响应文本,此处直接读取。
* 响应行格式:*( Response [status] ) => [ N bytes ],随后换行输出响应体结构;
* ShowFullResponse=false 时截断到 200 字符(对齐 C#,长度仍显示完整字节数)
* - ShowFullUrl=false 时仅显示路径+查询串;ShowRunTime=true 时请求行显示 [POST] (xxxms)
*/
public class SimApiRequestLogMiddleware <: IMiddleware {
@@ -82,10 +84,28 @@ public class SimApiRequestLogMiddleware <: IMiddleware {
}
sbHead.append(" ${url}\n")
// 响应信息:状态码 + 响应体(经 SimApiResponseWriter 缓存读取)
sb.append("*( Response [${context.response.statusCode}] ) =>")
sb.append(readResponseBody(context))
// 响应信息:状态码 + 响应体长度(bytes),响应体结构换行显示
let responseBody = readResponseBody(context)
let bodyLen = if (responseBody.isEmpty()) {
context.response.contentLength ?? 0
} else {
responseBody.size
}
sb.append("*( Response [${context.response.statusCode}] ) => [ ${bodyLen} bytes ]\n")
if (!responseBody.isEmpty()) {
let display = if (_options.simApiRequestLogOptions.showFullResponse) {
responseBody
} else if (responseBody.size > 200) {
// 对齐 C#ShowFullResponse=false 时截断到 200 字符(长度仍显示完整字节数)
responseBody[0..200] + "...(${responseBody.size})"
} else {
responseBody
}
sb.append(display)
if (!display.endsWith("\n")) {
sb.append("\n")
}
}
if (let Some(ex) <- exception) {
sb.append("Exception: ${ex.toString()}\n")
}
@@ -165,27 +185,13 @@ public class SimApiRequestLogMiddleware <: IMiddleware {
}
}
/// 响应体读取:从 SimApiResponseWriter 缓存取;未捕获到时回退 Content-Length
/// 响应体读取:从 SimApiResponseWriter 缓存取完整响应体;未捕获到时返回空串
/// (长度与截断由调用方处理)
private func readResponseBody(context: HttpContext): String {
let body = match (context.items.get(SimApiResponseWriter.responseBodyCacheKey)) {
match (context.items.get(SimApiResponseWriter.responseBodyCacheKey)) {
case Some(v) => if (let s: String <- v) { s } else { "" }
case None => ""
}
if (body.isEmpty()) {
// 未捕获到响应体(如 IActionResult 直写路径):记录 Content-Length 作为替代
if (let Some(len) <- context.response.contentLength) {
return " (响应体长度: ${len})"
}
return ""
}
if (_options.simApiRequestLogOptions.showFullResponse) {
return body
}
// 对齐 C#ShowFullResponse=false 时截断到 200 字符
if (body.size > 200) {
return body[0..200] + "...(${body.size})"
}
return body
}
/// 请求体截断:JSON 字段级截断(对齐 C#:仅对超长字符串字段截断),非 JSON 则整串截断