Skip to content

Commit

Permalink
implemented sending logs to systemd
Browse files Browse the repository at this point in the history
Signed-off-by: yihuaf <yihuaf@unkies.org>
  • Loading branch information
yihuaf committed May 27, 2023
1 parent 4fb9a36 commit 05305af
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 13 deletions.
12 changes: 12 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/youki/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ wasmtime = {version = "9.0.1", optional = true }
wasmtime-wasi = {version = "9.0.1", optional = true }
tracing = { version = "0.1.37", features = ["attributes"]}
tracing-subscriber = { version = "0.3.16", features = ["json", "env-filter"] }
tracing-journald = "0.3.0"

[dev-dependencies]
serial_test = "2.0.0"
Expand Down
18 changes: 15 additions & 3 deletions crates/youki/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ use crate::commands::info;

use liboci_cli::{CommonCmd, GlobalOpts, StandardCmd};

// Additional options that are not defined in OCI runtime-spec, but are used by Youki.
#[derive(Parser, Debug)]
struct YoukiExtendOpts {
/// Enable logging to systemd-journald
#[clap(long)]
pub systemd_log: bool,
}

// High-level commandline option definition
// This takes global options as well as individual commands as specified in [OCI runtime-spec](https://github.com/opencontainers/runtime-spec/blob/master/runtime.md)
// Also check [runc commandline documentation](https://github.com/opencontainers/runc/blob/master/man/runc.8.md) for more explanation
Expand All @@ -24,6 +32,9 @@ struct Opts {
#[clap(flatten)]
global: GlobalOpts,

#[clap(flatten)]
youki_extend: YoukiExtendOpts,

#[clap(subcommand)]
subcmd: SubCommand,
}
Expand Down Expand Up @@ -78,9 +89,10 @@ fn main() -> Result<()> {
let opts = Opts::parse();
let mut app = Opts::command();

if let Err(e) = crate::observability::init(&opts) {
eprintln!("log init failed: {e:?}");
}
crate::observability::init(&opts).map_err(|err| {
eprintln!("failed to initialize observability: {}", err);
err
})?;

tracing::debug!(
"started by user {} with {:?}",
Expand Down
27 changes: 17 additions & 10 deletions crates/youki/src/observability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ use std::fs::OpenOptions;
use std::path::PathBuf;
use std::str::FromStr;
use tracing::Level;
use tracing_subscriber::prelude::__tracing_subscriber_SubscriberExt;
use tracing_subscriber::util::SubscriberInitExt;
use tracing_subscriber::prelude::*;

const LOG_LEVEL_ENV_NAME: &str = "YOUKI_LOG_LEVEL";
const LOG_FORMAT_TEXT: &str = "text";
Expand Down Expand Up @@ -42,10 +41,12 @@ fn detect_log_level(is_debug: bool) -> Result<Level> {
Ok(Level::from_str(filter.as_ref())?)
}

#[derive(Debug, Default)]
pub struct ObservabilityConfig {
pub log_debug_flag: bool,
pub log_file: Option<PathBuf>,
pub log_format: Option<String>,
pub systemd_log: bool,
}

impl From<&crate::Opts> for ObservabilityConfig {
Expand All @@ -54,6 +55,7 @@ impl From<&crate::Opts> for ObservabilityConfig {
log_debug_flag: opts.global.debug,
log_file: opts.global.log.to_owned(),
log_format: opts.global.log_format.to_owned(),
systemd_log: opts.youki_extend.systemd_log,
}
}
}
Expand All @@ -68,12 +70,19 @@ where
let log_level_filter = tracing_subscriber::filter::LevelFilter::from(level);
let log_format = detect_log_format(config.log_format.as_deref())
.with_context(|| "failed to detect log format")?;

let subscriber = tracing_subscriber::registry().with(log_level_filter);
let systemd_journald = if config.systemd_log {
Some(tracing_journald::layer()?.with_syslog_identifier("youki".to_string()))
} else {
None
};
let subscriber = tracing_subscriber::registry()
.with(log_level_filter)
.with(systemd_journald);

// I really dislike how we have to specify individual branch for each
// combination, but I can't find any better way to do this. The tracing
// crate makes it hard to build a single layer with different conditions.
// crate makes it hard to build a single format layer with different
// conditions.
match (config.log_file.as_ref(), log_format) {
(None, LogFormat::Text) => {
// Text to stderr
Expand Down Expand Up @@ -197,9 +206,8 @@ mod tests {
let log_file = Path::join(temp_dir.path(), "test.log");
let _guard = LogLevelGuard::new("error").unwrap();
let config = ObservabilityConfig {
log_debug_flag: false,
log_file: Some(log_file),
log_format: None,
..Default::default()
};
init(config).map_err(|err| TestCallbackError::Other(err.into()))?;
Ok(())
Expand All @@ -220,9 +228,8 @@ mod tests {
// Note, we can only init the tracing once, so we have to test in a
// single unit test. The orders are important here.
let config = ObservabilityConfig {
log_debug_flag: false,
log_file: Some(log_file.clone()),
log_format: None,
..Default::default()
};
init(config).map_err(|err| TestCallbackError::Other(err.into()))?;
assert!(
Expand Down Expand Up @@ -265,9 +272,9 @@ mod tests {
// Note, we can only init the tracing once, so we have to test in a
// single unit test. The orders are important here.
let config = ObservabilityConfig {
log_debug_flag: false,
log_file: Some(log_file.clone()),
log_format: Some(LOG_FORMAT_JSON.to_owned()),
..Default::default()
};
init(config).map_err(|err| TestCallbackError::Other(err.into()))?;
assert!(
Expand Down

0 comments on commit 05305af

Please sign in to comment.