MCPcopy Create free account
hub / github.com/Project-MONAI/MONAI / LogfileHandler

Class LogfileHandler

monai/handlers/logfile_handler.py:29–90  ·  view source on GitHub ↗

Adds a `logging.FileHandler` to the attached engine's logger when the start event occurs and removes it again when then completed event occurs. A handler is needed to remove `FileHandler` object when the complete event occurs so that further runs of different engines write only to

Source from the content-addressed store, hash-verified

27
28
29class LogfileHandler:
30 """
31 Adds a `logging.FileHandler` to the attached engine's logger when the start event occurs and removes it again when
32 then completed event occurs.
33
34 A handler is needed to remove `FileHandler` object when the complete event occurs so that further runs of different
35 engines write only to the log files they should, rather than previous files. Multiple handlers can write to the same
36 file which allows output from train and evaluation engine objects to be condensed in one file. If the given output
37 directory doesn't exist it will by default be created when the start event occurs. This can be used in conjunction
38 with `CheckpointSaver` to save a log file to the same destination as the saved checkpoints. Since the handler is
39 added possibly after other logging events during initialisation, not all logging data will be retained.
40
41 Args:
42 output_dir: directory to save the log file to
43 filename: name of the file to save log to
44 loglevel: log level for the handler
45 formatter: format string for the `logging.Formatter` set for the handler
46 create_dir: if True, create `output_dir` if it doesn't exist
47 """
48
49 def __init__(
50 self,
51 output_dir: str,
52 filename: str = "log.txt",
53 loglevel: int = logging.INFO,
54 formatter: str = "%(asctime)s %(name)s %(levelname)s: %(message)s",
55 create_dir: bool = True,
56 ):
57 self.output_dir: str = output_dir
58 self.filename: str = filename
59 self.loglevel: int = loglevel
60 self.formatter: str = formatter
61 self.create_dir: bool = create_dir
62 self.logger: logging.Logger | None = None
63 self.handler: logging.FileHandler | None = None
64
65 def attach(self, engine: Engine) -> None:
66 self.logger = engine.logger
67 engine.add_event_handler(Events.STARTED, self._start)
68 engine.add_event_handler(Events.COMPLETED, self._completed)
69
70 def _start(self, engine: Engine) -> None:
71 if self.create_dir and not os.path.exists(self.output_dir):
72 os.makedirs(self.output_dir, exist_ok=True)
73
74 self.handler = logging.FileHandler(os.path.join(self.output_dir, self.filename))
75 self.handler.setLevel(self.loglevel)
76 self.handler.setFormatter(logging.Formatter(self.formatter))
77
78 if self.logger is not None:
79 self.logger.addHandler(self.handler)
80 else:
81 raise AttributeError("`self.logger` must not be None in start event")
82
83 def _completed(self, engine: Engine) -> None:
84 if self.logger is not None and self.handler is not None:
85 self.logger.removeHandler(self.handler)
86 self.handler.close()

Callers 3

test_logfileMethod · 0.90
test_filenameMethod · 0.90
test_createdirMethod · 0.90

Calls

no outgoing calls

Tested by 3

test_logfileMethod · 0.72
test_filenameMethod · 0.72
test_createdirMethod · 0.72

Used in the wild real call sites across dependent graphs

searching dependent graphs…