Coverage for muutils/logger/simplelogger.py: 54%
41 statements
« prev ^ index » next coverage.py v7.6.1, created at 2025-04-04 03:33 -0600
« prev ^ index » next coverage.py v7.6.1, created at 2025-04-04 03:33 -0600
1from __future__ import annotations
3import json
4import sys
5import time
6import typing
7from typing import TextIO, Union
9from muutils.json_serialize import JSONitem, json_serialize
12class NullIO:
13 """null IO class"""
15 def __init__(self) -> None:
16 pass
18 def write(self, msg: str) -> int:
19 """write to nothing! this throws away the message"""
20 return len(msg)
22 def flush(self) -> None:
23 """flush nothing! this is a no-op"""
24 pass
26 def close(self) -> None:
27 """close nothing! this is a no-op"""
28 pass
31AnyIO = Union[TextIO, NullIO]
34class SimpleLogger:
35 """logs training data to a jsonl file"""
37 def __init__(
38 self,
39 log_path: str | None = None,
40 log_file: AnyIO | None = None,
41 timestamp: bool = True,
42 ):
43 self._timestamp: bool = timestamp
44 self._log_path: str | None = log_path
46 self._log_file_handle: AnyIO
48 if (log_path is None) and (log_file is None):
49 print(
50 "[logger_internal] # no log file specified, will only write to console",
51 sys.stderr,
52 )
53 self._log_file_handle = sys.stdout
55 elif (log_path is not None) and (log_file is not None):
56 raise ValueError(
57 "cannot specify both log_path and log_file, use streams in `SimpleLogger`"
58 )
59 else:
60 # now exactly one of the two is None
61 if log_file is not None:
62 self._log_file_handle = log_file
63 else:
64 assert log_path is not None
65 self._log_file_handle = open(log_path, "w", encoding="utf-8")
67 def log(self, msg: JSONitem, console_print: bool = False, **kwargs):
68 """log a message to the log file, and optionally to the console"""
69 if console_print:
70 print(msg)
72 if not isinstance(msg, typing.Mapping):
73 msg = {"_msg": msg}
75 if self._timestamp:
76 msg["_timestamp"] = time.time()
78 if len(kwargs) > 0:
79 msg["_kwargs"] = kwargs
81 self._log_file_handle.write(json.dumps(json_serialize(msg)) + "\n")