Movatterモバイル変換


[0]ホーム

URL:


Docs.rs

Crate tracing

Cratetracing 

Source
Expand description

A scoped, structured logging and diagnostics system.

§Overview

tracing is a framework for instrumenting Rust programs to collectstructured, event-based diagnostic information.

In asynchronous systems like Tokio, interpreting traditional log messages canoften be quite challenging. Since individual tasks are multiplexed on the samethread, associated events and log lines are intermixed making it difficult totrace the logic flow.tracing expands upon logging-style diagnostics byallowing libraries and applications to record structured events with additionalinformation abouttemporality andcausality — unlike a log message, a spanintracing has a beginning and end time, may be entered and exited by theflow of execution, and may exist within a nested tree of similar spans. Inaddition,tracing spans arestructured, with the ability to record typeddata as well as textual messages.

Thetracing crate provides the APIs necessary for instrumenting librariesand applications to emit trace data.

Compiler support:requiresrustc 1.63+

§Core Concepts

The core oftracing’s API is composed ofspans,events andsubscribers. We’ll cover these in turn.

§Spans

To record the flow of execution through a program,tracing introduces theconcept ofspans. Unlike a log line that represents amoment intime, a span represents aperiod of time with a beginning and an end. When aprogram begins executing in a context or performing a unit of work, itenters that context’s span, and when it stops executing in that context,itexits the span. The span in which a thread is currently executing isreferred to as that thread’scurrent span.

For example:

usetracing::{span, Level};letspan =span!(Level::TRACE,"my_span");// `enter` returns a RAII guard which, when dropped, exits the span. this// indicates that we are in the span for the current lexical scope.let_enter = span.enter();// perform some work in the context of `my_span`...

Thespan module’s documentation provides further details on how touse spans.

Warning: In asynchronous code that uses async/await syntax,Span::enter may produce incorrect traces if the returned dropguard is held across an await point. Seethe method documentation for details.

§Events

AnEvent represents amoment in time. It signifies something thathappened while a trace was being recorded.Events are comparable to the logrecords emitted by unstructured logging code, but unlike a typical log line,anEvent may occur within the context of a span.

For example:

usetracing::{event, span, Level};// records an event outside of any span context:event!(Level::INFO,"something happened");letspan =span!(Level::INFO,"my_span");let_guard = span.enter();// records an event within "my_span".event!(Level::DEBUG,"something happened inside my_span");

In general, events should be used to represent points in timewithin aspan — a request returned with a given status code,n new items weretaken from a queue, and so on.

TheEvent struct documentation provides further details on usingevents.

§Subscribers

AsSpans andEvents occur, they are recorded or aggregated byimplementations of theSubscriber trait.Subscribers are notifiedwhen anEvent takes place and when aSpan is entered or exited. Thesenotifications are represented by the followingSubscriber trait methods:

  • event, called when anEvent takes place,
  • enter, called when execution enters aSpan,
  • exit, called when execution exits aSpan

In addition, subscribers may implement theenabled function tofilterthe notifications they receive based onmetadata describing eachSpanorEvent. If a call toSubscriber::enabled returnsfalse for a givenset of metadata, thatSubscriber willnot be notified about thecorrespondingSpan orEvent. For performance reasons, if no currentlyactive subscribers express interest in a given set of metadata by returningtrue, then the correspondingSpan orEvent will never be constructed.

§Usage

First, add this to yourCargo.toml:

[dependencies]tracing = "0.1"

§Recording Spans and Events

Spans and events are recorded using macros.

§Spans

Thespan! macro expands to aSpan struct which is used torecord a span. TheSpan::enter method on that struct records that thespan has been entered, and returns aRAII guard object, which will exitthe span when dropped.

For example:

usetracing::{span, Level};// Construct a new span named "my span" with trace log level.letspan =span!(Level::TRACE,"my span");// Enter the span, returning a guard object.let_enter = span.enter();// Any trace events that occur before the guard is dropped will occur// within the span.// Dropping the guard will exit the span.

The#[instrument] attribute provides an easy way toaddtracing spans to functions. A function annotated with#[instrument]will create and enter a span with that function’s name every time thefunction is called, with arguments to that function will be recorded asfields usingfmt::Debug.

For example:

