1- import logging
1+ from logging . handlers import RotatingFileHandler
22
33from rich .console import Console
44from rich .logging import RichHandler
@@ -29,9 +29,37 @@ def __init__(self, width=200, style=None, **kwargs):
2929 ** kwargs ,
3030 )
3131
32+
33+ class BytesToTextIOWrapper :
34+ def __init__ (self , handler , encoding = "utf-8" ):
35+ self .handler = handler
36+ self .encoding = encoding
37+
38+ def write (self , b ):
39+ if isinstance (b , bytes ):
40+ self .handler .stream .write (b .decode (self .encoding ))
41+ else :
42+ self .handler .stream .write (b )
43+ self .handler .flush ()
44+
45+ def flush (self ):
46+ self .handler .flush ()
47+
48+ def close (self ):
49+ self .handler .close ()
50+
51+
3252def setup_structlog () -> structlog .BoundLogger :
3353 log_date = Instant .now ().py_datetime ().strftime ("%Y%m%d" )
34- log_path = Path (f"cuul_{ log_date } _{ os .getpid ()} .log" )
54+ log_path = Path (f"{ log_date } _{ os .getpid ()} .log" )
55+ handler = RotatingFileHandler (
56+ filename = log_path ,
57+ mode = "a" , # text mode
58+ maxBytes = 10 * 1024 * 1024 ,
59+ backupCount = 5 ,
60+ encoding = "utf-8"
61+ )
62+ file_like = BytesToTextIOWrapper (handler )
3563 structlog .configure (
3664 cache_logger_on_first_use = True ,
3765 wrapper_class = structlog .make_filtering_bound_logger (logging .INFO ),
@@ -43,7 +71,7 @@ def setup_structlog() -> structlog.BoundLogger:
4371 structlog .processors .JSONRenderer (serializer = orjson .dumps ),
4472 ],
4573 logger_factory = structlog .BytesLoggerFactory (
46- file = log_path . open ( "wb" )
74+ file = file_like
4775 )
4876 )
4977 return structlog .get_logger ()
0 commit comments