-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathtracer_engine.rs
More file actions
104 lines (89 loc) · 3.54 KB
/
tracer_engine.rs
File metadata and controls
104 lines (89 loc) · 3.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
use super::otel_tracer::{OtelOptions, OtelTracer};
use opentelemetry::{global::Error, trace::TraceError};
use tracing::{level_filters::LevelFilter, Span};
use tracing_opentelemetry::OpenTelemetrySpanExt;
use tracing_subscriber::{layer::SubscriberExt, EnvFilter, Layer};
pub struct TracerOptions<'a> {
otel_options: Option<OtelOptions<'a>>,
}
impl<'a> TracerOptions<'a> {
pub fn new(endpoint: Option<&'a str>, level_filter: LevelFilter, namespace: String) -> Self {
Self {
otel_options: endpoint.map(|endpoint| OtelOptions {
endpoint,
level_filter,
namespace,
}),
}
}
}
/// This object initialises all tracers, given a TracerOptions struct.
/// If TracerOptions contains a OtelOptions struct then it initialises the
/// OtelTracer object as well.
pub struct TracerEngine {
use_otel: bool,
otel_setup_error: Option<TraceError>,
}
impl TracerEngine {
/// Initialises the stdout tracer, and (if required) the OpenTelemetry service for the crate
///
/// ## Arguments
/// * `options` - The caller-specified instance of TracerOptions.
/// * `service_name` - The name of the OpenTelemetry service to assign to the crate.
/// * `module_name` - The name of the current module.
///
/// ## Returns
/// An instance of TracerEngine
pub fn new(options: TracerOptions, service_name: &str, module_name: &str) -> Self {
let use_otel = options.otel_options.is_some();
let stdout_tracer = tracing_subscriber::fmt::layer().with_writer(std::io::stdout);
// if options.otel_options is provided then attempt to setup OtelTracer
let (otel_tracer, otel_setup_error) = options
.otel_options
.map(|otel_options| {
match OtelTracer::<_>::new(otel_options, service_name, module_name) {
Ok(otel_tracer) => (Some(otel_tracer), None),
Err(e) => (None, Some(e)),
}
})
.unwrap_or((None, None));
// If otel_tracer did not work, update the use_otel variable
let use_otel = use_otel && otel_tracer.is_some();
// This filter is applied to the stdout tracer
let log_filter = EnvFilter::from_default_env();
let subscriber = tracing_subscriber::Registry::default()
.with(stdout_tracer.with_filter(log_filter))
.with(otel_tracer.map(|otel_tracer| otel_tracer.layer));
// This is only called once, so will never panic
tracing::subscriber::set_global_default(subscriber)
.expect("tracing::subscriber::set_global_default should only be called once");
Self {
use_otel,
otel_setup_error,
}
}
/// Sets a span's parent to other_span
pub fn set_span_parent_to(span: &Span, parent_span: &Span) {
span.set_parent(parent_span.context());
}
pub fn use_otel(&self) -> bool {
self.use_otel
}
/// This sets a custom error handler for OpenTelemetry.
/// This is public so it can be used in the init_tracer macro,
/// but should not be called anywhere else.
pub fn set_otel_error_handler<F>(&self, f: F) -> Result<(), Error>
where
F: Fn(Error) + Send + Sync + 'static,
{
opentelemetry::global::set_error_handler(f)
}
pub fn get_otel_setup_error(&self) -> Option<&TraceError> {
self.otel_setup_error.as_ref()
}
}
impl Drop for TracerEngine {
fn drop(&mut self) {
opentelemetry::global::shutdown_tracer_provider()
}
}