|
| 1 | +# Logging |
| 2 | + |
| 3 | +The logging example connects the Rust [`log`][log] crate to the Node [`debug`][debug] module. Neon modules can write logs directly to `stdout` with typical crates like [`env_logger`][env-logger], but connecting logging to [`debug`][debug] more seamlessly integrates with the Node ecosystem. |
| 4 | + |
| 5 | +## Usage |
| 6 | + |
| 7 | +```sh |
| 8 | +# Only `INFO` logs on the top level crate |
| 9 | +DEBUG="INFO:logging" npm start |
| 10 | + |
| 11 | +# All logs on the top level crate |
| 12 | +DEBUG="*:logging" npm start |
| 13 | + |
| 14 | +# All `INFO` logs on any Rust crate |
| 15 | +DEBUG="INFO:*" npm start |
| 16 | + |
| 17 | +# All `WARN` and higher logs in our crate |
| 18 | +DEBUG="WARN:logging,ERROR:logging" |
| 19 | +``` |
| 20 | + |
| 21 | +## Libraries |
| 22 | + |
| 23 | +### [`log`][log] crate |
| 24 | + |
| 25 | +The [`log`][log] crate provides a logging facade used throughout the Rust ecosystem. It provides convenient macros for logging, but does not provide any facility to write or display logs. |
| 26 | + |
| 27 | +### [`debug`][debug] module |
| 28 | + |
| 29 | +the [`debug`][debug] node module provides a decorated version of `console.error` and is used throughout the Node library ecosystem, including in the [`express`][express] HTTP framework. It allows configurable log filtering with the `DEBUG` environment variable. |
| 30 | + |
| 31 | +## Design |
| 32 | + |
| 33 | +Rust code uses the typical logging facilities, but in order for it to be used, the [`Log`][log-trait] must be implemented. This example provides a simple [`Log`][log-trait] implementation that delegates to the [`debug`][debug] node module. |
| 34 | + |
| 35 | +### Initialization |
| 36 | + |
| 37 | +At initialization, the module calls `global.require("debug")` to get a copy of the function used to create logger instances. This function, as well as `enabled` and a [`Channel`][channel] are used to create a `Logger` instance and initialize the `log` crate. |
| 38 | + |
| 39 | +### Loggers |
| 40 | + |
| 41 | +The `Logger` struct maintains a map of logger names to logger instances that are lazily created as needed. Each logger is in an `Option` with `None` representing the disabled state. If an entry is missing, it is assumed to be in the `enabled` state until it can be further evaluated. |
| 42 | + |
| 43 | +## Limitations |
| 44 | + |
| 45 | +### Levels |
| 46 | + |
| 47 | +The provided implementation does not understand logger levels. Each level needs to be enabled individually. As an improvement, the logger level could be determined by checking `debug.enabled(...)` for each level from lowest to highest. |
| 48 | + |
| 49 | +### Multiple Contexts |
| 50 | + |
| 51 | +The `log` crate only supports a single global logger instance in a process. If the module is initialized multiple times with Web Workers, all logs will be sent to the instance that initialized. |
| 52 | + |
| 53 | +### Runtime level changes |
| 54 | + |
| 55 | +The `debug` module supports enabling and disabling logging at runtime, but for efficiency, our `Logging` implementation assumes that the result of `debug.enabled(..)` never changes. |
| 56 | + |
| 57 | +[log]: https://crates.io/crates/log |
| 58 | +[log-trait]: https://docs.rs/log/latest/log/trait.Log.html |
| 59 | +[debug]: https://www.npmjs.com/package/debug |
| 60 | +[env-logger]: https://crates.io/crates/env-logger |
| 61 | +[express]: https://www.npmjs.com/package/express |
| 62 | +[channel]: https://docs.rs/neon/latest/neon/event/struct.Channel.html |
0 commit comments