With the 0.83.0 release of the Chef Habitat Supervisor, it is possible to have greater control over logging output, including the ability to dynamically adjust the logging configuration of a running Supervisor. There are two main ways of configuring logging, each of which has their own strengths and weaknesses: using environment variables, and using a configuration file.
Environment Variable Configuration
It is still possible to configure logging via the
RUST_LOG environment variable. This approach is often useful for quickly re-configuring logging (requiring a restart), or for easily configuring logging in container-based deployments.
The configuration scheme is essentially the same as that described in the documentation of the Rust env_logger crate, with the exception that we do not allow additional regular expression-based filtering. The configuration values the Supervisor recognizes are described below:
Simple Logging Levels
The recognized values are, in increasing verbosity (or, equivalently, in decreasing severity):
RUST_LOG to one of these values will cause all log messages at that verbosity and below (equivalently, that severity and above) to be printed. This includes log messages from Habitat, as well as any libraries that it uses.
Rust Logging Levels
This is much finer grained than the simple logging levels above, and to fully leverage it requires some knowledge of both the internal code structure of Habitat itself, as well as of how Rust code is organized generally. Despite this, it allows you to target specific subsystems, which can be very helpful for troubleshooting.
RUST_LOG=habitat_sup::manager=info will cause all log messages at the
info level or more severe (i.e.,
info) originating anywhere in the module hierarchy rooted at
Note that Rust modules are identified first by the crate (or library) they come from, followed by a
::-delimited path of module names.
Multiple logging specifiers can be submitted, separated by commas. A simple logging level will act as the default, with additional module-targeted levels serving to refine the logging for the target code. If you supply multiple simple logging levels, only the last one will count. Any number of targeted logging levels are allowed, however.
RUST_LOG=info,habitat_sup::manager=debug,tokio_reactor=error will limit logs generally to the
info level, while additionally allowing
debug messages coming from the
habitat_sup::manager module hierarchy, and restricting log messages from the
tokio_reactor library to only
Dynamic, File-based Configuration
For further control over logging output, as well as the ability to change the configuration of a running Supervisor, a configuration file is needed. This file is processed by the log4rs crate, and shares many of the same concepts as the Log4J logging system of the Java ecosystem. The
log4rs configuration documentation can be found here.
Place an appropriate YAML configuration file at
/hab/sup/default/config/log.yml when the Supervisor starts up if you wish to take advantage of this style of configuration. Note that if such a file is present, it will take priority over any
RUST_LOG environment variable that may also be present.
Here is an example configuration file that mimics the default logging configuration of the Supervisor. It emits UTC timestamped message lines to standard output at the
refresh_rate configuration is very important. If it is present when the Supervisor starts, the file will be checked periodically for updates (according to the value of
refresh_rate; in the above example, the file will be checked every 5 seconds). If the file changes, then the current content of the file becomes the active configuration. This allows you to, for example, increase the logging level of a running supervisor if you suspect you are running into problems.
This dynamism also has a catch, though: you can change the refresh rate as well, and even remove it entirely. If you remove it, however, the Supervisor will stop checking for updates to the file. Any subsequent changes you might make would require a Supervisor restart to be recognized. Work is planned to make this more flexible, however.
You can also target individual module hierarchies with this configuration scheme, just as you can with the
RUST_LOG environment variable. For this, you will need to add a new top-level
loggers key to the file, like so:
loggers is a map of maps. Map keys are module paths (as described above in the
RUST_LOG environment variable documentation), while the values are maps with additional configuration. Here, we are only setting the logging level, but more advanced configurations are possible.
Users are encouraged to read the log4rs configuration documentation for further details.