Skip to content

Commit

Permalink
Get rid of tx_id to traceparent translation
Browse files Browse the repository at this point in the history
  • Loading branch information
aqrln committed Oct 7, 2024
1 parent 585e6fd commit 0ffdf7c
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 89 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions libs/telemetry/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ indexmap.workspace = true
itertools.workspace = true
once_cell = "1"
opentelemetry = { version = "0.17.0", features = ["rt-tokio", "serialize"] }
rand.workspace = true
serde.workspace = true
serde_json.workspace = true
thiserror = "1.0"
Expand Down
17 changes: 9 additions & 8 deletions libs/telemetry/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,6 @@ pub struct TraceParent {
}

impl TraceParent {
pub fn new_unsafe(trace_id: TraceId, span_id: SpanId, flags: TraceFlags) -> Self {
Self {
trace_id,
span_id,
flags,
}
}

pub fn from_remote_context(context: &opentelemetry::Context) -> Option<Self> {
let span = context.span();
let span_context = span.span_context();
Expand All @@ -57,6 +49,15 @@ impl TraceParent {
}
}

#[deprecated = "This must only be used to create an artificial traceparent for log capturing when tracing is disabled on the client"]
pub fn new_random() -> Self {
Self {
trace_id: TraceId::from_bytes(rand::random()),
span_id: SpanId::from_bytes(rand::random()),
flags: TraceFlags::SAMPLED,
}
}

pub fn trace_id(&self) -> TraceId {
self.trace_id
}
Expand Down
67 changes: 0 additions & 67 deletions query-engine/core/src/interactive_transactions/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
use derive_more::Display;
use opentelemetry::trace::{SpanId, TraceFlags, TraceId};
use serde::Deserialize;

use telemetry::helpers::TraceParent;

mod error;
mod manager;
mod transaction;
Expand All @@ -17,44 +14,6 @@ pub(crate) use transaction::*;
#[display(fmt = "{}", _0)]
pub struct TxId(String);

impl TxId {
/// This method, as well as `as_span_id`, are intentionally private because it is very easy to
/// misuse them. Both are used to provide deterministic trace_id and span_id derived from the
/// transaction id. Both rely on the fact that transaction id is a valid cuid.
fn as_trace_id(&self) -> TraceId {
let mut buffer = [0; 16];
let tx_id = self.0.as_bytes();
let len = tx_id.len();

// The first byte of CUID is always letter 'c'. Next 8 bytes after that represent timestamp
// in milliseconds. Next 4 bytes after that represent the counter.
// We take last 4 bytes of the timestamp and combine it with the counter.
buffer[0..8].copy_from_slice(&tx_id[(1 + 4)..(1 + 4 + 8)]);
// Last 8 bytes of cuid are totally random.
buffer[8..].copy_from_slice(&tx_id[len - 8..]);

TraceId::from_bytes(buffer)
}

fn as_span_id(&self) -> SpanId {
let mut buffer = [0; 8];
let tx_id = self.0.as_bytes();
let len = tx_id.len();

// Last 8 bytes of cuid are totally random.
buffer[..].copy_from_slice(&tx_id[len - 8..]);

SpanId::from_bytes(buffer)
}

/// Creates new artificial `TraceParent`. The span corresponding to this traceparent is never
/// emitted. Same transaction id is guaranteed to have traceparent with the same trace_id and
/// span_id.
pub fn as_traceparent(&self) -> TraceParent {
TraceParent::new_unsafe(self.as_trace_id(), self.as_span_id(), TraceFlags::SAMPLED)
}
}

impl Default for TxId {
fn default() -> Self {
#[allow(deprecated)]
Expand Down Expand Up @@ -82,29 +41,3 @@ where
Self(contents)
}
}

#[cfg(test)]
mod test {
use super::*;

#[test]
fn test_txid_into_traceid() {
let fixture = vec![
("clct0q6ma0000rb04768tiqbj", "71366d6130303030373638746971626a"),
// counter changed, trace id changed:
("clct0q6ma0002rb04cpa6zkmx", "71366d6130303032637061367a6b6d78"),
// fingerprint changed, trace id did not change, as that chunk is ignored:
("clct0q6ma00020000cpa6zkmx", "71366d6130303032637061367a6b6d78"),
// first 5 bytes changed, trace id did not change, as that chunk is ignored:
("00000q6ma00020000cpa6zkmx", "71366d6130303032637061367a6b6d78"),
// 6 th byte changed, trace id changed, as that chunk is part of the lsb of the timestamp
("0000006ma00020000cpa6zkmx", "30366d6130303032637061367a6b6d78"),
];

for (txid, expected_trace_id) in fixture {
let txid: TxId = txid.into();
let trace_id: opentelemetry::trace::TraceId = txid.as_trace_id();
assert_eq!(trace_id.to_string(), expected_trace_id);
}
}
}
20 changes: 6 additions & 14 deletions query-engine/query-engine/src/server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ async fn request_handler(cx: Arc<PrismaContext>, req: Request<Body>) -> Result<R
let headers = req.headers();
let tx_id = try_get_transaction_id(headers);
let (span, traceparent, capturer) =
setup_telemetry(info_span!("prisma:engine:query", user_facing = true), headers, &tx_id).await;
setup_telemetry(info_span!("prisma:engine:query", user_facing = true), headers).await;

let buffer = hyper::body::to_bytes(req.into_body()).await?;
let request_body = RequestBody::try_from_slice(buffer.as_ref(), cx.engine_protocol());
Expand Down Expand Up @@ -240,7 +240,6 @@ async fn transaction_start_handler(cx: Arc<PrismaContext>, req: Request<Body>) -
let (span, _traceparent, capturer) = setup_telemetry(
info_span!("prisma:engine:start_transaction", user_facing = true),
&headers,
&tx_opts.new_tx_id,
)
.await;

Expand Down Expand Up @@ -275,7 +274,6 @@ async fn transaction_commit_handler(
let (span, _traceparent, capturer) = setup_telemetry(
info_span!("prisma:engine:commit_transaction", user_facing = true),
req.headers(),
&Some(tx_id.clone()),
)
.await;

Expand All @@ -296,7 +294,6 @@ async fn transaction_rollback_handler(
let (span, _traceparent, capturer) = setup_telemetry(
info_span!("prisma:engine:rollback_transaction", user_facing = true),
req.headers(),
&Some(tx_id.clone()),
)
.await;

Expand Down Expand Up @@ -379,11 +376,7 @@ fn err_to_http_resp(
build_json_response(status, &err)
}

async fn setup_telemetry(
span: Span,
headers: &HeaderMap,
tx_id: &Option<TxId>,
) -> (Span, Option<TraceParent>, Capturer) {
async fn setup_telemetry(span: Span, headers: &HeaderMap) -> (Span, Option<TraceParent>, Capturer) {
let capture_settings = {
let settings = headers
.get("X-capture-telemetry")
Expand Down Expand Up @@ -429,11 +422,10 @@ async fn setup_telemetry(
// instead, we will fix the root cause of the problem by reworking the capturer to collect
// all spans and events which have the `span` created above as an ancestor and not rely on
// trace IDs at all. This will happen in a follow-up PR as part of Tracing GA work.
//
// TODO: for now, while this mechanism exists, just generate a random traceparent
// unconditionally, we already shouldn't need the transaction IDs here anymore even in the
// case of transactions.
let traceparent = tx_id.clone().unwrap_or_default().as_traceparent();
let traceparent = {
#[allow(deprecated)]
TraceParent::new_random()
};
let context = opentelemetry::global::get_text_map_propagator(|propagator| {
propagator.extract(&TraceParentExtractor::new(traceparent))
});
Expand Down

0 comments on commit 0ffdf7c

Please sign in to comment.