use crate::payload::{Payload, PayloadRaw};
use std::sync::Arc;
use uuid::Uuid;
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct TraceContext {
pub correlation_id: Uuid,
pub span_id: u64,
pub parent_id: Option<u64>,
}
impl TraceContext {
pub fn new() -> Self {
let correlation_id = Uuid::now_v7();
let span_id = correlation_id.as_u128() as u64; Self {
correlation_id,
span_id,
parent_id: None,
}
}
pub fn new_child(&self) -> Self {
Self {
correlation_id: self.correlation_id,
span_id: Uuid::now_v7().as_u128() as u64, parent_id: Some(self.span_id),
}
}
pub fn from_parts(correlation_id: Uuid, span_id: u64, parent_id: Option<u64>) -> Self {
Self {
correlation_id,
span_id,
parent_id,
}
}
}
impl Default for TraceContext {
fn default() -> Self {
Self::new()
}
}
pub trait LogTrace {
fn correlation_id(&self) -> Uuid;
fn span_id(&self) -> u64;
fn parent_id(&self) -> Option<u64>;
fn neuron_name(&self) -> String;
fn trace_context(&self) -> TraceContext {
TraceContext::from_parts(self.correlation_id(), self.span_id(), self.parent_id())
}
fn span_info(&self, name: &'static str) -> tracing::Span {
let correlation_id = self.correlation_id().to_string();
let span_id = self.span_id().to_string();
let parent_id = self
.parent_id()
.map(|id| id.to_string())
.unwrap_or_default();
let neuron = self.neuron_name();
tracing::info_span!(
target: "plexor::trace",
"plexor",
log_name = name,
correlation_id = %correlation_id,
span_id = %span_id,
parent_id = %parent_id,
neuron = %neuron
)
}
fn span_debug(&self, name: &'static str) -> tracing::Span {
let correlation_id = self.correlation_id().to_string();
let span_id = self.span_id().to_string();
let parent_id = self
.parent_id()
.map(|id| id.to_string())
.unwrap_or_default();
let neuron = self.neuron_name();
tracing::debug_span!(
target: "plexor::trace",
"plexor",
log_name = name,
correlation_id = %correlation_id,
span_id = %span_id,
parent_id = %parent_id,
neuron = %neuron
)
}
}
impl LogTrace for TraceContext {
fn correlation_id(&self) -> Uuid {
self.correlation_id
}
fn span_id(&self) -> u64 {
self.span_id
}
fn parent_id(&self) -> Option<u64> {
self.parent_id
}
fn neuron_name(&self) -> String {
"app".to_string()
}
fn trace_context(&self) -> TraceContext {
*self
}
}
impl LogTrace for Uuid {
fn correlation_id(&self) -> Uuid {
Uuid::nil()
}
fn span_id(&self) -> u64 {
0
}
fn parent_id(&self) -> Option<u64> {
None
}
fn neuron_name(&self) -> String {
"none".to_string()
}
fn span_info(&self, name: &'static str) -> tracing::Span {
tracing::info_span!(
target: "plexor::trace",
"plexor",
log_name = name,
ganglion_id = %self
)
}
fn span_debug(&self, name: &'static str) -> tracing::Span {
tracing::debug_span!(
target: "plexor::trace",
"plexor",
log_name = name,
ganglion_id = %self
)
}
}
impl<T, C> LogTrace for Payload<T, C>
where
T: Send + Sync + 'static,
C: crate::codec::Codec<T> + crate::codec::CodecName + Send + Sync + 'static,
{
fn correlation_id(&self) -> Uuid {
self.trace.correlation_id
}
fn span_id(&self) -> u64 {
self.trace.span_id
}
fn parent_id(&self) -> Option<u64> {
self.trace.parent_id
}
fn neuron_name(&self) -> String {
self.neuron.name()
}
fn trace_context(&self) -> TraceContext {
self.trace
}
}
impl<T, C> LogTrace for PayloadRaw<T, C>
where
T: Send + Sync + 'static,
C: crate::codec::Codec<T> + crate::codec::CodecName + Send + Sync + 'static,
{
fn correlation_id(&self) -> Uuid {
self.trace.correlation_id
}
fn span_id(&self) -> u64 {
self.trace.span_id
}
fn parent_id(&self) -> Option<u64> {
self.trace.parent_id
}
fn neuron_name(&self) -> String {
self.neuron.name()
}
fn trace_context(&self) -> TraceContext {
self.trace
}
}
impl LogTrace for crate::erasure::payload::SimplePayloadRawErased {
fn correlation_id(&self) -> Uuid {
self.trace.correlation_id
}
fn span_id(&self) -> u64 {
self.trace.span_id
}
fn parent_id(&self) -> Option<u64> {
self.trace.parent_id
}
fn neuron_name(&self) -> String {
self.neuron_name.clone()
}
fn trace_context(&self) -> TraceContext {
self.trace
}
}
impl<T, C> LogTrace for crate::erasure::payload::PayloadErasedWrapper<T, C>
where
T: Send + Sync + 'static,
C: crate::codec::Codec<T> + crate::codec::CodecName + Send + Sync + 'static,
{
fn correlation_id(&self) -> Uuid {
self.get_typed_payload().trace.correlation_id
}
fn span_id(&self) -> u64 {
self.get_typed_payload().trace.span_id
}
fn parent_id(&self) -> Option<u64> {
self.get_typed_payload().trace.parent_id
}
fn neuron_name(&self) -> String {
self.get_typed_payload().neuron.name()
}
fn trace_context(&self) -> TraceContext {
self.get_typed_payload().trace
}
}
impl<T, C> LogTrace for crate::erasure::payload::PayloadRawErasedWrapper<T, C>
where
T: Send + Sync + 'static,
C: crate::codec::Codec<T> + crate::codec::CodecName + Send + Sync + 'static,
{
fn correlation_id(&self) -> Uuid {
self.get_payload_raw().trace.correlation_id
}
fn span_id(&self) -> u64 {
self.get_payload_raw().trace.span_id
}
fn parent_id(&self) -> Option<u64> {
self.get_payload_raw().trace.parent_id
}
fn neuron_name(&self) -> String {
self.get_payload_raw().neuron.name()
}
fn trace_context(&self) -> TraceContext {
self.get_payload_raw().trace
}
}
impl<P: LogTrace + ?Sized> LogTrace for Arc<P> {
fn correlation_id(&self) -> Uuid {
(**self).correlation_id()
}
fn span_id(&self) -> u64 {
(**self).span_id()
}
fn parent_id(&self) -> Option<u64> {
(**self).parent_id()
}
fn neuron_name(&self) -> String {
(**self).neuron_name()
}
}