Conversation
489acde to
7ff7b03
Compare
7ff7b03 to
58caf0d
Compare
|
@dblnz would you like to get this into the next release (we have it scheduled for next week (Feb 25th) |
58caf0d to
3f6bb07
Compare
Yes, I'm rebasing it to include it in the release |
6e47f8f to
72aaf11
Compare
There was a problem hiding this comment.
Pull request overview
This PR fixes issue #990 by implementing proper filtering of guest tracing spans and events based on the max_log_level parameter. Previously, even though the log level was correctly received by guests, only logs were filtered while tracing spans and events were not.
Changes:
- Introduced a new
GuestLogFilterenum to unify log level conversions betweenlog::LevelFilter,tracing_core::LevelFilter, and u64 values passed across the host-guest boundary - Implemented filtering in the
GuestSubscriber::enabled()method to properly filter tracing spans and events based on the maximum log level - Updated trace span levels from
TracetoInfofor infrastructure calls (halt, dispatch_function, call_guest_function, call_host_function) to ensure they are visible at appropriate log levels and updated test expectations accordingly
Reviewed changes
Copilot reviewed 18 out of 22 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/hyperlight_common/src/log_level.rs | New file introducing GuestLogFilter enum with conversions to/from log::LevelFilter, tracing_core::LevelFilter, and u64 |
| src/hyperlight_common/src/lib.rs | Adds log_level module export |
| src/hyperlight_common/Cargo.toml | Adds tracing-core dependency |
| src/hyperlight_guest_tracing/src/subscriber.rs | Adds max_log_level field and implements filtering in enabled() method |
| src/hyperlight_guest_tracing/src/lib.rs | Updates init_guest_tracing to accept LevelFilter parameter |
| src/hyperlight_guest_tracing/Cargo.toml | Adds "log" feature to tracing dependency for log/tracing interop |
| src/hyperlight_guest_bin/src/lib.rs | Updates to use GuestLogFilter for initialization |
| src/hyperlight_guest_bin/src/guest_logger.rs | Minor parameter rename for clarity |
| src/hyperlight_guest_bin/src/guest_function/call.rs | Updates trace levels from Trace to Info and removes explicit parent span references |
| src/hyperlight_host/src/hypervisor/mod.rs | Removes old get_max_log_level function |
| src/hyperlight_host/src/hypervisor/hyperlight_vm.rs | Adds new get_max_log_level_filter and get_guest_log_filter functions with proper conversions |
| src/hyperlight_host/src/sandbox/uninitialized.rs | Updates imports to use tracing_core::LevelFilter |
| src/hyperlight_host/src/sandbox/trace/context.rs | Updates span levels from trace to info |
| src/hyperlight_host/tests/integration_test.rs | Updates test expectations to account for new info-level trace logs and converts to use tracing_core::LevelFilter |
| src/hyperlight_guest/src/exit.rs | Updates halt span level from Trace to Info |
| src/hyperlight_guest/src/guest_handle/io.rs | Removes explicit parent span reference |
| src/hyperlight_guest/src/guest_handle/host_comm.rs | Adds instrumentation and updates trace levels |
| src/tests/rust_guests/simpleguest/src/main.rs | CRITICAL BUG: Incorrect conversion logic in LogMessage function |
| Cargo.lock files | Updates dependency locks for tracing-core additions |
72aaf11 to
214c2de
Compare
214c2de to
f4c4af9
Compare
| use crate::sandbox::uninitialized::SandboxRuntimeConfig; | ||
|
|
||
| /// Get the logging level filter to pass to the guest entrypoint | ||
| fn get_max_log_level_filter() -> LevelFilter { |
There was a problem hiding this comment.
I know this is not related to this PR, but this code could be simplified. AI came up with this but I'm sure it can be further tweaked (not blocking, feel free to ignore if you wish)
fn get_max_log_level_filter() -> LevelFilter {
let rust_log = std::env::var("RUST_LOG").unwrap_or_default();
let level = rust_log
.split(',')
.find_map(|entry| {
entry
.strip_prefix("hyperlight_guest=")
.or_else(|| entry.strip_prefix("hyperlight_host="))
.or_else(|| {
// Fallback: global log level (no '=' present)
if !entry.contains('=') {
Some(entry)
} else {
None
}
})
})
.unwrap_or("");
tracing::info!("Determined guest log level: {}", level);
LevelFilter::from_str(level).unwrap_or(LevelFilter::ERROR)
}There was a problem hiding this comment.
This example is not quite the exact behaviour as before.
This matches hyperlight_guest and hyperlight_host exactly, while before it first checked for something that contains hyperlight_guest, afterwards for something that contains hyperlight_host. I've changed the logic and maintained the previous behaviour though.
There was a problem hiding this comment.
I am not sure which is best, because we can have hyperlight_guest_bin and missing hyperlight_guest, should we exactly check against hyperlight_guest?
Maybe we should prioritize hyperlight_guest and then if this is missing, take anything containing hyperlight_guest? What do you think?
There was a problem hiding this comment.
do we currently support different logging levels per-module, or do we have a single level for everything inside the guest? If everything is at the same level, then I think just picking some name like hyperlight-guest and documenting it is sufficient. In my opinion, I think I would prefer having users explicilty set the log level for guests, rather than silently inherting hyperlight-host's logging level
I haven't thought much about this, but maybe it makes sense to use a different env var than RUST_LOG for logging inside the guests? Otherwise, say the crate A exists both in the guest, and host. How would a user express that they want only the guest's A or only the host's A?
In any case, I think it would make sense to eventually allow different modules inside the guest to have different logging levels (like RUST_LOG usually allows).
There was a problem hiding this comment.
We currently have a single level for everything inside the guest.
We currently have no way to specify a trace level for the guest but a different one for the host (for the same module).
I'll make a separate issue to tackle this.
We'd need to change the API for the entrypoint for this. Or think of a way to do this per guest call (that would be even better because going forward, taking a snapshot after creation means the trace level is set in stone and cannot be changed afterwards)
f4c4af9 to
b243e36
Compare
…arent - To make the codebase more readable, remove the `parent` argument from the `#[instrument]` attribute. Signed-off-by: Doru Blânzeanu <dblnz@pm.me>
- The `max_log_level` argument provided to the guest function is now used to filter traces also Signed-off-by: Doru Blânzeanu <dblnz@pm.me>
… and logging - Adds a `GuestLogFilter` enum that is used as an intermediary type between the `u64` used as a register to call the guest entrypoint and the `log::LogFilter` or `tracing_core::LogFilter`. - Adds unit tests for the `GuestLogFilter`. Signed-off-by: Doru Blânzeanu <dblnz@pm.me>
b243e36 to
e7fe98b
Compare
- Add more comments and tests to verify the new logic works as expected Signed-off-by: Doru Blânzeanu <dblnz@pm.me>
e7fe98b to
57170e2
Compare
This closes #990.
Currently, when tracing guests, the max log level parameter provided to the guest is not used to filter out traces.
This PR adds the filtering capability for the guest tracing and also modifies some of the trace levels in the guest.
For that to work, a change in the
integration_tests.rswas necessary to update the number of expected logs inlog_messagetest