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 let now = Instant::now();
894 timings.idle += (now - timings.last).as_nanos() as u64;
895 timings.last = now;
896 }
897
898 if self.fmt_span.trace_enter() {
899 with_event_from_span!(id, span, "message" = "enter", |event| {
900 drop(extensions);
901 drop(span);
902 self.on_event(&event, ctx);
903 });
904 }
905 }
906 }
907
908 fn on_exit(&self, id: &Id, ctx: Context<'_, S>) {
909 if self.fmt_span.trace_exit() || self.fmt_span.trace_close() && self.fmt_span.fmt_timing {
910 let span = ctx.span(id).expect("Span not found, this is a bug");
911 let mut extensions = span.extensions_mut();
912 if let Some(timings) = extensions.get_mut::<Timings>() {
913 let now = Instant::now();
914 timings.busy += (now - timings.last).as_nanos() as u64;
915 timings.last = now;
916 }
917
918 if self.fmt_span.trace_exit() {
919 with_event_from_span!(id, span, "message" = "exit", |event| {
920 drop(extensions);
921 drop(span);
922 self.on_event(&event, ctx);
923 });
924 }
925 }
926 }
927
928 fn on_close(&self, id: Id, ctx: Context<'_, S>) {
929 if self.fmt_span.trace_close() {
930 let span = ctx.span(&id).expect("Span not found, this is a bug");
931 let extensions = span.extensions();
932 if let Some(timing) = extensions.get::<Timings>() {
933 let Timings {
934 busy,
935 mut idle,
936 last,
937 } = *timing;
938 idle += (Instant::now() - last).as_nanos() as u64;
939
940 let t_idle = field::display(TimingDisplay(idle));
941 let t_busy = field::display(TimingDisplay(busy));
942
943 with_event_from_span!(
944 id,
945 span,
946 "message" = "close",
947 "time.busy" = t_busy,
948 "time.idle" = t_idle,
949 |event| {
950 drop(extensions);
951 drop(span);
952 self.on_event(&event, ctx);
953 }
954 );
955 } else {
956 with_event_from_span!(id, span, "message" = "close", |event| {
957 drop(extensions);
958 drop(span);
959 self.on_event(&event, ctx);
960 });
961 }
962 }
963 }
964
965 fn on_event(&self, event: &Event<'_>, ctx: Context<'_, S>) {
966 thread_local! {
967 static BUF: RefCell<String> = const { RefCell::new(String::new()) };
968 }
969
970 BUF.with(|buf| {
971 let borrow = buf.try_borrow_mut();
972 let mut a;
973 let mut b;
974 let mut buf = match borrow {
975 Ok(buf) => {
976 a = buf;
977 &mut *a
978 }
979 _ => {
980 b = String::new();
981 &mut b
982 }
983 };
984
985 let ctx = self.make_ctx(ctx, event);
986 if self
987 .fmt_event
988 .format_event(
989 &ctx,
990 format::Writer::new(&mut buf).with_ansi(self.is_ansi),
991 event,
992 )
993 .is_ok()
994 {
995 let mut writer = self.make_writer.make_writer_for(event.metadata());
996 let res = io::Write::write_all(&mut writer, buf.as_bytes());
997 if self.log_internal_errors {
998 if let Err(e) = res {
999 eprintln!("[tracing-subscriber] Unable to write an event to the Writer for this Subscriber! Error: {}\n", e);
1000 }
1001 }
1002 } else if self.log_internal_errors {
1003 let err_msg = format!("Unable to format the following event. Name: {}; Fields: {:?}\n",
1004 event.metadata().name(), event.fields());
1005 let mut writer = self.make_writer.make_writer_for(event.metadata());
1006 let res = io::Write::write_all(&mut writer, err_msg.as_bytes());
1007 if let Err(e) = res {
1008 eprintln!("[tracing-subscriber] Unable to write an \"event formatting error\" to the Writer for this Subscriber! Error: {}\n", e);
1009 }
1010 }
1011
1012 buf.clear();
1013 });
1014 }
1015
1016 unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> {
1017 match () {
1022 _ if id == TypeId::of::<Self>() => Some(self as *const Self as *const ()),
1023 _ if id == TypeId::of::<E>() => Some(&self.fmt_event as *const E as *const ()),
1024 _ if id == TypeId::of::<N>() => Some(&self.fmt_fields as *const N as *const ()),
1025 _ if id == TypeId::of::<W>() => Some(&self.make_writer as *const W as *const ()),
1026 _ => None,
1027 }
1028 }
1029}
1030
1031pub struct FmtContext<'a, S, N> {
1033 pub(crate) ctx: Context<'a, S>,
1034 pub(crate) fmt_fields: &'a N,
1035 pub(crate) event: &'a Event<'a>,
1036}
1037
1038impl<S, N> fmt::Debug for FmtContext<'_, S, N> {
1039 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1040 f.debug_struct("FmtContext").finish()
1041 }
1042}
1043
1044impl<'writer, S, N> FormatFields<'writer> for FmtContext<'_, S, N>
1045where
1046 S: Subscriber + for<'lookup> LookupSpan<'lookup>,
1047 N: FormatFields<'writer> + 'static,
1048{
1049 fn format_fields<R: RecordFields>(
1050 &self,
1051 writer: format::Writer<'writer>,
1052 fields: R,
1053 ) -> fmt::Result {
1054 self.fmt_fields.format_fields(writer, fields)
1055 }
1056}
1057
1058impl<S, N> FmtContext<'_, S, N>
1059where
1060 S: Subscriber + for<'lookup> LookupSpan<'lookup>,
1061 N: for<'writer> FormatFields<'writer> + 'static,
1062{
1063 pub fn visit_spans<E, F>(&self, mut f: F) -> Result<(), E>
1069 where
1070 F: FnMut(&SpanRef<'_, S>) -> Result<(), E>,
1071 {
1072 if let Some(scope) = self.event_scope() {
1074 for span in scope.from_root() {
1075 f(&span)?;
1076 }
1077 }
1078 Ok(())
1079 }
1080
1081 #[inline]
1086 pub fn metadata(&self, id: &Id) -> Option<&'static Metadata<'static>>
1087 where
1088 S: for<'lookup> LookupSpan<'lookup>,
1089 {
1090 self.ctx.metadata(id)
1091 }
1092
1093 #[inline]
1100 pub fn span(&self, id: &Id) -> Option<SpanRef<'_, S>>
1101 where
1102 S: for<'lookup> LookupSpan<'lookup>,
1103 {
1104 self.ctx.span(id)
1105 }
1106
1107 #[inline]
1109 pub fn exists(&self, id: &Id) -> bool
1110 where
1111 S: for<'lookup> LookupSpan<'lookup>,
1112 {
1113 self.ctx.exists(id)
1114 }
1115
1116 #[inline]
1123 pub fn lookup_current(&self) -> Option<SpanRef<'_, S>>
1124 where
1125 S: for<'lookup> LookupSpan<'lookup>,
1126 {
1127 self.ctx.lookup_current()
1128 }
1129
1130 pub fn current_span(&self) -> Current {
1132 self.ctx.current_span()
1133 }
1134
1135 pub fn parent_span(&self) -> Option<SpanRef<'_, S>> {
1144 self.ctx.event_span(self.event)
1145 }
1146
1147 pub fn span_scope(&self, id: &Id) -> Option<registry::Scope<'_, S>>
1174 where
1175 S: for<'lookup> LookupSpan<'lookup>,
1176 {
1177 self.ctx.span_scope(id)
1178 }
1179
1180 pub fn event_scope(&self) -> Option<registry::Scope<'_, S>>
1205 where
1206 S: for<'lookup> registry::LookupSpan<'lookup>,
1207 {
1208 self.ctx.event_scope(self.event)
1209 }
1210
1211 pub fn field_format(&self) -> &N {
1219 self.fmt_fields
1220 }
1221}
1222
1223struct Timings {
1224 idle: u64,
1225 busy: u64,
1226 last: Instant,
1227}
1228
1229impl Timings {
1230 fn new() -> Self {
1231 Self {
1232 idle: 0,
1233 busy: 0,
1234 last: Instant::now(),
1235 }
1236 }
1237}
1238
1239#[cfg(test)]
1240mod test {
1241 use super::*;
1242 use crate::fmt::{
1243 self,
1244 format::{self, test::MockTime, Format},
1245 layer::Layer as _,
1246 test::{MockMakeWriter, MockWriter},
1247 time,
1248 };
1249 use crate::Registry;
1250 use format::FmtSpan;
1251 use regex::Regex;
1252 use tracing::subscriber::with_default;
1253 use tracing_core::dispatcher::Dispatch;
1254
1255 #[test]
1256 fn impls() {
1257 let f = Format::default().with_timer(time::Uptime::default());
1258 let fmt = fmt::Layer::default().event_format(f);
1259 let subscriber = fmt.with_subscriber(Registry::default());
1260 let _dispatch = Dispatch::new(subscriber);
1261
1262 let f = format::Format::default();
1263 let fmt = fmt::Layer::default().event_format(f);
1264 let subscriber = fmt.with_subscriber(Registry::default());
1265 let _dispatch = Dispatch::new(subscriber);
1266
1267 let f = format::Format::default().compact();
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
1273 #[test]
1274 fn fmt_layer_downcasts() {
1275 let f = format::Format::default();
1276 let fmt = fmt::Layer::default().event_format(f);
1277 let subscriber = fmt.with_subscriber(Registry::default());
1278
1279 let dispatch = Dispatch::new(subscriber);
1280 assert!(dispatch.downcast_ref::<fmt::Layer<Registry>>().is_some());
1281 }
1282
1283 #[test]
1284 fn fmt_layer_downcasts_to_parts() {
1285 let f = format::Format::default();
1286 let fmt = fmt::Layer::default().event_format(f);
1287 let subscriber = fmt.with_subscriber(Registry::default());
1288 let dispatch = Dispatch::new(subscriber);
1289 assert!(dispatch.downcast_ref::<format::DefaultFields>().is_some());
1290 assert!(dispatch.downcast_ref::<format::Format>().is_some())
1291 }
1292
1293 #[test]
1294 fn is_lookup_span() {
1295 fn assert_lookup_span<T: for<'a> crate::registry::LookupSpan<'a>>(_: T) {}
1296 let fmt = fmt::Layer::default();
1297 let subscriber = fmt.with_subscriber(Registry::default());
1298 assert_lookup_span(subscriber)
1299 }
1300
1301 fn sanitize_timings(s: String) -> String {
1302 let re = Regex::new("time\\.(idle|busy)=([0-9.]+)[mµn]s").unwrap();
1303 re.replace_all(s.as_str(), "timing").to_string()
1304 }
1305
1306 #[test]
1307 fn format_error_print_to_stderr() {
1308 struct AlwaysError;
1309
1310 impl std::fmt::Debug for AlwaysError {
1311 fn fmt(&self, _f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1312 Err(std::fmt::Error)
1313 }
1314 }
1315
1316 let make_writer = MockMakeWriter::default();
1317 let subscriber = crate::fmt::Subscriber::builder()
1318 .with_writer(make_writer.clone())
1319 .with_level(false)
1320 .with_ansi(false)
1321 .with_timer(MockTime)
1322 .finish();
1323
1324 with_default(subscriber, || {
1325 tracing::info!(?AlwaysError);
1326 });
1327 let actual = sanitize_timings(make_writer.get_string());
1328
1329 let expected = concat!(
1331 "Unable to format the following event. Name: event ",
1332 file!(),
1333 ":"
1334 );
1335 assert!(
1336 actual.as_str().starts_with(expected),
1337 "\nactual = {}\nshould start with expected = {}\n",
1338 actual,
1339 expected
1340 );
1341 }
1342
1343 #[test]
1344 fn format_error_ignore_if_log_internal_errors_is_false() {
1345 struct AlwaysError;
1346
1347 impl std::fmt::Debug for AlwaysError {
1348 fn fmt(&self, _f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1349 Err(std::fmt::Error)
1350 }
1351 }
1352
1353 let make_writer = MockMakeWriter::default();
1354 let subscriber = crate::fmt::Subscriber::builder()
1355 .with_writer(make_writer.clone())
1356 .with_level(false)
1357 .with_ansi(false)
1358 .with_timer(MockTime)
1359 .log_internal_errors(false)
1360 .finish();
1361
1362 with_default(subscriber, || {
1363 tracing::info!(?AlwaysError);
1364 });
1365 let actual = sanitize_timings(make_writer.get_string());
1366 assert_eq!("", actual.as_str());
1367 }
1368
1369 #[test]
1370 fn synthesize_span_none() {
1371 let make_writer = MockMakeWriter::default();
1372 let subscriber = crate::fmt::Subscriber::builder()
1373 .with_writer(make_writer.clone())
1374 .with_level(false)
1375 .with_ansi(false)
1376 .with_timer(MockTime)
1377 .finish();
1379
1380 with_default(subscriber, || {
1381 let span1 = tracing::info_span!("span1", x = 42);
1382 let _e = span1.enter();
1383 });
1384 let actual = sanitize_timings(make_writer.get_string());
1385 assert_eq!("", actual.as_str());
1386 }
1387
1388 #[test]
1389 fn synthesize_span_active() {
1390 let make_writer = MockMakeWriter::default();
1391 let subscriber = crate::fmt::Subscriber::builder()
1392 .with_writer(make_writer.clone())
1393 .with_level(false)
1394 .with_ansi(false)
1395 .with_timer(MockTime)
1396 .with_span_events(FmtSpan::ACTIVE)
1397 .finish();
1398
1399 with_default(subscriber, || {
1400 let span1 = tracing::info_span!("span1", x = 42);
1401 let _e = span1.enter();
1402 });
1403 let actual = sanitize_timings(make_writer.get_string());
1404 assert_eq!(
1405 "fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: enter\n\
1406 fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: exit\n",
1407 actual.as_str()
1408 );
1409 }
1410
1411 #[test]
1412 fn synthesize_span_close() {
1413 let make_writer = MockMakeWriter::default();
1414 let subscriber = crate::fmt::Subscriber::builder()
1415 .with_writer(make_writer.clone())
1416 .with_level(false)
1417 .with_ansi(false)
1418 .with_timer(MockTime)
1419 .with_span_events(FmtSpan::CLOSE)
1420 .finish();
1421
1422 with_default(subscriber, || {
1423 let span1 = tracing::info_span!("span1", x = 42);
1424 let _e = span1.enter();
1425 });
1426 let actual = sanitize_timings(make_writer.get_string());
1427 assert_eq!(
1428 "fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: close timing timing\n",
1429 actual.as_str()
1430 );
1431 }
1432
1433 #[test]
1434 fn synthesize_span_close_no_timing() {
1435 let make_writer = MockMakeWriter::default();
1436 let subscriber = crate::fmt::Subscriber::builder()
1437 .with_writer(make_writer.clone())
1438 .with_level(false)
1439 .with_ansi(false)
1440 .with_timer(MockTime)
1441 .without_time()
1442 .with_span_events(FmtSpan::CLOSE)
1443 .finish();
1444
1445 with_default(subscriber, || {
1446 let span1 = tracing::info_span!("span1", x = 42);
1447 let _e = span1.enter();
1448 });
1449 let actual = sanitize_timings(make_writer.get_string());
1450 assert_eq!(
1451 "span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: close\n",
1452 actual.as_str()
1453 );
1454 }
1455
1456 #[test]
1457 fn synthesize_span_full() {
1458 let make_writer = MockMakeWriter::default();
1459 let subscriber = crate::fmt::Subscriber::builder()
1460 .with_writer(make_writer.clone())
1461 .with_level(false)
1462 .with_ansi(false)
1463 .with_timer(MockTime)
1464 .with_span_events(FmtSpan::FULL)
1465 .finish();
1466
1467 with_default(subscriber, || {
1468 let span1 = tracing::info_span!("span1", x = 42);
1469 let _e = span1.enter();
1470 });
1471 let actual = sanitize_timings(make_writer.get_string());
1472 assert_eq!(
1473 "fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: new\n\
1474 fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: enter\n\
1475 fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: exit\n\
1476 fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: close timing timing\n",
1477 actual.as_str()
1478 );
1479 }
1480
1481 #[test]
1482 fn make_writer_based_on_meta() {
1483 struct MakeByTarget {
1484 make_writer1: MockMakeWriter,
1485 make_writer2: MockMakeWriter,
1486 }
1487
1488 impl<'a> MakeWriter<'a> for MakeByTarget {
1489 type Writer = MockWriter;
1490
1491 fn make_writer(&'a self) -> Self::Writer {
1492 self.make_writer1.make_writer()
1493 }
1494
1495 fn make_writer_for(&'a self, meta: &Metadata<'_>) -> Self::Writer {
1496 if meta.target() == "writer2" {
1497 return self.make_writer2.make_writer();
1498 }
1499 self.make_writer()
1500 }
1501 }
1502
1503 let make_writer1 = MockMakeWriter::default();
1504 let make_writer2 = MockMakeWriter::default();
1505
1506 let make_writer = MakeByTarget {
1507 make_writer1: make_writer1.clone(),
1508 make_writer2: make_writer2.clone(),
1509 };
1510
1511 let subscriber = crate::fmt::Subscriber::builder()
1512 .with_writer(make_writer)
1513 .with_level(false)
1514 .with_target(false)
1515 .with_ansi(false)
1516 .with_timer(MockTime)
1517 .with_span_events(FmtSpan::CLOSE)
1518 .finish();
1519
1520 with_default(subscriber, || {
1521 let span1 = tracing::info_span!("writer1_span", x = 42);
1522 let _e = span1.enter();
1523 tracing::info!(target: "writer2", "hello writer2!");
1524 let span2 = tracing::info_span!(target: "writer2", "writer2_span");
1525 let _e = span2.enter();
1526 tracing::warn!(target: "writer1", "hello writer1!");
1527 });
1528
1529 let actual = sanitize_timings(make_writer1.get_string());
1530 assert_eq!(
1531 "fake time writer1_span{x=42}:writer2_span: hello writer1!\n\
1532 fake time writer1_span{x=42}: close timing timing\n",
1533 actual.as_str()
1534 );
1535 let actual = sanitize_timings(make_writer2.get_string());
1536 assert_eq!(
1537 "fake time writer1_span{x=42}: hello writer2!\n\
1538 fake time writer1_span{x=42}:writer2_span: close timing timing\n",
1539 actual.as_str()
1540 );
1541 }
1542
1543 #[cfg(feature = "ansi")]
1546 #[test]
1547 fn layer_no_color() {
1548 const NO_COLOR: &str = "NO_COLOR";
1549
1550 struct RestoreEnvVar(Result<String, env::VarError>);
1557 impl Drop for RestoreEnvVar {
1558 fn drop(&mut self) {
1559 match self.0 {
1560 Ok(ref var) => env::set_var(NO_COLOR, var),
1561 Err(_) => env::remove_var(NO_COLOR),
1562 }
1563 }
1564 }
1565
1566 let _saved_no_color = RestoreEnvVar(env::var(NO_COLOR));
1567
1568 let cases: Vec<(Option<&str>, bool)> = vec![
1569 (Some("0"), false), (Some("off"), false), (Some("1"), false),
1572 (Some(""), true), (None, true),
1574 ];
1575
1576 for (var, ansi) in cases {
1577 if let Some(value) = var {
1578 env::set_var(NO_COLOR, value);
1579 } else {
1580 env::remove_var(NO_COLOR);
1581 }
1582
1583 let layer: Layer<()> = fmt::Layer::default();
1584 assert_eq!(
1585 layer.is_ansi, ansi,
1586 "NO_COLOR={:?}; Layer::default().is_ansi should be {}",
1587 var, ansi
1588 );
1589
1590 let layer: Layer<()> = fmt::Layer::default().with_ansi(true);
1592 assert!(
1593 layer.is_ansi,
1594 "NO_COLOR={:?}; Layer::default().with_ansi(true).is_ansi should be true",
1595 var
1596 );
1597
1598 let mut layer: Layer<()> = fmt::Layer::default();
1600 layer.set_ansi(true);
1601 assert!(
1602 layer.is_ansi,
1603 "NO_COLOR={:?}; layer.set_ansi(true); layer.is_ansi should be true",
1604 var
1605 );
1606 }
1607
1608 }
1611
1612 #[test]
1614 fn modify_span_events() {
1615 let make_writer = MockMakeWriter::default();
1616
1617 let inner_layer = fmt::Layer::default()
1618 .with_writer(make_writer.clone())
1619 .with_level(false)
1620 .with_ansi(false)
1621 .with_timer(MockTime)
1622 .with_span_events(FmtSpan::ACTIVE);
1623
1624 let (reloadable_layer, reload_handle) =
1625 crate::reload::Layer::new(inner_layer);
1626 let reload = reloadable_layer.with_subscriber(Registry::default());
1627
1628 with_default(reload, || {
1629 {
1630 let span1 = tracing::info_span!("span1", x = 42);
1631 let _e = span1.enter();
1632 }
1633
1634 let _ = reload_handle.modify(|s| s.set_span_events(FmtSpan::NONE));
1635
1636 {
1638 let span2 = tracing::info_span!("span2", x = 100);
1639 let _e = span2.enter();
1640 }
1641
1642 {
1643 let span3 = tracing::info_span!("span3", x = 42);
1644 let _e = span3.enter();
1645
1646 let _ = reload_handle.modify(|s| s.set_span_events(FmtSpan::ACTIVE));
1649 }
1650 });
1651 let actual = sanitize_timings(make_writer.get_string());
1652 assert_eq!(
1653 "fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: enter\n\
1654 fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: exit\n\
1655 fake time span3{x=42}: tracing_subscriber::fmt::fmt_layer::test: exit\n",
1656 actual.as_str()
1657 );
1658 }
1659}