diff --git a/src/agent/Cargo.lock b/src/agent/Cargo.lock index 14d2b36ea6..c3d86726e7 100644 --- a/src/agent/Cargo.lock +++ b/src/agent/Cargo.lock @@ -508,6 +508,15 @@ dependencies = [ "wyz", ] +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + [[package]] name = "block-buffer" version = "0.10.4" @@ -889,6 +898,16 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-mac" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +dependencies = [ + "generic-array", + "subtle", +] + [[package]] name = "darling" version = "0.14.4" @@ -1033,13 +1052,22 @@ dependencies = [ "syn 2.0.101", ] +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + [[package]] name = "digest" version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", + "block-buffer 0.10.4", "crypto-common", ] @@ -1543,6 +1571,16 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hmac" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +dependencies = [ + "crypto-mac", + "digest 0.9.0", +] + [[package]] name = "home" version = "0.5.9" @@ -2049,7 +2087,7 @@ dependencies = [ "serde", "serde_json", "serial_test", - "sha2", + "sha2 0.10.9", "slog", "slog-scope", "slog-stdlog", @@ -2133,7 +2171,7 @@ dependencies = [ "serde", "serde-enum-str", "serde_json", - "sha2", + "sha2 0.10.9", "slog", "slog-scope", "sysinfo", @@ -2210,6 +2248,23 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a7cbbd4ad467251987c6e5b47d53b11a5a05add08f2447a9e2d70aef1e0d138" +[[package]] +name = "libsystemd" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f4f0b5b062ba67aa075e331de778082c09e66b5ef32970ea5a1e9c37c9555d1" +dependencies = [ + "hmac", + "libc", + "log", + "nix 0.23.2", + "once_cell", + "serde", + "sha2 0.9.9", + "thiserror 1.0.69", + "uuid 0.8.2", +] + [[package]] name = "libz-sys" version = "1.1.22" @@ -2273,6 +2328,7 @@ dependencies = [ "serde_json", "slog", "slog-async", + "slog-journald", "slog-json", "slog-scope", "slog-term", @@ -2734,6 +2790,12 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + [[package]] name = "opentelemetry" version = "0.14.0" @@ -3498,7 +3560,7 @@ dependencies = [ "rkyv_derive", "seahash", "tinyvec", - "uuid", + "uuid 1.16.0", ] [[package]] @@ -3911,7 +3973,20 @@ checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", "cpufeatures", - "digest", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", ] [[package]] @@ -3922,7 +3997,7 @@ checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures", - "digest", + "digest 0.10.7", ] [[package]] @@ -3994,6 +4069,16 @@ dependencies = [ "thread_local", ] +[[package]] +name = "slog-journald" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83e14eb8c2f5d0c8fc9fbac40e6391095e4dc5cb334f7dce99c75cb1919eb39c" +dependencies = [ + "libsystemd", + "slog", +] + [[package]] name = "slog-json" version = "2.6.1" @@ -4133,6 +4218,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + [[package]] name = "syn" version = "1.0.109" @@ -4694,6 +4785,15 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "serde", +] + [[package]] name = "uuid" version = "1.16.0" @@ -4707,7 +4807,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b082222b4f6619906941c17eb2297fff4c2fb96cb60164170522942a200bd8" dependencies = [ "outref", - "uuid", + "uuid 1.16.0", "vsimd", ] diff --git a/src/libs/logging/Cargo.toml b/src/libs/logging/Cargo.toml index 033b41712e..aad6712c30 100644 --- a/src/libs/logging/Cargo.toml +++ b/src/libs/logging/Cargo.toml @@ -22,6 +22,7 @@ slog-json = "2.4.0" slog-term = "2.9.1" slog-async = "2.7.0" slog-scope = "4.4.0" +slog-journald = "2.2.0" lazy_static = "1.3.0" arc-swap = "1.5.0" diff --git a/src/libs/logging/src/lib.rs b/src/libs/logging/src/lib.rs index 1d5a8242d3..ec1edcd7bd 100644 --- a/src/libs/logging/src/lib.rs +++ b/src/libs/logging/src/lib.rs @@ -81,6 +81,11 @@ pub fn create_term_logger(level: slog::Level) -> (slog::Logger, slog_async::Asyn (logger, guard) } +pub enum LogDestination { + File(Box), + Journal, +} + // Creates a logger which prints output as JSON // XXX: 'writer' param used to make testing possible. pub fn create_logger( @@ -92,13 +97,43 @@ pub fn create_logger( where W: Write + Send + Sync + 'static, { - let json_drain = slog_json::Json::new(writer) - .add_default_keys() - .build() - .fuse(); + create_logger_with_destination(name, source, level, LogDestination::File(Box::new(writer))) +} + +// Creates a logger which prints output as JSON or to systemd journal +pub fn create_logger_with_destination( + name: &str, + source: &str, + level: slog::Level, + destination: LogDestination, +) -> (slog::Logger, slog_async::AsyncGuard) { + // Check the destination type before consuming it. + // The `matches` macro performs a non-consuming check (it borrows). + let is_journal_destination = matches!(destination, LogDestination::Journal); + + // The target type for boxed drain. Note that Err = slog::Never. + // Both `.fuse()` and `.ignore_res()` convert potential errors into a non-returning path + // (panic or ignore), so they never return an Err. + let drain: Box + Send> = match destination { + LogDestination::File(writer) => { + // `destination` is `File`. + let json_drain = slog_json::Json::new(writer) + .add_default_keys() + .build() + .fuse(); + + Box::new(json_drain) + } + LogDestination::Journal => { + // `destination` is `Journal`. + let journal_drain = slog_journald::JournaldDrain.ignore_res(); + + Box::new(journal_drain) + } + }; // Ensure only a unique set of key/value fields is logged - let unique_drain = UniqueDrain::new(json_drain).fuse(); + let unique_drain = UniqueDrain::new(drain).fuse(); // Adjust the level which will be applied to the log-system // Info is the default level, but if Debug flag is set, the overall log level will be changed to Debug here @@ -119,16 +154,28 @@ where .thread_name("slog-async-logger".into()) .build_with_guard(); - // Add some "standard" fields - let logger = slog::Logger::root( + // Create a base logger with common fields. + let base_logger = slog::Logger::root( async_drain.fuse(), - o!("version" => env!("CARGO_PKG_VERSION"), + o!( + "version" => env!("CARGO_PKG_VERSION"), "subsystem" => DEFAULT_SUBSYSTEM, "pid" => process::id().to_string(), "name" => name.to_string(), - "source" => source.to_string()), + "source" => source.to_string() + ), ); + // If not journal destination, the logger remains the base_logger. + let logger = if is_journal_destination { + // Use the .new() method to build a child logger which inherits all existing + // key-value pairs from its parent and supplements them with additional ones. + // This is the idiomatic way. + base_logger.new(o!("SYSLOG_IDENTIFIER" => "kata")) + } else { + base_logger + }; + (logger, guard) } @@ -502,7 +549,12 @@ mod tests { let record_key = "record-key-1"; let record_value = "record-key-2"; - let (logger, guard) = create_logger(name, source, level, writer); + let (logger, guard) = create_logger_with_destination( + name, + source, + level, + LogDestination::File(Box::new(writer)), + ); let msg = "foo, bar, baz"; @@ -661,7 +713,12 @@ mod tests { .reopen() .unwrap_or_else(|_| panic!("{:?}: failed to clone tempfile", msg)); - let (logger, logger_guard) = create_logger(name, source, d.slog_level, writer); + let (logger, logger_guard) = create_logger_with_destination( + name, + source, + d.slog_level, + LogDestination::File(Box::new(writer)), + ); // Call the logger (which calls the drain) (d.closure)(&logger, d.msg.to_owned()); diff --git a/src/runtime-rs/Cargo.lock b/src/runtime-rs/Cargo.lock index f14ca61754..2a1a05542c 100644 --- a/src/runtime-rs/Cargo.lock +++ b/src/runtime-rs/Cargo.lock @@ -851,6 +851,16 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-mac" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +dependencies = [ + "generic-array", + "subtle", +] + [[package]] name = "darling" version = "0.14.4" @@ -1787,6 +1797,16 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hmac" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +dependencies = [ + "crypto-mac", + "digest 0.9.0", +] + [[package]] name = "hmac" version = "0.12.1" @@ -2304,6 +2324,23 @@ version = "0.2.172" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" +[[package]] +name = "libsystemd" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f4f0b5b062ba67aa075e331de778082c09e66b5ef32970ea5a1e9c37c9555d1" +dependencies = [ + "hmac 0.11.0", + "libc", + "log", + "nix 0.23.2", + "once_cell", + "serde", + "sha2 0.9.3", + "thiserror 1.0.69", + "uuid 0.8.2", +] + [[package]] name = "libz-sys" version = "1.1.22" @@ -2390,6 +2427,7 @@ dependencies = [ "serde_json", "slog", "slog-async", + "slog-journald", "slog-json", "slog-scope", "slog-term", @@ -2797,7 +2835,7 @@ dependencies = [ "bitflags 1.3.2", "fuse-backend-rs", "hex", - "hmac", + "hmac 0.12.1", "httpdate", "lazy_static", "libc", @@ -4464,6 +4502,16 @@ dependencies = [ "thread_local", ] +[[package]] +name = "slog-journald" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83e14eb8c2f5d0c8fc9fbac40e6391095e4dc5cb334f7dce99c75cb1919eb39c" +dependencies = [ + "libsystemd", + "slog", +] + [[package]] name = "slog-json" version = "2.6.1" @@ -4617,9 +4665,9 @@ dependencies = [ [[package]] name = "subtle" -version = "2.5.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" @@ -5195,6 +5243,15 @@ dependencies = [ "rand 0.3.23", ] +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "serde", +] + [[package]] name = "uuid" version = "1.16.0" diff --git a/src/runtime-rs/crates/shim/src/logger.rs b/src/runtime-rs/crates/shim/src/logger.rs index c5d7f225cb..aa7cdfed5c 100644 --- a/src/runtime-rs/crates/shim/src/logger.rs +++ b/src/runtime-rs/crates/shim/src/logger.rs @@ -4,31 +4,22 @@ // SPDX-License-Identifier: Apache-2.0 // -use std::os::unix::fs::OpenOptionsExt; - use anyhow::{Context, Result}; -use crate::Error; - -pub(crate) fn set_logger(path: &str, sid: &str, is_debug: bool) -> Result { - //it's better to open the log pipe file with read & write option, - //otherwise, once the containerd reboot and closed the read endpoint, - //kata shim would write the log pipe with broken pipe error. - let fifo = std::fs::OpenOptions::new() - .custom_flags(libc::O_NONBLOCK) - .create(true) - .read(true) - .write(true) - .open(path) - .context(Error::FileOpen(path.to_string()))?; - +pub(crate) fn set_logger(_path: &str, sid: &str, is_debug: bool) -> Result { let level = if is_debug { slog::Level::Debug } else { slog::Level::Info }; - let (logger, async_guard) = logging::create_logger("kata-runtime", sid, level, fifo); + // Use journal logger to send logs to systemd journal with "kata" identifier + let (logger, async_guard) = logging::create_logger_with_destination( + "kata-runtime", + sid, + level, + logging::LogDestination::Journal, + ); // not reset global logger when drop slog_scope::set_global_logger(logger).cancel_reset();