fern/syslog.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
/*!
Example usage of `fern` with the `syslog` crate.
Be sure to depend on `syslog` and the `syslog` feature in `Cargo.toml`:
```toml
[dependencies]
fern = { version = "0.7", features = ["syslog-6"] }]
syslog = "6"
```
To use `syslog`, simply create the log you want, and pass it into `Dispatch::chain`:
```no_run
# use syslog6 as syslog;
# fn setup_logging() -> Result<(), Box<dyn std::error::Error>> {
let formatter = syslog::Formatter3164 {
facility: syslog::Facility::LOG_USER,
hostname: None,
process: "hello-world".to_owned(),
pid: 0,
};
fern::Dispatch::new()
.chain(syslog::unix(formatter)?)
.apply()?;
# Ok(())
# }
# fn main() { setup_logging().ok(); }
```
---
## Alternate syslog versions
If you're using syslog=4.0.0 exactly, one line "ok" will be printed to stdout on log configuration.
This is [a bug in syslog](https://github.com/Geal/rust-syslog/issues/39), and there is nothing we
can change in fern to fix that.
One way to avoid this is to use a different version of `syslog`, `fern` also supports. To pin syslog3,
use the `syslog-3` feature and depend on `syslog = "3"` instead.
```toml
[dependencies]
fern = { version = "0.7", features = ["syslog-3"] }]
syslog = "3"
```
The setup is very similar, except with less configuration to start the syslog logger:
```rust
# use syslog3 as syslog;
# fn setup_logging() -> Result<(), Box<dyn std::error::Error>> {
fern::Dispatch::new()
.chain(syslog::unix(syslog::Facility::LOG_USER)?)
.apply()?;
# Ok(())
# }
# fn main() { setup_logging().ok(); }
```
The rest of this document applies to all syslog versions, but the examples will be using
syslog 6 as it is the latest version.
---
One thing with `syslog` is that you don't generally want to apply any log formatting. The system
logger will handle that for you.
However, you probably will want to format messages you also send to stdout! Fortunately, selective
configuration is easy with fern:
```no_run
# use syslog6 as syslog;
# fn setup_logging() -> Result<(), Box<dyn std::error::Error>> {
let syslog_formatter = syslog::Formatter3164 {
facility: syslog::Facility::LOG_USER,
hostname: None,
process: "hello-world".to_owned(),
pid: 0,
};
// top level config
fern::Dispatch::new()
.chain(
// console config
fern::Dispatch::new()
.level(log::LevelFilter::Debug)
.format(move |out, message, record| {
out.finish(format_args!(
"[{}] {}",
record.level(),
message,
))
})
.chain(std::io::stdout())
)
.chain(
// syslog config
fern::Dispatch::new()
.level(log::LevelFilter::Info)
.chain(syslog::unix(syslog_formatter)?)
)
.apply()?;
# Ok(())
# }
# fn main() { setup_logging().ok(); }
```
With this, all info and above messages will be sent to the syslog with no formatting, and
the messages sent to the console will still look nice as usual.
---
One last pattern you might want to know: creating a log target which must be explicitly mentioned
in order to work.
```no_run
# use syslog6 as syslog;
# fn setup_logging() -> Result<(), Box<dyn std::error::Error>> {
# let formatter = syslog::Formatter3164 {
# facility: syslog::Facility::LOG_USER,
# hostname: None,
# process: "hello-world".to_owned(),
# pid: 0,
# };
fern::Dispatch::new()
// by default only accept warning messages from libraries so we don't spam
.level(log::LevelFilter::Warn)
// but accept Info and Debug if we explicitly mention syslog
.level_for("explicit-syslog", log::LevelFilter::Debug)
.chain(syslog::unix(formatter)?)
.apply()?;
# Ok(())
# }
# fn main() { setup_logging().ok(); }
```
With this configuration, only warning messages will get through by default. If we do want to
send info or debug messages, we can do so explicitly:
```no_run
# use log::{debug, info, warn};
# fn main() {
debug!("this won't get through");
// especially useful if this is from library you depend on.
info!("neither will this");
warn!("this will!");
info!(target: "explicit-syslog", "this will also show up!");
# }
```
*/