Skip to content

Commit 06ffd5d

Browse files
jan-auerclaude
andcommitted
feat(tracing): Replace println/eprintln with tracing
Applications embedding sentry-options as a dependency may have their own logging sinks (e.g. a Sentry SDK or structured log aggregator). Hard-coded eprintln/println bypasses those sinks entirely. By emitting events through the tracing crate instead, the host application decides how and where they are captured. The CLI gets a compact, time-free tracing-subscriber at INFO level so its own output is unaffected. Co-Authored-By: Claude <noreply@anthropic.com>
1 parent b7fa1ce commit 06ffd5d

10 files changed

Lines changed: 125 additions & 91 deletions

File tree

Cargo.lock

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

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,4 @@ sentry = { version = "0.46", default-features = false }
3434
chrono = "0.4"
3535
openssl = { version = "0.10", features = ["vendored"] }
3636
sha1 = "0.10"
37+
tracing = "0.1.41"

clients/rust/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ serde_json.workspace = true
1212
thiserror.workspace = true
1313
sha1.workspace = true
1414
num = "0.4.3"
15+
tracing.workspace = true
1516

1617
[dev-dependencies]
1718
tempfile.workspace = true

clients/rust/src/features.rs

Lines changed: 9 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
use num::bigint::{BigInt, Sign};
77
use std::cell::Cell;
88
use std::collections::HashMap;
9-
use std::sync::OnceLock;
109

1110
use serde_json::Value;
1211
use sha1::{Digest, Sha1};
@@ -345,61 +344,6 @@ fn eval_equals(ctx_val: &Value, condition_val: &Value) -> bool {
345344
}
346345
}
347346

348-
#[derive(Debug, PartialEq)]
349-
enum DebugLogLevel {
350-
None,
351-
Parse,
352-
Match,
353-
All,
354-
}
355-
356-
static DEBUG_LOG_LEVEL: OnceLock<DebugLogLevel> = OnceLock::new();
357-
static DEBUG_MATCH_SAMPLE_RATE: OnceLock<u64> = OnceLock::new();
358-
359-
fn debug_log_level() -> &'static DebugLogLevel {
360-
DEBUG_LOG_LEVEL.get_or_init(|| {
361-
match std::env::var("SENTRY_OPTIONS_FEATURE_DEBUG_LOG")
362-
.as_deref()
363-
.unwrap_or("")
364-
{
365-
"all" => DebugLogLevel::All,
366-
"parse" => DebugLogLevel::Parse,
367-
"match" => DebugLogLevel::Match,
368-
_ => DebugLogLevel::None,
369-
}
370-
})
371-
}
372-
373-
fn debug_match_sample_rate() -> u64 {
374-
*DEBUG_MATCH_SAMPLE_RATE.get_or_init(|| {
375-
std::env::var("SENTRY_OPTIONS_FEATURE_DEBUG_LOG_SAMPLE_RATE")
376-
.ok()
377-
.and_then(|v| v.parse::<f64>().ok())
378-
.map(|r| (r.clamp(0.0, 1.0) * 1000.0) as u64)
379-
.unwrap_or(1000)
380-
})
381-
}
382-
383-
fn debug_log_parse(msg: &str) {
384-
match debug_log_level() {
385-
DebugLogLevel::Parse | DebugLogLevel::All => eprintln!("[sentry-options/parse] {msg}"),
386-
_ => {}
387-
}
388-
}
389-
390-
fn debug_log_match(feature: &str, result: bool, context_id: u64) {
391-
match debug_log_level() {
392-
DebugLogLevel::Match | DebugLogLevel::All => {
393-
if context_id % 1000 < debug_match_sample_rate() {
394-
eprintln!(
395-
"[sentry-options/match] feature='{feature}' result={result} context_id={context_id}"
396-
);
397-
}
398-
}
399-
_ => {}
400-
}
401-
}
402-
403347
/// A handle for checking feature flags within a specific namespace.
404348
pub struct FeatureChecker {
405349
namespace: String,
@@ -427,24 +371,29 @@ impl FeatureChecker {
427371
let feature_val = match opts.get(&self.namespace, &key) {
428372
Ok(v) => v,
429373
Err(e) => {
430-
debug_log_parse(&format!("Failed to get feature '{key}': {e}"));
374+
tracing::debug!(key = %key, error = %e, "Failed to get feature");
431375
return false;
432376
}
433377
};
434378

435379
let feature = match Feature::from_json(&feature_val) {
436380
Some(f) => {
437-
debug_log_parse(&format!("Parsed feature '{key}'"));
381+
tracing::debug!(key = %key, "Parsed feature");
438382
f
439383
}
440384
None => {
441-
debug_log_parse(&format!("Failed to parse feature '{key}'"));
385+
tracing::debug!(key = %key, "Failed to parse feature");
442386
return false;
443387
}
444388
};
445389

446390
let result = feature.matches(context);
447-
debug_log_match(feature_name, result, context.id());
391+
tracing::debug!(
392+
feature = feature_name,
393+
result,
394+
context_id = context.id(),
395+
"Feature match result"
396+
);
448397
result
449398
}
450399
}

