1use crate::{
2 field::RecordFields,
3 fmt::{format, FormatEvent, FormatFields, MakeWriter, TestWriter},
4 layer::{self, Context},
5 registry::{self, LookupSpan, SpanRef},
6};
7use format::{FmtSpan, TimingDisplay};
8use std::{
9 any::TypeId, cell::RefCell, env, fmt, io, marker::PhantomData, ops::Deref, time::Instant,
10};
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 format::FmtSpan;
1261 use regex::Regex;
1262 use tracing::subscriber::with_default;
1263 use tracing_core::dispatcher::Dispatch;
1264
1265 #[test]
1266 fn impls() {
1267 let f = Format::default().with_timer(time::Uptime::default());
1268 let fmt = fmt::Layer::default().event_format(f);
1269 let subscriber = fmt.with_subscriber(Registry::default());
1270 let _dispatch = Dispatch::new(subscriber);
1271
1272 let f = format::Format::default();
1273 let fmt = fmt::Layer::default().event_format(f);
1274 let subscriber = fmt.with_subscriber(Registry::default());
1275 let _dispatch = Dispatch::new(subscriber);
1276
1277 let f = format::Format::default().compact();
1278 let fmt = fmt::Layer::default().event_format(f);
1279 let subscriber = fmt.with_subscriber(Registry::default());
1280 let _dispatch = Dispatch::new(subscriber);
1281 }
1282
1283 #[test]
1284 fn fmt_layer_downcasts() {
1285 let f = format::Format::default();
1286 let fmt = fmt::Layer::default().event_format(f);
1287 let subscriber = fmt.with_subscriber(Registry::default());
1288
1289 let dispatch = Dispatch::new(subscriber);
1290 assert!(dispatch.downcast_ref::<fmt::Layer<Registry>>().is_some());
1291 }
1292
1293 #[test]
1294 fn fmt_layer_downcasts_to_parts() {
1295 let f = format::Format::default();
1296 let fmt = fmt::Layer::default().event_format(f);
1297 let subscriber = fmt.with_subscriber(Registry::default());
1298 let dispatch = Dispatch::new(subscriber);
1299 assert!(dispatch.downcast_ref::<format::DefaultFields>().is_some());
1300 assert!(dispatch.downcast_ref::<format::Format>().is_some())
1301 }
1302
1303 #[test]
1304 fn is_lookup_span() {
1305 fn assert_lookup_span<T: for<'a> crate::registry::LookupSpan<'a>>(_: T) {}
1306 let fmt = fmt::Layer::default();
1307 let subscriber = fmt.with_subscriber(Registry::default());
1308 assert_lookup_span(subscriber)
1309 }
1310
1311 fn sanitize_timings(s: String) -> String {
1312 let re = Regex::new("time\\.(idle|busy)=([0-9.]+)[mµn]s").unwrap();
1313 re.replace_all(s.as_str(), "timing").to_string()
1314 }
1315
1316 #[test]
1317 fn format_error_print_to_stderr() {
1318 struct AlwaysError;
1319
1320 impl std::fmt::Debug for AlwaysError {
1321 fn fmt(&self, _f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1322 Err(std::fmt::Error)
1323 }
1324 }
1325
1326 let make_writer = MockMakeWriter::default();
1327 let subscriber = crate::fmt::Subscriber::builder()
1328 .with_writer(make_writer.clone())
1329 .with_level(false)
1330 .with_ansi(false)
1331 .with_timer(MockTime)
1332 .finish();
1333
1334 with_default(subscriber, || {
1335 tracing::info!(?AlwaysError);
1336 });
1337 let actual = sanitize_timings(make_writer.get_string());
1338
1339 let expected = concat!(
1341 "Unable to format the following event. Name: event ",
1342 file!(),
1343 ":"
1344 );
1345 assert!(
1346 actual.as_str().starts_with(expected),
1347 "\nactual = {}\nshould start with expected = {}\n",
1348 actual,
1349 expected
1350 );
1351 }
1352
1353 #[test]
1354 fn format_error_ignore_if_log_internal_errors_is_false() {
1355 struct AlwaysError;
1356
1357 impl std::fmt::Debug for AlwaysError {
1358 fn fmt(&self, _f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1359 Err(std::fmt::Error)
1360 }
1361 }
1362
1363 let make_writer = MockMakeWriter::default();
1364 let subscriber = crate::fmt::Subscriber::builder()
1365 .with_writer(make_writer.clone())
1366 .with_level(false)
1367 .with_ansi(false)
1368 .with_timer(MockTime)
1369 .log_internal_errors(false)
1370 .finish();
1371
1372 with_default(subscriber, || {
1373 tracing::info!(?AlwaysError);
1374 });
1375 let actual = sanitize_timings(make_writer.get_string());
1376 assert_eq!("", actual.as_str());
1377 }
1378
1379 #[test]
1380 fn synthesize_span_none() {
1381 let make_writer = MockMakeWriter::default();
1382 let subscriber = crate::fmt::Subscriber::builder()
1383 .with_writer(make_writer.clone())
1384 .with_level(false)
1385 .with_ansi(false)
1386 .with_timer(MockTime)
1387 .finish();
1389
1390 with_default(subscriber, || {
1391 let span1 = tracing::info_span!("span1", x = 42);
1392 let _e = span1.enter();
1393 });
1394 let actual = sanitize_timings(make_writer.get_string());
1395 assert_eq!("", actual.as_str());
1396 }
1397
1398 #[test]
1399 fn synthesize_span_active() {
1400 let make_writer = MockMakeWriter::default();
1401 let subscriber = crate::fmt::Subscriber::builder()
1402 .with_writer(make_writer.clone())
1403 .with_level(false)
1404 .with_ansi(false)
1405 .with_timer(MockTime)
1406 .with_span_events(FmtSpan::ACTIVE)
1407 .finish();
1408
1409 with_default(subscriber, || {
1410 let span1 = tracing::info_span!("span1", x = 42);
1411 let _e = span1.enter();
1412 });
1413 let actual = sanitize_timings(make_writer.get_string());
1414 assert_eq!(
1415 "fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: enter\n\
1416 fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: exit\n",
1417 actual.as_str()
1418 );
1419 }
1420
1421 #[test]
1422 fn synthesize_span_close() {
1423 let make_writer = MockMakeWriter::default();
1424 let subscriber = crate::fmt::Subscriber::builder()
1425 .with_writer(make_writer.clone())
1426 .with_level(false)
1427 .with_ansi(false)
1428 .with_timer(MockTime)
1429 .with_span_events(FmtSpan::CLOSE)
1430 .finish();
1431
1432 with_default(subscriber, || {
1433 let span1 = tracing::info_span!("span1", x = 42);
1434 let _e = span1.enter();
1435 });
1436 let actual = sanitize_timings(make_writer.get_string());
1437 assert_eq!(
1438 "fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: close timing timing\n",
1439 actual.as_str()
1440 );
1441 }
1442
1443 #[test]
1444 fn synthesize_span_close_no_timing() {
1445 let make_writer = MockMakeWriter::default();
1446 let subscriber = crate::fmt::Subscriber::builder()
1447 .with_writer(make_writer.clone())
1448 .with_level(false)
1449 .with_ansi(false)
1450 .with_timer(MockTime)
1451 .without_time()
1452 .with_span_events(FmtSpan::CLOSE)
1453 .finish();
1454
1455 with_default(subscriber, || {
1456 let span1 = tracing::info_span!("span1", x = 42);
1457 let _e = span1.enter();
1458 });
1459 let actual = sanitize_timings(make_writer.get_string());
1460 assert_eq!(
1461 "span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: close\n",
1462 actual.as_str()
1463 );
1464 }
1465
1466 #[test]
1467 fn synthesize_span_full() {
1468 let make_writer = MockMakeWriter::default();
1469 let subscriber = crate::fmt::Subscriber::builder()
1470 .with_writer(make_writer.clone())
1471 .with_level(false)
1472 .with_ansi(false)
1473 .with_timer(MockTime)
1474 .with_span_events(FmtSpan::FULL)
1475 .finish();
1476
1477 with_default(subscriber, || {
1478 let span1 = tracing::info_span!("span1", x = 42);
1479 let _e = span1.enter();
1480 });
1481 let actual = sanitize_timings(make_writer.get_string());
1482 assert_eq!(
1483 "fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: new\n\
1484 fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: enter\n\
1485 fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: exit\n\
1486 fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: close timing timing\n",
1487 actual.as_str()
1488 );
1489 }
1490
1491 #[test]
1492 fn make_writer_based_on_meta() {
1493 struct MakeByTarget {
1494 make_writer1: MockMakeWriter,
1495 make_writer2: MockMakeWriter,
1496 }
1497
1498 impl<'a> MakeWriter<'a> for MakeByTarget {
1499 type Writer = MockWriter;
1500
1501 fn make_writer(&'a self) -> Self::Writer {
1502 self.make_writer1.make_writer()
1503 }
1504
1505 fn make_writer_for(&'a self, meta: &Metadata<'_>) -> Self::Writer {
1506 if meta.target() == "writer2" {
1507 return self.make_writer2.make_writer();
1508 }
1509 self.make_writer()
1510 }
1511 }
1512
1513 let make_writer1 = MockMakeWriter::default();
1514 let make_writer2 = MockMakeWriter::default();
1515
1516 let make_writer = MakeByTarget {
1517 make_writer1: make_writer1.clone(),
1518 make_writer2: make_writer2.clone(),
1519 };
1520
1521 let subscriber = crate::fmt::Subscriber::builder()
1522 .with_writer(make_writer)
1523 .with_level(false)
1524 .with_target(false)
1525 .with_ansi(false)
1526 .with_timer(MockTime)
1527 .with_span_events(FmtSpan::CLOSE)
1528 .finish();
1529
1530 with_default(subscriber, || {
1531 let span1 = tracing::info_span!("writer1_span", x = 42);
1532 let _e = span1.enter();
1533 tracing::info!(target: "writer2", "hello writer2!");
1534 let span2 = tracing::info_span!(target: "writer2", "writer2_span");
1535 let _e = span2.enter();
1536 tracing::warn!(target: "writer1", "hello writer1!");
1537 });
1538
1539 let actual = sanitize_timings(make_writer1.get_string());
1540 assert_eq!(
1541 "fake time writer1_span{x=42}:writer2_span: hello writer1!\n\
1542 fake time writer1_span{x=42}: close timing timing\n",
1543 actual.as_str()
1544 );
1545 let actual = sanitize_timings(make_writer2.get_string());
1546 assert_eq!(
1547 "fake time writer1_span{x=42}: hello writer2!\n\
1548 fake time writer1_span{x=42}:writer2_span: close timing timing\n",
1549 actual.as_str()
1550 );
1551 }
1552
1553 #[cfg(feature = "ansi")]
1556 #[test]
1557 fn layer_no_color() {
1558 const NO_COLOR: &str = "NO_COLOR";
1559
1560 struct RestoreEnvVar(Result<String, env::VarError>);
1567 impl Drop for RestoreEnvVar {
1568 fn drop(&mut self) {
1569 match self.0 {
1570 Ok(ref var) => env::set_var(NO_COLOR, var),
1571 Err(_) => env::remove_var(NO_COLOR),
1572 }
1573 }
1574 }
1575
1576 let _saved_no_color = RestoreEnvVar(env::var(NO_COLOR));
1577
1578 let cases: Vec<(Option<&str>, bool)> = vec![
1579 (Some("0"), false), (Some("off"), false), (Some("1"), false),
1582 (Some(""), true), (None, true),
1584 ];
1585
1586 for (var, ansi) in cases {
1587 if let Some(value) = var {
1588 env::set_var(NO_COLOR, value);
1589 } else {
1590 env::remove_var(NO_COLOR);
1591 }
1592
1593 let layer: Layer<()> = fmt::Layer::default();
1594 assert_eq!(
1595 layer.is_ansi, ansi,
1596 "NO_COLOR={:?}; Layer::default().is_ansi should be {}",
1597 var, ansi
1598 );
1599
1600 let layer: Layer<()> = fmt::Layer::default().with_ansi(true);
1602 assert!(
1603 layer.is_ansi,
1604 "NO_COLOR={:?}; Layer::default().with_ansi(true).is_ansi should be true",
1605 var
1606 );
1607
1608 let mut layer: Layer<()> = fmt::Layer::default();
1610 layer.set_ansi(true);
1611 assert!(
1612 layer.is_ansi,
1613 "NO_COLOR={:?}; layer.set_ansi(true); layer.is_ansi should be true",
1614 var
1615 );
1616 }
1617
1618 }
1621
1622 #[test]
1624 fn modify_span_events() {
1625 let make_writer = MockMakeWriter::default();
1626
1627 let inner_layer = fmt::Layer::default()
1628 .with_writer(make_writer.clone())
1629 .with_level(false)
1630 .with_ansi(false)
1631 .with_timer(MockTime)
1632 .with_span_events(FmtSpan::ACTIVE);
1633
1634 let (reloadable_layer, reload_handle) =
1635 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}