1use crate::{
2 field::RecordFields,
3 fmt::{format, FormatEvent, FormatFields, MakeWriter, TestWriter},
4 layer::{self, Context},
5 registry::{self, LookupSpan, SpanRef},
6};
7use alloc::{fmt, format, string::String};
8use core::{any::TypeId, marker::PhantomData, ops::Deref};
9use format::{FmtSpan, TimingDisplay};
10use std::{cell::RefCell, env, eprintln, io, thread_local, time::Instant};
11use tracing_core::{
12 field,
13 span::{Attributes, Current, Id, Record},
14 Event, Metadata, Subscriber,
15};
16
17#[cfg_attr(docsrs, doc(cfg(all(feature = "fmt", feature = "std"))))]
63#[derive(Debug)]
64pub struct Layer<
65 S,
66 N = format::DefaultFields,
67 E = format::Format<format::Full>,
68 W = fn() -> io::Stdout,
69> {
70 make_writer: W,
71 fmt_fields: N,
72 fmt_event: E,
73 fmt_span: format::FmtSpanConfig,
74 is_ansi: bool,
75 log_internal_errors: bool,
76 _inner: PhantomData<fn(S)>,
77}
78
79impl<S> Layer<S> {
80 pub fn new() -> Self {
82 Self::default()
83 }
84}
85
86impl<S, N, E, W> Layer<S, N, E, W>
88where
89 S: Subscriber + for<'a> LookupSpan<'a>,
90 N: for<'writer> FormatFields<'writer> + 'static,
91 W: for<'writer> MakeWriter<'writer> + 'static,
92{
93 pub fn event_format<E2>(self, e: E2) -> Layer<S, N, E2, W>
116 where
117 E2: FormatEvent<S, N> + 'static,
118 {
119 Layer {
120 fmt_fields: self.fmt_fields,
121 fmt_event: e,
122 fmt_span: self.fmt_span,
123 make_writer: self.make_writer,
124 is_ansi: self.is_ansi,
125 log_internal_errors: self.log_internal_errors,
126 _inner: self._inner,
127 }
128 }
129
130 pub fn map_event_format<E2>(self, f: impl FnOnce(E) -> E2) -> Layer<S, N, E2, W>
146 where
147 E2: FormatEvent<S, N> + 'static,
148 {
149 Layer {
150 fmt_fields: self.fmt_fields,
151 fmt_event: f(self.fmt_event),
152 fmt_span: self.fmt_span,
153 make_writer: self.make_writer,
154 is_ansi: self.is_ansi,
155 log_internal_errors: self.log_internal_errors,
156 _inner: self._inner,
157 }
158 }
159}
160
161impl<S, N, E, W> Layer<S, N, E, W> {
163 pub fn with_writer<W2>(self, make_writer: W2) -> Layer<S, N, E, W2>
180 where
181 W2: for<'writer> MakeWriter<'writer> + 'static,
182 {
183 Layer {
184 fmt_fields: self.fmt_fields,
185 fmt_event: self.fmt_event,
186 fmt_span: self.fmt_span,
187 is_ansi: self.is_ansi,
188 log_internal_errors: self.log_internal_errors,
189 make_writer,
190 _inner: self._inner,
191 }
192 }
193
194 pub fn writer(&self) -> &W {
198 &self.make_writer
199 }
200
201 pub fn writer_mut(&mut self) -> &mut W {
229 &mut self.make_writer
230 }
231
232 #[cfg(feature = "ansi")]
239 #[cfg_attr(docsrs, doc(cfg(feature = "ansi")))]
240 pub fn set_ansi(&mut self, ansi: bool) {
241 self.is_ansi = ansi;
242 }
243
244 pub fn set_span_events(&mut self, kind: FmtSpan) {
259 self.fmt_span = format::FmtSpanConfig {
260 kind,
261 fmt_timing: self.fmt_span.fmt_timing,
262 }
263 }
264
265 pub fn with_test_writer(self) -> Layer<S, N, E, TestWriter> {
288 Layer {
289 fmt_fields: self.fmt_fields,
290 fmt_event: self.fmt_event,
291 fmt_span: self.fmt_span,
292 is_ansi: self.is_ansi,
293 log_internal_errors: self.log_internal_errors,
294 make_writer: TestWriter::default(),
295 _inner: self._inner,
296 }
297 }
298
299 pub fn with_ansi(self, ansi: bool) -> Self {
327 #[cfg(not(feature = "ansi"))]
328 if ansi {
329 const ERROR: &str =
330 "tracing-subscriber: the `ansi` crate feature is required to enable ANSI terminal colors";
331 #[cfg(debug_assertions)]
332 panic!("{}", ERROR);
333 #[cfg(not(debug_assertions))]
334 eprintln!("{}", ERROR);
335 }
336
337 Self {
338 is_ansi: ansi,
339 ..self
340 }
341 }
342
343 pub fn log_internal_errors(self, log_internal_errors: bool) -> Self {
355 Self {
356 log_internal_errors,
357 ..self
358 }
359 }
360
361 pub fn map_writer<W2>(self, f: impl FnOnce(W) -> W2) -> Layer<S, N, E, W2>
381 where
382 W2: for<'writer> MakeWriter<'writer> + 'static,
383 {
384 Layer {
385 fmt_fields: self.fmt_fields,
386 fmt_event: self.fmt_event,
387 fmt_span: self.fmt_span,
388 is_ansi: self.is_ansi,
389 log_internal_errors: self.log_internal_errors,
390 make_writer: f(self.make_writer),
391 _inner: self._inner,
392 }
393 }
394}
395
396impl<S, N, L, T, W> Layer<S, N, format::Format<L, T>, W>
397where
398 N: for<'writer> FormatFields<'writer> + 'static,
399{
400 pub fn with_timer<T2>(self, timer: T2) -> Layer<S, N, format::Format<L, T2>, W> {
415 Layer {
416 fmt_event: self.fmt_event.with_timer(timer),
417 fmt_fields: self.fmt_fields,
418 fmt_span: self.fmt_span,
419 make_writer: self.make_writer,
420 is_ansi: self.is_ansi,
421 log_internal_errors: self.log_internal_errors,
422 _inner: self._inner,
423 }
424 }
425
426 pub fn without_time(self) -> Layer<S, N, format::Format<L, ()>, W> {
428 Layer {
429 fmt_event: self.fmt_event.without_time(),
430 fmt_fields: self.fmt_fields,
431 fmt_span: self.fmt_span.without_time(),
432 make_writer: self.make_writer,
433 is_ansi: self.is_ansi,
434 log_internal_errors: self.log_internal_errors,
435 _inner: self._inner,
436 }
437 }
438
439 pub fn with_span_events(self, kind: FmtSpan) -> Self {
481 Layer {
482 fmt_span: self.fmt_span.with_kind(kind),
483 ..self
484 }
485 }
486
487 pub fn with_target(self, display_target: bool) -> Layer<S, N, format::Format<L, T>, W> {
489 Layer {
490 fmt_event: self.fmt_event.with_target(display_target),
491 ..self
492 }
493 }
494 pub fn with_file(self, display_filename: bool) -> Layer<S, N, format::Format<L, T>, W> {
499 Layer {
500 fmt_event: self.fmt_event.with_file(display_filename),
501 ..self
502 }
503 }
504
505 pub fn with_line_number(
510 self,
511 display_line_number: bool,
512 ) -> Layer<S, N, format::Format<L, T>, W> {
513 Layer {
514 fmt_event: self.fmt_event.with_line_number(display_line_number),
515 ..self
516 }
517 }
518
519 pub fn with_level(self, display_level: bool) -> Layer<S, N, format::Format<L, T>, W> {
521 Layer {
522 fmt_event: self.fmt_event.with_level(display_level),
523 ..self
524 }
525 }
526
527 pub fn with_thread_ids(self, display_thread_ids: bool) -> Layer<S, N, format::Format<L, T>, W> {
532 Layer {
533 fmt_event: self.fmt_event.with_thread_ids(display_thread_ids),
534 ..self
535 }
536 }
537
538 pub fn with_thread_names(
543 self,
544 display_thread_names: bool,
545 ) -> Layer<S, N, format::Format<L, T>, W> {
546 Layer {
547 fmt_event: self.fmt_event.with_thread_names(display_thread_names),
548 ..self
549 }
550 }
551
552 pub fn compact(self) -> Layer<S, N, format::Format<format::Compact, T>, W>
554 where
555 N: for<'writer> FormatFields<'writer> + 'static,
556 {
557 Layer {
558 fmt_event: self.fmt_event.compact(),
559 fmt_fields: self.fmt_fields,
560 fmt_span: self.fmt_span,
561 make_writer: self.make_writer,
562 is_ansi: self.is_ansi,
563 log_internal_errors: self.log_internal_errors,
564 _inner: self._inner,
565 }
566 }
567
568 #[cfg(feature = "ansi")]
570 #[cfg_attr(docsrs, doc(cfg(feature = "ansi")))]
571 pub fn pretty(self) -> Layer<S, format::Pretty, format::Format<format::Pretty, T>, W> {
572 Layer {
573 fmt_event: self.fmt_event.pretty(),
574 fmt_fields: format::Pretty::default(),
575 fmt_span: self.fmt_span,
576 make_writer: self.make_writer,
577 is_ansi: self.is_ansi,
578 log_internal_errors: self.log_internal_errors,
579 _inner: self._inner,
580 }
581 }
582
583 #[cfg(feature = "json")]
600 #[cfg_attr(docsrs, doc(cfg(feature = "json")))]
601 pub fn json(self) -> Layer<S, format::JsonFields, format::Format<format::Json, T>, W> {
602 Layer {
603 fmt_event: self.fmt_event.json(),
604 fmt_fields: format::JsonFields::new(),
605 fmt_span: self.fmt_span,
606 make_writer: self.make_writer,
607 is_ansi: false,
609 log_internal_errors: self.log_internal_errors,
610 _inner: self._inner,
611 }
612 }
613}
614
615#[cfg(feature = "json")]
616#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
617impl<S, T, W> Layer<S, format::JsonFields, format::Format<format::Json, T>, W> {
618 pub fn flatten_event(
622 self,
623 flatten_event: bool,
624 ) -> Layer<S, format::JsonFields, format::Format<format::Json, T>, W> {
625 Layer {
626 fmt_event: self.fmt_event.flatten_event(flatten_event),
627 fmt_fields: format::JsonFields::new(),
628 ..self
629 }
630 }
631
632 pub fn with_current_span(
637 self,
638 display_current_span: bool,
639 ) -> Layer<S, format::JsonFields, format::Format<format::Json, T>, W> {
640 Layer {
641 fmt_event: self.fmt_event.with_current_span(display_current_span),
642 fmt_fields: format::JsonFields::new(),
643 ..self
644 }
645 }
646
647 pub fn with_span_list(
652 self,
653 display_span_list: bool,
654 ) -> Layer<S, format::JsonFields, format::Format<format::Json, T>, W> {
655 Layer {
656 fmt_event: self.fmt_event.with_span_list(display_span_list),
657 fmt_fields: format::JsonFields::new(),
658 ..self
659 }
660 }
661}
662
663impl<S, N, E, W> Layer<S, N, E, W> {
664 pub fn fmt_fields<N2>(self, fmt_fields: N2) -> Layer<S, N2, E, W>
667 where
668 N2: for<'writer> FormatFields<'writer> + 'static,
669 {
670 Layer {
671 fmt_event: self.fmt_event,
672 fmt_fields,
673 fmt_span: self.fmt_span,
674 make_writer: self.make_writer,
675 is_ansi: self.is_ansi,
676 log_internal_errors: self.log_internal_errors,
677 _inner: self._inner,
678 }
679 }
680
681 pub fn map_fmt_fields<N2>(self, f: impl FnOnce(N) -> N2) -> Layer<S, N2, E, W>
698 where
699 N2: for<'writer> FormatFields<'writer> + 'static,
700 {
701 Layer {
702 fmt_event: self.fmt_event,
703 fmt_fields: f(self.fmt_fields),
704 fmt_span: self.fmt_span,
705 make_writer: self.make_writer,
706 is_ansi: self.is_ansi,
707 log_internal_errors: self.log_internal_errors,
708 _inner: self._inner,
709 }
710 }
711}
712
713impl<S> Default for Layer<S> {
714 fn default() -> Self {
715 let ansi = cfg!(feature = "ansi") && env::var("NO_COLOR").map_or(true, |v| v.is_empty());
718
719 Layer {
720 fmt_fields: format::DefaultFields::default(),
721 fmt_event: format::Format::default(),
722 fmt_span: format::FmtSpanConfig::default(),
723 make_writer: io::stdout,
724 is_ansi: ansi,
725 log_internal_errors: false,
726 _inner: PhantomData,
727 }
728 }
729}
730
731impl<S, N, E, W> Layer<S, N, E, W>
732where
733 S: Subscriber + for<'a> LookupSpan<'a>,
734 N: for<'writer> FormatFields<'writer> + 'static,
735 E: FormatEvent<S, N> + 'static,
736 W: for<'writer> MakeWriter<'writer> + 'static,
737{
738 #[inline]
739 fn make_ctx<'a>(&'a self, ctx: Context<'a, S>, event: &'a Event<'a>) -> FmtContext<'a, S, N> {
740 FmtContext {
741 ctx,
742 fmt_fields: &self.fmt_fields,
743 event,
744 }
745 }
746}
747
748#[derive(Default)]
758pub struct FormattedFields<E: ?Sized> {
759 _format_fields: PhantomData<fn(E)>,
760 was_ansi: bool,
761 pub fields: String,
763}
764
765impl<E: ?Sized> FormattedFields<E> {
766 pub fn new(fields: String) -> Self {
768 Self {
769 fields,
770 was_ansi: false,
771 _format_fields: PhantomData,
772 }
773 }
774
775 pub fn as_writer(&mut self) -> format::Writer<'_> {
780 format::Writer::new(&mut self.fields).with_ansi(self.was_ansi)
781 }
782}
783
784impl<E: ?Sized> fmt::Debug for FormattedFields<E> {
785 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
786 f.debug_struct("FormattedFields")
787 .field("fields", &self.fields)
788 .field("formatter", &format_args!("{}", std::any::type_name::<E>()))
789 .field("was_ansi", &self.was_ansi)
790 .finish()
791 }
792}
793
794impl<E: ?Sized> fmt::Display for FormattedFields<E> {
795 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
796 fmt::Display::fmt(&self.fields, f)
797 }
798}
799
800impl<E: ?Sized> Deref for FormattedFields<E> {
801 type Target = String;
802 fn deref(&self) -> &Self::Target {
803 &self.fields
804 }
805}
806
807macro_rules! with_event_from_span {
810 ($id:ident, $span:ident, $($field:literal = $value:expr),*, |$event:ident| $code:block) => {
811 let meta = $span.metadata();
812 let cs = meta.callsite();
813 let fs = field::FieldSet::new(&[$($field),*], cs);
814 #[allow(unused)]
815 let mut iter = fs.iter();
816 let v = [$(
817 (&iter.next().unwrap(), ::core::option::Option::Some(&$value as &dyn field::Value)),
818 )*];
819 let vs = fs.value_set(&v);
820 let $event = Event::new_child_of($id, meta, &vs);
821 $code
822 };
823}
824
825impl<S, N, E, W> layer::Layer<S> for Layer<S, N, E, W>
826where
827 S: Subscriber + for<'a> LookupSpan<'a>,
828 N: for<'writer> FormatFields<'writer> + 'static,
829 E: FormatEvent<S, N> + 'static,
830 W: for<'writer> MakeWriter<'writer> + 'static,
831{
832 fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>) {
833 let span = ctx.span(id).expect("Span not found, this is a bug");
834 let mut extensions = span.extensions_mut();
835
836 if extensions.get_mut::<FormattedFields<N>>().is_none() {
837 let mut fields = FormattedFields::<N>::new(String::new());
838 if self
839 .fmt_fields
840 .format_fields(fields.as_writer().with_ansi(self.is_ansi), attrs)
841 .is_ok()
842 {
843 fields.was_ansi = self.is_ansi;
844 extensions.insert(fields);
845 } else {
846 eprintln!(
847 "[tracing-subscriber] Unable to format the following event, ignoring: {:?}",
848 attrs
849 );
850 }
851 }
852
853 if self.fmt_span.fmt_timing
854 && self.fmt_span.trace_close()
855 && extensions.get_mut::<Timings>().is_none()
856 {
857 extensions.insert(Timings::new());
858 }
859
860 if self.fmt_span.trace_new() {
861 with_event_from_span!(id, span, "message" = "new", |event| {
862 drop(extensions);
863 drop(span);
864 self.on_event(&event, ctx);
865 });
866 }
867 }
868
869 fn on_record(&self, id: &Id, values: &Record<'_>, ctx: Context<'_, S>) {
870 let span = ctx.span(id).expect("Span not found, this is a bug");
871 let mut extensions = span.extensions_mut();
872 if let Some(fields) = extensions.get_mut::<FormattedFields<N>>() {
873 let _ = self.fmt_fields.add_fields(fields, values);
874 return;
875 }
876
877 let mut fields = FormattedFields::<N>::new(String::new());
878 if self
879 .fmt_fields
880 .format_fields(fields.as_writer().with_ansi(self.is_ansi), values)
881 .is_ok()
882 {
883 fields.was_ansi = self.is_ansi;
884 extensions.insert(fields);
885 }
886 }
887
888 fn on_enter(&self, id: &Id, ctx: Context<'_, S>) {
889 if self.fmt_span.trace_enter() || self.fmt_span.trace_close() && self.fmt_span.fmt_timing {
890 let span = ctx.span(id).expect("Span not found, this is a bug");
891 let mut extensions = span.extensions_mut();
892 if let Some(timings) = extensions.get_mut::<Timings>() {
893 if timings.entered_count == 0 {
894 let now = Instant::now();
895 timings.idle += (now - timings.last).as_nanos() as u64;
896 timings.last = now;
897 }
898 timings.entered_count += 1;
899 }
900
901 if self.fmt_span.trace_enter() {
902 with_event_from_span!(id, span, "message" = "enter", |event| {
903 drop(extensions);
904 drop(span);
905 self.on_event(&event, ctx);
906 });
907 }
908 }
909 }
910
911 fn on_exit(&self, id: &Id, ctx: Context<'_, S>) {
912 if self.fmt_span.trace_exit() || self.fmt_span.trace_close() && self.fmt_span.fmt_timing {
913 let span = ctx.span(id).expect("Span not found, this is a bug");
914 let mut extensions = span.extensions_mut();
915 if let Some(timings) = extensions.get_mut::<Timings>() {
916 timings.entered_count -= 1;
917 if timings.entered_count == 0 {
918 let now = Instant::now();
919 timings.busy += (now - timings.last).as_nanos() as u64;
920 timings.last = now;
921 }
922 }
923
924 if self.fmt_span.trace_exit() {
925 with_event_from_span!(id, span, "message" = "exit", |event| {
926 drop(extensions);
927 drop(span);
928 self.on_event(&event, ctx);
929 });
930 }
931 }
932 }
933
934 fn on_close(&self, id: Id, ctx: Context<'_, S>) {
935 if self.fmt_span.trace_close() {
936 let span = ctx.span(&id).expect("Span not found, this is a bug");
937 let extensions = span.extensions();
938 if let Some(timing) = extensions.get::<Timings>() {
939 let Timings {
940 busy,
941 mut idle,
942 last,
943 entered_count,
944 } = *timing;
945 debug_assert_eq!(entered_count, 0);
946 idle += (Instant::now() - last).as_nanos() as u64;
947
948 let t_idle = field::display(TimingDisplay(idle));
949 let t_busy = field::display(TimingDisplay(busy));
950
951 with_event_from_span!(
952 id,
953 span,
954 "message" = "close",
955 "time.busy" = t_busy,
956 "time.idle" = t_idle,
957 |event| {
958 drop(extensions);
959 drop(span);
960 self.on_event(&event, ctx);
961 }
962 );
963 } else {
964 with_event_from_span!(id, span, "message" = "close", |event| {
965 drop(extensions);
966 drop(span);
967 self.on_event(&event, ctx);
968 });
969 }
970 }
971 }
972
973 fn on_event(&self, event: &Event<'_>, ctx: Context<'_, S>) {
974 thread_local! {
975 static BUF: RefCell<String> = const { RefCell::new(String::new()) };
976 }
977
978 BUF.with(|buf| {
979 let borrow = buf.try_borrow_mut();
980 let mut a;
981 let mut b;
982 let mut buf = match borrow {
983 Ok(buf) => {
984 a = buf;
985 &mut *a
986 }
987 _ => {
988 b = String::new();
989 &mut b
990 }
991 };
992
993 let ctx = self.make_ctx(ctx, event);
994 if self
995 .fmt_event
996 .format_event(
997 &ctx,
998 format::Writer::new(&mut buf).with_ansi(self.is_ansi),
999 event,
1000 )
1001 .is_ok()
1002 {
1003 let mut writer = self.make_writer.make_writer_for(event.metadata());
1004 let res = io::Write::write_all(&mut writer, buf.as_bytes());
1005 if self.log_internal_errors {
1006 if let Err(e) = res {
1007 eprintln!("[tracing-subscriber] Unable to write an event to the Writer for this Subscriber! Error: {}\n", e);
1008 }
1009 }
1010 } else if self.log_internal_errors {
1011 let err_msg = format!("Unable to format the following event. Name: {}; Fields: {:?}\n",
1012 event.metadata().name(), event.fields());
1013 let mut writer = self.make_writer.make_writer_for(event.metadata());
1014 let res = io::Write::write_all(&mut writer, err_msg.as_bytes());
1015 if let Err(e) = res {
1016 eprintln!("[tracing-subscriber] Unable to write an \"event formatting error\" to the Writer for this Subscriber! Error: {}\n", e);
1017 }
1018 }
1019
1020 buf.clear();
1021 });
1022 }
1023
1024 unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> {
1025 match () {
1030 _ if id == TypeId::of::<Self>() => Some(self as *const Self as *const ()),
1031 _ if id == TypeId::of::<E>() => Some(&self.fmt_event as *const E as *const ()),
1032 _ if id == TypeId::of::<N>() => Some(&self.fmt_fields as *const N as *const ()),
1033 _ if id == TypeId::of::<W>() => Some(&self.make_writer as *const W as *const ()),
1034 _ => None,
1035 }
1036 }
1037}
1038
1039pub struct FmtContext<'a, S, N> {
1041 pub(crate) ctx: Context<'a, S>,
1042 pub(crate) fmt_fields: &'a N,
1043 pub(crate) event: &'a Event<'a>,
1044}
1045
1046impl<S, N> fmt::Debug for FmtContext<'_, S, N> {
1047 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1048 f.debug_struct("FmtContext").finish()
1049 }
1050}
1051
1052impl<'writer, S, N> FormatFields<'writer> for FmtContext<'_, S, N>
1053where
1054 S: Subscriber + for<'lookup> LookupSpan<'lookup>,
1055 N: FormatFields<'writer> + 'static,
1056{
1057 fn format_fields<R: RecordFields>(
1058 &self,
1059 writer: format::Writer<'writer>,
1060 fields: R,
1061 ) -> fmt::Result {
1062 self.fmt_fields.format_fields(writer, fields)
1063 }
1064}
1065
1066impl<S, N> FmtContext<'_, S, N>
1067where
1068 S: Subscriber + for<'lookup> LookupSpan<'lookup>,
1069 N: for<'writer> FormatFields<'writer> + 'static,
1070{
1071 pub fn visit_spans<E, F>(&self, mut f: F) -> Result<(), E>
1077 where
1078 F: FnMut(&SpanRef<'_, S>) -> Result<(), E>,
1079 {
1080 if let Some(scope) = self.event_scope() {
1082 for span in scope.from_root() {
1083 f(&span)?;
1084 }
1085 }
1086 Ok(())
1087 }
1088
1089 #[inline]
1094 pub fn metadata(&self, id: &Id) -> Option<&'static Metadata<'static>>
1095 where
1096 S: for<'lookup> LookupSpan<'lookup>,
1097 {
1098 self.ctx.metadata(id)
1099 }
1100
1101 #[inline]
1108 pub fn span(&self, id: &Id) -> Option<SpanRef<'_, S>>
1109 where
1110 S: for<'lookup> LookupSpan<'lookup>,
1111 {
1112 self.ctx.span(id)
1113 }
1114
1115 #[inline]
1117 pub fn exists(&self, id: &Id) -> bool
1118 where
1119 S: for<'lookup> LookupSpan<'lookup>,
1120 {
1121 self.ctx.exists(id)
1122 }
1123
1124 #[inline]
1131 pub fn lookup_current(&self) -> Option<SpanRef<'_, S>>
1132 where
1133 S: for<'lookup> LookupSpan<'lookup>,
1134 {
1135 self.ctx.lookup_current()
1136 }
1137
1138 pub fn current_span(&self) -> Current {
1140 self.ctx.current_span()
1141 }
1142
1143 pub fn parent_span(&self) -> Option<SpanRef<'_, S>> {
1152 self.ctx.event_span(self.event)
1153 }
1154
1155 pub fn span_scope(&self, id: &Id) -> Option<registry::Scope<'_, S>>
1182 where
1183 S: for<'lookup> LookupSpan<'lookup>,
1184 {
1185 self.ctx.span_scope(id)
1186 }
1187
1188 pub fn event_scope(&self) -> Option<registry::Scope<'_, S>>
1213 where
1214 S: for<'lookup> registry::LookupSpan<'lookup>,
1215 {
1216 self.ctx.event_scope(self.event)
1217 }
1218
1219 pub fn field_format(&self) -> &N {
1227 self.fmt_fields
1228 }
1229}
1230
1231struct Timings {
1232 idle: u64,
1233 busy: u64,
1234 last: Instant,
1235 entered_count: u64,
1236}
1237
1238impl Timings {
1239 fn new() -> Self {
1240 Self {
1241 idle: 0,
1242 busy: 0,
1243 last: Instant::now(),
1244 entered_count: 0,
1245 }
1246 }
1247}
1248
1249#[cfg(test)]
1250mod test {
1251 use super::*;
1252 use crate::fmt::{
1253 self,
1254 format::{self, test::MockTime, Format},
1255 layer::Layer as _,
1256 test::{MockMakeWriter, MockWriter},
1257 time,
1258 };
1259 use crate::Registry;
1260 use alloc::{string::ToString, vec, vec::Vec};
1261 use format::FmtSpan;
1262 use regex::Regex;
1263 use tracing::subscriber::with_default;
1264 use tracing_core::dispatcher::Dispatch;
1265
1266 #[test]
1267 fn impls() {
1268 let f = Format::default().with_timer(time::Uptime::default());
1269 let fmt = fmt::Layer::default().event_format(f);
1270 let subscriber = fmt.with_subscriber(Registry::default());
1271 let _dispatch = Dispatch::new(subscriber);
1272
1273 let f = format::Format::default();
1274 let fmt = fmt::Layer::default().event_format(f);
1275 let subscriber = fmt.with_subscriber(Registry::default());
1276 let _dispatch = Dispatch::new(subscriber);
1277
1278 let f = format::Format::default().compact();
1279 let fmt = fmt::Layer::default().event_format(f);
1280 let subscriber = fmt.with_subscriber(Registry::default());
1281 let _dispatch = Dispatch::new(subscriber);
1282 }
1283
1284 #[test]
1285 fn fmt_layer_downcasts() {
1286 let f = format::Format::default();
1287 let fmt = fmt::Layer::default().event_format(f);
1288 let subscriber = fmt.with_subscriber(Registry::default());
1289
1290 let dispatch = Dispatch::new(subscriber);
1291 assert!(dispatch.downcast_ref::<fmt::Layer<Registry>>().is_some());
1292 }
1293
1294 #[test]
1295 fn fmt_layer_downcasts_to_parts() {
1296 let f = format::Format::default();
1297 let fmt = fmt::Layer::default().event_format(f);
1298 let subscriber = fmt.with_subscriber(Registry::default());
1299 let dispatch = Dispatch::new(subscriber);
1300 assert!(dispatch.downcast_ref::<format::DefaultFields>().is_some());
1301 assert!(dispatch.downcast_ref::<format::Format>().is_some())
1302 }
1303
1304 #[test]
1305 fn is_lookup_span() {
1306 fn assert_lookup_span<T: for<'a> crate::registry::LookupSpan<'a>>(_: T) {}
1307 let fmt = fmt::Layer::default();
1308 let subscriber = fmt.with_subscriber(Registry::default());
1309 assert_lookup_span(subscriber)
1310 }
1311
1312 fn sanitize_timings(s: String) -> String {
1313 let re = Regex::new("time\\.(idle|busy)=([0-9.]+)[mµn]s").unwrap();
1314 re.replace_all(s.as_str(), "timing").to_string()
1315 }
1316
1317 #[test]
1318 fn format_error_print_to_stderr() {
1319 struct AlwaysError;
1320
1321 impl std::fmt::Debug for AlwaysError {
1322 fn fmt(&self, _f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1323 Err(std::fmt::Error)
1324 }
1325 }
1326
1327 let make_writer = MockMakeWriter::default();
1328 let subscriber = crate::fmt::Subscriber::builder()
1329 .with_writer(make_writer.clone())
1330 .with_level(false)
1331 .with_ansi(false)
1332 .with_timer(MockTime)
1333 .finish();
1334
1335 with_default(subscriber, || {
1336 tracing::info!(?AlwaysError);
1337 });
1338 let actual = sanitize_timings(make_writer.get_string());
1339
1340 let expected = concat!(
1342 "Unable to format the following event. Name: event ",
1343 file!(),
1344 ":"
1345 );
1346 assert!(
1347 actual.as_str().starts_with(expected),
1348 "\nactual = {}\nshould start with expected = {}\n",
1349 actual,
1350 expected
1351 );
1352 }
1353
1354 #[test]
1355 fn format_error_ignore_if_log_internal_errors_is_false() {
1356 struct AlwaysError;
1357
1358 impl std::fmt::Debug for AlwaysError {
1359 fn fmt(&self, _f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1360 Err(std::fmt::Error)
1361 }
1362 }
1363
1364 let make_writer = MockMakeWriter::default();
1365 let subscriber = crate::fmt::Subscriber::builder()
1366 .with_writer(make_writer.clone())
1367 .with_level(false)
1368 .with_ansi(false)
1369 .with_timer(MockTime)
1370 .log_internal_errors(false)
1371 .finish();
1372
1373 with_default(subscriber, || {
1374 tracing::info!(?AlwaysError);
1375 });
1376 let actual = sanitize_timings(make_writer.get_string());
1377 assert_eq!("", actual.as_str());
1378 }
1379
1380 #[test]
1381 fn synthesize_span_none() {
1382 let make_writer = MockMakeWriter::default();
1383 let subscriber = crate::fmt::Subscriber::builder()
1384 .with_writer(make_writer.clone())
1385 .with_level(false)
1386 .with_ansi(false)
1387 .with_timer(MockTime)
1388 .finish();
1390
1391 with_default(subscriber, || {
1392 let span1 = tracing::info_span!("span1", x = 42);
1393 let _e = span1.enter();
1394 });
1395 let actual = sanitize_timings(make_writer.get_string());
1396 assert_eq!("", actual.as_str());
1397 }
1398
1399 #[test]
1400 fn synthesize_span_active() {
1401 let make_writer = MockMakeWriter::default();
1402 let subscriber = crate::fmt::Subscriber::builder()
1403 .with_writer(make_writer.clone())
1404 .with_level(false)
1405 .with_ansi(false)
1406 .with_timer(MockTime)
1407 .with_span_events(FmtSpan::ACTIVE)
1408 .finish();
1409
1410 with_default(subscriber, || {
1411 let span1 = tracing::info_span!("span1", x = 42);
1412 let _e = span1.enter();
1413 });
1414 let actual = sanitize_timings(make_writer.get_string());
1415 assert_eq!(
1416 "fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: enter\n\
1417 fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: exit\n",
1418 actual.as_str()
1419 );
1420 }
1421
1422 #[test]
1423 fn synthesize_span_close() {
1424 let make_writer = MockMakeWriter::default();
1425 let subscriber = crate::fmt::Subscriber::builder()
1426 .with_writer(make_writer.clone())
1427 .with_level(false)
1428 .with_ansi(false)
1429 .with_timer(MockTime)
1430 .with_span_events(FmtSpan::CLOSE)
1431 .finish();
1432
1433 with_default(subscriber, || {
1434 let span1 = tracing::info_span!("span1", x = 42);
1435 let _e = span1.enter();
1436 });
1437 let actual = sanitize_timings(make_writer.get_string());
1438 assert_eq!(
1439 "fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: close timing timing\n",
1440 actual.as_str()
1441 );
1442 }
1443
1444 #[test]
1445 fn synthesize_span_close_no_timing() {
1446 let make_writer = MockMakeWriter::default();
1447 let subscriber = crate::fmt::Subscriber::builder()
1448 .with_writer(make_writer.clone())
1449 .with_level(false)
1450 .with_ansi(false)
1451 .with_timer(MockTime)
1452 .without_time()
1453 .with_span_events(FmtSpan::CLOSE)
1454 .finish();
1455
1456 with_default(subscriber, || {
1457 let span1 = tracing::info_span!("span1", x = 42);
1458 let _e = span1.enter();
1459 });
1460 let actual = sanitize_timings(make_writer.get_string());
1461 assert_eq!(
1462 "span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: close\n",
1463 actual.as_str()
1464 );
1465 }
1466
1467 #[test]
1468 fn synthesize_span_full() {
1469 let make_writer = MockMakeWriter::default();
1470 let subscriber = crate::fmt::Subscriber::builder()
1471 .with_writer(make_writer.clone())
1472 .with_level(false)
1473 .with_ansi(false)
1474 .with_timer(MockTime)
1475 .with_span_events(FmtSpan::FULL)
1476 .finish();
1477
1478 with_default(subscriber, || {
1479 let span1 = tracing::info_span!("span1", x = 42);
1480 let _e = span1.enter();
1481 });
1482 let actual = sanitize_timings(make_writer.get_string());
1483 assert_eq!(
1484 "fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: new\n\
1485 fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: enter\n\
1486 fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: exit\n\
1487 fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: close timing timing\n",
1488 actual.as_str()
1489 );
1490 }
1491
1492 #[test]
1493 fn make_writer_based_on_meta() {
1494 struct MakeByTarget {
1495 make_writer1: MockMakeWriter,
1496 make_writer2: MockMakeWriter,
1497 }
1498
1499 impl<'a> MakeWriter<'a> for MakeByTarget {
1500 type Writer = MockWriter;
1501
1502 fn make_writer(&'a self) -> Self::Writer {
1503 self.make_writer1.make_writer()
1504 }
1505
1506 fn make_writer_for(&'a self, meta: &Metadata<'_>) -> Self::Writer {
1507 if meta.target() == "writer2" {
1508 return self.make_writer2.make_writer();
1509 }
1510 self.make_writer()
1511 }
1512 }
1513
1514 let make_writer1 = MockMakeWriter::default();
1515 let make_writer2 = MockMakeWriter::default();
1516
1517 let make_writer = MakeByTarget {
1518 make_writer1: make_writer1.clone(),
1519 make_writer2: make_writer2.clone(),
1520 };
1521
1522 let subscriber = crate::fmt::Subscriber::builder()
1523 .with_writer(make_writer)
1524 .with_level(false)
1525 .with_target(false)
1526 .with_ansi(false)
1527 .with_timer(MockTime)
1528 .with_span_events(FmtSpan::CLOSE)
1529 .finish();
1530
1531 with_default(subscriber, || {
1532 let span1 = tracing::info_span!("writer1_span", x = 42);
1533 let _e = span1.enter();
1534 tracing::info!(target: "writer2", "hello writer2!");
1535 let span2 = tracing::info_span!(target: "writer2", "writer2_span");
1536 let _e = span2.enter();
1537 tracing::warn!(target: "writer1", "hello writer1!");
1538 });
1539
1540 let actual = sanitize_timings(make_writer1.get_string());
1541 assert_eq!(
1542 "fake time writer1_span{x=42}:writer2_span: hello writer1!\n\
1543 fake time writer1_span{x=42}: close timing timing\n",
1544 actual.as_str()
1545 );
1546 let actual = sanitize_timings(make_writer2.get_string());
1547 assert_eq!(
1548 "fake time writer1_span{x=42}: hello writer2!\n\
1549 fake time writer1_span{x=42}:writer2_span: close timing timing\n",
1550 actual.as_str()
1551 );
1552 }
1553
1554 #[cfg(feature = "ansi")]
1557 #[test]
1558 fn layer_no_color() {
1559 const NO_COLOR: &str = "NO_COLOR";
1560
1561 struct RestoreEnvVar(Result<String, env::VarError>);
1568 impl Drop for RestoreEnvVar {
1569 fn drop(&mut self) {
1570 match self.0 {
1571 Ok(ref var) => env::set_var(NO_COLOR, var),
1572 Err(_) => env::remove_var(NO_COLOR),
1573 }
1574 }
1575 }
1576
1577 let _saved_no_color = RestoreEnvVar(env::var(NO_COLOR));
1578
1579 let cases: Vec<(Option<&str>, bool)> = vec![
1580 (Some("0"), false), (Some("off"), false), (Some("1"), false),
1583 (Some(""), true), (None, true),
1585 ];
1586
1587 for (var, ansi) in cases {
1588 if let Some(value) = var {
1589 env::set_var(NO_COLOR, value);
1590 } else {
1591 env::remove_var(NO_COLOR);
1592 }
1593
1594 let layer: Layer<()> = fmt::Layer::default();
1595 assert_eq!(
1596 layer.is_ansi, ansi,
1597 "NO_COLOR={:?}; Layer::default().is_ansi should be {}",
1598 var, ansi
1599 );
1600
1601 let layer: Layer<()> = fmt::Layer::default().with_ansi(true);
1603 assert!(
1604 layer.is_ansi,
1605 "NO_COLOR={:?}; Layer::default().with_ansi(true).is_ansi should be true",
1606 var
1607 );
1608
1609 let mut layer: Layer<()> = fmt::Layer::default();
1611 layer.set_ansi(true);
1612 assert!(
1613 layer.is_ansi,
1614 "NO_COLOR={:?}; layer.set_ansi(true); layer.is_ansi should be true",
1615 var
1616 );
1617 }
1618
1619 }
1622
1623 #[test]
1625 fn modify_span_events() {
1626 let make_writer = MockMakeWriter::default();
1627
1628 let inner_layer = fmt::Layer::default()
1629 .with_writer(make_writer.clone())
1630 .with_level(false)
1631 .with_ansi(false)
1632 .with_timer(MockTime)
1633 .with_span_events(FmtSpan::ACTIVE);
1634
1635 let (reloadable_layer, reload_handle) = crate::reload::Layer::new(inner_layer);
1636 let reload = reloadable_layer.with_subscriber(Registry::default());
1637
1638 with_default(reload, || {
1639 {
1640 let span1 = tracing::info_span!("span1", x = 42);
1641 let _e = span1.enter();
1642 }
1643
1644 let _ = reload_handle.modify(|s| s.set_span_events(FmtSpan::NONE));
1645
1646 {
1648 let span2 = tracing::info_span!("span2", x = 100);
1649 let _e = span2.enter();
1650 }
1651
1652 {
1653 let span3 = tracing::info_span!("span3", x = 42);
1654 let _e = span3.enter();
1655
1656 let _ = reload_handle.modify(|s| s.set_span_events(FmtSpan::ACTIVE));
1659 }
1660 });
1661 let actual = sanitize_timings(make_writer.get_string());
1662 assert_eq!(
1663 "fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: enter\n\
1664 fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: exit\n\
1665 fake time span3{x=42}: tracing_subscriber::fmt::fmt_layer::test: exit\n",
1666 actual.as_str()
1667 );
1668 }
1669}