Skip to content

Commit b2c1733

Browse files
[TRUNK-14129] Add structured logging (#380)
Switches our logging to use the tracing library, which gives us support for structured logs, using the sentry publisher so that these logs go to sentry. Adds a single span for execution so we can map out executions as we encounter issues, and converts our use of error to warn to avoid spamming oncall. Logging with quiet flag: ![2025-02-10-075854_1119x70_scrot](https://github.com/user-attachments/assets/190f41fa-5b70-480a-a934-2ff8da2449b2) With default verbosity: ![2025-02-10-075802_1161x70_scrot](https://github.com/user-attachments/assets/731c5369-4ef8-4dcc-b3c2-fa505fed9a0a) With single verbosity: ![2025-02-10-075815_1119x144_scrot](https://github.com/user-attachments/assets/8f8d22c0-9445-4abe-a486-8cd422699f56) With double verbosity: ![2025-02-10-075833_1400x231_scrot](https://github.com/user-attachments/assets/04434607-c7cf-4927-8d34-3b4754487c73) Fake error uploaded to sentry: https://trunkio.sentry.io/issues/6293011644/?environment=development&project=4507772986982400&query=is%3Aunresolved%20issue.priority%3A%5Bhigh%2C%20medium%5D&referrer=issue-stream&statsPeriod=14d&stream_index=0
1 parent efdad1f commit b2c1733

File tree

31 files changed

+357
-231
lines changed

31 files changed

+357
-231
lines changed

Cargo.lock

Lines changed: 191 additions & 18 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ log = "0.4.14"
2222
http = "1.1.0"
2323
tokio-retry = { version = "0.3", default-features = false }
2424
constants = { version = "0.0.0", path = "../constants" }
25+
tracing = "0.1.41"
2526
sentry = { version = "=0.36.0", features = ["debug-images"] }
2627

2728
[dev-dependencies]

api/src/call_api.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,8 @@ where
129129
let duration = Duration::from_secs(REPORT_SLOW_PROGRESS_TIMEOUT_SECS);
130130
time::sleep(duration).await;
131131
let time_elapsed = Instant::now().duration_since(report_slow_progress_start);
132-
sentry::capture_message(
133-
report_slow_progress_message(time_elapsed).as_ref(),
134-
sentry::Level::Error,
135-
);
132+
let message = report_slow_progress_message(time_elapsed);
133+
tracing::warn!("{:?}", message);
136134
});
137135

138136
let check_progress_start = time::Instant::now();
@@ -146,7 +144,7 @@ where
146144
let instant = interval.tick().await;
147145
let time_elapsed = instant.duration_since(check_progress_start);
148146
let log_message = log_progress_message(time_elapsed, log_count);
149-
log::debug!("{}", log_message);
147+
tracing::debug!("{}", log_message);
150148
log_count += 1;
151149
}
152150
});

api/src/client.rs

