Note
Click here to download the full example code
Logging¶
We illustrate basic dman
logging functionality.
When using dman
you might have seen certain warning messages pop up,
originating from the logger. This logger can be configured using dman.log.config()
.
import dman
dman.log.config(level=dman.log.INFO)
dman.log.info("This is some info.")
[01/04/23 10:12:24] INFO This is some info. example5_logging.py:15
The syntax is similar to that of logging.basicConfig()
.
- dman.log.config(*, level=None, filename: Optional[str] = None, filemode: str = 'a', stream=None, format: Optional[str] = None, datefmt: Optional[str] = None, handlers: Optional[List[Handler]] = None, force: bool = False, **kwargs)
Configure the
dman
logger.This function does nothing if the
dman
logger already has handlers configured, unless if theforce
keyword argument is set to true.The default behavior is to create a
DmanHandler
using thedefault_handler()
method. Any keyword arguments not specified below are passed to that method.- Parameters:
level (_type_, optional) – Set the logger level to the specified level.
filename (str, optional) – Specifies that a FileHandler be created, using the specified filename, rather than a StreamHandler.
filemode (str, optional) – Specifies the mode to open the file, if filename is specified (if filemode is unspecified, it defaults to ‘a’).
stream (optional) – Use the specified stream to initialize the StreamHandler. Note that this argument is incompatible with ‘filename’ - if both are present, ‘stream’ is ignored.
format (str, optional) – Use the specified format string for the handler.
datefmt (str, optional) – Use the specified date/time format.
handlers (List[backend.Handler], optional) – If specified, this should be an iterable of already created handlers, which will be added to the root handler. Any handler in the list which does not have a formatter assigned will be assigned the formatter created in this function.
force (bool, optional) – If this keyword is specified as true, any existing handlers attached to the root logger are removed and closed, before carrying out the configuration as specified by the other arguments.. Defaults to False.
Note that you could specify a stream created using open(filename, mode) rather than passing the filename and mode in. However, it should be remembered that StreamHandler does not close its stream (since it may be using sys.stdout or sys.stderr), whereas FileHandler closes its stream when the handler is closed.
By default we use the RichHandler
from rich
. If you want
to use more standard logging you can use the following configuration
dman.log.config(
level=dman.log.INFO, use_rich=False, datefmt="%Y-%m-%d %H:%M:%S", force=True
)
dman.log.backend.basicConfig
dman.log.info("This is some info.")
2023-01-04 10:12:24 INFO: This is some info.
The dman
logger also supports some additional functionality.
dman.log.config(level=dman.log.INFO, force=True, show_path=False)
with dman.log.layer("example", "layer", prefix="owner"):
dman.log.info("Indented", label="example")
dman.log.io("This is an io command", label="example")
dman.log.emphasize("This is an emphasized command", label="example")
[01/04/23 10:12:24] INFO <layer owner=example>
INFO [example]: Indented
INFO [example]: This is an io command
INFO [example]: This is an emphasized command
INFO <end layer owner=example>
It is also used extensively during saving, loading and other internal functionality.
_ = dman.save("person", {"name": "Adam", "age": 25, "position": [23, 12]})
INFO <saving key=person>
INFO [mount]: Creating empty directory
".dman/cache/examples:fundamentals:example5_logging
/person".
INFO [save]: saving dict with key "person" to
".dman/cache/examples:fundamentals:example5_logging
/person/person.json".
INFO <serializing type=dict(3)>
INFO <serializing type=list(2)>
INFO <end serializing type=list(2)>
INFO <end serializing type=dict(3)>
INFO [save]: finished saving dict with key "person"
to
".dman/cache/examples:fundamentals:example5_logging
/person/person.json".
INFO <end saving key=person>
Since these logs can be quite verbose when you set the level to INFO
,
it can be useful to save the file somewhere. In fact you can do so
within the dman
file tree.
@dman.modelclass
class Experiment:
value: int
log: dman.FileTarget = dman.recordfield(
name="dman.log", default_factory=dman.FileTarget
)
exp = Experiment(25)
dman.log.config(
level=dman.log.INFO, stream=exp.log, force=True, console_style={"width": 160}
)
dman.clean("experiment", generator="")
dman.save("experiment", exp, generator="")
dman.tui.walk_directory(
dman.mount("experiment", generator=""),
show_content=True,
console=dman.tui.Console(width=180),
)
📂 .dman/experiment
┣━━ 📄 dman.log (2.4 kB)
┃ ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
┃ [01/04/23 10:12:24] INFO <loading key=experiment> repository.py:294
┃ INFO [load]: file not available at ".dman/experiment/experiment.json", using default repository.py:296
┃ INFO <end loading key=experiment> repository.py:294
┃ INFO <saving key=experiment> repository.py:217
┃ INFO [mount]: Creating empty directory ".dman/experiment". path.py:418
┃ INFO [save]: saving Experiment with key "experiment" to ".dman/experiment/experiment.json". repository.py:220
┃ INFO <serializing type=Experiment> serializables.py:626
┃ INFO [modelclass]: serializing modelclass with fields ['value', 'log']. modelclasses.py:499
┃ INFO [modelclass]: serializing value of type: "int" modelclasses.py:521
┃ INFO [modelclass]: serializing log of type: "Record" modelclasses.py:521
┃ INFO <serializing type=Record> serializables.py:626
┃ INFO <end serializing type=Record> serializables.py:626
┃ INFO <end serializing type=Experiment> serializables.py:626
┃ INFO [save]: finished saving Experiment with key "experiment" to ".dman/experiment/experiment.json". repository.py:227
┃ INFO <end saving key=experiment> repository.py:217
┃
┃ ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
┗━━ 📄 experiment.json (285 bytes)
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
{
"_ser__type": "Experiment",
"_ser__content": {
"value": 25,
"log": {
"_ser__type": "_ser__record",
"_ser__content": {
"target": "dman.log",
"sto_type": "_storable__stream"
}
}
}
}
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Total running time of the script: ( 0 minutes 0.056 seconds)