Skip to content

Commit 547e2b7

Browse files
committed
use nullhandler if subprocess
1 parent a69a4ba commit 547e2b7

File tree

1 file changed

+63
-74
lines changed

1 file changed

+63
-74
lines changed

snakemake/logging.py

Lines changed: 63 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -243,8 +243,52 @@ def log_handler(self, msg):
243243
self.check_response(response, "/update_workflow_status")
244244

245245

246-
class DefaultFormatter(_logging.Formatter):
246+
# Helper functions for logging
247+
def format_dict(dict_like, omit_keys=None, omit_values=None):
248+
from snakemake.io import Namedlist
249+
250+
omit_keys = omit_keys or []
251+
omit_values = omit_values or []
252+
253+
if isinstance(dict_like, Namedlist):
254+
items = dict_like.items()
255+
elif isinstance(dict_like, dict):
256+
items = dict_like.items()
257+
else:
258+
raise ValueError(
259+
"bug: format_dict applied to something neither a dict nor a Namedlist"
260+
)
261+
return ", ".join(
262+
f"{name}={value}"
263+
for name, value in items
264+
if name not in omit_keys and value not in omit_values
265+
)
266+
267+
268+
format_resources = partial(format_dict, omit_keys={"_cores", "_nodes"})
269+
format_wildcards = format_dict
270+
247271

272+
def format_resource_names(resources, omit_resources="_cores _nodes".split()):
273+
return ", ".join(name for name in resources if name not in omit_resources)
274+
275+
276+
def format_percentage(done, total):
277+
"""Format percentage from given fraction while avoiding superfluous precision."""
278+
if done == total:
279+
return "100%"
280+
if done == 0:
281+
return "0%"
282+
precision = 0
283+
fraction = done / total
284+
fmt_precision = "{{:.{}%}}".format
285+
fmt = lambda fraction: fmt_precision(precision).format(fraction)
286+
while fmt(fraction) == "100%" or fmt(fraction) == "0%":
287+
precision += 1
288+
return fmt(fraction)
289+
290+
291+
class DefaultFormatter(_logging.Formatter):
248292
def __init__(self, printreason=False, show_failed_logs=False, printshellcmds=False):
249293
self.printreason = printreason
250294
self.show_failed_logs = show_failed_logs
@@ -256,7 +300,9 @@ def format(self, record):
256300
Override format method to format Snakemake-specific log messages.
257301
"""
258302
msg = record.msg
259-
level = msg.get("level", "INFO") # Default to "INFO" if level not in message
303+
level = msg.get(
304+
"level", "INFO"
305+
).lower() # Default to "INFO" if level not in message
260306

261307
# Call specific handlers based on the log level
262308
if level == "info":
@@ -360,7 +406,7 @@ def format_progress(self, msg):
360406
"""Format for progress log."""
361407
done = msg["done"]
362408
total = msg["total"]
363-
return f"{done} of {total} steps ({self._format_percentage(done, total)}) done"
409+
return f"{done} of {total} steps ({format_percentage(done, total)}) done"
364410

365411
def format_job_finished(self, msg):
366412
"""Format for job_finished log."""
@@ -501,20 +547,6 @@ def timestamp(self):
501547
"""Helper method to format the timestamp."""
502548
return f"[{time.asctime()}]"
503549

504-
def _format_percentage(self, done, total):
505-
"""Helper method to format percentage."""
506-
if done == total:
507-
return "100%"
508-
if done == 0:
509-
return "0%"
510-
precision = 0
511-
fraction = done / total
512-
fmt_precision = "{{:.{}%}}".format
513-
fmt = lambda fraction: fmt_precision(precision).format(fraction)
514-
while fmt(fraction) == "100%" or fmt(fraction) == "0%":
515-
precision += 1
516-
return fmt(fraction)
517-
518550

519551
def show_logs(logs):
520552
"""Helper method to show logs."""
@@ -540,50 +572,6 @@ def show_logs(logs):
540572
yield "=" * max_len
541573

542574

543-
def format_dict(dict_like, omit_keys=None, omit_values=None):
544-
from snakemake.io import Namedlist
545-
546-
omit_keys = omit_keys or []
547-
omit_values = omit_values or []
548-
549-
if isinstance(dict_like, Namedlist):
550-
items = dict_like.items()
551-
elif isinstance(dict_like, dict):
552-
items = dict_like.items()
553-
else:
554-
raise ValueError(
555-
"bug: format_dict applied to something neither a dict nor a Namedlist"
556-
)
557-
return ", ".join(
558-
f"{name}={value}"
559-
for name, value in items
560-
if name not in omit_keys and value not in omit_values
561-
)
562-
563-
564-
format_resources = partial(format_dict, omit_keys={"_cores", "_nodes"})
565-
format_wildcards = format_dict
566-
567-
568-
def format_resource_names(resources, omit_resources="_cores _nodes".split()):
569-
return ", ".join(name for name in resources if name not in omit_resources)
570-
571-
572-
def format_percentage(done, total):
573-
"""Format percentage from given fraction while avoiding superfluous precision."""
574-
if done == total:
575-
return "100%"
576-
if done == 0:
577-
return "0%"
578-
precision = 0
579-
fraction = done / total
580-
fmt_precision = "{{:.{}%}}".format
581-
fmt = lambda fraction: fmt_precision(precision).format(fraction)
582-
while fmt(fraction) == "100%" or fmt(fraction) == "0%":
583-
precision += 1
584-
return fmt(fraction)
585-
586-
587575
class DefaultFilter:
588576
def __init__(
589577
self,
@@ -688,7 +676,6 @@ def emit(self, record):
688676
"""
689677
with self._output_lock:
690678
try:
691-
692679
level = record.msg.get("level", "INFO").lower()
693680