Lines changed: 7 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ impl ApiClient {
3232
.ok()
3333
.and_then(|s| if s.is_empty() { None } else { Some(s) })
3434
.unwrap_or_else(|| DEFAULT_ORIGIN.to_string());
35+
tracing::info!("Using public api address {}", host);
3536

3637
let mut trunk_client_default_headers = HeaderMap::new();
3738
trunk_client_default_headers.append(
@@ -208,9 +209,11 @@ impl ApiClient {
208209
)
209210
},
210211
log_progress_message: |time_elapsed, _| {
212+
println!("Callled, {}", time_elapsed.as_secs());
211213
format!("Uploading bundle to S3 is taking longer than expected. It has taken {} seconds so far.", time_elapsed.as_secs())
212214
},
213215
report_slow_progress_message: |time_elapsed| {
216+
println!("oofed, {}", time_elapsed.as_secs());
214217
format!("Uploading bundle to S3 is taking longer than {} seconds", time_elapsed.as_secs())
215218
},
216219
}
@@ -315,20 +318,15 @@ pub(crate) fn status_code_help<T: FnMut(&Response) -> String>(
315318

316319
#[cfg(test)]
317320
mod tests {
318-
use std::{
319-
sync::{
320-
atomic::{AtomicUsize, Ordering},
321-
Arc,
322-
},
323-
time::Duration,
321+
use std::sync::{
322+
atomic::{AtomicUsize, Ordering},
323+
Arc,
324324
};
325325

326326
use axum::{http::StatusCode, response::Response};
327327
use context;
328328
use lazy_static::lazy_static;
329-
use tempfile::NamedTempFile;
330-
use test_utils::{mock_logger, mock_sentry, mock_server::MockServerBuilder};
331-
use tokio::time;
329+
use test_utils::mock_server::MockServerBuilder;
332330

333331
use super::ApiClient;
334332
use crate::message;
@@ -417,52 +415,6 @@ mod tests {
417415
assert_eq!(CALL_COUNT.load(Ordering::Relaxed), 6);
418416
}
419417

420-
#[tokio::test(start_paused = true)]
421-
async fn logs_and_reports_for_slow_api_calls() {
422-
let mut mock_server_builder = MockServerBuilder::new();
423-
let logs = mock_logger(None);
424-
let (events, guard) = mock_sentry();
425-
426-
async fn slow_s3_upload_handler() -> Response<String> {
427-
time::sleep(Duration::from_secs(11)).await;
428-
Response::new(String::from("OK"))
429-
}
430-
mock_server_builder.set_s3_upload_handler(slow_s3_upload_handler);
431-
432-
let state = mock_server_builder.spawn_mock_server().await;
433-
434-
let mut api_client = ApiClient::new(String::from("mock-token")).unwrap();
435-
api_client.host.clone_from(&state.host);
436-
437-
let bundle_file = NamedTempFile::new().unwrap();
438-
api_client
439-
.put_bundle_to_s3(format!("{}/s3upload", state.host), bundle_file)
440-
.await
441-
.unwrap();
442-
443-
let first_two_slow_s3_upload_logs = logs
444-
.lock()
445-
.unwrap()
446-
.iter()
447-
.filter(|(_, message)| message.starts_with("Uploading bundle to S3"))
448-
.take(2)
449-
.cloned()
450-
.collect::<Vec<_>>();
451-
assert_eq!(first_two_slow_s3_upload_logs, vec![
452-
(log::Level::Debug, String::from("Uploading bundle to S3 is taking longer than expected. It has taken 2 seconds so far.")),
453-
(log::Level::Debug, String::from("Uploading bundle to S3 is taking longer than expected. It has taken 4 seconds so far.")),
454-
]);
455-
456-
guard.flush(None);
457-
assert_eq!(
458-
*events.try_lock().unwrap(),
459-
vec![(
460-
sentry::Level::Error,
461-
String::from("Uploading bundle to S3 is taking longer than 10 seconds"),
462-
),]
463-
);
464-
}
465-
466418
#[tokio::test(start_paused = true)]
467419
async fn get_quarantining_config_not_found() {
468420
let mut mock_server_builder = MockServerBuilder::new();

bundle/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ glob = "0.3.0"
1515
regex = { version = "1.10.3", default-features = false, features = ["std"] }
1616
serde = { version = "1.0.215", default-features = false, features = ["derive"] }
1717
serde_json = "1.0.133"
18+
tracing = "0.1.41"
1819
tsify-next = { version = "0.5.4", optional = true }
1920
wasm-bindgen = { version = "0.2.95", optional = true }
2021
pyo3-stub-gen = { version = "0.6.0", optional = true }

bundle/src/bundler.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ impl BundlerUtil {
8383
.iter()
8484
.fold(tempfile::tempfile()?, |f, event| {
8585
if let Err(e) = serde_json::to_writer(&f, event) {
86-
log::error!("Failed to write BEP event: {}", e);
86+
tracing::warn!("Failed to write BEP event: {}", e);
8787
}
8888
f
8989
});
@@ -99,7 +99,7 @@ impl BundlerUtil {
9999
let total_bytes_out = std::fs::metadata(bundle_path)?.len();
100100
let size_reduction = 1.0 - total_bytes_out as f64 / total_bytes_in as f64;
101101

102-
log::info!(
102+
tracing::info!(
103103
"Total bytes in: {}, total bytes out: {} (size reduction: {:.2}%)",
104104
total_bytes_in,
105105
total_bytes_out,

bundle/src/files.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,15 +245,15 @@ impl BundledFile {
245245
}
246246
}
247247
if !is_allowed {
248-
log::warn!("File {:?} from glob {:?} is not allowed", path, glob_path);
248+
tracing::warn!("File {:?} from glob {:?} is not allowed", path, glob_path);
249249
return Ok(None);
250250
}
251251

252252
// When start is provided, check if file is stale
253253
if let Some(start) = start {
254254
let modified = path.metadata()?.modified()?;
255255
if modified < start {
256-
log::warn!("File {:?} from glob {:?} is stale", path, glob_path);
256+
tracing::warn!("File {:?} from glob {:?} is stale", path, glob_path);
257257
return Ok(None);
258258
}
259259
}

cli-tests/src/quarantine.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -100,31 +100,31 @@ async fn quarantines_tests_regardless_of_upload() {
100100
// First run won't quarantine any tests
101101
*QUARANTINE_CONFIG_RESPONSE.lock().unwrap() = QuarantineConfigResponse::None;
102102
*CREATE_BUNDLE_RESPONSE.lock().unwrap() = CreateBundleResponse::Error;
103-
command.assert().failure().stderr(upload_failure.clone());
103+
command.assert().failure().stdout(upload_failure.clone());
104104

105105
// Second run quarantines all, but 1 test
106106
*QUARANTINE_CONFIG_RESPONSE.lock().unwrap() = QuarantineConfigResponse::Some;
107107
*CREATE_BUNDLE_RESPONSE.lock().unwrap() = CreateBundleResponse::Error;
108-
command.assert().failure().stderr(upload_failure.clone());
108+
command.assert().failure().stdout(upload_failure.clone());
109109

110110
// Third run will quarantine all tests
111111
*QUARANTINE_CONFIG_RESPONSE.lock().unwrap() = QuarantineConfigResponse::All;
112112
*CREATE_BUNDLE_RESPONSE.lock().unwrap() = CreateBundleResponse::Error;
113-
command.assert().success().stderr(upload_failure.clone());
113+
command.assert().success().stdout(upload_failure.clone());
114114

115115
// Fourth run will quarantine all tests, and upload them
116116
*QUARANTINE_CONFIG_RESPONSE.lock().unwrap() = QuarantineConfigResponse::All;
117117
*CREATE_BUNDLE_RESPONSE.lock().unwrap() = CreateBundleResponse::Success;
118118
command
119119
.assert()
120120
.success()
121-
.stderr(upload_failure.clone().not());
121+
.stdout(upload_failure.clone().not());
122122

123123
// Fifth run will run with quarantining disabled, but will log upload failure
124124
// there is no provided exit code, so it will default to success.
125125
*QUARANTINE_CONFIG_RESPONSE.lock().unwrap() = QuarantineConfigResponse::Disabled;
126126
*CREATE_BUNDLE_RESPONSE.lock().unwrap() = CreateBundleResponse::Error;
127-
command.assert().success().stderr(upload_failure.clone());
127+
command.assert().success().stdout(upload_failure.clone());
128128
}
129129

130130
#[tokio::test(flavor = "multi_thread")]
@@ -200,28 +200,28 @@ async fn do_no_quarantines_tests_when_use_quarantined_disabled() {
200200
// First run won't quarantine any tests
201201
*QUARANTINE_CONFIG_RESPONSE.lock().unwrap() = QuarantineConfigResponse::None;
202202
*CREATE_BUNDLE_RESPONSE.lock().unwrap() = CreateBundleResponse::Error;
203-
command.assert().success().stderr(upload_failure.clone());
203+
command.assert().success().stdout(upload_failure.clone());
204204

205205
// Second run won't quarantine even when config generates 1 quarantined test
206206
*QUARANTINE_CONFIG_RESPONSE.lock().unwrap() = QuarantineConfigResponse::Some;
207207
*CREATE_BUNDLE_RESPONSE.lock().unwrap() = CreateBundleResponse::Error;
208-
command.assert().success().stderr(upload_failure.clone());
208+
command.assert().success().stdout(upload_failure.clone());
209209

210210
// Third run won't quarantine even when config generates all tests quarantined
211211
*QUARANTINE_CONFIG_RESPONSE.lock().unwrap() = QuarantineConfigResponse::All;
212212
*CREATE_BUNDLE_RESPONSE.lock().unwrap() = CreateBundleResponse::Error;
213-
command.assert().success().stderr(upload_failure.clone());
213+
command.assert().success().stdout(upload_failure.clone());
214214

215215
// Fourth run won't quarantine tests even when config generates all tests quarantined and upload is successful
216216
*QUARANTINE_CONFIG_RESPONSE.lock().unwrap() = QuarantineConfigResponse::All;
217217
*CREATE_BUNDLE_RESPONSE.lock().unwrap() = CreateBundleResponse::Success;
218218
command
219219
.assert()
220220
.success()
221-
.stderr(upload_failure.clone().not());
221+
.stdout(upload_failure.clone().not());
222222

223223
// Fifth run will run with quarantining disabled, but will log upload failure
224224
*QUARANTINE_CONFIG_RESPONSE.lock().unwrap() = QuarantineConfigResponse::Disabled;
225225
*CREATE_BUNDLE_RESPONSE.lock().unwrap() = CreateBundleResponse::Error;
226-
command.assert().success().stderr(upload_failure.clone());
226+
command.assert().success().stdout(upload_failure.clone());
227227
}

cli-tests/src/test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ async fn test_command_fails_with_no_junit_files_no_quarantine_successful_upload(
8787
.assert()
8888
.failure()
8989
.code(128)
90-
.stderr(predicate::str::contains(
90+
.stdout(predicate::str::contains(
9191
"No JUnit files found, not quarantining any tests",
9292
));
9393

cli-tests/src/upload.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ async fn upload_bundle_invalid_repo_root() {
433433
.command()
434434
.assert()
435435
.failure()
436-
.stderr(predicate::str::contains(
436+
.stdout(predicate::str::contains(
437437
"Error: Failed to open git repository at \"../\"",
438438
));
439439

@@ -456,7 +456,7 @@ async fn upload_bundle_invalid_repo_root_explicit() {
456456
.command()
457457
.assert()
458458
.failure()
459-
.stderr(predicate::str::contains(
459+
.stdout(predicate::str::contains(
460460
"Error: Failed to open git repository at",
461461
));
462462

@@ -508,7 +508,7 @@ async fn upload_bundle_with_no_junit_files_no_quarantine_successful_upload() {
508508
.assert()
509509
.code(0)
510510
.success()
511-
.stderr(predicate::str::contains(
511+
.stdout(predicate::str::contains(
512512
"No JUnit files found, not quarantining any tests",
513513
));
514514

0 commit comments

Comments
 (0)