Logging#
Loggers record diagnostics: notes that help a developer or a user troubleshoot a problem, and warnings about conditions that are surprising but do not stop the command. Command results go through the reporter.
The conventions are:
Every module creates one logger named after itself, at import time:
from logging import getLogger log = getLogger(__name__)
Library code emits records and does not configure handlers, levels, or propagation. When conda runs as a CLI,
conda.cli.main.init_loggersattaches the handlers and sets the level from the verbosity flags. When another program imports conda, that program configures logging.Use lazy
%-style arguments rather than f-strings so formatting only happens if the record is emitted.Pass
exc_info=Truetolog.debugto record a traceback without showing it to the user.
Level |
Use for |
Visible when |
|---|---|---|
|
Internal state, decisions taken, caught-and-ignored exceptions |
|
|
Notable steps in normal operation |
|
|
Something is wrong or degraded, but conda can continue |
Always (default level) |
The -v flags map to levels in context.log_level:
Flags |
|
Logging level |
|---|---|---|
(none) |
0 |
|
|
1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
From conda/core/envs_manager.py:
log.warning(
"Unable to register environment. Could not create %s. Reason: %s",
user_environments_txt_directory,
exc,
)
A filter on the CLI handlers redacts channel tokens in URLs (/t/<token>/). Log those URLs as
they are. Do not log other secrets.
See Choosing between a logger and the reporter for whether to log a message or render it.
How conda configures logging#
Module-level loggers named after __name__ form a hierarchy. conda.core.link sits under
conda.core, which sits under conda. A parent’s level and handlers apply to its children
unless a child overrides them.
conda.gateways.logging.initialize_logging sets the conda logger to WARNING and attaches a
stderr handler with propagate = False, so conda records do not reach the root logger.
conda.cli.main.init_loggers calls that function, then set_log_level(context.log_level).
That sets the handler level from the verbosity flags and also attaches stderr handlers on the
root logger and the requests loggers. Importing conda as a library does none of this. The
embedding application configures logging.