Skip to content

Commit 1f38791

Browse files
author
Jonathan Woollett-Light
committed
feat: Support additional log filtering options
Add the ` FilterFn` layer to support filtering by crates, modules and spans. With `tracing::instrument` spans wrap functions, this would support filtering to specific functions. Signed-off-by: Jonathan Woollett-Light <[email protected]>
1 parent ca449f1 commit 1f38791

File tree

5 files changed

+209
-109
lines changed

5 files changed

+209
-109
lines changed

src/api_server/src/request/logger.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub(crate) fn parse_put_logger(body: &Body) -> Result<ParsedRequest, Error> {
2222
mod tests {
2323
use std::path::PathBuf;
2424

25-
use vmm::vmm_config::logger::Level;
25+
use vmm::vmm_config::logger::LevelFilter;
2626

2727
use super::*;
2828
use crate::parsed_request::tests::vmm_action_from_request;
@@ -38,9 +38,10 @@ mod tests {
3838

3939
let mut expected_cfg = LoggerConfig {
4040
log_path: Some(PathBuf::from("log")),
41-
level: Some(Level::Warn),
41+
level: Some(LevelFilter::Warn),
4242
show_level: Some(false),
4343
show_log_origin: Some(false),
44+
filter: None,
4445
};
4546
match vmm_action_from_request(parse_put_logger(&Body::new(body)).unwrap()) {
4647
VmmAction::ConfigureLogger(cfg) => assert_eq!(cfg, expected_cfg),
@@ -56,9 +57,10 @@ mod tests {
5657

5758
expected_cfg = LoggerConfig {
5859
log_path: Some(PathBuf::from("log")),
59-
level: Some(Level::Debug),
60+
level: Some(LevelFilter::Debug),
6061
show_level: Some(false),
6162
show_log_origin: Some(false),
63+
filter: None,
6264
};
6365
match vmm_action_from_request(parse_put_logger(&Body::new(body)).unwrap()) {
6466
VmmAction::ConfigureLogger(cfg) => assert_eq!(cfg, expected_cfg),

src/firecracker/src/api_server_adapter.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,10 @@ impl MutEventSubscriber for ApiServerAdapter {
132132
}
133133

134134
#[allow(clippy::too_many_arguments)]
135-
pub(crate) fn run_with_api(
135+
pub(crate) fn run_with_api<
136+
F: Fn(&tracing::Metadata<'_>) -> bool,
137+
G: Fn(&tracing::Metadata<'_>) -> bool,
138+
>(
136139
seccomp_filters: &mut BpfThreadMap,
137140
config_json: Option<String>,
138141
bind_path: PathBuf,
@@ -142,7 +145,7 @@ pub(crate) fn run_with_api(
142145
api_payload_limit: usize,
143146
mmds_size_limit: usize,
144147
metadata_json: Option<&str>,
145-
logger_handles: vmm::vmm_config::logger::LoggerHandles,
148+
logger_handles: vmm::vmm_config::logger::LoggerHandles<F, G>,
146149
) -> Result<(), ApiServerError> {
147150
// FD to notify of API events. This is a blocking eventfd by design.
148151
// It is used in the config/pre-boot loop which is a simple blocking loop

src/firecracker/src/main.rs

+41-4
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use vmm::resources::VmResources;
2626
use vmm::signal_handler::register_signal_handlers;
2727
use vmm::version_map::{FC_VERSION_TO_SNAP_VERSION, VERSION_MAP};
2828
use vmm::vmm_config::instance_info::{InstanceInfo, VmState};
29-
use vmm::vmm_config::logger::Level;
29+
use vmm::vmm_config::logger::LevelFilter;
3030
use vmm::vmm_config::metrics::{init_metrics, MetricsConfig};
3131
use vmm::{EventManager, FcExitCode, HTTP_MAX_PAYLOAD_SIZE};
3232

@@ -47,8 +47,13 @@ enum MainError {
4747
ParseArguments(#[from] utils::arg_parser::Error),
4848
#[error("When printing Snapshot Data format: {0}")]
4949
PrintSnapshotDataFormat(#[from] SnapshotVersionError),
50-
#[error("Invalid value for logger level: {0}.Possible values: [Error, Warning, Info, Debug]")]
51-
InvalidLogLevel(<Level as FromStr>::Err),
50+
#[error(
51+
"Invalid value for logger level: {0}.Possible values: [Off, Error, Warning, Info, Debug, \
52+
Trace]"
53+
)]
54+
InvalidLogLevel(<LevelFilter as FromStr>::Err),
55+
#[error("Failed to deserialize log filter: {0}")]
56+
DeserializeLogFilter(serde_json::Error),
5257
#[error("Could not initialize logger: {0}")]
5358
LoggerInitialization(vmm::vmm_config::logger::InitLoggerError),
5459
#[error("Could not initialize metrics: {0:?}")]
@@ -173,6 +178,27 @@ fn main_exec() -> Result<(), MainError> {
173178
"Path to a file that contains metadata in JSON format to add to the mmds.",
174179
),
175180
)
181+
.arg(
182+
Argument::new("start-time-us").takes_value(true).help(
183+
"Process start time (wall clock, microseconds). This parameter is optional.",
184+
),
185+
)
186+
.arg(Argument::new("start-time-cpu-us").takes_value(true).help(
187+
"Process start CPU time (wall clock, microseconds). This parameter is optional.",
188+
))
189+
.arg(Argument::new("parent-cpu-time-us").takes_value(true).help(
190+
"Parent process CPU time (wall clock, microseconds). This parameter is optional.",
191+
))
192+
.arg(
193+
Argument::new("config-file")
194+
.takes_value(true)
195+
.help("Path to a file that contains the microVM configuration in JSON format."),
196+
)
197+
.arg(
198+
Argument::new(MMDS_CONTENT_ARG).takes_value(true).help(
199+
"Path to a file that contains metadata in JSON format to add to the mmds.",
200+
),
201+
)
176202
.arg(
177203
Argument::new("no-api")
178204
.takes_value(false)
@@ -187,6 +213,11 @@ fn main_exec() -> Result<(), MainError> {
187213
.takes_value(true)
188214
.help("Path to a fifo or a file used for configuring the logger on startup."),
189215
)
216+
.arg(
217+
Argument::new("log-filter")
218+
.takes_value(true)
219+
.help("Filter for logging, if set overrides `level`."),
220+
)
190221
.arg(
191222
Argument::new("level")
192223
.takes_value(true)
@@ -270,15 +301,21 @@ fn main_exec() -> Result<(), MainError> {
270301
let logger_handles = {
271302
let level_res = arguments
272303
.single_value("level")
273-
.map(|s| Level::from_str(s))
304+
.map(|s| LevelFilter::from_str(s))
274305
.transpose();
275306
let level = level_res.map_err(MainError::InvalidLogLevel)?;
276307

308+
let filter = if let Some(log_filter) = arguments.single_value("log-filter") {
309+
Some(serde_json::from_str(log_filter).map_err(MainError::DeserializeLogFilter)?)
310+
} else {
311+
None
312+
};
277313
let logger_config = vmm::vmm_config::logger::LoggerConfig {
278314
log_path: arguments.single_value("log-path").map(PathBuf::from),
279315
level,
280316
show_level: Some(arguments.flag_present("show-level")),
281317
show_log_origin: Some(arguments.flag_present("show-log-origin")),
318+
filter,
282319
};
283320
logger_config
284321
.init()

src/vmm/src/rpc_interface.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ trait MmdsRequestHandler {
259259
}
260260

261261
/// Enables pre-boot setup and instantiation of a Firecracker VMM.
262-
pub struct PrebootApiController<'a> {
262+
pub struct PrebootApiController<'a, F, G> {
263263
seccomp_filters: &'a BpfThreadMap,
264264
instance_info: InstanceInfo,
265265
vm_resources: &'a mut VmResources,
@@ -272,11 +272,11 @@ pub struct PrebootApiController<'a> {
272272
// should cleanly teardown if they occur.
273273
fatal_error: Option<FcExitCode>,
274274
/// Handles that allow re-configuring the logger.
275-
logger_handles: LoggerHandles,
275+
logger_handles: LoggerHandles<F, G>,
276276
}
277277

278278
// TODO Remove when `EventManager` implements `std::fmt::Debug`.
279-
impl<'a> fmt::Debug for PrebootApiController<'a> {
279+
impl<'a, F, G> fmt::Debug for PrebootApiController<'a, F, G> {
280280
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
281281
f.debug_struct("PrebootApiController")
282282
.field("seccomp_filters", &self.seccomp_filters)
@@ -290,7 +290,7 @@ impl<'a> fmt::Debug for PrebootApiController<'a> {
290290
}
291291
}
292292

293-
impl MmdsRequestHandler for PrebootApiController<'_> {
293+
impl<F, G> MmdsRequestHandler for PrebootApiController<'_, F, G> {
294294
fn mmds(&mut self) -> MutexGuard<'_, Mmds> {
295295
self.vm_resources.locked_mmds_or_default()
296296
}
@@ -315,14 +315,16 @@ pub type ApiRequest = Box<VmmAction>;
315315
/// Shorthand type for a response containing a boxed Result.
316316
pub type ApiResponse = Box<std::result::Result<VmmData, VmmActionError>>;
317317

318-
impl<'a> PrebootApiController<'a> {
318+
impl<'a, F: Fn(&tracing::Metadata<'_>) -> bool, G: Fn(&tracing::Metadata<'_>) -> bool>
319+
PrebootApiController<'a, F, G>
320+
{
319321
/// Constructor for the PrebootApiController.
320322
pub fn new(
321323
seccomp_filters: &'a BpfThreadMap,
322324
instance_info: InstanceInfo,
323325
vm_resources: &'a mut VmResources,
324326
event_manager: &'a mut EventManager,
325-
logger_handles: LoggerHandles,
327+
logger_handles: LoggerHandles<F, G>,
326328
) -> Self {
327329
Self {
328330
seccomp_filters,
@@ -350,7 +352,7 @@ impl<'a> PrebootApiController<'a> {
350352
boot_timer_enabled: bool,
351353
mmds_size_limit: usize,
352354
metadata_json: Option<&str>,
353-
logger_handles: LoggerHandles,
355+
logger_handles: LoggerHandles<F, G>,
354356
) -> Result<(VmResources, Arc<Mutex<Vmm>>), FcExitCode> {
355357
let mut vm_resources = VmResources::default();
356358
// Silence false clippy warning. Clippy suggests using

0 commit comments

Comments
 (0)