22import time
33from collections import defaultdict , deque
44from threading import Event , Thread
5- from types import EllipsisType
65from typing import Any , Dict , List , TextIO
76
87import yaml
@@ -27,29 +26,33 @@ def __init__(
2726 self .merge_output = merge_output
2827
2928 self .file_handlers : Dict [int , Dict [str , TextIO ]] = {}
30-
3129 self .buffer_limit = 20000
3230 self .buffers : Dict [int , List [Dict ]] = defaultdict (list )
3331
32+ self .max_args_count = 100
33+ self .max_item_count = 100
34+ self .max_line_length = 1024
35+ self .max_nest_depth = 5
36+
3437 # asyncio
3538 self .log_queue = deque ()
3639 self ._stop_event = Event ()
3740 self .writer_thread = Thread (target = self ._writer_loop )
3841 self .total_calls_processed = 0
3942
4043 self ._serialize_handlers = {
41- type (None ): lambda x : x ,
42- bool : lambda x : x ,
43- int : lambda x : x ,
44- float : lambda x : x ,
45- str : lambda x : x ,
44+ type (None ): lambda x , depth : x ,
45+ bool : lambda x , depth : x ,
46+ int : lambda x , depth : x ,
47+ float : lambda x , depth : x ,
48+ str : lambda x , depth : x ,
4649 list : self ._serialize_list ,
4750 tuple : self ._serialize_tuple ,
4851 set : self ._serialize_set ,
4952 dict : self ._serialize_dict ,
5053 type : self ._serialize_type ,
5154 slice : self ._serialize_slice ,
52- EllipsisType : self ._serialize_ellipsis ,
55+ type ( Ellipsis ) : self ._serialize_ellipsis ,
5356 }
5457
5558 def open (self ):
@@ -157,60 +160,86 @@ def dump_call(
157160 ):
158161 """记录一次API调用"""
159162 try :
163+ total_args = len (args ) + len (kwargs )
164+ if total_args > self .max_args_count :
165+ if len (args ) < self .max_args_count :
166+ kwargs = dict (
167+ list (kwargs .items ())[: self .max_args_count - len (args ) - 1 ]
168+ )
169+ kwargs ["__truncated__" ] = "<Truncated: max args exceeded>"
170+ else :
171+ args = tuple (
172+ list (args )[: self .max_args_count - 1 ]
173+ + ["<Truncated: max args exceeded>" ]
174+ )
175+ kwargs = {}
160176 call_record = {
161177 "level" : level ,
162178 "api" : api_name ,
163- "args" : [self ._serialize_item (arg ) for arg in args ],
179+ "args" : [self ._serialize_item (arg , depth = 0 ) for arg in args ],
164180 "kwargs" : {
165- key : self ._serialize_item (value ) for key , value in kwargs .items ()
181+ key : self ._serialize_item (value , depth = 0 )
182+ for key , value in kwargs .items ()
166183 },
167- # "output_summary": self._serialize_item(output)
184+ # "output_summary": self._serialize_item(output, depth=0 )
168185 }
169186 self .log_queue .append (call_record )
170187 except Exception as e :
171188 print (f"[ConfigSerializer] Error serializing call for '{ api_name } ': { e } " )
172189
173- def _serialize_list (self , item : list ) -> Dict :
190+ def _serialize_list (self , item : list , depth : int ) -> Dict :
191+ if len (item ) > self .max_item_count :
192+ item = item [: self .max_item_count - 1 ] + ["<Truncated: max item count>" ]
174193 return {
175194 "type" : "list" ,
176- "value" : [self ._serialize_item (sub_item ) for sub_item in item ],
195+ "value" : [self ._serialize_item (sub_item , depth ) for sub_item in item ],
177196 }
178197
179- def _serialize_tuple (self , item : tuple ) -> Dict :
198+ def _serialize_tuple (self , item : tuple , depth : int ) -> Dict :
199+ if len (item ) > self .max_item_count :
200+ item = item [: self .max_item_count - 1 ] + ("<Truncated: max item count>" ,)
180201 return {
181202 "type" : "tuple" ,
182- "value" : [self ._serialize_item (sub_item ) for sub_item in item ],
203+ "value" : [self ._serialize_item (sub_item , depth ) for sub_item in item ],
183204 }
184205
185- def _serialize_set (self , item : set ) -> Dict :
206+ def _serialize_set (self , item : set , depth : int ) -> Dict :
207+ if len (item ) > self .max_item_count :
208+ item = set (list (item )[: self .max_item_count - 1 ])
186209 return {
187210 "type" : "set" ,
188- "value" : [self ._serialize_item (sub_item ) for sub_item in item ],
211+ "value" : [self ._serialize_item (sub_item , depth ) for sub_item in item ],
189212 }
190213
191- def _serialize_dict (self , item : dict ) -> Dict :
214+ def _serialize_dict (self , item : dict , depth : int ) -> Dict :
215+ if len (item ) > self .max_item_count :
216+ item = dict (list (item .keys ())[: self .max_item_count - 1 ])
217+ item ["__truncated__" ] = "<Truncated: max item count>"
192218 return {
193219 "type" : "dict" ,
194- "value" : {str (k ): self ._serialize_item (v ) for k , v in item .items ()},
220+ "value" : {str (k ): self ._serialize_item (v , depth ) for k , v in item .items ()},
195221 }
196222
197- def _serialize_type (self , item : type ) -> Dict :
223+ def _serialize_type (self , item : type , depth : int ) -> Dict :
198224 return {"type" : "type" , "value" : f"{ item .__module__ } .{ item .__name__ } " }
199225
200- def _serialize_slice (self , item : slice ) -> Dict :
226+ def _serialize_slice (self , item : slice , depth : int ) -> Dict :
201227 return {
202228 "type" : "slice" ,
203229 "value" : {"start" : item .start , "stop" : item .stop , "step" : item .step },
204230 }
205231
206- def _serialize_ellipsis (self , item : Any ) -> Dict :
232+ def _serialize_ellipsis (self , item : Any , depth : int ) -> Dict :
207233 return {"type" : "ellipsis" , "value" : "..." }
208234
209- def _serialize_item (self , item : Any ) -> Any :
235+ def _serialize_item (self , item : Any , depth = 0 ) -> Any :
210236 """递归序列化对象"""
237+ if depth > self .max_nest_depth :
238+ return "<Truncated: max depth exceeded>"
239+
211240 handler = self ._serialize_handlers .get (type (item ))
212241 if handler :
213- return handler (item )
242+ return handler (item , depth = depth + 1 )
214243
215244 special_serialization = self .dialect .serialize_special_type (item )
216245 if special_serialization is not None :
@@ -228,6 +257,8 @@ def format_arg(arg: Any) -> str:
228257 if arg is None or isinstance (arg , (bool , int , float )):
229258 return str (arg )
230259 if isinstance (arg , str ):
260+ if len (arg ) > 100 :
261+ return f'"{ arg [:97 ]} ..."'
231262 return f'"{ arg } "'
232263
233264 if isinstance (arg , dict ) and "type" in arg :
@@ -252,7 +283,11 @@ def format_arg(arg: Any) -> str:
252283
253284 args_str = ", " .join (format_arg (arg ) for arg in args )
254285 kwargs_str = ", " .join (f"{ k } ={ format_arg (v )} " for k , v in kwargs .items ())
255- return f"{ api_name } ({ args_str + (', ' + kwargs_str if kwargs_str else '' )} )"
286+ result = f"{ api_name } ({ args_str + (', ' + kwargs_str if kwargs_str else '' )} )"
287+
288+ if len (result ) > self .max_line_length :
289+ result = result [: self .max_line_length - 4 ] + "...)"
290+ return result
256291
257292 def get_apis_and_configs (self ):
258293 if self .merge_output :
0 commit comments