Skip to content

Commit 3060f3c

Browse files
committed
Add debug logging for all Oxide API requests
Currently only the `auth` CLI subcommand will log any request details when debug logging is enabled. Adding debug logging for all requests will enable users to troubleshoot issues on any API endpoint. To do this, we add add pre and post-request hooks via Progenitor. However, this does not lend itself to tracking the duration of the request, or creating a single log event with the details from the the `Request` and `Response`. We add a `LogCtx` inner type to the client to act as a store while requests are in flight, but need something to associate the start and end. We could inject a header into the request, but on failure this will not be available to us. Instead, we use the tokio `task::Id` as an identifier, which is unique within a given runtime. This raises the possibility of a client shared between runtimes associating the wrong start with a finished request. We do not have a way to detect which runtime a task is associated with, `runtime::Id` is an unstable feature, but we will log a warning if we find a response without a corresponding request, along with the response details. Should a request be run outside of a task, we fall back to logging separate events for start and end. We also create a `Span` that includes the log event. This is ignored by the CLI, but may be useful for other consumers of the SDK that want to integrate it with their monitoring infrastructure. An example event: { "timestamp": "2025-03-12T15:25:58.487790Z", "level": "DEBUG", "message": "request succeeded", "url": "https://oxide.sys.r3.oxide-preview.com/v1/disks?project=will", "path": "/v1/disks", "remote_addr": "45.154.216.35:443", "http.request.method": "GET", "http.response.content_length": 998, "http.response.status_code": 200, "start_time": "2025-03-12T15:25:58.048984Z", "duration_ms": 438, "oxide.request_id": "5d738e7a-ad78-4938-b682-c43f7b2a84be", "target": "oxide::tracing" } Closes #1014
1 parent 8d600fe commit 3060f3c

15 files changed

+914
-70
lines changed

Cargo.lock

+120-30
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+3-2
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,13 @@ crossterm = { version = "0.27.0", features = [ "event-stream" ] }
2323
dialoguer = "0.10.4"
2424
dirs = "4.0.0"
2525
dropshot = "0.13.0"
26-
env_logger = "0.10.2"
2726
expectorate = { version = "1.1.0", features = ["predicates"] }
2827
flume = "0.11.1"
2928
futures = "0.3.31"
3029
httpmock = "0.7.0"
3130
humantime = "2"
3231
indicatif = "0.17"
3332
libc = "0.2.170"
34-
log = "0.4.26"
3533
md5 = "0.7.0"
3634
newline-converter = "0.3.0"
3735
oauth2 = "5.0.0"
@@ -43,6 +41,7 @@ predicates = "3.1.3"
4341
pretty_assertions = "1.4.1"
4442
progenitor = { git = "https://github.com/oxidecomputer/progenitor", default-features = false }
4543
progenitor-client = "0.9.1"
44+
quote = "1.0.39"
4645
rand = "0.8.5"
4746
ratatui = "0.26.3"
4847
rcgen = "0.10.0"
@@ -62,6 +61,8 @@ thouart = { git = "https://github.com/oxidecomputer/thouart" }
6261
tokio = { version = "1.44.0", features = ["full"] }
6362
toml = "0.8.20"
6463
toml_edit = "0.22.24"
64+
tracing = "0.1.41"
65+
tracing-subscriber = { version = "0.3.19", features = ["env-filter","json"] }
6566
url = "2.5.4"
6667
uuid = { version = "1.15.1", features = ["serde", "v4"] }
6768

cli/Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,9 @@ colored = { workspace = true }
2828
crossterm = { workspace = true }
2929
dialoguer = { workspace = true }
3030
dirs = { workspace = true }
31-
env_logger = { workspace = true }
3231
futures = { workspace = true }
3332
humantime = { workspace = true }
3433
indicatif = { workspace = true }
35-
log = { workspace = true }
3634
md5 = { workspace = true }
3735
oauth2 = { workspace = true }
3836
open = { workspace = true }
@@ -49,6 +47,8 @@ thouart = { workspace = true }
4947
toml = { workspace = true }
5048
toml_edit = { workspace = true }
5149
tokio = { workspace = true }
50+
tracing = { workspace = true }
51+
tracing-subscriber = { workspace = true }
5252
url = { workspace = true }
5353
uuid = { workspace = true }
5454

cli/src/cli_builder.rs

+16-7
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
// License, v. 2.0. If a copy of the MPL was not distributed with this
33
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
44

5-
// Copyright 2024 Oxide Computer Company
5+
// Copyright 2025 Oxide Computer Company
66

77
use std::{any::TypeId, collections::BTreeMap, marker::PhantomData, net::IpAddr, path::PathBuf};
88

99
use anyhow::{bail, Result};
1010
use async_trait::async_trait;
1111
use clap::{Arg, ArgMatches, Command, CommandFactory, FromArgMatches};
12-
use log::LevelFilter;
12+
use tracing_subscriber::EnvFilter;
1313

1414
use crate::{
1515
context::Context,
@@ -229,11 +229,20 @@ impl<'a> NewCli<'a> {
229229
timeout,
230230
} = OxideCli::from_arg_matches(&matches).expect("failed to parse OxideCli from args");
231231

232-
let mut log_builder = env_logger::builder();
233-
if debug {
234-
log_builder.filter_level(LevelFilter::Debug);
235-
}
236-
log_builder.init();
232+
let env_filter = if debug {
233+
EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("debug"))
234+
} else {
235+
EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info"))
236+
};
237+
238+
tracing_subscriber::fmt()
239+
.with_env_filter(env_filter)
240+
.with_writer(std::io::stderr)
241+
.json()
242+
.flatten_event(true)
243+
.with_current_span(false)
244+
.with_span_list(false)
245+
.init();
237246

238247
let mut client_config = ClientConfig::default();
239248

0 commit comments

Comments
 (0)