Re-introduce option to use syslog for logging. (#121)

This commit is contained in:
Tim Bruijnzeels
2019-11-28 13:13:32 +01:00
parent b24ac3d806
commit 491fdb9a4f
2 changed files with 59 additions and 3 deletions
+5 -1
View File
@@ -17,7 +17,7 @@ clokwerk = "^0.1"
chrono = { version = "^0.4", features = ["serde"] }
clap = "^2.32"
derive_more = "^0.13"
fern = "^0.5"
fern = { version = "^0.5", features = ["syslog-4"] }
futures = "0.1"
hex = "^0.3"
lazy_static = "^1.1"
@@ -35,6 +35,10 @@ tokio = "^0.1"
uuid = "0.7"
xml-rs = "0.8.0"
[target.'cfg(unix)'.dependencies]
libc = "^0.2"
syslog = "^4.0"
[build-dependencies]
ignore = "^0.4"
+54 -2
View File
@@ -7,9 +7,11 @@ use std::path::PathBuf;
use std::str::FromStr;
use clap::{App, Arg};
use log::LevelFilter;
use log::{error, LevelFilter};
use serde::de;
use serde::{Deserialize, Deserializer};
#[cfg(unix)]
use syslog::Facility;
use toml;
use rpki::uri;
@@ -57,6 +59,10 @@ impl ConfigDefaults {
fn log_file() -> PathBuf {
PathBuf::from("./krill.log")
}
fn syslog_facility() -> String {
"daemon".to_string()
}
fn auth_token() -> Token {
match env::var("KRILL_AUTH_TOKEN") {
Ok(token) => Token::from(token),
@@ -115,6 +121,9 @@ pub struct Config {
#[serde(default = "ConfigDefaults::log_file")]
log_file: PathBuf,
#[serde(default = "ConfigDefaults::syslog_facility")]
syslog_facility: String,
#[serde(default = "ConfigDefaults::auth_token")]
pub auth_token: Token,
@@ -181,6 +190,7 @@ impl Config {
let log_type = LogType::Stderr;
let mut log_file = data_dir.clone();
log_file.push("krill.log");
let syslog_facility = ConfigDefaults::syslog_facility();
let auth_token = Token::from("secret");
let ca_refresh = 3600;
@@ -196,6 +206,7 @@ impl Config {
log_level,
log_type,
log_file,
syslog_facility,
auth_token,
ca_refresh,
}
@@ -273,6 +284,11 @@ impl Config {
match self.log_type {
LogType::File => self.file_logger(&self.log_file),
LogType::Stderr => self.stderr_logger(),
LogType::Syslog => {
let facility = Facility::from_str(&self.syslog_facility)
.map_err(|_| ConfigError::other("Invalid syslog_facility"))?;
self.syslog_logger(facility)
}
}
}
@@ -300,7 +316,41 @@ impl Config {
.map_err(|e| ConfigError::Other(format!("Failed to init file logging: {}", e)))
}
/// Creates and returns a fern logger
/// Creates a syslog logger and configures correctly.
#[cfg(unix)]
fn syslog_logger(&self, facility: syslog::Facility) -> Result<(), ConfigError> {
let process = env::current_exe()
.ok()
.and_then(|path| {
path.file_name()
.and_then(std::ffi::OsStr::to_str)
.map(ToString::to_string)
})
.unwrap_or_else(|| String::from("krill"));
let pid = unsafe { libc::getpid() };
let formatter = syslog::Formatter3164 {
facility,
hostname: None,
process,
pid,
};
let logger = syslog::unix(formatter.clone())
.or_else(|_| syslog::tcp(formatter.clone(), ("127.0.0.1", 601)))
.or_else(|_| syslog::udp(formatter, ("127.0.0.1", 0), ("127.0.0.1", 514)));
match logger {
Ok(logger) => self
.fern_logger()
.chain(logger)
.apply()
.map_err(|e| ConfigError::Other(format!("Failed to init syslog: {}", e))),
Err(err) => {
let msg = format!("Cannot connect to syslog: {}", err);
Err(ConfigError::Other(msg))
}
}
}
/// Creates and returns a fern logger with log level tweaks
fn fern_logger(&self) -> fern::Dispatch {
let framework_level = match self.log_level {
LevelFilter::Off => LevelFilter::Off,
@@ -396,6 +446,7 @@ impl From<uri::Error> for ConfigError {
pub enum LogType {
Stderr,
File,
Syslog,
}
impl<'de> Deserialize<'de> for LogType {
@@ -407,6 +458,7 @@ impl<'de> Deserialize<'de> for LogType {
match string.as_str() {
"stderr" => Ok(LogType::Stderr),
"file" => Ok(LogType::File),
"syslog" => Ok(LogType::Syslog),
_ => Err(de::Error::custom(format!(
"expected \"stderr\" or \"file\", found : \"{}\"",
string