1pub mod context;
7pub mod exporter;
8pub mod tracer;
9
10pub use context::{
11    extract_from_axum_headers, extract_trace_context, inject_into_axum_headers,
12    inject_trace_context, TraceContext,
13};
14pub use exporter::{
15    ExporterError, ExporterType, JaegerExporter, OtlpCompression, OtlpExporter, OtlpProtocol,
16};
17pub use tracer::{init_tracer, shutdown_tracer, TracingConfig};
18
19use opentelemetry::global::BoxedSpan;
20use opentelemetry::trace::{Span, SpanKind, Status, Tracer};
21use opentelemetry::{global, KeyValue};
22use std::time::SystemTime;
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq)]
26pub enum Protocol {
27    Http,
28    Grpc,
29    WebSocket,
30    GraphQL,
31}
32
33impl Protocol {
34    pub fn as_str(&self) -> &'static str {
35        match self {
36            Protocol::Http => "http",
37            Protocol::Grpc => "grpc",
38            Protocol::WebSocket => "websocket",
39            Protocol::GraphQL => "graphql",
40        }
41    }
42}
43
44pub fn create_request_span(
46    protocol: Protocol,
47    operation_name: &str,
48    attributes: Vec<KeyValue>,
49) -> BoxedSpan {
50    let tracer = global::tracer("mockforge");
51
52    let mut span = tracer
53        .span_builder(operation_name.to_string())
54        .with_kind(SpanKind::Server)
55        .with_start_time(SystemTime::now())
56        .with_attributes(attributes)
57        .start(&tracer);
58
59    span.set_attribute(KeyValue::new("mockforge.protocol", protocol.as_str()));
61
62    span
63}
64
65pub fn record_success(span: &mut BoxedSpan, attributes: Vec<KeyValue>) {
67    for attr in attributes {
68        span.set_attribute(attr);
69    }
70    span.set_status(Status::Ok);
71}
72
73pub fn record_error(span: &mut BoxedSpan, error_message: &str) {
75    span.set_status(Status::error(error_message.to_string()));
76    span.set_attribute(KeyValue::new("error", true));
77    span.set_attribute(KeyValue::new("error.message", error_message.to_string()));
78}
79
80#[cfg(test)]
81mod tests {
82    use super::*;
83
84    #[test]
85    fn test_protocol_as_str() {
86        assert_eq!(Protocol::Http.as_str(), "http");
87        assert_eq!(Protocol::Grpc.as_str(), "grpc");
88        assert_eq!(Protocol::WebSocket.as_str(), "websocket");
89        assert_eq!(Protocol::GraphQL.as_str(), "graphql");
90    }
91}