Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add custom OpenTelemetrySpanExt trait #700

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 16 additions & 16 deletions crates/block-producer/src/block_builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::{
};

use futures::FutureExt;
use miden_node_utils::tracing::{OpenTelemetrySpanExt, OtelStatus};
use miden_node_utils::tracing::OpenTelemetrySpanExt;
use miden_objects::{
account::AccountId,
batch::ProvenBatch,
Expand Down Expand Up @@ -106,7 +106,7 @@ impl BlockBuilder {
.and_then(|proven_block| async { self.inject_failure(proven_block) })
.and_then(|proven_block| self.commit_block(mempool, proven_block))
// Handle errors by propagating the error to the root span and rolling back the block.
.inspect_err(|err| Span::current().set_status(OtelStatus::Error { description: format!("{err:?}").into() }))
.inspect_err(|err| Span::current().set_error(err))
.or_else(|_err| self.rollback_block(mempool).never_error())
// Error has been handled, this is just type manipulation to remove the result wrapper.
.unwrap_or_else(|_| ())
Expand Down Expand Up @@ -197,9 +197,9 @@ impl BlockBuilder {
async fn simulate_proving(&self) {
let proving_duration = rand::thread_rng().gen_range(self.simulated_proof_time.clone());

Span::current().set_attribute("range.min_s", self.simulated_proof_time.start.as_secs_f64());
Span::current().set_attribute("range.max_s", self.simulated_proof_time.end.as_secs_f64());
Span::current().set_attribute("dice_roll_s", proving_duration.as_secs_f64());
Span::current().set_attribute("range.min_s", self.simulated_proof_time.start);
Span::current().set_attribute("range.max_s", self.simulated_proof_time.end);
Span::current().set_attribute("dice_roll_s", proving_duration);

tokio::time::sleep(proving_duration).await;
}
Expand Down Expand Up @@ -282,8 +282,8 @@ struct ProvenBlock {
impl SelectedBlock {
fn inject_telemetry(&self) {
let span = Span::current();
span.set_attribute("block.number", i64::from(self.block_number.as_u32()));
span.set_attribute("block.batches.count", i64::from(self.batches.len() as u32));
span.set_attribute("block.number", self.block_number);
span.set_attribute("block.batches.count", self.batches.len() as u32);
}
}

Expand Down Expand Up @@ -319,17 +319,17 @@ impl ProvenBlock {
let span = Span::current();
let header = self.block.header();

span.set_attribute("block.hash", header.hash().to_hex());
span.set_attribute("block.sub_hash", header.sub_hash().to_hex());
span.set_attribute("block.parent_hash", header.prev_hash().to_hex());
span.set_attribute("block.hash", header.hash());
span.set_attribute("block.sub_hash", header.sub_hash());
span.set_attribute("block.parent_hash", header.prev_hash());

span.set_attribute("block.protocol.version", i64::from(header.version()));

span.set_attribute("block.commitments.kernel", header.kernel_root().to_hex());
span.set_attribute("block.commitments.nullifier", header.nullifier_root().to_hex());
span.set_attribute("block.commitments.account", header.account_root().to_hex());
span.set_attribute("block.commitments.chain", header.chain_root().to_hex());
span.set_attribute("block.commitments.note", header.note_root().to_hex());
span.set_attribute("block.commitments.transaction", header.tx_hash().to_hex());
span.set_attribute("block.commitments.kernel", header.kernel_root());
span.set_attribute("block.commitments.nullifier", header.nullifier_root());
span.set_attribute("block.commitments.account", header.account_root());
span.set_attribute("block.commitments.chain", header.chain_root());
span.set_attribute("block.commitments.note", header.note_root());
span.set_attribute("block.commitments.transaction", header.tx_hash());
}
}
6 changes: 2 additions & 4 deletions crates/utils/src/tracing/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
pub mod grpc;
mod span_ext;

// Re-export useful traits for open-telemetry traces. This avoids requiring other crates from
// importing that family of crates directly.
pub use opentelemetry::trace::Status as OtelStatus;
pub use tracing_opentelemetry::OpenTelemetrySpanExt;
pub use span_ext::{OpenTelemetrySpanExt, ToValue};
84 changes: 84 additions & 0 deletions crates/utils/src/tracing/span_ext.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
use core::time::Duration;

use miden_objects::{block::BlockNumber, Digest};
use opentelemetry::{trace::Status, Key, Value};

/// Utility functions for converting types into [`opentelemetry::Value`].
pub trait ToValue {
fn to_value(&self) -> Value;
}

impl ToValue for Duration {
fn to_value(&self) -> Value {
self.as_secs_f64().into()
}
}

impl ToValue for Digest {
fn to_value(&self) -> Value {
self.to_hex().into()
}
}

impl ToValue for f64 {
fn to_value(&self) -> Value {
(*self).into()
}
}

impl ToValue for BlockNumber {
fn to_value(&self) -> Value {
i64::from(self.as_u32()).into()
}
}

impl ToValue for u32 {
fn to_value(&self) -> Value {
i64::from(*self).into()
}
}

impl ToValue for i64 {
fn to_value(&self) -> Value {
(*self).into()
}
}

/// Utility functions based on [`tracing_opentelemetry::OpenTelemetrySpanExt`].
///
/// This is a sealed trait. It and cannot be implemented outside of this module.
pub trait OpenTelemetrySpanExt: private::Sealed {
fn set_attribute(&self, key: impl Into<Key>, value: impl ToValue);
fn set_error(&self, err: &dyn std::error::Error);
}

impl<S> OpenTelemetrySpanExt for S
where
S: tracing_opentelemetry::OpenTelemetrySpanExt,
{
/// Sets an attribute on `Span`.
///
/// Implementations for `ToValue` should be added to this crate (miden-node-utils).
fn set_attribute(&self, key: impl Into<Key>, value: impl ToValue) {
tracing_opentelemetry::OpenTelemetrySpanExt::set_attribute(self, key, value.to_value());
}

/// Sets a status on `Span` based on an error.
fn set_error(&self, err: &dyn std::error::Error) {
// Coalesce all sources into one string.
let mut description = format!("{err}");
let current = err;
while let Some(cause) = current.source() {
description.push_str(format!("\nCaused by: {cause}").as_str());
}
tracing_opentelemetry::OpenTelemetrySpanExt::set_status(
self,
Status::Error { description: description.into() },
);
}
}

mod private {
pub trait Sealed {}
impl<S> Sealed for S where S: tracing_opentelemetry::OpenTelemetrySpanExt {}
}
Loading