Skip to content

Commit 7b3776c

Browse files
authored
Have Opentelemetry error handler to use tracing::error (#852)
* Set global opentelemetry error handler to use tracing::error * Add OTel HTTP support * Revert "Add OTel HTTP support" This reverts commit 513c533. * attempting to write a new test to validate this new setting * Added test
1 parent cb61f8d commit 7b3776c

File tree

2 files changed

+79
-3
lines changed

2 files changed

+79
-3
lines changed

core/src/telemetry/otel.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use super::{
1212
};
1313
use crate::{abstractions::dbg_panic, telemetry::metrics::DEFAULT_S_BUCKETS};
1414
use opentelemetry::{
15-
self,
15+
self, global,
1616
metrics::{Meter, MeterProvider as MeterProviderT},
1717
Key, KeyValue, Value,
1818
};
@@ -121,6 +121,9 @@ pub(super) fn augment_meter_provider_with_defaults(
121121
pub fn build_otlp_metric_exporter(
122122
opts: OtelCollectorOptions,
123123
) -> Result<CoreOtelMeter, anyhow::Error> {
124+
global::set_error_handler(|err| {
125+
tracing::error!("{}", err);
126+
})?;
124127
let exporter = match opts.protocol {
125128
OtlpProtocol::Grpc => {
126129
let mut exporter = opentelemetry_otlp::TonicExporterBuilder::default()

tests/integ_tests/metrics_tests.rs

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
use anyhow::anyhow;
22
use assert_matches::assert_matches;
3-
use std::string::ToString;
4-
use std::{collections::HashMap, env, net::SocketAddr, sync::Arc, time::Duration};
3+
use std::{
4+
collections::HashMap,
5+
env,
6+
net::SocketAddr,
7+
string::ToString,
8+
sync::{Arc, Mutex},
9+
time::Duration,
10+
};
511
use temporal_client::{
612
WorkflowClientTrait, WorkflowOptions, WorkflowService, REQUEST_LATENCY_HISTOGRAM_NAME,
713
};
@@ -48,6 +54,7 @@ use temporal_sdk_core_test_utils::{
4854
PROMETHEUS_QUERY_API,
4955
};
5056
use tokio::{join, sync::Barrier, task::AbortHandle};
57+
use tracing_subscriber::fmt::MakeWriter;
5158
use url::Url;
5259

5360
static ANY_PORT: &str = "127.0.0.1:0";
@@ -900,3 +907,69 @@ async fn evict_on_complete_does_not_count_as_forced_eviction() {
900907
// Metric shouldn't show up at all, since it's zero the whole time.
901908
assert!(!body.contains("temporal_sticky_cache_total_forced_eviction"));
902909
}
910+
911+
struct CapturingWriter {
912+
buf: Arc<Mutex<Vec<u8>>>,
913+
}
914+
915+
impl MakeWriter<'_> for CapturingWriter {
916+
type Writer = CapturingHandle;
917+
918+
fn make_writer(&self) -> Self::Writer {
919+
CapturingHandle(self.buf.clone())
920+
}
921+
}
922+
923+
struct CapturingHandle(Arc<Mutex<Vec<u8>>>);
924+
925+
impl std::io::Write for CapturingHandle {
926+
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
927+
let mut b = self.0.lock().unwrap();
928+
b.extend_from_slice(buf);
929+
Ok(buf.len())
930+
}
931+
fn flush(&mut self) -> std::io::Result<()> {
932+
Ok(())
933+
}
934+
}
935+
936+
#[tokio::test]
937+
async fn otel_errors_logged_as_errors() {
938+
// Set up tracing subscriber to capture ERROR logs
939+
let logs = Arc::new(Mutex::new(Vec::new()));
940+
let writer = CapturingWriter { buf: logs.clone() };
941+
let subscriber = tracing_subscriber::fmt().with_writer(writer).finish();
942+
let _guard = tracing::subscriber::set_default(subscriber);
943+
944+
let opts = OtelCollectorOptionsBuilder::default()
945+
.url("https://localhostt:9995/v1/metrics".parse().unwrap()) // Invalid endpoint
946+
.build()
947+
.unwrap();
948+
let exporter = build_otlp_metric_exporter(opts).unwrap();
949+
950+
let telemopts = TelemetryOptionsBuilder::default()
951+
.metrics(Arc::new(exporter) as Arc<dyn CoreMeter>)
952+
.build()
953+
.unwrap();
954+
955+
let rt = CoreRuntime::new_assume_tokio(telemopts).unwrap();
956+
let mut starter = CoreWfStarter::new_with_runtime("otel_errors_logged_as_errors", rt);
957+
let _worker = starter.get_worker().await;
958+
959+
// Wait to allow exporter to attempt sending metrics and fail.
960+
tokio::time::sleep(Duration::from_secs(2)).await;
961+
962+
let logs = logs.lock().unwrap();
963+
let log_str = String::from_utf8_lossy(&logs);
964+
965+
assert!(
966+
log_str.contains("ERROR"),
967+
"Expected ERROR log not found in logs: {}",
968+
log_str
969+
);
970+
assert!(
971+
log_str.contains("Metrics exporter otlp failed with the grpc server returns error"),
972+
"Expected an OTel exporter error message in logs: {}",
973+
log_str
974+
);
975+
}

0 commit comments

Comments
 (0)