"termcolor",
]
+[[package]]
+name = "error-chain"
+version = "0.12.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc"
+dependencies = [
+ "version_check",
+]
+
[[package]]
name = "extend"
version = "1.1.1"
"sha2",
"structopt",
"subtle",
+ "syslog",
"thiserror",
"tokio",
"void",
"syn",
]
+[[package]]
+name = "hostname"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867"
+dependencies = [
+ "libc",
+ "match_cfg",
+ "winapi",
+]
+
[[package]]
name = "http"
version = "0.2.4"
dependencies = [
"bytes",
"fnv",
- "itoa",
+ "itoa 0.4.7",
]
[[package]]
"http-body",
"httparse",
"httpdate",
- "itoa",
+ "itoa 0.4.7",
"pin-project-lite",
"socket2",
"tokio",
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
+[[package]]
+name = "itoa"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754"
+
[[package]]
name = "lazy-regex"
version = "2.2.1"
[[package]]
name = "libc"
-version = "0.2.98"
+version = "0.2.132"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
+checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5"
[[package]]
name = "lock_api"
"cfg-if",
]
+[[package]]
+name = "match_cfg"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4"
+
[[package]]
name = "memchr"
version = "2.4.0"
"libc",
]
+[[package]]
+name = "num_threads"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44"
+dependencies = [
+ "libc",
+]
+
[[package]]
name = "object"
version = "0.26.0"
"unicode-xid",
]
+[[package]]
+name = "syslog"
+version = "6.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "978044cc68150ad5e40083c9f6a725e6fd02d7ba1bcf691ec2ff0d66c0b41acc"
+dependencies = [
+ "error-chain",
+ "hostname",
+ "libc",
+ "log",
+ "time",
+]
+
[[package]]
name = "tempfile"
version = "3.2.0"
"syn",
]
+[[package]]
+name = "time"
+version = "0.3.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c3f9a28b618c3a6b9251b6908e9c99e04b9e5c02e6581ccbb67d59c34ef7f9b"
+dependencies = [
+ "itoa 1.0.3",
+ "libc",
+ "num_threads",
+]
+
[[package]]
name = "tokio"
version = "1.8.2"
#[derive(StructOpt,Debug)]
pub struct LogOpts {
/// Increase debug level
+ ///
+ /// May be repeated for more verbosity.
+ ///
+ /// When using syslog, one `-D` this arranges to send to syslog even
+ /// trace messages (mapped onto syslog level `DEBUG`);
+ /// and two -`D` means to send to syslog even messages from lower layers
+ /// (normally just the hippotat modules log to
+ /// syslog).
#[structopt(long, short="D", parse(from_occurrences))]
debug: usize,
+
+ /// Syslog facility to use
+ #[structopt(long, parse(try_from_str=parse_syslog_facility))]
+ syslog_facility: Option<syslog::Facility>,
+}
+
+#[throws(AE)]
+fn parse_syslog_facility(s: &str) -> syslog::Facility {
+ s.parse().map_err(|()| anyhow!("unrecognised syslog facility: {:?}", s))?
+}
+
+#[derive(Debug)]
+struct FilteringLogWrapper<T>(T);
+
+impl<T> FilteringLogWrapper<T> {
+ fn wanted(&self, md: &log::Metadata<'_>) -> bool {
+ let first = |mod_path| {
+ let mod_path: &str = mod_path; // can't do in args as breaks lifetimes
+ mod_path.split_once("::").map(|s| s.0).unwrap_or(mod_path)
+ };
+ first(md.target()) == first(module_path!())
+ }
+}
+
+impl<T> log::Log for FilteringLogWrapper<T> where T: log::Log {
+ fn enabled(&self, md: &log::Metadata<'_>) -> bool {
+ self.wanted(md) && self.0.enabled(md)
+ }
+
+ fn log(&self, record: &log::Record<'_>) {
+ if self.wanted(record.metadata()) {
+ self.0.log(record)
+ }
+ }
+
+ fn flush(&self) {
+ self.0.flush()
+ }
}
impl LogOpts {
#[throws(AE)]
pub fn log_init(&self) {
- let env = env_logger::Env::new()
- .filter("HIPPOTAT_LOG")
- .write_style("HIPPOTAT_LOG_STYLE");
+ if let Some(facility) = self.syslog_facility {
+ let f = syslog::Formatter3164 {
+ facility,
+ hostname: None,
+ process: "hippotatd".into(),
+ pid: std::process::id(),
+ };
+ let l = syslog::unix(f)
+ // syslog::Error is not Sync.
+ // https://github.com/Geal/rust-syslog/issues/65
+ .map_err(|e| anyhow!(e.to_string()))
+ .context("set up syslog logger")?;
+ let l = syslog::BasicLogger::new(l);
+ let l = if self.debug < 2 {
+ Box::new(FilteringLogWrapper(l)) as _
+ } else {
+ Box::new(l) as _
+ };
+ log::set_boxed_logger(l).context("install syslog logger")?;
+ log::set_max_level(if self.debug < 1 {
+ log::LevelFilter::Debug
+ } else {
+ log::LevelFilter::Trace
+ });
+ } else {
+ let env = env_logger::Env::new()
+ .filter("HIPPOTAT_LOG")
+ .write_style("HIPPOTAT_LOG_STYLE");
- let mut logb = env_logger::Builder::new();
- logb.filter(Some("hippotat"),
- *[ log::LevelFilter::Info,
- log::LevelFilter::Debug ]
- .get(self.debug)
- .unwrap_or(
- &log::LevelFilter::Trace
- ));
- logb.parse_env(env);
- logb.init();
+ let mut logb = env_logger::Builder::new();
+ logb.filter(Some("hippotat"),
+ *[ log::LevelFilter::Info,
+ log::LevelFilter::Debug ]
+ .get(self.debug)
+ .unwrap_or(
+ &log::LevelFilter::Trace
+ ));
+ logb.parse_env(env);
+ logb.init();
+ }
}
}