Skip to content

Commit a81c6c6

Browse files
authored
stackdriver: avoid calling log from inside exporter (#709)
1 parent 6d07ff0 commit a81c6c6

File tree

2 files changed

+47
-31
lines changed

2 files changed

+47
-31
lines changed

opentelemetry-stackdriver/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ documentation = "https://docs.rs/opentelemetry-stackdriver/"
66
repository = "https://github.com/open-telemetry/opentelemetry-rust"
77
license = "Apache-2.0"
88
edition = "2018"
9+
exclude = ["/proto"]
910

1011
[dependencies]
1112
async-trait = "0.1.48"
@@ -15,7 +16,6 @@ hex = "0.4"
1516
http = "0.2"
1617
hyper = "0.14.2"
1718
hyper-rustls = { version = "0.22.1", optional = true }
18-
log = "0.4"
1919
opentelemetry = { version = "0.16", path = "../opentelemetry" }
2020
prost = "0.9"
2121
prost-types = "0.9"

opentelemetry-stackdriver/src/lib.rs

+46-30
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,12 @@ use std::{
2323
use async_trait::async_trait;
2424
use futures::stream::StreamExt;
2525
use opentelemetry::{
26-
sdk::export::trace::{ExportResult, SpanData, SpanExporter},
26+
global::handle_error,
27+
sdk::export::{
28+
trace::{ExportResult, SpanData, SpanExporter},
29+
ExportError,
30+
},
31+
trace::TraceError,
2732
Value,
2833
};
2934
use thiserror::Error;
@@ -61,22 +66,6 @@ pub struct StackDriverExporter {
6166
maximum_shutdown_duration: Duration,
6267
}
6368

64-
impl fmt::Debug for StackDriverExporter {
65-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66-
#[allow(clippy::unneeded_field_pattern)]
67-
let Self {
68-
maximum_shutdown_duration,
69-
pending_count,
70-
tx: _,
71-
} = self;
72-
f.debug_struct("StackDriverExporter")
73-
.field("tx", &"(elided)")
74-
.field("pending_count", pending_count)
75-
.field("maximum_shutdown_duration", maximum_shutdown_duration)
76-
.finish()
77-
}
78-
}
79-
8069
impl StackDriverExporter {
8170
pub fn builder() -> Builder {
8271
Builder::default()
@@ -91,10 +80,7 @@ impl StackDriverExporter {
9180
impl SpanExporter for StackDriverExporter {
9281
async fn export(&mut self, batch: Vec<SpanData>) -> ExportResult {
9382
match self.tx.try_send(batch) {
94-
Err(e) => {
95-
log::error!("Unable to send to export_inner {:?}", e);
96-
Err(e.into())
97-
}
83+
Err(e) => Err(e.into()),
9884
Ok(()) => {
9985
self.pending_count.fetch_add(1, Ordering::Relaxed);
10086
Ok(())
@@ -112,6 +98,22 @@ impl SpanExporter for StackDriverExporter {
11298
}
11399
}
114100

101+
impl fmt::Debug for StackDriverExporter {
102+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103+
#[allow(clippy::unneeded_field_pattern)]
104+
let Self {
105+
tx: _,
106+
pending_count,
107+
maximum_shutdown_duration,
108+
} = self;
109+
f.debug_struct("StackDriverExporter")
110+
.field("tx", &"(elided)")
111+
.field("pending_count", pending_count)
112+
.field("maximum_shutdown_duration", maximum_shutdown_duration)
113+
.finish()
114+
}
115+
}
116+
115117
/// Helper type to build a `StackDriverExporter`.
116118
#[derive(Clone, Default)]
117119
pub struct Builder {
@@ -141,10 +143,13 @@ impl Builder {
141143
self
142144
}
143145

144-
pub async fn build(
146+
pub async fn build<A: Authorizer>(
145147
self,
146-
authenticator: impl Authorizer,
147-
) -> Result<(StackDriverExporter, impl Future<Output = ()>), Error> {
148+
authenticator: A,
149+
) -> Result<(StackDriverExporter, impl Future<Output = ()>), Error>
150+
where
151+
Error: From<A::Error>,
152+
{
148153
let Self {
149154
maximum_shutdown_duration,
150155
num_concurrent_requests,
@@ -217,7 +222,10 @@ struct ExporterContext<'a, A> {
217222
scopes: Arc<Vec<&'static str>>,
218223
}
219224

220-
impl<A: Authorizer> ExporterContext<'_, A> {
225+
impl<A: Authorizer> ExporterContext<'_, A>
226+
where
227+
Error: From<A::Error>,
228+
{
221229
async fn export(mut self, batch: Vec<SpanData>) {
222230
use proto::devtools::cloudtrace::v2::span::time_event::Value;
223231

@@ -327,9 +335,9 @@ impl<A: Authorizer> ExporterContext<'_, A> {
327335

328336
self.pending_count.fetch_sub(1, Ordering::Relaxed);
329337
if let Err(e) = self.authorizer.authorize(&mut req, &self.scopes).await {
330-
log::error!("StackDriver authentication failed {}", e);
338+
handle_error(TraceError::from(Error::from(e)));
331339
} else if let Err(e) = self.trace_client.batch_write_spans(req).await {
332-
log::error!("StackDriver push failed {}", e);
340+
handle_error(TraceError::from(Error::TonicRpc(e)));
333341
}
334342

335343
let client = match &mut self.log_client {
@@ -351,9 +359,9 @@ impl<A: Authorizer> ExporterContext<'_, A> {
351359
});
352360

353361
if let Err(e) = self.authorizer.authorize(&mut req, &self.scopes).await {
354-
log::error!("StackDriver authentication failed {}", e);
362+
handle_error(TraceError::from(Error::from(e)));
355363
} else if let Err(e) = client.client.write_log_entries(req).await {
356-
log::error!("StackDriver push failed {}", e);
364+
handle_error(TraceError::from(Error::TonicRpc(e)));
357365
}
358366
}
359367
}
@@ -498,12 +506,20 @@ pub enum Error {
498506
#[error("{0}")]
499507
Other(#[from] Box<dyn std::error::Error + Send + Sync>),
500508
#[error("tonic error: {0}")]
501-
Tonic(#[from] tonic::transport::Error),
509+
TonicRpc(#[from] tonic::Status),
510+
#[error("tonic error: {0}")]
511+
TonicTransport(#[from] tonic::transport::Error),
502512
#[cfg(feature = "yup-oauth2")]
503513
#[error("authorizer error: {0}")]
504514
Yup(#[from] yup_oauth2::Error),
505515
}
506516

517+
impl ExportError for Error {
518+
fn exporter_name(&self) -> &'static str {
519+
"stackdriver"
520+
}
521+
}
522+
507523
/// As defined in https://cloud.google.com/logging/docs/reference/v2/rpc/google.logging.type#google.logging.type.LogSeverity.
508524
enum LogSeverity {
509525
Default = 0,

0 commit comments

Comments
 (0)