@@ -26,7 +26,7 @@ def flush(self):
2626
2727
2828def build_log (
29- config_dict : dict , log_file : str | None = None , fallback : str = "prod"
29+ config_dict : dict | str , log_file : str | None = None , fallback : str = "prod"
3030) -> logging .Logger :
3131 """Build a logger from a configuration dictionary.
3232
@@ -39,18 +39,52 @@ def build_log(
3939 log_file
4040 The path to the log file.
4141 """
42- if isinstance (config_dict , str | dict ):
42+ # Accept either:
43+ # - a str pointing to a logging properties file
44+ # - a plain logging dict (handlers/formatters/etc.)
45+ # - a dict already containing "options" -> {"logging": ...}
46+ # If a dict is provided and it already contains an "options" key, assume
47+ # caller set options explicitly (so we must not wrap it).
48+ if isinstance (config_dict , str ) or (
49+ isinstance (config_dict , dict ) and "options" not in config_dict
50+ ):
4351 config_dict = {"options" : {"logging" : config_dict }}
4452
45- if "logging" in config_dict ["options" ]:
53+ if (
54+ isinstance (config_dict , dict )
55+ and "options" in config_dict
56+ and "logging" in config_dict ["options" ]
57+ ):
4658 log_config = config_dict ["options" ]["logging" ]
4759 # if it's a str, interpret it as a path to a file
4860 if isinstance (log_config , str ):
4961 log_config = Props .read_from (log_config )
5062
5163 if log_file is not None :
5264 Path (log_file ).parent .mkdir (parents = True , exist_ok = True )
53- log_config ["handlers" ]["dataflow" ]["filename" ] = log_file
65+ # Ensure the logging config has a handlers->dataflow entry; create
66+ # minimal structure if needed so we can set the filename.
67+ if isinstance (log_config , dict ):
68+ handlers = log_config .setdefault ("handlers" , {})
69+ dataflow = handlers .setdefault ("dataflow" , {})
70+ # Set the filename for the dataflow handler
71+ dataflow ["filename" ] = log_file
72+ dataflow .setdefault ("class" , "logging.FileHandler" )
73+ dataflow .setdefault ("level" , "INFO" )
74+ log_config .setdefault ("version" , 1 )
75+ if (
76+ "handlers" in log_config
77+ and "dataflow" in log_config ["handlers" ]
78+ and "root" not in log_config
79+ and "loggers" not in log_config
80+ ):
81+ dataflow_level = log_config ["handlers" ]["dataflow" ].get (
82+ "level" , "INFO"
83+ )
84+ log_config ["root" ] = {
85+ "level" : dataflow_level ,
86+ "handlers" : ["dataflow" ],
87+ }
5488
5589 dictConfig (log_config )
5690 log = logging .getLogger (config_dict ["options" ].get ("logger" , "prod" ))
0 commit comments