694681
if level == "job_info":
@@ -736,20 +723,14 @@ def decorate(self, record, message):
736723

737724

738725
class Logger:
739-
740726
def __init__(self):
741727
from snakemake_interface_executor_plugins.settings import ExecMode
742728

743729
self.logger = _logging.getLogger(__name__)
744730
self.stream_handler = None
745-
self.printshellcmds = False
746-
self.printreason = False
747731
self.debug_dag = False
748-
self.quiet = set()
749732
self.logfile = None
750-
self.last_msg_was_job_info = False
751733
self.mode = ExecMode.DEFAULT
752-
self.show_failed_logs = False
753734
self.logfile_handler = None
754735
self.dryrun = False
755736
self.level = 0
@@ -774,6 +755,7 @@ def setup_logfile(self):
774755
self.logfile_handler.setFormatter(self.default_formatter)
775756
self.logfile_handler.addFilter(self.default_filter)
776757
self.logfile_handler.setLevel(self.level)
758+
self.logfile_handler.name = "DefaultLogFileHandler"
777759
self.logger.addHandler(self.logfile_handler)
778760

779761
def cleanup(self):
@@ -825,9 +807,7 @@ def handler(self, msg):
825807
"resources_info": _logging.WARNING,
826808
"host": _logging.INFO,
827809
"job_stats": _logging.WARNING,
828-
}.get(
829-
custom_level, _logging.INFO
830-
) # Default to INFO if not recognized
810+
}.get(custom_level, _logging.INFO) # Default to INFO if not recognized
831811

832812
record = self.logger.makeRecord(
833813
name=self.logger.name,
@@ -922,6 +902,7 @@ def get_logfile(self):
922902

923903
logger = Logger()
924904

905+
925906
def setup_logger(
926907
handler=[],
927908
quiet=False,
@@ -936,18 +917,20 @@ def setup_logger(
936917
dryrun=False,
937918
):
938919
from snakemake.settings.types import Quietness
920+
from snakemake_interface_executor_plugins.settings import ExecMode
939921

940922
if mode is None:
941923
mode = get_default_exec_mode()
942924

943925
if quiet is None:
944-
# not quiet at all
945926
quiet = set()
927+
946928
elif isinstance(quiet, bool):
947929
if quiet:
948930
quiet = {Quietness.PROGRESS, Quietness.RULES}
949931
else:
950932
quiet = set()
933+
951934
elif not isinstance(quiet, set):
952935
raise ValueError(
953936
"Unsupported value provided for quiet mode (either bool, None or set allowed)."
@@ -958,6 +941,7 @@ def setup_logger(
958941
stream=sys.stdout if stdout else sys.stderr,
959942
mode=mode,
960943
)
944+
stream_handler.name = "DefaultStreamHandler"
961945
formatter = DefaultFormatter(
962946
printreason=printreason,
963947
show_failed_logs=show_failed_logs,
@@ -966,8 +950,13 @@ def setup_logger(
966950
filter = DefaultFilter(quiet=quiet, debug_dag=debug_dag)
967951
logger.default_formatter = formatter
968952
logger.default_filter = filter
969-
logger.set_stream_handler(stream_handler)
970-
logger.set_level(_logging.DEBUG if debug else _logging.INFO)
953+
954+
if mode == ExecMode.SUBPROCESS:
955+
logger.set_stream_handler(_logging.NullHandler())
956+
else:
957+
logger.set_stream_handler(stream_handler)
958+
logger.set_level(_logging.DEBUG if debug else _logging.INFO)
959+
971960
logger.quiet = quiet
972961
logger.printshellcmds = printshellcmds
973962
logger.printreason = printreason

0 commit comments

Comments
 (0)