Logging
Maestral makes extensive use of Python’s logging module to collect debug, status and error information from different parts of the program and distribute it to the appropriate channels.
Broadly speaking, the builtin log levels are used as follows:
Level |
Typical messages |
---|---|
DEBUG |
Individual sync progress, conflict resolution, daemon startup and environment info |
INFO |
Cumulative sync progress, sync errors that require user resolution (e.g., insufficient space) |
WARNING |
Failure to initialise non-critical functionality (e.g., desktop notifications, system keyring) |
ERROR |
Errors that prevent all syncing (revoked access token, deleted folder, etc) |
Maestral defines a number of log handlers to process those messages, some of them for
internal usage, others for external communication. For instance, cached logging handlers
are used to populate the public APIs Maestral.status
and
Maestral.fatal_errors
and therefore use fixed log levels. Logging to stderr,
the systemd journal (if applicable) and to our log files uses the user defined log level
from Maestral.log_level
which defaults to INFO.
Target |
Log level |
Enabled |
---|---|---|
Log file |
User defined (default: INFO) |
Always |
Stderr |
User defined (default: INFO) |
If verbose flag is passed |
Systemd journal |
User defined (default: INFO) |
If started as systemd service |
Systemd notify status |
INFO |
If started as systemd notify service |
INFO |
Always |
|
Desktop notifications |
WARNING |
Always |
ERROR |
Always |
All custom handlers are defined in the maestral.logging
module. Maestral also
subclasses the default logging.LogRecord
to guarantee that any surrogate escape
characters in file paths are replaced before emitting a log and flushing to any streams.
Otherwise, incorrectly encoded file paths could prevent logging from working properly
in exactly those cases where it would be particularly useful.