usetracing::{Level, event, instrument};#[instrument]pub fnmy_function(my_arg: usize) {// This event will be recorded inside a span named `my_function` with the    // field `my_arg`.event!(Level::INFO,"inside my_function!");// ...}

For functions which don’t have built-in tracing support and can’t havethe#[instrument] attribute applied (such as from an external crate),theSpan struct has ain_scope() methodwhich can be used to easily wrap synchronous code in a span.

For example:

usetracing::info_span;letjson =info_span!("json.parse").in_scope(|| serde_json::from_slice(&buf))?;

You can find more examples showing how to use this cratehere.

§Events

Events are recorded using theevent! macro:

usetracing::{event, Level};event!(Level::INFO,"something has happened!");

§Using the Macros

Thespan! andevent! macros as well as the#[instrument] attributeuse fairly similar syntax, with some exceptions.

§Configuring Attributes

Both macros require aLevel specifying the verbosity of the span orevent. Optionally, the,target andparent span may be overridden. If thetarget and parent span are not overridden, they will default to themodule path where the macro was invoked and the current span (as determinedby the subscriber), respectively.

For example:

span!(target:"app_spans", Level::TRACE,"my span");event!(target:"app_events", Level::INFO,"something has happened!");
letspan =span!(Level::TRACE,"my span");event!(parent:&span, Level::INFO,"something has happened!");

The span macros also take a string literal after the level, to set the nameof the span (as above). In the case of the event macros, the name of the event canbe overridden (the default isevent file:line) using thename: specifier.

span!(Level::TRACE,"my span");event!(name:"some_info", Level::INFO,"something has happened!");

§Recording Fields

Structured fields on spans and events are specified using the syntaxfield_name = field_value. Fields are separated by commas.

// records an event with two fields://  - "answer", with the value 42//  - "question", with the value "life, the universe and everything"event!(Level::INFO, answer =42, question ="life, the universe, and everything");

As shorthand, local variables may be used as field values without anassignment, similar tostruct initializers. For example:

letuser ="ferris";span!(Level::TRACE,"login", user);// is equivalent to:span!(Level::TRACE,"login", user = user);

Field names can include dots, but should not be terminated by them:

letuser ="ferris";letemail ="ferris@rust-lang.org";span!(Level::TRACE,"login", user, user.email = email);

Since field names can include dots, fields on local structs can be usedusing the local variable shorthand:

letuser = User {    name:"ferris",    email:"ferris@rust-lang.org",};// the span will have the fields `user.name = "ferris"` and// `user.email = "ferris@rust-lang.org"`.span!(Level::TRACE,"login", user.name, user.email);

Fields with names that are not Rust identifiers, or with names that are Rust reserved words,may be created using quoted string literals. However, this may not be used with the localvariable shorthand.

// records an event with fields whose names are not Rust identifiers//  - "guid:x-request-id", containing a `:`, with the value "abcdef"//  - "type", which is a reserved word, with the value "request"span!(Level::TRACE,"api","guid:x-request-id"="abcdef","type"="request");

Constant expressions can also be used as field names. Constantsmust be enclosed in curly braces ({}) to indicate that thevalueof the constant is to be used as the field name, rather than theconstant’s name. For example:

constRESOURCE_NAME:&str ="foo";// this span will have the field `foo = "some_id"`span!(Level::TRACE,"get", { RESOURCE_NAME } ="some_id");

The? sigil is shorthand that specifies a field should be recorded usingitsfmt::Debug implementation:

#[derive(Debug)]structMyStruct {    field:&'staticstr,}letmy_struct = MyStruct {    field:"Hello world!"};// `my_struct` will be recorded using its `fmt::Debug` implementation.event!(Level::TRACE, greeting =?my_struct);// is equivalent to:event!(Level::TRACE, greeting = tracing::field::debug(&my_struct));

The% sigil operates similarly, but indicates that the value should berecorded using itsfmt::Display implementation:

// `my_struct.field` will be recorded using its `fmt::Display` implementation.event!(Level::TRACE, greeting = %my_struct.field);// is equivalent to:event!(Level::TRACE, greeting = tracing::field::display(&my_struct.field));

The% and? sigils may also be used with local variable shorthand:

// `my_struct.field` will be recorded using its `fmt::Display` implementation.event!(Level::TRACE, %my_struct.field);

