pub trait Visit {
    fn record_debug(&mut self, field: &Field, value: &dyn Debug);

    fn record_value(&mut self, field: &Field, value: Value<'_>) { ... }
    fn record_f64(&mut self, field: &Field, value: f64) { ... }
    fn record_i64(&mut self, field: &Field, value: i64) { ... }
    fn record_u64(&mut self, field: &Field, value: u64) { ... }
    fn record_i128(&mut self, field: &Field, value: i128) { ... }
    fn record_u128(&mut self, field: &Field, value: u128) { ... }
    fn record_bool(&mut self, field: &Field, value: bool) { ... }
    fn record_str(&mut self, field: &Field, value: &str) { ... }
    fn record_error(&mut self, field: &Field, value: &(dyn Error + 'static)) { ... }
Expand description

Visits typed values.

An instance of Visit (“a visitor”) represents the logic necessary to record field values of various types. When an implementor of Value is recorded, it calls the appropriate method on the provided visitor to indicate the type that value should be recorded as.

When a Subscriber implementation records an Event or a set of Values added to a Span, it can pass an &mut Visit to the record method on the provided ValueSet or Event. This visitor will then be used to record all the field-value pairs present on that Event or ValueSet.


A simple visitor that writes to a string might be implemented like so:

use std::fmt::{self, Write};
use tracing::field::{Value, Visit, Field};
pub struct StringVisitor<'a> {
    string: &'a mut String,

impl<'a> Visit for StringVisitor<'a> {
    fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) {
        write!(self.string, "{} = {:?}; ", field.name(), value).unwrap();

This visitor will format each recorded value using fmt::Debug, and append the field name and formatted value to the provided string, regardless of the type of the recorded value. When all the values have been recorded, the StringVisitor may be dropped, allowing the string to be printed or stored in some other data structure.

The Visit trait provides default implementations for record_i64, record_u64, record_bool, record_str, and record_error, which simply forward the recorded value to record_debug. Thus, record_debug is the only method which a Visit implementation must implement. However, visitors may override the default implementations of these functions in order to implement type-specific behavior.

Additionally, when a visitor receives a value of a type it does not care about, it is free to ignore those values completely. For example, a visitor which only records numeric data might look like this:

pub struct SumVisitor {
    sum: i64,

impl Visit for SumVisitor {
    fn record_i64(&mut self, _field: &Field, value: i64) {
       self.sum += value;

    fn record_u64(&mut self, _field: &Field, value: u64) {
        self.sum += value as i64;

    fn record_debug(&mut self, _field: &Field, _value: &fmt::Debug) {
        // Do nothing

This visitor (which is probably not particularly useful) keeps a running sum of all the numeric values it records, and ignores all other values. A more practical example of recording typed values is presented in examples/counters.rs, which demonstrates a very simple metrics system implemented using tracing.

Note: The record_error trait method is only
available when the Rust standard library is present, as it requires the
std::error::Error trait.

Required Methods

Visit a value implementing fmt::Debug.

Provided Methods

Visits an arbitrary type implementing the valuable crate’s Valuable trait.

Visit a double-precision floating point value.

Visit a signed 64-bit integer value.

Visit an unsigned 64-bit integer value.

Visit a signed 128-bit integer value.

Visit an unsigned 128-bit integer value.

Visit a boolean value.

Visit a string value.

Records a type implementing Error.

Note: This is only enabled when the Rust standard library is

Implementations on Foreign Types