1#![doc(html_logo_url = "https://raw.githubusercontent.com/emit-rs/emit/main/asset/logo.svg")]
157#![deny(missing_docs)]
158
159use emit::well_known::KEY_SPAN_LINKS;
160use emit::{
161 well_known::{
162 KEY_ERR, KEY_EVT_KIND, KEY_LVL, KEY_SPAN_ID, KEY_SPAN_KIND, KEY_SPAN_NAME, KEY_SPAN_PARENT,
163 KEY_TRACE_ID, LVL_DEBUG, LVL_ERROR, LVL_INFO, LVL_WARN,
164 },
165 Filter, Props,
166};
167use opentelemetry::trace::{Link, SamplingDecision, SamplingResult, TraceState};
168use opentelemetry::{
169 logs::{AnyValue, LogRecord, Logger, LoggerProvider, Severity},
170 trace::{
171 SpanContext, SpanId, SpanKind, Status, TraceContextExt, TraceId, Tracer, TracerProvider,
172 },
173 Context, ContextGuard, Key, KeyValue, TraceFlags, Value,
174};
175use std::fmt::{Display, Formatter};
176use std::{borrow::Cow, cell::RefCell, fmt, ops::ControlFlow, sync::Arc};
177
178mod internal_metrics;
179
180pub use internal_metrics::*;
181
182pub fn setup<L: Logger + Send + Sync + 'static, T: Tracer + Send + Sync + 'static>(
237 logger_provider: impl LoggerProvider<Logger = L>,
238 tracer_provider: impl TracerProvider<Tracer = T>,
239) -> emit::Setup<
240 OpenTelemetryEmitter<L>,
241 OpenTelemetryIsSampledFilter,
242 OpenTelemetryCtxt<emit::setup::DefaultCtxt, T>,
243>
244where
245 T::Span: Send + Sync + 'static,
246{
247 let name = "emit";
248 let metrics = Arc::new(InternalMetrics::default());
249
250 emit::setup()
251 .emit_to(OpenTelemetryEmitter::new(
252 metrics.clone(),
253 logger_provider.logger(name),
254 ))
255 .emit_when(OpenTelemetryIsSampledFilter {})
256 .map_ctxt(|ctxt| {
257 OpenTelemetryCtxt::wrap(metrics.clone(), tracer_provider.tracer(name), ctxt)
258 })
259}
260
261pub struct OpenTelemetryCtxt<C, T> {
269 tracer: T,
270 metrics: Arc<InternalMetrics>,
271 inner: C,
272}
273
274pub struct OpenTelemetryFrame<F> {
278 slot: Option<Context>,
282 active: bool,
286 options: OpenTelemetryFrameOptions,
287 inner: F,
289}
290
291#[derive(Debug, Clone, Copy, Default)]
292struct OpenTelemetryFrameOptions {
293 end_on_close: bool,
297 update_default_name_on_close: bool,
300}
301
302pub struct OpenTelemetryProps<P: ?Sized> {
306 ctxt: emit::span::SpanCtxt,
307 inner: *const P,
309}
310
311impl<C, T> OpenTelemetryCtxt<C, T> {
312 fn wrap(metrics: Arc<InternalMetrics>, tracer: T, ctxt: C) -> Self {
313 OpenTelemetryCtxt {
314 tracer,
315 inner: ctxt,
316 metrics,
317 }
318 }
319
320 pub fn metric_source(&self) -> EmitOpenTelemetryMetrics {
328 EmitOpenTelemetryMetrics {
329 metrics: self.metrics.clone(),
330 }
331 }
332}
333
334impl<P: emit::Props + ?Sized> emit::Props for OpenTelemetryProps<P> {
335 fn for_each<'kv, F: FnMut(emit::Str<'kv>, emit::Value<'kv>) -> ControlFlow<()>>(
336 &'kv self,
337 mut for_each: F,
338 ) -> ControlFlow<()> {
339 self.ctxt.for_each(&mut for_each)?;
340
341 unsafe { &*self.inner }.for_each(|k, v| {
345 if k != emit::well_known::KEY_TRACE_ID && k != emit::well_known::KEY_SPAN_ID {
346 for_each(k, v)?;
347 }
348
349 ControlFlow::Continue(())
350 })
351 }
352}
353
354thread_local! {
355 static ACTIVE_FRAME_STACK: RefCell<Vec<ActiveFrame>> = RefCell::new(Vec::new());
356}
357
358struct ActiveFrame {
359 _guard: ContextGuard,
360 options: OpenTelemetryFrameOptions,
361}
362
363fn push(guard: ActiveFrame) {
364 ACTIVE_FRAME_STACK.with(|stack| stack.borrow_mut().push(guard));
365}
366
367fn pop() -> Option<ActiveFrame> {
368 ACTIVE_FRAME_STACK.with(|stack| stack.borrow_mut().pop())
369}
370
371fn with_current(f: impl FnOnce(&mut ActiveFrame)) {
372 ACTIVE_FRAME_STACK.with(|stack| {
373 if let Some(frame) = stack.borrow_mut().last_mut() {
374 f(frame);
375 }
376 })
377}
378
379impl<C: emit::Ctxt, T: Tracer> emit::Ctxt for OpenTelemetryCtxt<C, T>
380where
381 T::Span: Send + Sync + 'static,
382{
383 type Current = OpenTelemetryProps<C::Current>;
384
385 type Frame = OpenTelemetryFrame<C::Frame>;
386
387 fn open_root<P: emit::Props>(&self, props: P) -> Self::Frame {
388 let (incoming, props) = incoming_span_ctxt(&self.tracer, props, false);
389
390 let (slot, options) = match incoming {
391 IncomingSpanCtxt::None => (Some(Context::new()), Default::default()),
393 IncomingSpanCtxt::Same => (None, Default::default()),
395 IncomingSpanCtxt::Different(context, options) => (Some(context), options),
397 };
398
399 OpenTelemetryFrame {
400 active: false,
401 options,
402 slot,
403 inner: self.inner.open_root(props),
404 }
405 }
406
407 fn open_disabled<P: Props>(&self, props: P) -> Self::Frame {
408 let (incoming, props) = incoming_span_ctxt(&self.tracer, props, true);
409
410 let (slot, options) = match incoming {
411 IncomingSpanCtxt::None => (None, Default::default()),
413 IncomingSpanCtxt::Same => (None, Default::default()),
414 IncomingSpanCtxt::Different(context, options) => (Some(context), options),
416 };
417
418 OpenTelemetryFrame {
419 active: false,
420 options,
421 slot,
422 inner: self.inner.open_disabled(props),
423 }
424 }
425
426 fn open_push<P: Props>(&self, props: P) -> Self::Frame {
427 let (incoming, props) = incoming_span_ctxt(&self.tracer, props, false);
428
429 let (slot, options) = match incoming {
430 IncomingSpanCtxt::None => (None, Default::default()),
433 IncomingSpanCtxt::Same => (None, Default::default()),
434 IncomingSpanCtxt::Different(context, options) => (Some(context), options),
437 };
438
439 OpenTelemetryFrame {
440 active: false,
441 options,
442 slot,
443 inner: self.inner.open_push(props),
444 }
445 }
446
447 fn enter(&self, local: &mut Self::Frame) {
448 self.inner.enter(&mut local.inner);
449
450 if let Some(ctxt) = local.slot.take() {
451 let guard = ctxt.attach();
452
453 push(ActiveFrame {
454 _guard: guard,
455 options: local.options,
456 });
457 local.active = true;
458 }
459 }
460
461 fn with_current<R, F: FnOnce(&Self::Current) -> R>(&self, with: F) -> R {
462 let ctxt = Context::current();
463 let span = ctxt.span();
464
465 let trace_id = span.span_context().trace_id().to_bytes();
471 let span_id = span.span_context().span_id().to_bytes();
472
473 self.inner.with_current(|props| {
474 let props = OpenTelemetryProps {
475 ctxt: emit::span::SpanCtxt::new(
476 emit::TraceId::from_bytes(trace_id),
477 None,
479 emit::SpanId::from_bytes(span_id),
480 ),
481 inner: props as *const C::Current,
482 };
483
484 with(&props)
485 })
486 }
487
488 fn exit(&self, frame: &mut Self::Frame) {
489 self.inner.exit(&mut frame.inner);
490
491 if frame.active {
492 frame.slot = Some(Context::current());
493
494 if let Some(active) = pop() {
495 frame.options = active.options;
496 }
497 frame.active = false;
498 }
499 }
500
501 fn close(&self, mut frame: Self::Frame) {
502 if frame.options.end_on_close {
504 if let Some(ctxt) = frame.slot.take() {
507 self.metrics.span_unexpected_close.increment();
508
509 let span = ctxt.span();
510 span.end();
511 }
512 }
513 }
514}
515
516fn incoming_span_ctxt<T: Tracer>(
517 tracer: &T,
518 props: impl emit::Props,
519 suppress: bool,
520) -> (IncomingSpanCtxt, impl Props)
521where
522 T::Span: Send + Sync + 'static,
523{
524 let span_id = props.pull::<emit::SpanId, _>(KEY_SPAN_ID);
525
526 let Some(span_id) = span_id else {
527 return (
528 IncomingSpanCtxt::None,
529 ExcludeSpanCtxtProps { inner: props },
530 );
531 };
532
533 let ctxt = Context::current();
534
535 let span_id = otel_span_id(span_id);
536
537 if span_id == ctxt.span().span_context().span_id() {
539 return (
540 IncomingSpanCtxt::Same,
541 ExcludeSpanCtxtProps { inner: props },
542 );
543 }
544
545 let span_links = props
550 .get(KEY_SPAN_LINKS)
551 .map(|links| {
552 otel_span_links(
553 links,
554 ctxt.span().span_context().trace_flags(),
555 ctxt.span().span_context().is_remote(),
556 ctxt.span().span_context().trace_state(),
557 )
558 })
559 .unwrap_or_default();
560
561 let span_kind = props
562 .pull::<emit::span::SpanKind, _>(KEY_SPAN_KIND)
563 .map(|kind| match kind {
564 emit::span::SpanKind::Client => SpanKind::Client,
565 emit::span::SpanKind::Server => SpanKind::Server,
566 emit::span::SpanKind::Producer => SpanKind::Producer,
567 emit::span::SpanKind::Consumer => SpanKind::Consumer,
568 _ => SpanKind::Internal,
569 })
570 .unwrap_or(SpanKind::Internal);
571
572 let span_name = props.pull::<String, _>(KEY_SPAN_NAME).map(Cow::Owned);
573
574 let update_default_name_on_close = span_name.is_none();
578
579 let trace_id = props.pull::<emit::TraceId, _>(KEY_TRACE_ID);
580
581 let trace_id = trace_id.map(otel_trace_id);
582
583 let mut span = tracer
584 .span_builder(span_name.unwrap_or(Cow::Borrowed("emit_span")))
585 .with_kind(span_kind)
586 .with_span_id(span_id);
587
588 if let Some(trace_id) = trace_id {
589 span = span.with_trace_id(trace_id);
590 }
591
592 span = span.with_links(span_links);
593
594 if suppress {
596 span = span.with_sampling_result(SamplingResult {
597 decision: SamplingDecision::Drop,
598 attributes: vec![],
599 trace_state: Default::default(),
600 });
601 }
602
603 let ctxt = ctxt.with_span(span.start(tracer));
604
605 (
606 IncomingSpanCtxt::Different(
607 ctxt,
608 OpenTelemetryFrameOptions {
609 update_default_name_on_close,
610 end_on_close: true,
611 },
612 ),
613 ExcludeSpanCtxtProps { inner: props },
614 )
615}
616
617enum IncomingSpanCtxt {
618 None,
619 Same,
620 Different(Context, OpenTelemetryFrameOptions),
621}
622
623struct ExcludeSpanCtxtProps<P> {
628 inner: P,
629}
630
631impl<P: emit::Props> emit::Props for ExcludeSpanCtxtProps<P> {
632 fn for_each<'kv, F: FnMut(emit::Str<'kv>, emit::Value<'kv>) -> ControlFlow<()>>(
633 &'kv self,
634 mut for_each: F,
635 ) -> ControlFlow<()> {
636 self.inner.for_each(|key, value| match key.get() {
637 KEY_TRACE_ID | KEY_SPAN_ID | KEY_SPAN_PARENT | KEY_SPAN_NAME | KEY_SPAN_KIND
639 | KEY_SPAN_LINKS => ControlFlow::Continue(()),
640 _ => for_each(key, value),
642 })
643 }
644}
645
646pub struct OpenTelemetryEmitter<L> {
652 logger: L,
653 span_name: Box<MessageFormatter>,
654 log_body: Box<MessageFormatter>,
655 metrics: Arc<InternalMetrics>,
656}
657
658type MessageFormatter = dyn Fn(&emit::event::Event<&dyn emit::props::ErasedProps>, &mut fmt::Formatter) -> fmt::Result
659 + Send
660 + Sync;
661
662fn default_span_name() -> Box<MessageFormatter> {
663 Box::new(|evt, f| {
664 if let Some(name) = evt.props().get(KEY_SPAN_NAME) {
665 write!(f, "{}", name)
666 } else {
667 write!(f, "{}", evt.msg())
668 }
669 })
670}
671
672fn default_log_body() -> Box<MessageFormatter> {
673 Box::new(|evt, f| write!(f, "{}", evt.msg()))
674}
675
676struct MessageRenderer<'a, P> {
677 pub fmt: &'a MessageFormatter,
678 pub evt: &'a emit::event::Event<'a, P>,
679}
680
681impl<'a, P: emit::props::Props> fmt::Display for MessageRenderer<'a, P> {
682 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
683 (self.fmt)(&self.evt.erase(), f)
684 }
685}
686
687impl<L> OpenTelemetryEmitter<L> {
688 fn new(metrics: Arc<InternalMetrics>, logger: L) -> Self {
689 OpenTelemetryEmitter {
690 logger,
691 span_name: default_span_name(),
692 log_body: default_log_body(),
693 metrics,
694 }
695 }
696
697 pub fn with_span_name(
703 mut self,
704 writer: impl Fn(
705 &emit::event::Event<&dyn emit::props::ErasedProps>,
706 &mut fmt::Formatter,
707 ) -> fmt::Result
708 + Send
709 + Sync
710 + 'static,
711 ) -> Self {
712 self.span_name = Box::new(writer);
713 self
714 }
715
716 pub fn with_log_body(
722 mut self,
723 writer: impl Fn(
724 &emit::event::Event<&dyn emit::props::ErasedProps>,
725 &mut fmt::Formatter,
726 ) -> fmt::Result
727 + Send
728 + Sync
729 + 'static,
730 ) -> Self {
731 self.log_body = Box::new(writer);
732 self
733 }
734
735 pub fn metric_source(&self) -> EmitOpenTelemetryMetrics {
743 EmitOpenTelemetryMetrics {
744 metrics: self.metrics.clone(),
745 }
746 }
747}
748
749impl<L: Logger> emit::Emitter for OpenTelemetryEmitter<L> {
750 fn emit<E: emit::event::ToEvent>(&self, evt: E) {
751 let evt = evt.to_event();
752
753 if emit::kind::is_span_filter().matches(&evt) {
758 let mut emitted = false;
759 with_current(|frame| {
760 if frame.options.end_on_close {
761 let ctxt = Context::current();
762 let span = ctxt.span();
763
764 let span_id = span.span_context().span_id();
765
766 let evt_span_id = evt
767 .props()
768 .pull::<emit::SpanId, _>(KEY_SPAN_ID)
769 .map(otel_span_id);
770
771 if Some(span_id) == evt_span_id {
773 let mut status = Status::Ok;
774 let mut status_is_descriptive_err = false;
775 let mut span_links = Vec::new();
776
777 let _ = evt.props().for_each(|k, v| {
778 if k == KEY_LVL {
779 if let Some(emit::Level::Error) = v.by_ref().cast::<emit::Level>() {
780 if !status_is_descriptive_err {
782 status = Status::error("error");
783 }
784
785 return ControlFlow::Continue(());
786 }
787 }
788
789 if k == KEY_ERR {
790 span.add_event(
791 "exception",
792 vec![KeyValue::new("exception.message", v.to_string())],
793 );
794
795 status = Status::error(v.to_string());
796 status_is_descriptive_err = true;
797
798 return ControlFlow::Continue(());
799 }
800
801 if k == KEY_SPAN_LINKS {
802 span_links = otel_span_links(
803 v,
804 span.span_context().trace_flags(),
805 span.span_context().is_remote(),
806 span.span_context().trace_state(),
807 );
808
809 return ControlFlow::Continue(());
810 }
811
812 if k == KEY_TRACE_ID
814 || k == KEY_SPAN_ID
815 || k == KEY_SPAN_PARENT
816 || k == KEY_EVT_KIND
817 || k == KEY_SPAN_KIND
818 || k == KEY_SPAN_NAME
819 {
820 return ControlFlow::Continue(());
821 }
822
823 if let Some(v) = otel_span_value(v) {
824 span.set_attribute(KeyValue::new(k.to_cow(), v));
825 }
826
827 ControlFlow::Continue(())
828 });
829
830 if frame.options.update_default_name_on_close {
831 span.update_name(
832 MessageRenderer {
833 fmt: &self.span_name,
834 evt: &evt,
835 }
836 .to_string(),
837 );
838 }
839
840 span.set_status(status);
841
842 for link in span_links {
843 span.add_link(link.span_context, Default::default());
844 }
845
846 if let Some(extent) = evt.extent().and_then(|ex| ex.as_range()) {
847 span.end_with_timestamp(extent.end.to_system_time());
848 } else {
849 span.end();
850 }
851
852 frame.options.end_on_close = false;
853 emitted = true;
854 }
855 }
856 });
857
858 if emitted {
859 return;
860 } else {
861 self.metrics.span_unexpected_emit.increment();
862 }
863 }
864
865 let mut record = self.logger.create_log_record();
867
868 let body = format!(
869 "{}",
870 MessageRenderer {
871 fmt: &self.log_body,
872 evt: &evt,
873 }
874 );
875
876 record.set_body(AnyValue::String(body.into()));
877
878 let mut trace_id = None;
879 let mut span_id = None;
880 let mut attributes = Vec::new();
881 {
882 let _ = evt.props().for_each(|k, v| {
883 if k == KEY_LVL {
884 match v.by_ref().cast::<emit::Level>() {
885 Some(emit::Level::Debug) => {
886 record.set_severity_number(Severity::Debug);
887 record.set_severity_text(LVL_DEBUG);
888 }
889 Some(emit::Level::Info) => {
890 record.set_severity_number(Severity::Info);
891 record.set_severity_text(LVL_INFO);
892 }
893 Some(emit::Level::Warn) => {
894 record.set_severity_number(Severity::Warn);
895 record.set_severity_text(LVL_WARN);
896 }
897 Some(emit::Level::Error) => {
898 record.set_severity_number(Severity::Error);
899 record.set_severity_text(LVL_ERROR);
900 }
901 None => {
902 record.set_severity_text("unknown");
903 }
904 }
905
906 return ControlFlow::Continue(());
907 }
908
909 if k == KEY_TRACE_ID {
910 if let Some(id) = v.by_ref().cast::<emit::TraceId>() {
911 trace_id = Some(otel_trace_id(id));
912
913 return ControlFlow::Continue(());
914 }
915 }
916
917 if k == KEY_SPAN_ID {
918 if let Some(id) = v.by_ref().cast::<emit::SpanId>() {
919 span_id = Some(otel_span_id(id));
920
921 return ControlFlow::Continue(());
922 }
923 }
924
925 if k == KEY_SPAN_PARENT {
926 if v.by_ref().cast::<emit::SpanId>().is_some() {
927 return ControlFlow::Continue(());
928 }
929 }
930
931 if k == KEY_SPAN_NAME || k == KEY_SPAN_KIND || k == KEY_SPAN_LINKS {
933 return ControlFlow::Continue(());
934 }
935
936 if let Some(v) = otel_log_value(v) {
937 attributes.push((Key::new(k.to_cow()), v));
938 }
939
940 ControlFlow::Continue(())
941 });
942 }
943
944 record.add_attributes(attributes);
945
946 if let Some(extent) = evt.extent() {
947 record.set_timestamp(extent.as_point().to_system_time());
948 }
949
950 let context = Context::current();
951 let span = context.span();
952 let span = span.span_context();
953
954 let trace_id = trace_id.unwrap_or_else(|| span.trace_id());
955 let span_id = span_id.unwrap_or_else(|| span.span_id());
956 let trace_flags = Some(span.trace_flags());
957
958 record.set_trace_context(trace_id, span_id, trace_flags);
959
960 self.logger.emit(record);
961 }
962
963 fn blocking_flush(&self, _: std::time::Duration) -> bool {
964 false
965 }
966}
967
968pub struct OpenTelemetryIsSampledFilter {}
972
973impl emit::Filter for OpenTelemetryIsSampledFilter {
974 fn matches<E: emit::event::ToEvent>(&self, evt: E) -> bool {
975 let evt = evt.to_event();
976
977 if emit::kind::is_span_filter().matches(&evt) {
979 let ctxt = Context::current();
980 let span = ctxt.span();
981 let span_ctxt = span.span_context();
982
983 span_ctxt == &SpanContext::NONE || span_ctxt.is_sampled()
984 } else {
985 true
987 }
988 }
989}
990
991fn otel_trace_id(trace_id: emit::TraceId) -> TraceId {
992 TraceId::from_bytes(trace_id.to_bytes())
993}
994
995fn otel_span_id(span_id: emit::SpanId) -> SpanId {
996 SpanId::from_bytes(span_id.to_bytes())
997}
998
999fn otel_span_value(v: emit::Value) -> Option<Value> {
1000 match any_value::serialize(&v) {
1001 Ok(Some(av)) => match av {
1002 AnyValue::Int(v) => Some(Value::I64(v)),
1003 AnyValue::Double(v) => Some(Value::F64(v)),
1004 AnyValue::String(v) => Some(Value::String(v)),
1005 AnyValue::Boolean(v) => Some(Value::Bool(v)),
1006 _ => Some(Value::String(v.to_string().into())),
1008 },
1009 Ok(None) => None,
1010 Err(()) => Some(Value::String(v.to_string().into())),
1011 }
1012}
1013
1014fn otel_log_value(v: emit::Value) -> Option<AnyValue> {
1015 match any_value::serialize(&v) {
1016 Ok(v) => v,
1017 Err(()) => Some(AnyValue::String(v.to_string().into())),
1018 }
1019}
1020
1021fn otel_span_links(
1022 v: emit::Value,
1023 trace_flags: TraceFlags,
1024 is_remote: bool,
1025 trace_state: &TraceState,
1026) -> Vec<Link> {
1027 use serde::ser::{
1031 Error, Impossible, Serialize, SerializeSeq, SerializeTuple, SerializeTupleStruct,
1032 SerializeTupleVariant, Serializer, StdError,
1033 };
1034
1035 struct Extract<'a> {
1036 links: Vec<Link>,
1037 trace_flags: TraceFlags,
1038 is_remote: bool,
1039 trace_state: &'a TraceState,
1040 }
1041
1042 #[derive(Debug)]
1043 struct ExtractError;
1044
1045 impl fmt::Display for ExtractError {
1046 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1047 f.write_str("unsupported value for span links")
1048 }
1049 }
1050
1051 impl StdError for ExtractError {}
1052
1053 impl Error for ExtractError {
1054 fn custom<T>(_: T) -> Self
1055 where
1056 T: Display,
1057 {
1058 ExtractError
1059 }
1060 }
1061
1062 impl<'a> Serializer for Extract<'a> {
1063 type Ok = Vec<Link>;
1064 type Error = ExtractError;
1065 type SerializeSeq = Self;
1066 type SerializeTuple = Self;
1067 type SerializeTupleStruct = Self;
1068 type SerializeTupleVariant = Self;
1069 type SerializeMap = Impossible<Self::Ok, Self::Error>;
1070 type SerializeStruct = Impossible<Self::Ok, Self::Error>;
1071 type SerializeStructVariant = Impossible<Self::Ok, Self::Error>;
1072
1073 fn serialize_bool(self, _: bool) -> Result<Self::Ok, Self::Error> {
1074 Err(ExtractError)
1075 }
1076
1077 fn serialize_i8(self, _: i8) -> Result<Self::Ok, Self::Error> {
1078 Err(ExtractError)
1079 }
1080
1081 fn serialize_i16(self, _: i16) -> Result<Self::Ok, Self::Error> {
1082 Err(ExtractError)
1083 }
1084
1085 fn serialize_i32(self, _: i32) -> Result<Self::Ok, Self::Error> {
1086 Err(ExtractError)
1087 }
1088
1089 fn serialize_i64(self, _: i64) -> Result<Self::Ok, Self::Error> {
1090 Err(ExtractError)
1091 }
1092
1093 fn serialize_u8(self, _: u8) -> Result<Self::Ok, Self::Error> {
1094 Err(ExtractError)
1095 }
1096
1097 fn serialize_u16(self, _: u16) -> Result<Self::Ok, Self::Error> {
1098 Err(ExtractError)
1099 }
1100
1101 fn serialize_u32(self, _: u32) -> Result<Self::Ok, Self::Error> {
1102 Err(ExtractError)
1103 }
1104
1105 fn serialize_u64(self, _: u64) -> Result<Self::Ok, Self::Error> {
1106 Err(ExtractError)
1107 }
1108
1109 fn serialize_f32(self, _: f32) -> Result<Self::Ok, Self::Error> {
1110 Err(ExtractError)
1111 }
1112
1113 fn serialize_f64(self, _: f64) -> Result<Self::Ok, Self::Error> {
1114 Err(ExtractError)
1115 }
1116
1117 fn serialize_char(self, _: char) -> Result<Self::Ok, Self::Error> {
1118 Err(ExtractError)
1119 }
1120
1121 fn serialize_str(self, _: &str) -> Result<Self::Ok, Self::Error> {
1122 Err(ExtractError)
1123 }
1124
1125 fn serialize_bytes(self, _: &[u8]) -> Result<Self::Ok, Self::Error> {
1126 Err(ExtractError)
1127 }
1128
1129 fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
1130 Err(ExtractError)
1131 }
1132
1133 fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
1134 where
1135 T: ?Sized + Serialize,
1136 {
1137 value.serialize(self)
1138 }
1139
1140 fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
1141 Err(ExtractError)
1142 }
1143
1144 fn serialize_unit_struct(self, _: &'static str) -> Result<Self::Ok, Self::Error> {
1145 Err(ExtractError)
1146 }
1147
1148 fn serialize_unit_variant(
1149 self,
1150 _: &'static str,
1151 _: u32,
1152 _: &'static str,
1153 ) -> Result<Self::Ok, Self::Error> {
1154 Err(ExtractError)
1155 }
1156
1157 fn serialize_newtype_struct<T>(
1158 self,
1159 _: &'static str,
1160 value: &T,
1161 ) -> Result<Self::Ok, Self::Error>
1162 where
1163 T: ?Sized + Serialize,
1164 {
1165 value.serialize(self)
1166 }
1167
1168 fn serialize_newtype_variant<T>(
1169 self,
1170 _: &'static str,
1171 _: u32,
1172 _: &'static str,
1173 value: &T,
1174 ) -> Result<Self::Ok, Self::Error>
1175 where
1176 T: ?Sized + Serialize,
1177 {
1178 value.serialize(self)
1179 }
1180
1181 fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
1182 Ok(self)
1183 }
1184
1185 fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple, Self::Error> {
1186 Ok(self)
1187 }
1188
1189 fn serialize_tuple_struct(
1190 self,
1191 _: &'static str,
1192 _: usize,
1193 ) -> Result<Self::SerializeTupleStruct, Self::Error> {
1194 Ok(self)
1195 }
1196
1197 fn serialize_tuple_variant(
1198 self,
1199 _: &'static str,
1200 _: u32,
1201 _: &'static str,
1202 _: usize,
1203 ) -> Result<Self::SerializeTupleVariant, Self::Error> {
1204 Ok(self)
1205 }
1206
1207 fn serialize_map(self, _: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
1208 Err(ExtractError)
1209 }
1210
1211 fn serialize_struct(
1212 self,
1213 _: &'static str,
1214 _: usize,
1215 ) -> Result<Self::SerializeStruct, Self::Error> {
1216 Err(ExtractError)
1217 }
1218
1219 fn serialize_struct_variant(
1220 self,
1221 _: &'static str,
1222 _: u32,
1223 _: &'static str,
1224 _: usize,
1225 ) -> Result<Self::SerializeStructVariant, Self::Error> {
1226 Err(ExtractError)
1227 }
1228 }
1229
1230 impl<'a> SerializeSeq for Extract<'a> {
1231 type Ok = Vec<Link>;
1232 type Error = ExtractError;
1233
1234 fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
1235 where
1236 T: ?Sized + Serialize,
1237 {
1238 self.links.push(value.serialize(ParseLink {
1239 trace_flags: self.trace_flags,
1240 is_remote: self.is_remote,
1241 trace_state: self.trace_state,
1242 })?);
1243
1244 Ok(())
1245 }
1246
1247 fn end(self) -> Result<Self::Ok, Self::Error> {
1248 Ok(self.links)
1249 }
1250 }
1251
1252 impl<'a> SerializeTuple for Extract<'a> {
1253 type Ok = Vec<Link>;
1254 type Error = ExtractError;
1255
1256 fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
1257 where
1258 T: ?Sized + Serialize,
1259 {
1260 self.links.push(value.serialize(ParseLink {
1261 trace_flags: self.trace_flags,
1262 is_remote: self.is_remote,
1263 trace_state: self.trace_state,
1264 })?);
1265
1266 Ok(())
1267 }
1268
1269 fn end(self) -> Result<Self::Ok, Self::Error> {
1270 Ok(self.links)
1271 }
1272 }
1273
1274 impl<'a> SerializeTupleStruct for Extract<'a> {
1275 type Ok = Vec<Link>;
1276 type Error = ExtractError;
1277
1278 fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
1279 where
1280 T: ?Sized + Serialize,
1281 {
1282 self.links.push(value.serialize(ParseLink {
1283 trace_flags: self.trace_flags,
1284 is_remote: self.is_remote,
1285 trace_state: self.trace_state,
1286 })?);
1287
1288 Ok(())
1289 }
1290
1291 fn end(self) -> Result<Self::Ok, Self::Error> {
1292 Ok(self.links)
1293 }
1294 }
1295
1296 impl<'a> SerializeTupleVariant for Extract<'a> {
1297 type Ok = Vec<Link>;
1298 type Error = ExtractError;
1299
1300 fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
1301 where
1302 T: ?Sized + Serialize,
1303 {
1304 self.links.push(value.serialize(ParseLink {
1305 trace_flags: self.trace_flags,
1306 is_remote: self.is_remote,
1307 trace_state: &self.trace_state,
1308 })?);
1309
1310 Ok(())
1311 }
1312
1313 fn end(self) -> Result<Self::Ok, Self::Error> {
1314 Ok(self.links)
1315 }
1316 }
1317
1318 struct ParseLink<'a> {
1319 trace_flags: TraceFlags,
1320 is_remote: bool,
1321 trace_state: &'a TraceState,
1322 }
1323
1324 impl<'a> Serializer for ParseLink<'a> {
1325 type Ok = Link;
1326 type Error = ExtractError;
1327 type SerializeSeq = Impossible<Self::Ok, Self::Error>;
1328 type SerializeTuple = Impossible<Self::Ok, Self::Error>;
1329 type SerializeTupleStruct = Impossible<Self::Ok, Self::Error>;
1330 type SerializeTupleVariant = Impossible<Self::Ok, Self::Error>;
1331 type SerializeMap = Impossible<Self::Ok, Self::Error>;
1332 type SerializeStruct = Impossible<Self::Ok, Self::Error>;
1333 type SerializeStructVariant = Impossible<Self::Ok, Self::Error>;
1334
1335 fn serialize_bool(self, _: bool) -> Result<Self::Ok, Self::Error> {
1336 Err(ExtractError)
1337 }
1338
1339 fn serialize_i8(self, _: i8) -> Result<Self::Ok, Self::Error> {
1340 Err(ExtractError)
1341 }
1342
1343 fn serialize_i16(self, _: i16) -> Result<Self::Ok, Self::Error> {
1344 Err(ExtractError)
1345 }
1346
1347 fn serialize_i32(self, _: i32) -> Result<Self::Ok, Self::Error> {
1348 Err(ExtractError)
1349 }
1350
1351 fn serialize_i64(self, _: i64) -> Result<Self::Ok, Self::Error> {
1352 Err(ExtractError)
1353 }
1354
1355 fn serialize_u8(self, _: u8) -> Result<Self::Ok, Self::Error> {
1356 Err(ExtractError)
1357 }
1358
1359 fn serialize_u16(self, _: u16) -> Result<Self::Ok, Self::Error> {
1360 Err(ExtractError)
1361 }
1362
1363 fn serialize_u32(self, _: u32) -> Result<Self::Ok, Self::Error> {
1364 Err(ExtractError)
1365 }
1366
1367 fn serialize_u64(self, _: u64) -> Result<Self::Ok, Self::Error> {
1368 Err(ExtractError)
1369 }
1370
1371 fn serialize_f32(self, _: f32) -> Result<Self::Ok, Self::Error> {
1372 Err(ExtractError)
1373 }
1374
1375 fn serialize_f64(self, _: f64) -> Result<Self::Ok, Self::Error> {
1376 Err(ExtractError)
1377 }
1378
1379 fn serialize_char(self, _: char) -> Result<Self::Ok, Self::Error> {
1380 Err(ExtractError)
1381 }
1382
1383 fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
1384 let link = emit::span::SpanLink::try_from_str(v).map_err(|_| ExtractError)?;
1385
1386 Ok(Link::new(
1387 SpanContext::new(
1388 otel_trace_id(*link.trace_id()),
1389 otel_span_id(*link.span_id()),
1390 self.trace_flags,
1391 self.is_remote,
1392 self.trace_state.clone(),
1393 ),
1394 Vec::new(),
1395 0,
1396 ))
1397 }
1398
1399 fn serialize_bytes(self, _: &[u8]) -> Result<Self::Ok, Self::Error> {
1400 Err(ExtractError)
1401 }
1402
1403 fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
1404 Err(ExtractError)
1405 }
1406
1407 fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
1408 where
1409 T: ?Sized + Serialize,
1410 {
1411 value.serialize(self)
1412 }
1413
1414 fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
1415 Err(ExtractError)
1416 }
1417
1418 fn serialize_unit_struct(self, _: &'static str) -> Result<Self::Ok, Self::Error> {
1419 Err(ExtractError)
1420 }
1421
1422 fn serialize_unit_variant(
1423 self,
1424 _: &'static str,
1425 _: u32,
1426 _: &'static str,
1427 ) -> Result<Self::Ok, Self::Error> {
1428 Err(ExtractError)
1429 }
1430
1431 fn serialize_newtype_struct<T>(
1432 self,
1433 _: &'static str,
1434 value: &T,
1435 ) -> Result<Self::Ok, Self::Error>
1436 where
1437 T: ?Sized + Serialize,
1438 {
1439 value.serialize(self)
1440 }
1441
1442 fn serialize_newtype_variant<T>(
1443 self,
1444 _: &'static str,
1445 _: u32,
1446 _: &'static str,
1447 value: &T,
1448 ) -> Result<Self::Ok, Self::Error>
1449 where
1450 T: ?Sized + Serialize,
1451 {
1452 value.serialize(self)
1453 }
1454
1455 fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
1456 Err(ExtractError)
1457 }
1458
1459 fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple, Self::Error> {
1460 Err(ExtractError)
1461 }
1462
1463 fn serialize_tuple_struct(
1464 self,
1465 _: &'static str,
1466 _: usize,
1467 ) -> Result<Self::SerializeTupleStruct, Self::Error> {
1468 Err(ExtractError)
1469 }
1470
1471 fn serialize_tuple_variant(
1472 self,
1473 _: &'static str,
1474 _: u32,
1475 _: &'static str,
1476 _: usize,
1477 ) -> Result<Self::SerializeTupleVariant, Self::Error> {
1478 Err(ExtractError)
1479 }
1480
1481 fn serialize_map(self, _: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
1482 Err(ExtractError)
1483 }
1484
1485 fn serialize_struct(
1486 self,
1487 _: &'static str,
1488 _: usize,
1489 ) -> Result<Self::SerializeStruct, Self::Error> {
1490 Err(ExtractError)
1491 }
1492
1493 fn serialize_struct_variant(
1494 self,
1495 _: &'static str,
1496 _: u32,
1497 _: &'static str,
1498 _: usize,
1499 ) -> Result<Self::SerializeStructVariant, Self::Error> {
1500 Err(ExtractError)
1501 }
1502 }
1503
1504 v.serialize(Extract {
1505 links: Vec::new(),
1506 trace_flags,
1507 is_remote,
1508 trace_state,
1509 })
1510 .unwrap_or_default()
1511}
1512
1513mod any_value {
1514 use std::{collections::HashMap, fmt};
1515
1516 use opentelemetry::{logs::AnyValue, Key, StringValue};
1517 use serde::ser::{
1518 Error, Serialize, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant,
1519 SerializeTuple, SerializeTupleStruct, SerializeTupleVariant, Serializer, StdError,
1520 };
1521
1522 pub(crate) fn serialize(value: impl Serialize) -> Result<Option<AnyValue>, ()> {
1531 value.serialize(ValueSerializer).map_err(|_| ())
1532 }
1533
1534 struct ValueSerializer;
1535
1536 struct ValueSerializeSeq {
1537 value: Vec<AnyValue>,
1538 }
1539
1540 struct ValueSerializeTuple {
1541 value: Vec<AnyValue>,
1542 }
1543
1544 struct ValueSerializeTupleStruct {
1545 value: Vec<AnyValue>,
1546 }
1547
1548 struct ValueSerializeMap {
1549 key: Option<Key>,
1550 value: HashMap<Key, AnyValue>,
1551 }
1552
1553 struct ValueSerializeStruct {
1554 value: HashMap<Key, AnyValue>,
1555 }
1556
1557 struct ValueSerializeTupleVariant {
1558 variant: &'static str,
1559 value: Vec<AnyValue>,
1560 }
1561
1562 struct ValueSerializeStructVariant {
1563 variant: &'static str,
1564 value: HashMap<Key, AnyValue>,
1565 }
1566
1567 #[derive(Debug)]
1568 struct ValueError(String);
1569
1570 impl fmt::Display for ValueError {
1571 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1572 fmt::Display::fmt(&self.0, f)
1573 }
1574 }
1575
1576 impl Error for ValueError {
1577 fn custom<T>(msg: T) -> Self
1578 where
1579 T: fmt::Display,
1580 {
1581 ValueError(msg.to_string())
1582 }
1583 }
1584
1585 impl StdError for ValueError {}
1586
1587 impl Serializer for ValueSerializer {
1588 type Ok = Option<AnyValue>;
1589
1590 type Error = ValueError;
1591
1592 type SerializeSeq = ValueSerializeSeq;
1593
1594 type SerializeTuple = ValueSerializeTuple;
1595
1596 type SerializeTupleStruct = ValueSerializeTupleStruct;
1597
1598 type SerializeTupleVariant = ValueSerializeTupleVariant;
1599
1600 type SerializeMap = ValueSerializeMap;
1601
1602 type SerializeStruct = ValueSerializeStruct;
1603
1604 type SerializeStructVariant = ValueSerializeStructVariant;
1605
1606 fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
1607 Ok(Some(AnyValue::Boolean(v)))
1608 }
1609
1610 fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
1611 self.serialize_i64(v as i64)
1612 }
1613
1614 fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
1615 self.serialize_i64(v as i64)
1616 }
1617
1618 fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
1619 self.serialize_i64(v as i64)
1620 }
1621
1622 fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
1623 Ok(Some(AnyValue::Int(v)))
1624 }
1625
1626 fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
1627 if let Ok(v) = v.try_into() {
1628 self.serialize_i64(v)
1629 } else {
1630 self.collect_str(&v)
1631 }
1632 }
1633
1634 fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
1635 self.serialize_i64(v as i64)
1636 }
1637
1638 fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
1639 self.serialize_i64(v as i64)
1640 }
1641
1642 fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
1643 self.serialize_i64(v as i64)
1644 }
1645
1646 fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
1647 if let Ok(v) = v.try_into() {
1648 self.serialize_i64(v)
1649 } else {
1650 self.collect_str(&v)
1651 }
1652 }
1653
1654 fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
1655 if let Ok(v) = v.try_into() {
1656 self.serialize_i64(v)
1657 } else {
1658 self.collect_str(&v)
1659 }
1660 }
1661
1662 fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
1663 self.serialize_f64(v as f64)
1664 }
1665
1666 fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
1667 Ok(Some(AnyValue::Double(v)))
1668 }
1669
1670 fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
1671 self.collect_str(&v)
1672 }
1673
1674 fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
1675 Ok(Some(AnyValue::String(StringValue::from(v.to_owned()))))
1676 }
1677
1678 fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
1679 Ok(Some(AnyValue::Bytes(Box::new(v.to_owned()))))
1680 }
1681
1682 fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
1683 Ok(None)
1684 }
1685
1686 fn serialize_some<T: serde::Serialize + ?Sized>(
1687 self,
1688 value: &T,
1689 ) -> Result<Self::Ok, Self::Error> {
1690 value.serialize(self)
1691 }
1692
1693 fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
1694 Ok(None)
1695 }
1696
1697 fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
1698 name.serialize(self)
1699 }
1700
1701 fn serialize_unit_variant(
1702 self,
1703 _: &'static str,
1704 _: u32,
1705 variant: &'static str,
1706 ) -> Result<Self::Ok, Self::Error> {
1707 variant.serialize(self)
1708 }
1709
1710 fn serialize_newtype_struct<T: serde::Serialize + ?Sized>(
1711 self,
1712 _: &'static str,
1713 value: &T,
1714 ) -> Result<Self::Ok, Self::Error> {
1715 value.serialize(self)
1716 }
1717
1718 fn serialize_newtype_variant<T: serde::Serialize + ?Sized>(
1719 self,
1720 _: &'static str,
1721 _: u32,
1722 variant: &'static str,
1723 value: &T,
1724 ) -> Result<Self::Ok, Self::Error> {
1725 let mut map = self.serialize_map(Some(1))?;
1726 map.serialize_entry(variant, value)?;
1727 map.end()
1728 }
1729
1730 fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
1731 Ok(ValueSerializeSeq { value: Vec::new() })
1732 }
1733
1734 fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple, Self::Error> {
1735 Ok(ValueSerializeTuple { value: Vec::new() })
1736 }
1737
1738 fn serialize_tuple_struct(
1739 self,
1740 _: &'static str,
1741 _: usize,
1742 ) -> Result<Self::SerializeTupleStruct, Self::Error> {
1743 Ok(ValueSerializeTupleStruct { value: Vec::new() })
1744 }
1745
1746 fn serialize_tuple_variant(
1747 self,
1748 _: &'static str,
1749 _: u32,
1750 variant: &'static str,
1751 _: usize,
1752 ) -> Result<Self::SerializeTupleVariant, Self::Error> {
1753 Ok(ValueSerializeTupleVariant {
1754 variant,
1755 value: Vec::new(),
1756 })
1757 }
1758
1759 fn serialize_map(self, _: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
1760 Ok(ValueSerializeMap {
1761 key: None,
1762 value: HashMap::new(),
1763 })
1764 }
1765
1766 fn serialize_struct(
1767 self,
1768 _: &'static str,
1769 _: usize,
1770 ) -> Result<Self::SerializeStruct, Self::Error> {
1771 Ok(ValueSerializeStruct {
1772 value: HashMap::new(),
1773 })
1774 }
1775
1776 fn serialize_struct_variant(
1777 self,
1778 _: &'static str,
1779 _: u32,
1780 variant: &'static str,
1781 _: usize,
1782 ) -> Result<Self::SerializeStructVariant, Self::Error> {
1783 Ok(ValueSerializeStructVariant {
1784 variant,
1785 value: HashMap::new(),
1786 })
1787 }
1788 }
1789
1790 impl SerializeSeq for ValueSerializeSeq {
1791 type Ok = Option<AnyValue>;
1792
1793 type Error = ValueError;
1794
1795 fn serialize_element<T: serde::Serialize + ?Sized>(
1796 &mut self,
1797 value: &T,
1798 ) -> Result<(), Self::Error> {
1799 if let Some(value) = value.serialize(ValueSerializer)? {
1800 self.value.push(value);
1801 }
1802
1803 Ok(())
1804 }
1805
1806 fn end(self) -> Result<Self::Ok, Self::Error> {
1807 Ok(Some(AnyValue::ListAny(Box::new(self.value))))
1808 }
1809 }
1810
1811 impl SerializeTuple for ValueSerializeTuple {
1812 type Ok = Option<AnyValue>;
1813
1814 type Error = ValueError;
1815
1816 fn serialize_element<T: serde::Serialize + ?Sized>(
1817 &mut self,
1818 value: &T,
1819 ) -> Result<(), Self::Error> {
1820 if let Some(value) = value.serialize(ValueSerializer)? {
1821 self.value.push(value);
1822 }
1823
1824 Ok(())
1825 }
1826
1827 fn end(self) -> Result<Self::Ok, Self::Error> {
1828 Ok(Some(AnyValue::ListAny(Box::new(self.value))))
1829 }
1830 }
1831
1832 impl SerializeTupleStruct for ValueSerializeTupleStruct {
1833 type Ok = Option<AnyValue>;
1834
1835 type Error = ValueError;
1836
1837 fn serialize_field<T: serde::Serialize + ?Sized>(
1838 &mut self,
1839 value: &T,
1840 ) -> Result<(), Self::Error> {
1841 if let Some(value) = value.serialize(ValueSerializer)? {
1842 self.value.push(value);
1843 }
1844
1845 Ok(())
1846 }
1847
1848 fn end(self) -> Result<Self::Ok, Self::Error> {
1849 Ok(Some(AnyValue::ListAny(Box::new(self.value))))
1850 }
1851 }
1852
1853 impl SerializeTupleVariant for ValueSerializeTupleVariant {
1854 type Ok = Option<AnyValue>;
1855
1856 type Error = ValueError;
1857
1858 fn serialize_field<T: serde::Serialize + ?Sized>(
1859 &mut self,
1860 value: &T,
1861 ) -> Result<(), Self::Error> {
1862 if let Some(value) = value.serialize(ValueSerializer)? {
1863 self.value.push(value);
1864 }
1865
1866 Ok(())
1867 }
1868
1869 fn end(self) -> Result<Self::Ok, Self::Error> {
1870 Ok(Some(AnyValue::Map({
1871 let mut variant = HashMap::new();
1872 variant.insert(
1873 Key::from(self.variant),
1874 AnyValue::ListAny(Box::new(self.value)),
1875 );
1876 Box::new(variant)
1877 })))
1878 }
1879 }
1880
1881 impl SerializeMap for ValueSerializeMap {
1882 type Ok = Option<AnyValue>;
1883
1884 type Error = ValueError;
1885
1886 fn serialize_key<T: serde::Serialize + ?Sized>(
1887 &mut self,
1888 key: &T,
1889 ) -> Result<(), Self::Error> {
1890 let key = match key.serialize(ValueSerializer)? {
1891 Some(AnyValue::String(key)) => Key::from(String::from(key)),
1892 key => Key::from(format!("{:?}", key)),
1893 };
1894
1895 self.key = Some(key);
1896
1897 Ok(())
1898 }
1899
1900 fn serialize_value<T: serde::Serialize + ?Sized>(
1901 &mut self,
1902 value: &T,
1903 ) -> Result<(), Self::Error> {
1904 let key = self
1905 .key
1906 .take()
1907 .ok_or_else(|| Self::Error::custom("missing key"))?;
1908
1909 if let Some(value) = value.serialize(ValueSerializer)? {
1910 self.value.insert(key, value);
1911 }
1912
1913 Ok(())
1914 }
1915
1916 fn end(self) -> Result<Self::Ok, Self::Error> {
1917 Ok(Some(AnyValue::Map(Box::new(self.value))))
1918 }
1919 }
1920
1921 impl SerializeStruct for ValueSerializeStruct {
1922 type Ok = Option<AnyValue>;
1923
1924 type Error = ValueError;
1925
1926 fn serialize_field<T: serde::Serialize + ?Sized>(
1927 &mut self,
1928 key: &'static str,
1929 value: &T,
1930 ) -> Result<(), Self::Error> {
1931 let key = Key::from(key);
1932
1933 if let Some(value) = value.serialize(ValueSerializer)? {
1934 self.value.insert(key, value);
1935 }
1936
1937 Ok(())
1938 }
1939
1940 fn end(self) -> Result<Self::Ok, Self::Error> {
1941 Ok(Some(AnyValue::Map(Box::new(self.value))))
1942 }
1943 }
1944
1945 impl SerializeStructVariant for ValueSerializeStructVariant {
1946 type Ok = Option<AnyValue>;
1947
1948 type Error = ValueError;
1949
1950 fn serialize_field<T: serde::Serialize + ?Sized>(
1951 &mut self,
1952 key: &'static str,
1953 value: &T,
1954 ) -> Result<(), Self::Error> {
1955 let key = Key::from(key);
1956
1957 if let Some(value) = value.serialize(ValueSerializer)? {
1958 self.value.insert(key, value);
1959 }
1960
1961 Ok(())
1962 }
1963
1964 fn end(self) -> Result<Self::Ok, Self::Error> {
1965 Ok(Some(AnyValue::Map({
1966 let mut variant = HashMap::new();
1967 variant.insert(Key::from(self.variant), AnyValue::Map(Box::new(self.value)));
1968 Box::new(variant)
1969 })))
1970 }
1971 }
1972}
1973
1974#[cfg(test)]
1975mod tests {
1976 use std::io;
1977
1978 use super::*;
1979
1980 use emit::runtime::AmbientSlot;
1981
1982 use opentelemetry::trace::{SamplingDecision, SamplingResult, TraceState};
1983
1984 use opentelemetry_sdk::{
1985 logs::{in_memory_exporter::InMemoryLogExporter, SdkLoggerProvider},
1986 trace::{in_memory_exporter::InMemorySpanExporter, SdkTracerProvider},
1987 };
1988
1989 fn build(
1990 slot: &AmbientSlot,
1991 ) -> (
1992 InMemoryLogExporter,
1993 InMemorySpanExporter,
1994 SdkLoggerProvider,
1995 SdkTracerProvider,
1996 ) {
1997 let logger_exporter = InMemoryLogExporter::default();
1998
1999 let logger_provider = SdkLoggerProvider::builder()
2000 .with_simple_exporter(logger_exporter.clone())
2001 .build();
2002
2003 let tracer_exporter = InMemorySpanExporter::default();
2004
2005 let tracer_provider = SdkTracerProvider::builder()
2006 .with_simple_exporter(tracer_exporter.clone())
2007 .build();
2008
2009 let _ = setup(logger_provider.clone(), tracer_provider.clone()).init_slot(slot);
2010
2011 (
2012 logger_exporter,
2013 tracer_exporter,
2014 logger_provider,
2015 tracer_provider,
2016 )
2017 }
2018
2019 #[test]
2020 fn emit_log() {
2021 let slot = AmbientSlot::new();
2022 let (logs, _, _, _) = build(&slot);
2023
2024 emit::emit!(rt: slot.get(), "test {attr}", attr: "log");
2025
2026 let logs = logs.get_emitted_logs().unwrap();
2027
2028 assert_eq!(1, logs.len());
2029
2030 let Some(AnyValue::String(body)) = logs[0].record.body() else {
2031 panic!("unexpected log body value");
2032 };
2033
2034 assert_eq!("test log", body.as_str());
2035 }
2036
2037 #[test]
2038 fn emit_log_trace_context() {
2039 let slot = AmbientSlot::new();
2040 let (logs, _, _, _) = build(&slot);
2041
2042 emit::emit!(rt: slot.get(), "test log", trace_id: "4bf92f3577b34da6a3ce929d0e0e4736", span_id: "00f067aa0ba902b7");
2043
2044 let logs = logs.get_emitted_logs().unwrap();
2045
2046 assert_eq!(1, logs.len());
2047
2048 assert_eq!(
2049 "4bf92f3577b34da6a3ce929d0e0e4736",
2050 logs[0].record.trace_context().unwrap().trace_id.to_string()
2051 );
2052 assert_eq!(
2053 "00f067aa0ba902b7",
2054 logs[0].record.trace_context().unwrap().span_id.to_string()
2055 );
2056 }
2057
2058 #[test]
2059 fn emit_span() {
2060 static SLOT: AmbientSlot = AmbientSlot::new();
2061 let (_, spans, _, _) = build(&SLOT);
2062
2063 #[emit::span(rt: SLOT.get(), "emit {attr}", attr: "span")]
2064 fn emit_span() -> emit::span::SpanCtxt {
2065 emit::span::SpanCtxt::current(SLOT.get().ctxt())
2066 }
2067
2068 let ctxt = emit_span();
2069
2070 let spans = spans.get_finished_spans().unwrap();
2071
2072 assert_eq!(1, spans.len());
2073
2074 assert_eq!("emit {attr}", spans[0].name);
2075
2076 assert_eq!(
2077 ctxt.trace_id().unwrap().to_bytes(),
2078 spans[0].span_context.trace_id().to_bytes()
2079 );
2080 assert_eq!(
2081 ctxt.span_id().unwrap().to_bytes(),
2082 spans[0].span_context.span_id().to_bytes()
2083 );
2084 assert!(ctxt.span_parent().is_none());
2085 assert_eq!(
2086 opentelemetry::trace::SpanId::INVALID,
2087 spans[0].parent_span_id
2088 );
2089 }
2090
2091 #[test]
2092 fn emit_span_direct() {
2093 let slot = AmbientSlot::new();
2094 let (logs, spans, _, _) = build(&slot);
2095
2096 emit::emit!(
2097 rt: slot.get(),
2098 evt: emit::Span::new(
2099 emit::mdl!(),
2100 "test",
2101 "2024-01-01T00:00:00.000Z".parse::<emit::Timestamp>().unwrap().."2024-01-01T00:00:01.000Z".parse::<emit::Timestamp>().unwrap(),
2102 emit::span::SpanCtxt::new_root(slot.get().rng()),
2103 ),
2104 );
2105
2106 let logs = logs.get_emitted_logs().unwrap();
2107 let spans = spans.get_finished_spans().unwrap();
2108
2109 assert_eq!(1, logs.len());
2110 assert_eq!(0, spans.len());
2111 }
2112
2113 #[test]
2114 fn emit_span_otel_span() {
2115 static SLOT: AmbientSlot = AmbientSlot::new();
2116 let (_, spans, _, tracer_provider) = build(&SLOT);
2117
2118 #[emit::span(rt: SLOT.get(), "emit span")]
2119 fn emit_span(tracer_provider: &SdkTracerProvider) -> (SpanContext, emit::span::SpanCtxt) {
2120 fn otel_span(tracer_provider: &SdkTracerProvider) -> SpanContext {
2121 use opentelemetry::trace::TracerProvider;
2122
2123 tracer_provider
2124 .tracer("otel_span")
2125 .in_span("otel span", |cx| cx.span().span_context().clone())
2126 }
2127
2128 (
2129 otel_span(&tracer_provider),
2130 emit::span::SpanCtxt::current(SLOT.get().ctxt()),
2131 )
2132 }
2133
2134 let (otel_ctxt, emit_ctxt) = emit_span(&tracer_provider);
2135
2136 let spans = spans.get_finished_spans().unwrap();
2137
2138 assert_eq!(2, spans.len());
2139
2140 assert_eq!(
2141 otel_ctxt.trace_id().to_bytes(),
2142 emit_ctxt.trace_id().unwrap().to_bytes()
2143 );
2144
2145 assert_eq!("otel span", spans[0].name);
2146
2147 assert_eq!(
2148 otel_ctxt.trace_id().to_bytes(),
2149 spans[0].span_context.trace_id().to_bytes()
2150 );
2151 assert_eq!(
2152 otel_ctxt.span_id().to_bytes(),
2153 spans[0].span_context.span_id().to_bytes()
2154 );
2155 assert_eq!(
2156 emit_ctxt.span_id().unwrap().to_bytes(),
2157 spans[0].parent_span_id.to_bytes()
2158 );
2159
2160 assert_eq!("emit span", spans[1].name);
2161
2162 assert_eq!(
2163 emit_ctxt.trace_id().unwrap().to_bytes(),
2164 spans[1].span_context.trace_id().to_bytes()
2165 );
2166 assert_eq!(
2167 emit_ctxt.span_id().unwrap().to_bytes(),
2168 spans[1].span_context.span_id().to_bytes()
2169 );
2170 assert!(emit_ctxt.span_parent().is_none());
2171 }
2172
2173 #[test]
2174 fn emit_span_otel_log() {
2175 static SLOT: AmbientSlot = AmbientSlot::new();
2176 let (logs, _, logger_provider, _) = build(&SLOT);
2177
2178 #[emit::span(rt: SLOT.get(), "emit span")]
2179 fn emit_span(logger_provider: &SdkLoggerProvider) -> emit::span::SpanCtxt {
2180 use opentelemetry::logs::LoggerProvider;
2181
2182 let logger = logger_provider.logger("otel_logger");
2183
2184 let mut log = logger.create_log_record();
2185
2186 log.set_body(AnyValue::String("test log".into()));
2187
2188 logger.emit(log);
2189
2190 emit::span::SpanCtxt::current(SLOT.get().ctxt())
2191 }
2192
2193 let ctxt = emit_span(&logger_provider);
2194
2195 let logs = logs.get_emitted_logs().unwrap();
2196
2197 assert_eq!(1, logs.len());
2198
2199 assert!(logs[0]
2200 .record
2201 .trace_context()
2202 .unwrap()
2203 .trace_flags
2204 .unwrap()
2205 .is_sampled());
2206
2207 assert_eq!(
2208 ctxt.trace_id().unwrap().to_bytes(),
2209 logs[0].record.trace_context().unwrap().trace_id.to_bytes()
2210 );
2211 assert_eq!(
2212 ctxt.span_id().unwrap().to_bytes(),
2213 logs[0].record.trace_context().unwrap().span_id.to_bytes()
2214 );
2215 }
2216
2217 #[test]
2218 fn emit_span_span_name() {
2219 static SLOT: AmbientSlot = AmbientSlot::new();
2220 let (_, spans, _, _) = build(&SLOT);
2221
2222 #[emit::span(rt: SLOT.get(), "emit span", span_name: "custom name")]
2223 fn emit_span() {}
2224
2225 emit_span();
2226
2227 let spans = spans.get_finished_spans().unwrap();
2228
2229 assert_eq!(1, spans.len());
2230
2231 assert_eq!("custom name", spans[0].name);
2232 }
2233
2234 #[test]
2235 fn emit_span_span_kind() {
2236 static SLOT: AmbientSlot = AmbientSlot::new();
2237 let (_, spans, _, _) = build(&SLOT);
2238
2239 #[emit::span(rt: SLOT.get(), "emit span", span_kind: "producer")]
2240 fn emit_span() {}
2241
2242 emit_span();
2243
2244 let spans = spans.get_finished_spans().unwrap();
2245
2246 assert_eq!(1, spans.len());
2247
2248 assert_eq!(SpanKind::Producer, spans[0].span_kind);
2249 }
2250
2251 #[test]
2252 fn emit_span_span_links() {
2253 static SLOT: AmbientSlot = AmbientSlot::new();
2254 let (_, spans, _, _) = build(&SLOT);
2255
2256 #[emit::span(
2257 rt: SLOT.get(),
2258 "emit span",
2259 #[emit::as_serde]
2260 span_links: [
2261 "4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7",
2262 ],
2263 )]
2264 fn emit_span() {}
2265
2266 emit_span();
2267
2268 let spans = spans.get_finished_spans().unwrap();
2269
2270 assert_eq!(1, spans.len());
2271
2272 assert_eq!(1, spans[0].links.links.len());
2273
2274 assert_eq!(
2275 "4bf92f3577b34da6a3ce929d0e0e4736",
2276 spans[0].links.links[0].span_context.trace_id().to_string()
2277 );
2278 assert_eq!(
2279 "00f067aa0ba902b7",
2280 spans[0].links.links[0].span_context.span_id().to_string()
2281 );
2282 }
2283
2284 #[test]
2285 fn emit_span_ok() {
2286 static SLOT: AmbientSlot = AmbientSlot::new();
2287 let (_, spans, _, _) = build(&SLOT);
2288
2289 #[emit::span(rt: SLOT.get(), ok_lvl: "info", "emit span")]
2290 fn emit_span() -> Result<(), io::Error> {
2291 Ok(())
2292 }
2293
2294 let _ = emit_span();
2295
2296 let spans = spans.get_finished_spans().unwrap();
2297
2298 assert_eq!(1, spans.len());
2299
2300 assert_eq!(Status::Ok, spans[0].status);
2301 }
2302
2303 #[test]
2304 fn emit_span_err() {
2305 static SLOT: AmbientSlot = AmbientSlot::new();
2306 let (_, spans, _, _) = build(&SLOT);
2307
2308 #[emit::span(rt: SLOT.get(), err_lvl: "error", "emit span")]
2309 fn emit_span() -> Result<(), io::Error> {
2310 Err(io::Error::new(io::ErrorKind::Other, "something failed!"))
2311 }
2312
2313 let _ = emit_span();
2314
2315 let spans = spans.get_finished_spans().unwrap();
2316
2317 assert_eq!(1, spans.len());
2318
2319 assert_eq!(Status::error("something failed!"), spans[0].status);
2320 }
2321
2322 #[test]
2323 fn emit_span_lvl_err() {
2324 static SLOT: AmbientSlot = AmbientSlot::new();
2325 let (_, spans, _, _) = build(&SLOT);
2326
2327 #[emit::span(rt: SLOT.get(), ok_lvl: "error", "emit span")]
2328 fn emit_span() -> Result<(), io::Error> {
2329 Ok(())
2330 }
2331
2332 let _ = emit_span();
2333
2334 let spans = spans.get_finished_spans().unwrap();
2335
2336 assert_eq!(1, spans.len());
2337
2338 assert_eq!(Status::error("error"), spans[0].status);
2339 }
2340
2341 #[test]
2342 fn emit_span_unsampled_otel_span() {
2343 static SLOT: AmbientSlot = AmbientSlot::new();
2344 let (_, spans, _, tracer_provider) = build(&SLOT);
2345
2346 #[emit::span(rt: SLOT.get(), when: emit::filter::from_fn(|_| false), "emit span")]
2347 fn emit_span(tracer_provider: &SdkTracerProvider) -> SpanContext {
2348 fn otel_span(tracer_provider: &SdkTracerProvider) -> SpanContext {
2349 use opentelemetry::trace::TracerProvider;
2350
2351 tracer_provider
2352 .tracer("otel_span")
2353 .in_span("otel span", |cx| cx.span().span_context().clone())
2354 }
2355
2356 otel_span(&tracer_provider)
2357 }
2358
2359 let otel_ctxt = emit_span(&tracer_provider);
2360
2361 let spans = spans.get_finished_spans().unwrap();
2362
2363 assert_eq!(0, spans.len());
2364
2365 assert!(!otel_ctxt.is_sampled());
2366 }
2367
2368 #[test]
2369 fn emit_span_unsampled_emit_span() {
2370 static SLOT: AmbientSlot = AmbientSlot::new();
2371 let (_, spans, _, _) = build(&SLOT);
2372
2373 #[emit::span(rt: SLOT.get(), when: emit::filter::from_fn(|_| false), "emit span")]
2374 fn emit_span_outer() {
2375 #[emit::span(rt: SLOT.get(), "emit span")]
2376 fn emit_span_inner() {}
2377
2378 emit_span_inner()
2379 }
2380
2381 emit_span_outer();
2382
2383 let spans = spans.get_finished_spans().unwrap();
2384
2385 assert_eq!(0, spans.len());
2386 }
2387
2388 #[test]
2389 fn emit_span_unsampled_otel_log() {
2390 static SLOT: AmbientSlot = AmbientSlot::new();
2391 let (logs, _, logger_provider, _) = build(&SLOT);
2392
2393 #[emit::span(rt: SLOT.get(), when: emit::filter::from_fn(|_| false), "emit span")]
2394 fn emit_span(logger_provider: &SdkLoggerProvider) -> emit::span::SpanCtxt {
2395 use opentelemetry::logs::LoggerProvider;
2396
2397 let logger = logger_provider.logger("otel_logger");
2398
2399 let mut log = logger.create_log_record();
2400
2401 log.set_body(AnyValue::String("test log".into()));
2402
2403 logger.emit(log);
2404
2405 emit::span::SpanCtxt::current(SLOT.get().ctxt())
2406 }
2407
2408 let ctxt = emit_span(&logger_provider);
2409
2410 let logs = logs.get_emitted_logs().unwrap();
2411
2412 assert_eq!(1, logs.len());
2413
2414 assert!(!logs[0]
2415 .record
2416 .trace_context()
2417 .unwrap()
2418 .trace_flags
2419 .unwrap()
2420 .is_sampled());
2421
2422 assert_eq!(
2423 ctxt.trace_id().unwrap().to_bytes(),
2424 logs[0].record.trace_context().unwrap().trace_id.to_bytes()
2425 );
2426 assert_eq!(
2427 ctxt.span_id().unwrap().to_bytes(),
2428 logs[0].record.trace_context().unwrap().span_id.to_bytes()
2429 );
2430 }
2431
2432 #[test]
2433 fn emit_ctxt_clear_otel_ctxt() {
2434 static SLOT: AmbientSlot = AmbientSlot::new();
2435 let (_, _, _, tracer_provider) = build(&SLOT);
2436
2437 fn otel_span(tracer_provider: &SdkTracerProvider) -> SpanContext {
2438 use opentelemetry::trace::TracerProvider;
2439
2440 tracer_provider
2441 .tracer("otel_span")
2442 .in_span("otel span", |_| {
2443 emit::Frame::root(SLOT.get().ctxt(), emit::Empty)
2444 .call(|| Context::current().span().span_context().clone())
2445 })
2446 }
2447
2448 let cx = otel_span(&tracer_provider);
2449
2450 assert_eq!(SpanContext::NONE, cx);
2451 }
2452
2453 #[test]
2454 fn emit_ctxt_push_otel_ctxt() {
2455 static SLOT: AmbientSlot = AmbientSlot::new();
2456 let (_, _, _, tracer_provider) = build(&SLOT);
2457
2458 fn otel_span(tracer_provider: &SdkTracerProvider) -> (SpanContext, SpanContext) {
2459 use opentelemetry::trace::TracerProvider;
2460
2461 tracer_provider
2462 .tracer("otel_span")
2463 .in_span("otel span", |_| {
2464 let outer = Context::current().span().span_context().clone();
2465
2466 let inner = emit::Frame::push(SLOT.get().ctxt(), emit::Empty)
2467 .call(|| Context::current().span().span_context().clone());
2468
2469 (outer, inner)
2470 })
2471 }
2472
2473 let (outer, inner) = otel_span(&tracer_provider);
2474
2475 assert_eq!(outer.trace_id(), inner.trace_id());
2476 assert_eq!(outer.span_id(), inner.span_id());
2477 assert_eq!(outer.trace_flags(), inner.trace_flags());
2478 }
2479
2480 #[test]
2481 fn otel_span_emit_span() {
2482 static SLOT: AmbientSlot = AmbientSlot::new();
2483 let (_, spans, _, tracer_provider) = build(&SLOT);
2484
2485 fn otel_span(tracer_provider: &SdkTracerProvider) -> (SpanContext, emit::span::SpanCtxt) {
2486 use opentelemetry::trace::TracerProvider;
2487
2488 #[emit::span(rt: SLOT.get(), "emit span")]
2489 fn emit_span() -> emit::span::SpanCtxt {
2490 emit::span::SpanCtxt::current(SLOT.get().ctxt())
2491 }
2492
2493 tracer_provider
2494 .tracer("otel_span")
2495 .in_span("otel span", |cx| {
2496 (cx.span().span_context().clone(), emit_span())
2497 })
2498 }
2499
2500 let (otel_ctxt, emit_ctxt) = otel_span(&tracer_provider);
2501
2502 let spans = spans.get_finished_spans().unwrap();
2503
2504 assert_eq!(2, spans.len());
2505
2506 assert_eq!(
2507 otel_ctxt.trace_id().to_bytes(),
2508 emit_ctxt.trace_id().unwrap().to_bytes()
2509 );
2510
2511 assert_eq!("emit span", spans[0].name);
2512
2513 assert_eq!(
2514 emit_ctxt.trace_id().unwrap().to_bytes(),
2515 spans[0].span_context.trace_id().to_bytes()
2516 );
2517 assert_eq!(
2518 emit_ctxt.span_id().unwrap().to_bytes(),
2519 spans[0].span_context.span_id().to_bytes()
2520 );
2521 assert!(emit_ctxt.span_parent().is_none(),);
2522 assert!(emit_ctxt.span_parent().is_none(),);
2523
2524 assert_eq!("otel span", spans[1].name);
2525
2526 assert_eq!(
2527 otel_ctxt.trace_id().to_bytes(),
2528 spans[1].span_context.trace_id().to_bytes()
2529 );
2530 assert_eq!(
2531 otel_ctxt.span_id().to_bytes(),
2532 spans[1].span_context.span_id().to_bytes()
2533 );
2534 assert_eq!(SpanId::INVALID, spans[1].parent_span_id);
2535 }
2536
2537 #[test]
2538 fn otel_span_emit_log() {
2539 static SLOT: AmbientSlot = AmbientSlot::new();
2540 let (logs, _, _, tracer_provider) = build(&SLOT);
2541
2542 fn otel_span(tracer_provider: &SdkTracerProvider) -> SpanContext {
2543 use opentelemetry::trace::TracerProvider;
2544
2545 tracer_provider
2546 .tracer("otel_span")
2547 .in_span("otel span", |cx| {
2548 emit::emit!(rt: SLOT.get(), "emit event");
2549
2550 cx.span().span_context().clone()
2551 })
2552 }
2553
2554 let ctxt = otel_span(&tracer_provider);
2555
2556 let logs = logs.get_emitted_logs().unwrap();
2557
2558 assert_eq!(1, logs.len());
2559
2560 assert!(logs[0]
2561 .record
2562 .trace_context()
2563 .unwrap()
2564 .trace_flags
2565 .unwrap()
2566 .is_sampled());
2567
2568 assert_eq!(
2569 ctxt.trace_id(),
2570 logs[0].record.trace_context().unwrap().trace_id
2571 );
2572 assert_eq!(
2573 ctxt.span_id(),
2574 logs[0].record.trace_context().unwrap().span_id
2575 );
2576 }
2577
2578 #[test]
2579 fn otel_span_unsampled_emit_span() {
2580 static SLOT: AmbientSlot = AmbientSlot::new();
2581 let (logs, spans, _, tracer_provider) = build(&SLOT);
2582
2583 #[emit::span(rt: SLOT.get(), "emit {attr}", attr: "span")]
2584 fn emit_span() {
2585 emit::emit!(rt: SLOT.get(), "emit event");
2586 }
2587
2588 fn otel_span(tracer_provider: &SdkTracerProvider) {
2589 use opentelemetry::trace::TracerProvider;
2590
2591 let tracer = tracer_provider.tracer("otel_span");
2592
2593 let span = tracer
2594 .span_builder("otel span")
2595 .with_sampling_result(SamplingResult {
2596 decision: SamplingDecision::RecordOnly,
2597 attributes: Vec::new(),
2598 trace_state: TraceState::NONE,
2599 });
2600
2601 let span = span.start(&tracer);
2602 let cx = Context::current_with_span(span);
2603 let _guard = cx.attach();
2604
2605 emit_span();
2606 }
2607
2608 otel_span(&tracer_provider);
2609
2610 let logs = logs.get_emitted_logs().unwrap();
2611 let spans = spans.get_finished_spans().unwrap();
2612
2613 assert_eq!(1, logs.len());
2614 assert_eq!(0, spans.len());
2615
2616 assert!(!logs[0]
2617 .record
2618 .trace_context()
2619 .unwrap()
2620 .trace_flags
2621 .unwrap()
2622 .is_sampled());
2623 }
2624
2625 #[test]
2626 fn otel_span_unsampled_emit_log() {
2627 static SLOT: AmbientSlot = AmbientSlot::new();
2628 let (logs, _, _, tracer_provider) = build(&SLOT);
2629
2630 fn otel_span(tracer_provider: &SdkTracerProvider) -> SpanContext {
2631 use opentelemetry::trace::TracerProvider;
2632
2633 let tracer = tracer_provider.tracer("otel_span");
2634
2635 let span = tracer.span_builder("otel span");
2636
2637 let span = span
2638 .with_sampling_result(SamplingResult {
2639 decision: SamplingDecision::Drop,
2640 attributes: vec![],
2641 trace_state: Default::default(),
2642 })
2643 .start(&tracer);
2644 let cx = Context::current_with_span(span);
2645 let _guard = cx.attach();
2646
2647 emit::emit!(rt: SLOT.get(), "emit event");
2648
2649 Context::current().span().span_context().clone()
2650 }
2651
2652 let ctxt = otel_span(&tracer_provider);
2653
2654 let logs = logs.get_emitted_logs().unwrap();
2655
2656 assert_eq!(1, logs.len());
2657
2658 assert!(!logs[0]
2659 .record
2660 .trace_context()
2661 .unwrap()
2662 .trace_flags
2663 .unwrap()
2664 .is_sampled());
2665
2666 assert_eq!(
2667 ctxt.trace_id(),
2668 logs[0].record.trace_context().unwrap().trace_id
2669 );
2670 assert_eq!(
2671 ctxt.span_id(),
2672 logs[0].record.trace_context().unwrap().span_id
2673 );
2674 }
2675
2676 #[test]
2677 fn emit_value_to_otel_attribute() {
2678 use opentelemetry::Key;
2679 use std::collections::HashMap;
2680
2681 #[derive(serde::Serialize)]
2682 struct Struct {
2683 a: i32,
2684 b: i32,
2685 c: i32,
2686 }
2687
2688 #[derive(serde::Serialize)]
2689 struct Newtype(i32);
2690
2691 #[derive(serde::Serialize)]
2692 enum Enum {
2693 Unit,
2694 Newtype(i32),
2695 Struct { a: i32, b: i32, c: i32 },
2696 Tuple(i32, i32, i32),
2697 }
2698
2699 struct Bytes<B>(B);
2700
2701 impl<B: AsRef<[u8]>> serde::Serialize for Bytes<B> {
2702 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
2703 where
2704 S: serde::Serializer,
2705 {
2706 serializer.serialize_bytes(self.0.as_ref())
2707 }
2708 }
2709
2710 struct Map {
2711 a: i32,
2712 b: i32,
2713 c: i32,
2714 }
2715
2716 impl serde::Serialize for Map {
2717 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
2718 where
2719 S: serde::Serializer,
2720 {
2721 use serde::ser::SerializeMap;
2722
2723 let mut map = serializer.serialize_map(Some(3))?;
2724
2725 map.serialize_entry(&"a", &self.a)?;
2726 map.serialize_entry(&"b", &self.b)?;
2727 map.serialize_entry(&"c", &self.c)?;
2728
2729 map.end()
2730 }
2731 }
2732
2733 let slot = AmbientSlot::new();
2734 let (logs, _, _, _) = build(&slot);
2735
2736 emit::emit!(
2737 rt: slot.get(),
2738 "test log",
2739 str_value: "a string",
2740 u8_value: 1u8,
2741 u16_value: 2u16,
2742 u32_value: 42u32,
2743 u64_value: 2147483660u64,
2744 u128_small_value: 2147483660u128,
2745 u128_big_value: 9223372036854775820u128,
2746 i8_value: 1i8,
2747 i16_value: 2i16,
2748 i32_value: 42i32,
2749 i64_value: 2147483660i64,
2750 i128_small_value: 2147483660i128,
2751 i128_big_value: 9223372036854775820i128,
2752 f64_value: 4.2,
2753 bool_value: true,
2754 #[emit::as_serde]
2755 bytes_value: Bytes([1, 1, 1]),
2756 #[emit::as_serde]
2757 unit_value: (),
2758 #[emit::as_serde]
2759 some_value: Some(42),
2760 #[emit::as_serde]
2761 none_value: None::<i32>,
2762 #[emit::as_serde]
2763 slice_value: [1, 1, 1] as [i32; 3],
2764 #[emit::as_serde]
2765 map_value: Map { a: 1, b: 1, c: 1 },
2766 #[emit::as_serde]
2767 struct_value: Struct { a: 1, b: 1, c: 1 },
2768 #[emit::as_serde]
2769 tuple_value: (1, 1, 1),
2770 #[emit::as_serde]
2771 newtype_value: Newtype(42),
2772 #[emit::as_serde]
2773 unit_variant_value: Enum::Unit,
2774 #[emit::as_serde]
2775 unit_variant_value: Enum::Unit,
2776 #[emit::as_serde]
2777 newtype_variant_value: Enum::Newtype(42),
2778 #[emit::as_serde]
2779 struct_variant_value: Enum::Struct { a: 1, b: 1, c: 1 },
2780 #[emit::as_serde]
2781 tuple_variant_value: Enum::Tuple(1, 1, 1),
2782 );
2783
2784 let logs = logs.get_emitted_logs().unwrap();
2785
2786 let get = |needle: &str| -> Option<AnyValue> {
2787 logs[0].record.attributes_iter().find_map(|(k, v)| {
2788 if k.as_str() == needle {
2789 Some(v.clone())
2790 } else {
2791 None
2792 }
2793 })
2794 };
2795
2796 assert_eq!(
2797 AnyValue::String("a string".into()),
2798 get("str_value").unwrap()
2799 );
2800
2801 assert_eq!(AnyValue::Int(1), get("i8_value").unwrap());
2802 assert_eq!(AnyValue::Int(2), get("i16_value").unwrap());
2803 assert_eq!(AnyValue::Int(42), get("i32_value").unwrap());
2804 assert_eq!(AnyValue::Int(2147483660), get("i64_value").unwrap());
2805 assert_eq!(AnyValue::Int(2147483660), get("i128_small_value").unwrap());
2806 assert_eq!(
2807 AnyValue::String("9223372036854775820".into()),
2808 get("i128_big_value").unwrap()
2809 );
2810
2811 assert_eq!(AnyValue::Double(4.2), get("f64_value").unwrap());
2812
2813 assert_eq!(AnyValue::Boolean(true), get("bool_value").unwrap());
2814
2815 assert_eq!(None, get("unit_value"));
2816 assert_eq!(None, get("none_value"));
2817 assert_eq!(AnyValue::Int(42), get("some_value").unwrap());
2818
2819 assert_eq!(
2820 AnyValue::ListAny(Box::new(vec![
2821 AnyValue::Int(1),
2822 AnyValue::Int(1),
2823 AnyValue::Int(1)
2824 ])),
2825 get("slice_value").unwrap()
2826 );
2827
2828 assert_eq!(
2829 AnyValue::Map({
2830 let mut map = HashMap::<Key, AnyValue>::default();
2831
2832 map.insert(Key::from("a"), AnyValue::Int(1));
2833 map.insert(Key::from("b"), AnyValue::Int(1));
2834 map.insert(Key::from("c"), AnyValue::Int(1));
2835
2836 Box::new(map)
2837 }),
2838 get("map_value").unwrap()
2839 );
2840
2841 assert_eq!(
2842 AnyValue::Map({
2843 let mut map = HashMap::<Key, AnyValue>::default();
2844
2845 map.insert(Key::from("a"), AnyValue::Int(1));
2846 map.insert(Key::from("b"), AnyValue::Int(1));
2847 map.insert(Key::from("c"), AnyValue::Int(1));
2848
2849 Box::new(map)
2850 }),
2851 get("struct_value").unwrap()
2852 );
2853
2854 assert_eq!(
2855 AnyValue::ListAny(Box::new(vec![
2856 AnyValue::Int(1),
2857 AnyValue::Int(1),
2858 AnyValue::Int(1)
2859 ])),
2860 get("tuple_value").unwrap()
2861 );
2862
2863 assert_eq!(
2864 AnyValue::String("Unit".into()),
2865 get("unit_variant_value").unwrap()
2866 );
2867
2868 assert_eq!(
2869 AnyValue::Map({
2870 let mut map = HashMap::new();
2871
2872 map.insert(Key::from("Newtype"), AnyValue::Int(42));
2873
2874 Box::new(map)
2875 }),
2876 get("newtype_variant_value").unwrap()
2877 );
2878
2879 assert_eq!(
2880 AnyValue::Map({
2881 let mut map = HashMap::new();
2882
2883 map.insert(
2884 Key::from("Struct"),
2885 AnyValue::Map({
2886 let mut map = HashMap::new();
2887 map.insert(Key::from("a"), AnyValue::Int(1));
2888 map.insert(Key::from("b"), AnyValue::Int(1));
2889 map.insert(Key::from("c"), AnyValue::Int(1));
2890 Box::new(map)
2891 }),
2892 );
2893
2894 Box::new(map)
2895 }),
2896 get("struct_variant_value").unwrap()
2897 );
2898
2899 assert_eq!(
2900 AnyValue::Map({
2901 let mut map = HashMap::new();
2902
2903 map.insert(
2904 Key::from("Tuple"),
2905 AnyValue::ListAny(Box::new(vec![
2906 AnyValue::Int(1),
2907 AnyValue::Int(1),
2908 AnyValue::Int(1),
2909 ])),
2910 );
2911
2912 Box::new(map)
2913 }),
2914 get("tuple_variant_value").unwrap()
2915 );
2916 }
2917}