Additionally, a span may declare fields with the special valueEmpty,which indicates that that the value for that field does not currently existbut may be recorded later. For example:

usetracing::{trace_span, field};// Create a span with two fields: `greeting`, with the value "hello world", and// `parting`, without a value.letspan =trace_span!("my_span", greeting ="hello world", parting = field::Empty);// ...// Now, record a value for parting as well.span.record("parting",&"goodbye world!");

Finally, events may also include human-readable messages, in the form of aformat string and (optional) arguments,after the event’skey-value fields. If a format string and arguments are provided,they will implicitly create a new field namedmessage whose value is theprovided set of format arguments.

For example:

letquestion ="the ultimate question of life, the universe, and everything";letanswer =42;// records an event with the following fields:// - `question.answer` with the value 42,// - `question.tricky` with the value `true`,// - "message", with the value "the answer to the ultimate question of life, the//    universe, and everything is 42."event!(    Level::DEBUG,    question.answer = answer,    question.tricky =true,"the answer to {} is {}.", question, answer);

Specifying a formatted message in this manner does not allocate by default.

§Shorthand Macros

tracing also offers a number of macros with preset verbosity levels.Thetrace!,debug!,info!,warn!, anderror! behavesimilarly to theevent! macro, but with theLevel argument alreadyspecified, while the correspondingtrace_span!,debug_span!,info_span!,warn_span!, anderror_span! macros are the same,but for thespan! macro.

These are intended both as a shorthand, and for compatibility with thelogcrate (see the next section).

§Forlog Users

Users of thelog crate should note thattracing exposes a set ofmacros for creatingEvents (trace!,debug!,info!,warn!, anderror!) which may be invoked with the same syntax as the similarly-namedmacros from thelog crate. Often, the process of converting a project tousetracing can begin with a simple drop-in replacement.

Let’s consider thelog crate’s yak-shaving example:

usestd::{error::Error, io};usetracing::{debug, error, info, span, warn, Level};// the `#[tracing::instrument]` attribute creates and enters a span// every time the instrumented function is called. The span is named after the// the function or method. Parameters passed to the function are recorded as fields.#[tracing::instrument]pub fnshave(yak: usize) ->Result<(), Box<dynError +'static>> {// this creates an event at the DEBUG level with two fields:    // - `excitement`, with the key "excitement" and the value "yay!"    // - `message`, with the key "message" and the value "hello! I'm gonna shave a yak."    //    // unlike other fields, `message`'s shorthand initialization is just the string itself.debug!(excitement ="yay!","hello! I'm gonna shave a yak.");ifyak ==3{warn!("could not locate yak!");// note that this is intended to demonstrate `tracing`'s features, not idiomatic        // error handling! in a library or application, you should consider returning        // a dedicated `YakError`. libraries like snafu or thiserror make this easy.returnErr(io::Error::new(io::ErrorKind::Other,"shaving yak failed!").into());    }else{debug!("yak shaved successfully");    }Ok(())}pub fnshave_all(yaks: usize) -> usize {// Constructs a new span named "shaving_yaks" at the TRACE level,    // and a field whose key is "yaks". This is equivalent to writing:    //    // let span = span!(Level::TRACE, "shaving_yaks", yaks = yaks);    //    // local variables (`yaks`) can be used as field values    // without an assignment, similar to struct initializers.let_span =span!(Level::TRACE,"shaving_yaks", yaks).entered();info!("shaving yaks");letmutyaks_shaved =0;foryakin1..=yaks {letres = shave(yak);debug!(yak, shaved = res.is_ok());if letErr(referror) = res {// Like spans, events can also use the field initialization shorthand.            // In this instance, `yak` is the field being initalized.error!(yak, error = error.as_ref(),"failed to shave yak!");        }else{            yaks_shaved +=1;        }debug!(yaks_shaved);    }    yaks_shaved}

§In libraries

Libraries should link only to thetracing crate, and use the providedmacros to record whatever information will be useful to downstreamconsumers.

§In executables

In order to record trace events, executables have to use aSubscriberimplementation compatible withtracing. ASubscriber implements away of collecting trace data, such as by logging it to standard output.

This library does not contain anySubscriber implementations; these areprovided byother crates.

