Skip to content

Commit 326bdf9

Browse files
authored
Fix opera log non-json data overload (#998)
* fix: skip non-json body logging for multipart uploads * Update truncation implementation
1 parent cbe4e5e commit 326bdf9

File tree

1 file changed

+46
-6
lines changed

1 file changed

+46
-6
lines changed

backend/middleware/opera_log_middleware.py

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import json
12
import time
23

34
from asyncio import Queue
@@ -150,7 +151,7 @@ async def dispatch(self, request: Request, call_next: Any) -> Response:
150151

151152
return response
152153

153-
async def get_request_args(self, request: Request) -> dict[str, Any] | None:
154+
async def get_request_args(self, request: Request) -> dict[str, Any] | None: # noqa: C901
154155
"""
155156
获取请求参数
156157
@@ -178,26 +179,65 @@ async def get_request_args(self, request: Request) -> dict[str, Any] | None:
178179
if body_data:
179180
# 注意:非 json 数据默认使用 data 作为键
180181
if 'application/json' not in content_type:
181-
args['data'] = str(body_data)
182+
args['data'] = body_data.decode('utf-8', 'ignore') if isinstance(body_data, bytes) else str(body_data)
182183
else:
183184
json_data = await request.json()
184185
if isinstance(json_data, dict):
185186
args['json'] = await self.desensitization(json_data)
186187
else:
187-
args['data'] = str(body_data)
188+
args['data'] = str(json_data)
188189

189190
# 表单参数
190191
form_data = await request.form()
191192
if len(form_data) > 0:
193+
serialized_form = {}
192194
for k, v in form_data.items():
193-
form_data = {k: v.filename} if isinstance(v, UploadFile) else {k: v}
195+
if isinstance(v, UploadFile):
196+
serialized_form[k] = {
197+
'filename': v.filename,
198+
'content_type': v.content_type,
199+
'size': v.size,
200+
}
201+
else:
202+
serialized_form[k] = v
194203
if 'multipart/form-data' not in content_type:
195-
args['x-www-form-urlencoded'] = await self.desensitization(form_data)
204+
args['x-www-form-urlencoded'] = await self.desensitization(serialized_form)
196205
else:
197-
args['form-data'] = await self.desensitization(form_data)
206+
args['form-data'] = await self.desensitization(serialized_form)
207+
208+
if args:
209+
args = self.truncate(args)
198210

199211
return args or None
200212

213+
@staticmethod
214+
def truncate(args: dict[str, Any]) -> dict[str, Any]:
215+
"""
216+
截断处理
217+
218+
:param args: 需要截断的请求参数字典
219+
:return:
220+
"""
221+
max_size = 10240 # 数据最大大小(字节)
222+
223+
try:
224+
args_str = json.dumps(args, ensure_ascii=False)
225+
args_size = len(args_str.encode('utf-8'))
226+
227+
if args_size > max_size:
228+
truncated_str = args_str[:max_size]
229+
return {
230+
'_truncated': True,
231+
'_original_size': args_size,
232+
'_max_size': max_size,
233+
'_message': f'数据过大已截断:原始大小 {args_size} 字节,限制 {max_size} 字节',
234+
'data_preview': truncated_str,
235+
}
236+
except Exception as e:
237+
log.error(f'请求参数截断处理失败:{e}')
238+
239+
return args
240+
201241
@staticmethod
202242
@sync_to_async
203243
def desensitization(args: dict[str, Any]) -> dict[str, Any]:

0 commit comments

Comments
 (0)