Skip to content

Commit cc29827

Browse files
authored
add with_console_options config, deprecate console_mode (#33)
1 parent a259a08 commit cc29827

File tree

7 files changed

+94
-73
lines changed

7 files changed

+94
-73
lines changed

README.md

-2
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@ Here's a simple manual tracing (aka logging) example:
4040
fn main() -> Result<(), Box<dyn std::error::Error>> {
4141
let shutdown_handler = logfire::configure()
4242
.install_panic_handler()
43-
.send_to_logfire(true)
44-
.console_mode(logfire::ConsoleMode::Fallback)
4543
.finish()?;
4644

4745
logfire::info!("Hello, {name}!", name = "world");

examples/basic.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,7 @@ static BASIC_COUNTER: LazyLock<Counter<u64>> = LazyLock::new(|| {
1212
});
1313

1414
fn main() -> Result<(), Box<dyn std::error::Error>> {
15-
let shutdown_handler = logfire::configure()
16-
.install_panic_handler()
17-
.console_mode(logfire::ConsoleMode::Fallback)
18-
.finish()?;
15+
let shutdown_handler = logfire::configure().install_panic_handler().finish()?;
1916

2017
logfire::info!("Hello, world!");
2118

src/bridges/tracing.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1383,7 +1383,7 @@ mod tests {
13831383
let handler = crate::configure()
13841384
.local()
13851385
.send_to_logfire(false)
1386-
.console_options(console_options.clone())
1386+
.with_console(Some(console_options.clone()))
13871387
.install_panic_handler()
13881388
.with_default_level_filter(LevelFilter::TRACE)
13891389
.finish()

src/config.rs

+36-26
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ use opentelemetry_sdk::{
1212
metrics::reader::MetricReader,
1313
trace::{IdGenerator, SpanProcessor},
1414
};
15-
use tracing::Level;
1615

1716
use crate::ConfigureError;
1817

@@ -65,44 +64,55 @@ impl From<bool> for SendToLogfire {
6564
}
6665

6766
/// Options for controlling console output.
68-
#[expect(clippy::struct_excessive_bools)] // Config options, bools make sense here.
6967
#[derive(Debug, Clone)]
7068
pub struct ConsoleOptions {
71-
/// Whether to show colors in the console.
72-
pub colors: ConsoleColors,
73-
/// How spans are shown in the console.
74-
pub span_style: SpanStyle,
75-
/// Whether to include timestamps in the console output.
76-
pub include_timestamps: bool,
77-
/// Whether to include tags in the console output.
78-
pub include_tags: bool,
79-
/// Whether to show verbose output.
80-
///
81-
/// It includes the filename, log level, and line number.
82-
pub verbose: bool,
83-
/// The minimum log level to show in the console.
84-
pub min_log_level: Level,
85-
/// Whether to print the URL of the Logfire project after initialization.
86-
pub show_project_link: bool,
8769
/// Where to send output
88-
pub target: Target,
70+
pub(crate) target: Target,
71+
// TODO: support the below configuration options (inherited from Python SDK)
72+
73+
// /// Whether to show colors in the console.
74+
// colors: ConsoleColors,
75+
// /// How spans are shown in the console.
76+
// span_style: SpanStyle,
77+
// /// Whether to include timestamps in the console output.
78+
// include_timestamps: bool,
79+
// /// Whether to include tags in the console output.
80+
// include_tags: bool,
81+
// /// Whether to show verbose output.
82+
// ///
83+
// /// It includes the filename, log level, and line number.
84+
// verbose: bool,
85+
// /// The minimum log level to show in the console.
86+
// min_log_level: Level,
87+
// /// Whether to print the URL of the Logfire project after initialization.
88+
// show_project_link: bool,
8989
}
9090

91+
#[expect(clippy::derivable_impls)] // When the other options are implemented, we will need this.
9192
impl Default for ConsoleOptions {
9293
fn default() -> Self {
9394
ConsoleOptions {
94-
colors: ConsoleColors::default(),
95-
span_style: SpanStyle::default(),
96-
include_timestamps: true,
97-
include_tags: true,
98-
verbose: false,
99-
min_log_level: Level::INFO,
100-
show_project_link: true,
95+
// colors: ConsoleColors::default(),
96+
// span_style: SpanStyle::default(),
97+
// include_timestamps: true,
98+
// include_tags: true,
99+
// verbose: false,
100+
// min_log_level: Level::INFO,
101+
// show_project_link: true,
101102
target: Target::default(),
102103
}
103104
}
104105
}
105106

107+
impl ConsoleOptions {
108+
/// Set the target for console output.
109+
#[must_use]
110+
pub fn with_target(mut self, target: Target) -> Self {
111+
self.target = target;
112+
self
113+
}
114+
}
115+
106116
/// Whether to show colors in the console.
107117
#[derive(Default, Debug, Clone, Copy)]
108118
pub enum ConsoleColors {

src/internal/exporters/console.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -347,15 +347,12 @@ mod tests {
347347
fn test_print_to_console() {
348348
let output = Arc::new(Mutex::new(Vec::new()));
349349

350-
let console_options = ConsoleOptions {
351-
target: Target::Pipe(output.clone()),
352-
..ConsoleOptions::default()
353-
};
350+
let console_options = ConsoleOptions::default().with_target(Target::Pipe(output.clone()));
354351

355352
let handler = crate::configure()
356353
.local()
357354
.send_to_logfire(false)
358-
.console_options(console_options)
355+
.with_console(Some(console_options))
359356
.install_panic_handler()
360357
.with_default_level_filter(LevelFilter::TRACE)
361358
.finish()
@@ -387,7 +384,7 @@ mod tests {
387384
1970-01-01T00:00:00.000002Z DEBUG logfire::internal::exporters::console::tests debug span
388385
1970-01-01T00:00:00.000003Z DEBUG logfire::internal::exporters::console::tests debug span with explicit parent
389386
1970-01-01T00:00:00.000004Z INFO logfire::internal::exporters::console::tests hello world log
390-
[2m1970-01-01T00:00:00.000005Z[0m[31m ERROR[0m [2;3mlogfire[0m [1mpanic: oh no![0m [3mlocation[0m=src/internal/exporters/console.rs:373:17, [3mbacktrace[0m=disabled backtrace
387+
[2m1970-01-01T00:00:00.000005Z[0m[31m ERROR[0m [2;3mlogfire[0m [1mpanic: oh no![0m [3mlocation[0m=src/internal/exporters/console.rs:370:17, [3mbacktrace[0m=disabled backtrace
391388
"#);
392389
}
393390
}

src/lib.rs

+52-33
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ use std::cell::RefCell;
100100
use std::collections::HashMap;
101101
use std::panic::PanicHookInfo;
102102
use std::sync::{Arc, Once};
103-
use std::{backtrace::Backtrace, env::VarError, str::FromStr, sync::OnceLock, time::Duration};
103+
use std::{backtrace::Backtrace, env::VarError, sync::OnceLock, time::Duration};
104104

105105
use bridges::tracing::LogfireTracingPendingSpanNotSentLayer;
106106
use opentelemetry::trace::TracerProvider;
@@ -190,30 +190,39 @@ pub enum ConfigureError {
190190
Other(#[from] Box<dyn std::error::Error + Send + Sync>),
191191
}
192192

193-
/// Whether to print to the console.
194-
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
195-
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
196-
#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
197-
pub enum ConsoleMode {
198-
/// Write to console if no logfire token
199-
#[default]
200-
Fallback,
201-
/// Force write to console
202-
Force,
203-
}
193+
#[expect(deprecated)]
194+
mod deprecated {
195+
use std::str::FromStr;
196+
197+
/// Whether to print to the console.
198+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
199+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
200+
#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
201+
#[deprecated(since = "0.4.0", note = "use `ConsoleOptions` instead")]
202+
pub enum ConsoleMode {
203+
/// Write to console if no logfire token
204+
#[default]
205+
Fallback,
206+
/// Force write to console
207+
Force,
208+
}
204209

205-
impl FromStr for ConsoleMode {
206-
type Err = String;
210+
impl FromStr for ConsoleMode {
211+
type Err = String;
207212

208-
fn from_str(s: &str) -> Result<Self, Self::Err> {
209-
match s {
210-
"fallback" => Ok(ConsoleMode::Fallback),
211-
"force" => Ok(ConsoleMode::Force),
212-
_ => Err(format!("invalid console mode: {s}")),
213+
fn from_str(s: &str) -> Result<Self, Self::Err> {
214+
match s {
215+
"fallback" => Ok(ConsoleMode::Fallback),
216+
"force" => Ok(ConsoleMode::Force),
217+
_ => Err(format!("invalid console mode: {s}")),
218+
}
213219
}
214220
}
215221
}
216222

223+
#[expect(deprecated)]
224+
use deprecated::ConsoleMode;
225+
217226
/// Main entry point to configure logfire.
218227
///
219228
/// This should be called once at the start of the program.
@@ -241,7 +250,9 @@ pub fn configure() -> LogfireConfigBuilder {
241250
local: false,
242251
send_to_logfire: None,
243252
token: None,
244-
console_options: None,
253+
console_options: Some(ConsoleOptions::default()),
254+
#[expect(deprecated)]
255+
console_mode: ConsoleMode::Force,
245256
additional_span_processors: Vec::new(),
246257
advanced: None,
247258
metrics: None,
@@ -260,6 +271,10 @@ pub struct LogfireConfigBuilder {
260271
// service_version: Option<String>,
261272
// environment: Option<String>,
262273
console_options: Option<ConsoleOptions>,
274+
/// Deprecated setting, `Force` implies use `console_options`, `Fallback` will filter
275+
/// them out if `send_to_logfire` is false.
276+
#[expect(deprecated)]
277+
console_mode: ConsoleMode,
263278

264279
// config_dir: Option<PathBuf>,
265280
// data_dir: Option<Path>,
@@ -323,6 +338,8 @@ impl LogfireConfigBuilder {
323338

324339
/// Whether to log to the console.
325340
#[must_use]
341+
#[deprecated(note = "use `console_options()` instead")]
342+
#[expect(deprecated)]
326343
pub fn console_mode(mut self, console_mode: ConsoleMode) -> Self {
327344
// FIXME: remove this API and make it match Python, see `console_options()` below
328345
match console_mode {
@@ -334,10 +351,12 @@ impl LogfireConfigBuilder {
334351
self
335352
}
336353

337-
/// Set the options for logging to console.
338-
#[cfg(test)] // FIXME: not all options exposed actually work yet, so not public
339-
pub fn console_options(mut self, console_options: ConsoleOptions) -> Self {
340-
self.console_options = Some(console_options);
354+
/// Sets console options. Set to `None` to disable console logging.
355+
///
356+
/// If not set, will use `ConsoleOptions::default()`.
357+
#[must_use]
358+
pub fn with_console(mut self, console_options: Option<ConsoleOptions>) -> Self {
359+
self.console_options = console_options;
341360
self
342361
}
343362

@@ -495,15 +514,15 @@ impl LogfireConfigBuilder {
495514
);
496515
}
497516

498-
// TODO make this behaviour closer to Python
499-
let mut console_options = self.console_options;
500-
if console_options.is_none() && !send_to_logfire {
501-
// FIXME: in Python the console and logfire settings are independent, we should not have
502-
// "fallback" like this.
503-
console_options = Some(ConsoleOptions::default());
504-
}
505-
506-
let console_writer = console_options.map(ConsoleWriter::new).map(Arc::new);
517+
let console_writer = self
518+
.console_options
519+
// NB deprecated behaviour: if set to fallback and sending to logfire, disable console
520+
.filter(
521+
#[expect(deprecated)]
522+
|_| !(self.console_mode == ConsoleMode::Fallback && send_to_logfire),
523+
)
524+
.map(ConsoleWriter::new)
525+
.map(Arc::new);
507526

508527
if let Some(console_writer) = console_writer.clone() {
509528
tracer_provider_builder = tracer_provider_builder.with_span_processor(

tests/test_basic_exports.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1032,7 +1032,7 @@ fn test_basic_span() {
10321032
"code.lineno",
10331033
),
10341034
value: I64(
1035-
647,
1035+
666,
10361036
),
10371037
},
10381038
KeyValue {

0 commit comments

Comments
 (0)