The simplest way to use a subscriber is to call theset_global_defaultfunction:

extern cratetracing;letmy_subscriber = FooSubscriber::new();tracing::subscriber::set_global_default(my_subscriber)    .expect("setting tracing default failed");
Warning: In general, libraries shouldnot callset_global_default()! Doing so will cause conflicts when     executables that depend on the library try to set the default later.

This subscriber will be used as the default in all threads for theremainder of the duration of the program, similar to setting the loggerin thelog crate.

In addition, the default subscriber can be set through using thewith_default function. This follows thetokio pattern of usingclosures to represent executing code in a context that is exited at the endof the closure. For example:

letmy_subscriber = FooSubscriber::new();tracing::subscriber::with_default(my_subscriber, || {// Any trace events generated in this closure or by functions it calls    // will be collected by `my_subscriber`.})

This approach allows trace data to be collected by multiple subscriberswithin different contexts in the program. Note that the override only applies to thecurrently executing thread; other threads will not see the change from with_default.

Any trace events generated outside the context of a subscriber will not be collected.

Once a subscriber has been set, instrumentation points may be added to theexecutable using thetracing crate’s macros.

§log Compatibility

Thelog crate provides a simple, lightweight logging facade for Rust.Whiletracing builds uponlog’s foundation with richer structureddiagnostic data,log’s simplicity and ubiquity make it the “lowest commondenominator” for text-based logging in Rust — a vast majority of Rustlibraries and applications either emit or consumelog records. Therefore,tracing provides multiple forms of interoperability withlog:tracinginstrumentation can emitlog records, and a compatibility layer enablestracingSubscribers to consumelog records astracingEvents.

§Emittinglog Records

This crate provides two feature flags, “log” and “log-always”, which willcausespans andevents to emitlog records. When the “log” feature isenabled, if notracingSubscriber is active, invoking an event macro orcreating a span with fields will emit alog record. This is intendedprimarily for use in libraries which wish to emit diagnostics that can beconsumed by applications usingtracingorlog, without paying theadditional overhead of emitting both forms of diagnostics whentracing isin use.

Enabling the “log-always” feature will causelog records to be emittedeven if atracingSubscriberis set. This is intended to be used inapplications where alogLogger is being used to record a textual log,andtracing is used only to record other forms of diagnostics (such asmetrics, profiling, or distributed tracing data). Unlike the “log” feature,libraries generally shouldnot enable the “log-always” feature, as doingso will prevent applications from being able to opt out of thelog records.

Seehere for more details on this crate’s feature flags.

The generatedlog records’ messages will be a string representation of thespan or event’s fields, and all additional information recorded bylog(target, verbosity level, module path, file, and line number) will also bepopulated. Additionally,log records are also generated when spans areentered, exited, and closed. Since these additional span lifecycle logs havethe potential to be very verbose, and don’t include additional fields, theywill always be emitted at theTrace level, rather than inheriting thelevel of the span that generated them. Furthermore, they are are categorizedunder a separatelog target, “tracing::span” (and its sub-target,“tracing::span::active”, for the logs on entering and exiting a span), whichmay be enabled or disabled separately from otherlog records emitted bytracing.

§Consuminglog Records

Thetracing-log crate provides a compatibility layer whichallows atracingSubscriber to consumelog records as though theyweretracingevents. This allows applications usingtracing to recordthe logs emitted by dependencies usinglog as events within the context ofthe application’s trace tree. Seethat crate’s documentationfor details.

§Related Crates

In addition totracing andtracing-core, thetokio-rs/tracing repositorycontains several additional crates designed to be used with thetracing ecosystem.This includes a collection ofSubscriber implementations, as well as utilityand adapter crates to assist in writingSubscribers and instrumentingapplications.

In particular, the following crates are likely to be of interest:

  • tracing-futures provides a compatibility layer with thefuturescrate, allowing spans to be attached toFutures,Streams, andExecutors.
  • tracing-subscriber providesSubscriber implementations andutilities for working withSubscribers. This includes aFmtSubscriberFmtSubscriber for logging formatted trace data to stdout, with similarfiltering and formatting to theenv_logger crate.
  • tracing-log provides a compatibility layer with thelog crate,allowing log messages to be recorded astracingEvents within thetrace tree. This is useful when a project usingtracing havedependencies which uselog. Note that if you’re usingtracing-subscriber’sFmtSubscriber, you don’t need to depend ontracing-log directly.
  • tracing-appender provides utilities for outputting tracing data,including a file appender and non blocking writer.

Additionally, there are also several third-party crates which are notmaintained by thetokio project. These include:

If you’re the maintainer of atracing ecosystem crate not listed above,please let us know! We’d love to add your project to the list!

Note: Some of these ecosystem crates are currently     unreleased and/or in earlier stages of development. They may be less stable     thantracing andtracing-core.

§Crate Feature Flags

The following cratefeature flags are available:

  • A set of features controlling thestatic verbosity level.

  • log: causes trace instrumentation points to emitlog records as wellas trace events, if a defaulttracing subscriber has not been set. Thisis intended for use in libraries whose users may be using eithertracingorlog.

  • log-always: Emitlog records from alltracing spans and events, evenif atracing subscriber has been set. This should be set only byapplications which intend to collect traces and logs separately; if anadapter is used to convertlog records intotracing events, this willcause duplicate events to occur.

  • attributes: Includes support for the#[instrument] attribute.This is on by default, but does bring in thesyn crate as a dependency,which may add to the compile time of crates that do not already use it.

  • std: Depend on the Rust standard library (enabled by default).

    no_std users may disable this feature withdefault-features = false:

    [dependencies]tracing = { version = "0.1.38", default-features = false }
Note:tracing'sno_std support     requiresliballoc.

§Unstable Features

These feature flags enableunstable features. The public API may break in 0.1.xreleases. To enable these features, the--cfg tracing_unstable must be passed torustc when compiling.

The following unstable feature flags are currently available:

§Enabling Unstable Features

The easiest way to set thetracing_unstable cfg is to use theRUSTFLAGSenv variable when runningcargo commands:

RUSTFLAGS="--cfg tracing_unstable" cargo build

Alternatively, the following can be added to the.cargo/config file in aproject to automatically enable the cfg flag for that project:

[build]rustflags = ["--cfg", "tracing_unstable"]

§Supported Rust Versions

Tracing is built against the latest stable release. The minimum supportedversion is 1.63. The current Tracing version is not guaranteed to build onRust versions earlier than the minimum supported version.

Tracing follows the same compiler support policies as the rest of the Tokioproject. The current stable Rust compiler and the three most recent minorversions before it will always be supported. For example, if the currentstable compiler version is 1.69, the minimum supported version will not beincreased past 1.66, three minor versions prior. Increasing the minimumsupported compiler version is not considered a semver breaking change aslong as doing so complies with this policy.

Modules§

dispatcher
Dispatches trace events toSubscribers.
event
Events represent single points in time during the execution of a program.
field
Span andEvent key-value data.
instrument
Attach a span to astd::future::Future.
level_filters
Trace verbosity level filtering.
span
Spans represent periods of time in which a program was executing in aparticular context.
subscriber
Collects and records trace data.

Macros§

debug
Constructs an event at the debug level.
debug_span
Constructs a span at the debug level.
enabled
Checks whether a span or event isenabled based on the providedmetadata.
error
Constructs an event at the error level.
error_span
Constructs a span at the error level.
event
Constructs a newEvent.
event_enabled
Tests whether an event with the specified level and target would be enabled.
info
Constructs an event at the info level.
info_span
Constructs a span at the info level.
span
Constructs a new span.
span_enabled
Tests whether a span with the specified level and target would be enabled.
trace
Constructs an event at the trace level.
trace_span
Constructs a span at the trace level.
warn
Constructs an event at the warn level.
warn_span
Constructs a span at the warn level.

Structs§

Dispatch
Dispatch trace data to aSubscriber.
Event
Events represent single points in time where something occurred during theexecution of a program.
Level
Describes the level of verbosity of a span or event.
Metadata
Metadata describing aspan orevent.
Span
A handle representing a span, with the capability to enter the span if itexists.

Traits§

Instrument
Attaches spans to astd::future::Future.
Subscriber
Trait representing the functions required to collect trace data.
Value
A field value of an erased type.

Attribute Macros§

instrumentattributes
Instruments a function to create and enter atracingspan every timethe function is called.

[8]ページ先頭

©2009-2025 Movatter.jp