sentry-options-cli/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ sentry-options-validation.workspace = true
1616
thiserror.workspace = true
1717
walkdir = "2.5.0"
1818
tempfile.workspace = true
19+
tracing.workspace = true
20+
tracing-subscriber = { version = "0.3.19", features = ["fmt"] }
1921

2022
[dev-dependencies]
2123
tempfile.workspace = true

sentry-options-cli/src/main.rs

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ fn cli_validate_schema(schemas: String, quiet: bool) -> Result<()> {
218218
SchemaRegistry::from_directory(Path::new(&schemas))?;
219219

220220
if !quiet {
221-
println!("Schema validation successful");
221+
tracing::info!("Schema validation successful");
222222
}
223223
Ok(())
224224
}
@@ -229,7 +229,7 @@ fn cli_validate_values(schemas: String, root: String, quiet: bool) -> Result<()>
229229
ensure_no_duplicate_keys(&grouped)?;
230230

231231
if !quiet {
232-
println!("Values validation successful");
232+
tracing::info!("Values validation successful");
233233
}
234234
Ok(())
235235
}
@@ -252,7 +252,7 @@ fn cli_write(args: WriteArgs, quiet: bool) -> Result<()> {
252252
write_json(PathBuf::from(&out_path), json_outputs)?;
253253

254254
if !quiet {
255-
println!("Successfully wrote {} output files", num_files);
255+
tracing::info!(num_files, "Successfully wrote output files");
256256
}
257257
}
258258
OutputFormat::Configmap => {
@@ -276,11 +276,12 @@ fn cli_write(args: WriteArgs, quiet: bool) -> Result<()> {
276276

277277
if !quiet {
278278
match out_path {
279-
Some(path) => eprintln!("Successfully wrote ConfigMap to {}", path.display()),
280-
None => eprintln!(
281-
"Successfully generated ConfigMap: sentry-options-{}",
282-
namespace
283-
),
279+
Some(path) => {
280+
tracing::info!(path = %path.display(), "Successfully wrote ConfigMap")
281+
}
282+
None => {
283+
tracing::info!(name = %format!("sentry-options-{namespace}"), "Successfully generated ConfigMap")
284+
}
284285
}
285286
}
286287
}
@@ -292,7 +293,7 @@ fn cli_fetch_schemas(config: String, out: String, quiet: bool) -> Result<()> {
292293
let config = repo_schema_config::RepoSchemaConfigs::from_file(Path::new(&config))?;
293294
schema_retriever::fetch_all_schemas(&config, Path::new(&out), quiet)?;
294295
if !quiet {
295-
println!("Successfully fetched schemas to {}", out);
296+
tracing::info!(path = %out, "Successfully fetched schemas");
296297
}
297298
Ok(())
298299
}
@@ -329,7 +330,7 @@ fn cli_validate_schema_changes(
329330
)?;
330331

331332
if !quiet {
332-
eprintln!("Schema validation passed");
333+
tracing::info!("Schema validation passed");
333334
}
334335

335336
Ok(())
@@ -342,6 +343,12 @@ fn cli_check_option_usage(deletions: String, root: String) -> Result<()> {
342343
}
343344

344345
fn main() {
346+
tracing_subscriber::fmt()
347+
.compact()
348+
.without_time()
349+
.with_max_level(tracing::Level::INFO)
350+
.init();
351+
345352
let cli = Cli::parse();
346353

347354
let result = match cli.command {
@@ -359,7 +366,7 @@ fn main() {
359366
};
360367

361368
if let Err(e) = result {
362-
eprintln!("{}", e);
369+
tracing::error!(error = %e);
363370
std::process::exit(1);
364371
}
365372
}

sentry-options-cli/src/schema_evolution.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -304,19 +304,18 @@ pub fn detect_changes(
304304
}
305305

306306
if !quiet {
307-
eprintln!("Schema Changes:");
308307
if changelog.is_empty() {
309-
eprintln!("\tNo changes");
310-
}
311-
for change in &changelog {
312-
eprintln!("\t{}", change);
308+
tracing::info!("No schema changes");
309+
} else {
310+
for change in &changelog {
311+
tracing::info!(%change, "Schema change detected");
312+
}
313313
}
314314
}
315315

316316
if !errors.is_empty() {
317-
println!("Errors:");
318317
for error in &errors {
319-
println!("\t{}", error);
318+
tracing::error!(%error, "Schema validation error");
320319
}
321320
return Err(ValidationError::ValidationErrors(errors));
322321
}

sentry-options-cli/src/schema_retriever.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub fn fetch_all_schemas(config: &RepoSchemaConfigs, out_dir: &Path, quiet: bool
2222
repo_names.sort();
2323

2424
if !quiet {
25-
println!("Fetching schemas...");
25+
tracing::info!("Fetching schemas");
2626
}
2727

2828
// Fetch all repos in parallel, collecting results
@@ -58,7 +58,7 @@ pub fn fetch_all_schemas(config: &RepoSchemaConfigs, out_dir: &Path, quiet: bool
5858
match result {
5959
Ok(()) => {
6060
if !quiet {
61-
println!(" Fetched {}", repo_name);
61+
tracing::info!(repo = repo_name, "Fetched schema");
6262
}
6363
}
6464
Err(e) => errors.push(e),

0 commit comments

Comments
 (0)