Skip to content

Commit 3b961d2

Browse files
authored
make configuration options match Python more closely (#11)
* make configuration options match Python more closely * coverage
1 parent 8b0f42f commit 3b961d2

File tree

5 files changed

+289
-110
lines changed

5 files changed

+289
-110
lines changed

src/config.rs

+119
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1+
//! Configuration options for the Logfire SDK.
2+
//!
3+
//! See [`LogfireConfigBuilder`][crate::LogfireConfigBuilder] for documentation of all these options.
4+
15
use std::{fmt::Display, str::FromStr};
26

7+
use opentelemetry_sdk::trace::{IdGenerator, SpanProcessor};
38
use tracing::Level;
49

510
use crate::ConfigureError;
@@ -42,6 +47,16 @@ impl FromStr for SendToLogfire {
4247
}
4348
}
4449

50+
impl From<bool> for SendToLogfire {
51+
fn from(b: bool) -> Self {
52+
if b {
53+
SendToLogfire::Yes
54+
} else {
55+
SendToLogfire::No
56+
}
57+
}
58+
}
59+
4560
/// Options for controlling console output.
4661
#[expect(clippy::struct_excessive_bools)] // Config options, bools make sense here.
4762
pub struct ConsoleOptions {
@@ -100,3 +115,107 @@ pub enum SpanStyle {
100115
#[default]
101116
ShowParents,
102117
}
118+
119+
/// Options primarily used for testing by Logfire developers.
120+
pub struct AdvancedOptions {
121+
/// Root URL for the Logfire API.
122+
pub(crate) base_url: String,
123+
/// Generator for trace and span IDs.
124+
pub(crate) id_generator: Option<BoxedIdGenerator>,
125+
//
126+
//
127+
// TODO: arguments below supported by Python
128+
129+
// /// Generator for nanosecond start and end timestamps of spans.
130+
// pub ns_timestamp_generator: Option,
131+
132+
// /// Configuration for OpenTelemetry logging. This is experimental and may be removed.
133+
// pub log_record_processors: Vec<Box<dyn LogRecordProcessor>>,
134+
}
135+
136+
impl Default for AdvancedOptions {
137+
fn default() -> Self {
138+
AdvancedOptions {
139+
base_url: "https://logfire-api.pydantic.dev".to_string(),
140+
id_generator: None,
141+
}
142+
}
143+
}
144+
145+
impl AdvancedOptions {
146+
/// Set the base URL for the Logfire API.
147+
#[must_use]
148+
pub fn with_base_url<T: AsRef<str>>(mut self, base_url: T) -> Self {
149+
self.base_url = base_url.as_ref().into();
150+
self
151+
}
152+
153+
/// Set the ID generator for trace and span IDs.
154+
#[must_use]
155+
pub fn with_id_generator<T: IdGenerator + Send + Sync + 'static>(
156+
mut self,
157+
generator: T,
158+
) -> Self {
159+
self.id_generator = Some(BoxedIdGenerator::new(Box::new(generator)));
160+
self
161+
}
162+
}
163+
164+
/// Wrapper around a `SpanProcessor` to use in `additional_span_processors`.
165+
#[derive(Debug)]
166+
pub(crate) struct BoxedSpanProcessor(Box<dyn SpanProcessor>);
167+
168+
impl BoxedSpanProcessor {
169+
pub fn new(processor: Box<dyn SpanProcessor + Send + Sync>) -> Self {
170+
BoxedSpanProcessor(processor)
171+
}
172+
}
173+
174+
impl SpanProcessor for BoxedSpanProcessor {
175+
fn on_start(&self, span: &mut opentelemetry_sdk::trace::Span, cx: &opentelemetry::Context) {
176+
self.0.on_start(span, cx);
177+
}
178+
179+
fn on_end(&self, span: opentelemetry_sdk::trace::SpanData) {
180+
self.0.on_end(span);
181+
}
182+
183+
fn force_flush(&self) -> opentelemetry_sdk::error::OTelSdkResult {
184+
self.0.force_flush()
185+
}
186+
187+
fn shutdown(&self) -> opentelemetry_sdk::error::OTelSdkResult {
188+
self.0.shutdown()
189+
}
190+
}
191+
192+
/// Wrapper around an `IdGenerator` to use in `id_generator`.
193+
#[derive(Debug)]
194+
pub(crate) struct BoxedIdGenerator(Box<dyn IdGenerator>);
195+
196+
impl BoxedIdGenerator {
197+
pub fn new(generator: Box<dyn IdGenerator>) -> Self {
198+
BoxedIdGenerator(generator)
199+
}
200+
}
201+
202+
impl IdGenerator for BoxedIdGenerator {
203+
fn new_trace_id(&self) -> opentelemetry::trace::TraceId {
204+
self.0.new_trace_id()
205+
}
206+
207+
fn new_span_id(&self) -> opentelemetry::trace::SpanId {
208+
self.0.new_span_id()
209+
}
210+
}
211+
212+
#[cfg(test)]
213+
mod tests {
214+
use crate::config::SendToLogfire;
215+
216+
#[test]
217+
fn test_send_to_logfire_from_bool() {
218+
assert_eq!(SendToLogfire::from(true), SendToLogfire::Yes);
219+
assert_eq!(SendToLogfire::from(false), SendToLogfire::No);
220+
}
221+
}

src/internal/exporters/remove_pending.rs

+10-13
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ impl<Inner: SpanExporter> SpanExporter for RemovePendingSpansExporter<Inner> {
5252
mod tests {
5353
use std::time::Duration;
5454

55-
use crate::config::SendToLogfire;
55+
use crate::config::AdvancedOptions;
5656
use crate::set_local_logfire;
5757
use crate::tests::DeterministicExporter;
5858
use crate::tests::DeterministicIdGenerator;
@@ -62,15 +62,17 @@ mod tests {
6262
use opentelemetry_sdk::trace::BatchConfigBuilder;
6363
use opentelemetry_sdk::trace::BatchSpanProcessor;
6464
use opentelemetry_sdk::trace::InMemorySpanExporterBuilder;
65-
use opentelemetry_sdk::trace::SdkTracerProvider;
6665
use tracing::Level;
6766
use tracing::level_filters::LevelFilter;
6867

6968
#[test]
7069
fn test_remove_pending_spans() {
7170
let exporter = InMemorySpanExporterBuilder::new().build();
72-
let provider = SdkTracerProvider::builder()
73-
.with_span_processor(
71+
72+
let config = crate::configure()
73+
.send_to_logfire(false)
74+
.install_panic_handler()
75+
.with_additional_span_processor(
7476
BatchSpanProcessor::builder(DeterministicExporter::new(
7577
RemovePendingSpansExporter(exporter.clone()),
7678
))
@@ -83,15 +85,10 @@ mod tests {
8385
)
8486
.build(),
8587
)
86-
.with_id_generator(DeterministicIdGenerator::new())
87-
.build();
88-
89-
let mut config = crate::configure();
90-
config
91-
.send_to_logfire(SendToLogfire::No)
92-
.install_panic_handler()
93-
.with_tracer_provider(provider)
94-
.with_defalt_level_filter(LevelFilter::TRACE);
88+
.with_default_level_filter(LevelFilter::TRACE)
89+
.with_advanced_options(
90+
AdvancedOptions::default().with_id_generator(DeterministicIdGenerator::new()),
91+
);
9592

9693
let guard = set_local_logfire(config).unwrap();
9794

0 commit comments

Comments
 (0)