Struct JsonLayer

Source
pub struct JsonLayer<S: for<'lookup> LookupSpan<'lookup> = Registry, W = fn() -> Stdout> { /* private fields */ }
Expand description

Layer that implements logging JSON to a configured output. This is a lower-level API that may change a bit in next versions.

See fmt::Layer for an alternative especially if you’re migrating from tracing_subscriber.

Implementations§

Source§

impl<S> JsonLayer<S>
where S: Subscriber + for<'lookup> LookupSpan<'lookup>,

Source

pub fn stdout() -> JsonLayer<S, fn() -> Stdout>

Creates an empty JsonLayer which will output logs to stdout.

Source

pub fn stderr() -> JsonLayer<S, fn() -> Stderr>

Creates an empty JsonLayer which will output logs to stderr.

Source

pub fn new<W>(make_writer: W) -> JsonLayer<S, W>
where W: for<'writer> MakeWriter<'writer> + 'static,

Creates an empty JsonLayer which will output logs to the configured Writer.

Source§

impl<S, W> JsonLayer<S, W>
where S: Subscriber + for<'lookup> LookupSpan<'lookup>,

Source

pub fn with_writer<W2>(self, make_writer: W2) -> JsonLayer<S, W2>
where W2: for<'writer> MakeWriter<'writer> + 'static,

Sets the MakeWriter that the JsonLayer being built will use to write events.

§Examples

Using stderr rather than stdout:

let layer = json_subscriber::JsonLayer::stdout()
    .with_writer(std::io::stderr);
Source

pub fn writer(&self) -> &W

Borrows the writer for this subscriber.

Source

pub fn writer_mut(&mut self) -> &mut W

Mutably borrows the writer for this subscriber.

This method is primarily expected to be used with the reload::Handle::modify method.

§Examples
let layer = json_subscriber::JsonLayer::stdout().with_writer(non_blocking(std::io::stderr()));
let (layer, reload_handle) = reload::Layer::new(layer);

tracing_subscriber::registry().with(layer).init();

info!("This will be logged to stderr");
reload_handle.modify(|subscriber| *subscriber.writer_mut() = non_blocking(std::io::stdout()));
info!("This will be logged to stdout");
Source

pub fn with_test_writer(self) -> JsonLayer<S, TestWriter>

Configures the subscriber to support libtest’s output capturing when used in unit tests.

See TestWriter for additional details.

§Examples

Using TestWriter to let cargo test capture test output:

let layer = json_subscriber::JsonLayer::stdout()
    .with_test_writer();
Source

pub fn log_internal_errors(&mut self, log_internal_errors: bool) -> &mut Self

Sets whether to write errors from FormatEvent to the writer. Defaults to true.

By default, fmt::JsonLayer will write any FormatEvent-internal errors to the writer. These errors are unlikely and will only occur if there is a bug in the FormatEvent implementation or its dependencies.

If writing to the writer fails, the error message is printed to stderr as a fallback.

Source

pub fn map_writer<W2>(self, f: impl FnOnce(W) -> W2) -> JsonLayer<S, W2>
where W2: for<'writer> MakeWriter<'writer> + 'static,

Updates the MakeWriter by applying a function to the existing MakeWriter.

This sets the MakeWriter that the subscriber being built will use to write events.

§Examples

Redirect output to stderr if level is <= WARN:

use tracing_subscriber::fmt::writer::MakeWriterExt;

let stderr = std::io::stderr.with_max_level(tracing::Level::WARN);
let layer = json_subscriber::JsonLayer::stdout()
    .map_writer(move |w| stderr.or_else(w));
Source

pub fn add_static_field(&mut self, key: impl Into<String>, value: Value)

Adds a new static field with a given key to the output.

§Examples

Print hostname in each log:

let mut layer = json_subscriber::JsonLayer::stdout();
layer.add_static_field(
    "hostname",
    serde_json::Value::String(get_hostname().to_owned()),
);
Source

pub fn remove_field(&mut self, key: impl Into<String>)

Removes a field that was inserted to the output. This can only remove fields that have a static key, not keys added with add_multiple_dynamic_fields.

§Examples

Add a field and then remove it:

let mut layer = json_subscriber::JsonLayer::stdout();
layer.add_static_field(
    "deleteMe",
    serde_json::json!("accident"),
);
layer.remove_field("deleteMe");
Source

pub fn add_dynamic_field<Fun, Res>( &mut self, key: impl Into<String>, mapper: Fun, )
where for<'a> Fun: Fn(&'a Event<'_>, &Context<'_, S>) -> Option<Res> + Send + Sync + 'a, Res: Serialize,

Adds a new dynamic field with a given key to the output. This method is more general than add_static_field but also more expensive.

This method takes a closure argument that will be called with the event and tracing context. Through these, the parent span can be accessed among other things. This closure returns an Option where nothing will be added to the output if None is returned.

§Examples

Print an atomic counter.

static COUNTER: AtomicU32 = AtomicU32::new(42);

let mut layer = json_subscriber::JsonLayer::stdout();
layer.add_dynamic_field(
    "counter",
    |_event, _context| {
        Some(serde_json::Value::Number(COUNTER.load(Ordering::Relaxed).into()))
});
Source

pub fn add_multiple_dynamic_fields<Fun, Res>(&mut self, mapper: Fun)
where for<'a> Fun: Fn(&'a Event<'_>, &Context<'_, S>) -> Res + Send + Sync + 'a, Res: IntoIterator<Item = (String, Value)>,

Adds multiple new dynamic field where the keys may not be known when calling this method.

This method takes a closure argument that will be called with the event and tracing context. Through these, the parent span can be accessed among other things. This closure returns a value which can be iterated over to return a tuple of a String which will be used as a JSON key and a serde_json::Value which will be used as a value. In most cases returning HashMap<String, serde_json::Value> should be sufficient.

It is the user’s responsibility to make sure that no two keys clash as that would create an invalid JSON. It’s generally better to use add_dynamic_field instead if the field names are known.

§Examples

Print either a question or an answer:


let mut layer = json_subscriber::JsonLayer::stdout();
layer.add_multiple_dynamic_fields(
    |_event, _context| {
        if condition {
            [("question".to_owned(), serde_json::Value::String("What?".to_owned()))]
        } else {
            [("answer".to_owned(), serde_json::Value::Number(42.into()))]
        }
});
Source

pub fn add_from_span<Fun, Res>(&mut self, key: impl Into<String>, mapper: Fun)
where for<'a> Fun: Fn(&'a SpanRef<'_, S>) -> Option<Res> + Send + Sync + 'a, Res: Serialize,

Adds a new dynamic field with a given key to the output. This method is a specialized version of add_dynamic_field where just a reference to the parent span is needed.

This method takes a closure argument that will be called with the parent span context. This closure returns an Option where nothing will be added to the output if None is returned.

§Examples

Print uppercase target:


let mut layer = json_subscriber::JsonLayer::stdout();
layer.add_from_span(
    "TARGET",
    |span| Some(span.metadata().target().to_uppercase())
);
Source

pub fn serialize_extension<Ext: Serialize + 'static>( &mut self, key: impl Into<String>, )

Adds a field with a given key to the output. The value will be serialized JSON of the provided extension. Other Layers may add these extensions to the span.

The serialization happens every time a log line is emitted so if the extension changes, the latest version will be emitted.

If the extension is not found, nothing is added to the output.

§Examples
struct FooLayer;

#[derive(Serialize)]
struct Foo(String);

impl<S: Subscriber + for<'lookup> LookupSpan<'lookup>> Layer<S> for FooLayer {
    fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>) {
        let span = ctx.span(id).unwrap();
        let mut extensions = span.extensions_mut();
        let foo = Foo("hello".to_owned());
        extensions.insert(foo);
    }
}

let foo_layer = FooLayer;

let mut layer = json_subscriber::JsonLayer::stdout();
layer.serialize_extension::<Foo>("foo");

registry().with(foo_layer).with(layer);
Source

pub fn add_from_extension_ref<Ext, Fun, Res>( &mut self, key: impl Into<String>, mapper: Fun, )
where Ext: 'static, for<'a> Fun: Fn(&'a Ext) -> Option<&'a Res> + Send + Sync + 'a, Res: Serialize,

Adds a field with a given key to the output. The user-provided closure can transform the extension and return reference to any serializable structure.

The mapping and serialization happens every time a log line is emitted so if the extension changes, the latest version will be emitted.

If the extension is not found, or the mapping returns None, nothing is added to the output.

Use Self::add_from_extension if you cannot return a reference.

§Examples
struct FooLayer;

#[derive(Serialize)]
struct Foo(String);

impl<S: Subscriber + for<'lookup> LookupSpan<'lookup>> Layer<S> for FooLayer {
    fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>) {
        let span = ctx.span(id).unwrap();
        let mut extensions = span.extensions_mut();
        let foo = Foo("hello".to_owned());
        extensions.insert(foo);
    }
}

let foo_layer = FooLayer;

let mut layer = json_subscriber::JsonLayer::stdout();
layer.add_from_extension_ref::<Foo, _, _>("foo", |foo| Some(&foo.0));

registry().with(foo_layer).with(layer);
Source

pub fn add_from_extension<Ext, Fun, Res>( &mut self, key: impl Into<String>, mapper: Fun, )
where Ext: 'static, for<'a> Fun: Fn(&'a Ext) -> Option<Res> + Send + Sync + 'a, Res: Serialize,

Adds a field with a given key to the output. The user-provided closure can transform the extension and return any serializable structure.

The mapping and serialization happens every time a log line is emitted so if the extension changes, the latest version will be emitted.

If the extension is not found, or the mapping returns None, nothing is added to the output.

Use Self::add_from_extension_ref if you want to return a reference to data in the extension.

§Examples
struct FooLayer;

#[derive(Serialize)]
struct Foo(String);

impl<S: Subscriber + for<'lookup> LookupSpan<'lookup>> Layer<S> for FooLayer {
    fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>) {
        let span = ctx.span(id).unwrap();
        let mut extensions = span.extensions_mut();
        let foo = Foo("hello".to_owned());
        extensions.insert(foo);
    }
}

let foo_layer = FooLayer;

let mut layer = json_subscriber::JsonLayer::stdout();
layer.add_from_extension::<Foo, _, _>("foo", |foo| foo.0.parse::<u64>().ok());

registry().with(foo_layer).with(layer);
Source

pub fn with_event(&mut self, key: impl Into<String>) -> &mut Self

Print all event fields in an object with the key as specified.

Source

pub fn with_top_level_flattened_current_span(&mut self) -> &mut Self

Print all current span fields, each as its own top level member of the JSON.

It is the user’s responsibility to make sure that the field names will not clash with other defined members of the output JSON. If they clash, invalid JSON with multiple fields with the same key may be generated.

It’s therefore preferable to use with_current_span instead.

Source

pub fn with_top_level_flattened_span_list(&mut self) -> &mut Self

Print all parent spans’ fields, each as its own top level member of the JSON.

If multiple spans define the same field, the one furthest from the root span will be kept.

It is the user’s responsibility to make sure that the field names will not clash with other defined members of the output JSON. If they clash, invalid JSON with multiple fields with the same key may be generated.

It’s therefore preferable to use with_span_list instead.

Source

pub fn with_flattened_event(&mut self) -> &mut Self

Print all event fields, each as its own top level member of the JSON.

It is the user’s responsibility to make sure that the field names will not clash with other defined members of the output JSON. If they clash, invalid JSON with multiple fields with the same key may be generated.

It’s therefore preferable to use with_event instead.

Source

pub fn with_current_span(&mut self, key: impl Into<String>) -> &mut Self

Sets whether or not the log line will include the current span in formatted events.

Source

pub fn with_span_list(&mut self, key: impl Into<String>) -> &mut Self

Sets whether or not the formatter will include a list (from root to leaf) of all currently entered spans in formatted events.

Source

pub fn with_flattened_span_fields( &mut self, key: impl Into<String>, ) -> &mut Self

Sets the formatter to include an object containing all parent spans’ fields. If multiple ancestor spans recorded the same field, the span closer to the leaf span overrides the values of spans that are closer to the root spans.

Source

pub fn with_timer<T: FormatTime + Send + Sync + 'static>( &mut self, key: impl Into<String>, timer: T, ) -> &mut Self

Use the given timer for log message timestamps with the timestamp key.

See the time module for the provided timer implementations.

Source

pub fn with_target(&mut self, key: impl Into<String>) -> &mut Self

Sets whether or not an event’s target is displayed. It will use the target key if so.

Source

pub fn with_file(&mut self, key: impl Into<String>) -> &mut Self

Sets whether or not an event’s source code file path is displayed. It will use the file key if so.

Source

pub fn with_line_number(&mut self, key: impl Into<String>) -> &mut Self

Sets whether or not an event’s source code line number is displayed. It will use the line_number key if so.

Source

pub fn with_level(&mut self, key: impl Into<String>) -> &mut Self

Sets whether or not an event’s level is displayed. It will use the level key if so.

Source

pub fn with_thread_names(&mut self, key: impl Into<String>) -> &mut Self

Sets whether or not the name of the current thread is displayed when formatting events. It will use the threadName key if so.

Source

pub fn with_thread_ids(&mut self, key: impl Into<String>) -> &mut Self

Sets whether or not the thread ID of the current thread is displayed when formatting events. It will use the threadId key if so.

Source

pub fn with_opentelemetry_ids( &mut self, display_opentelemetry_ids: bool, ) -> &mut Self

Available on crate features opentelemetry or tracing-opentelemetry-0-28 or tracing-opentelemetry-0-29 or tracing-opentelemetry-0-30 or tracing-opentelemetry-0-31 only.

Sets whether or not OpenTelemetry trace ID and span ID is displayed when formatting events. It will use the openTelemetry key if so and the value will be an object with traceId and spanId fields, each being a string.

This works only if your tracing-opentelemetry version and this crate’s features match. If you update that dependency, you need to change the feature here or this call will do nothing.

Trait Implementations§

Source§

impl<S, W> Layer<S> for JsonLayer<S, W>
where S: Subscriber + for<'lookup> LookupSpan<'lookup>, W: for<'writer> MakeWriter<'writer> + 'static,

Source§

fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>)

Notifies this layer that a new span was constructed with the given Attributes and Id.
Source§

fn on_record(&self, id: &Id, values: &Record<'_>, ctx: Context<'_, S>)

Notifies this layer that a span with the given Id recorded the given values.
Source§

fn on_enter(&self, _id: &Id, _ctx: Context<'_, S>)

Notifies this layer that a span with the given ID was entered.
Source§

fn on_exit(&self, _id: &Id, _ctx: Context<'_, S>)

Notifies this layer that the span with the given ID was exited.
Source§

fn on_close(&self, _id: Id, _ctx: Context<'_, S>)

Notifies this layer that the span with the given ID has been closed.
Source§

fn on_event(&self, event: &Event<'_>, ctx: Context<'_, S>)

Notifies this layer that an event has occurred.
Source§

fn on_register_dispatch(&self, subscriber: &Dispatch)

Performs late initialization when installing this layer as a Subscriber. Read more
Source§

fn on_layer(&mut self, subscriber: &mut S)

Performs late initialization when attaching a Layer to a Subscriber. Read more
Source§

fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest

Registers a new callsite with this layer, returning whether or not the layer is interested in being notified about the callsite, similarly to Subscriber::register_callsite. Read more
Source§

fn enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, S>) -> bool

Returns true if this layer is interested in a span or event with the given metadata in the current Context, similarly to Subscriber::enabled. Read more
Source§

fn on_follows_from(&self, _span: &Id, _follows: &Id, _ctx: Context<'_, S>)

Notifies this layer that a span with the ID span recorded that it follows from the span with the ID follows.
Source§

fn event_enabled(&self, _event: &Event<'_>, _ctx: Context<'_, S>) -> bool

Called before on_event, to determine if on_event should be called. Read more
Source§

fn on_id_change(&self, _old: &Id, _new: &Id, _ctx: Context<'_, S>)

Notifies this layer that a span ID has been cloned, and that the subscriber returned a different ID.
Source§

fn and_then<L>(self, layer: L) -> Layered<L, Self, S>
where L: Layer<S>, Self: Sized,

Composes this layer around the given Layer, returning a Layered struct implementing Layer. Read more
Source§

fn with_subscriber(self, inner: S) -> Layered<Self, S>
where Self: Sized,

Composes this Layer with the given Subscriber, returning a Layered struct that implements Subscriber. Read more
Source§

fn with_filter<F>(self, filter: F) -> Filtered<Self, F, S>
where Self: Sized, F: Filter<S>,

Combines self with a Filter, returning a Filtered layer. Read more
Source§

fn boxed(self) -> Box<dyn Layer<S> + Send + Sync>
where Self: Sized + Layer<S> + Send + Sync + 'static, S: Subscriber,

Erases the type of this Layer, returning a Boxed dyn Layer trait object. Read more

Auto Trait Implementations§

§

impl<S, W> Freeze for JsonLayer<S, W>
where W: Freeze,

§

impl<S = Registry, W = fn() -> Stdout> !RefUnwindSafe for JsonLayer<S, W>

§

impl<S, W> Send for JsonLayer<S, W>
where W: Send,

§

impl<S, W> Sync for JsonLayer<S, W>
where W: Sync,

§

impl<S, W> Unpin for JsonLayer<S, W>
where W: Unpin,

§

impl<S = Registry, W = fn() -> Stdout> !UnwindSafe for JsonLayer<S, W>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FutureExt for T

Source§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
Source§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
Source§

impl<T> FutureExt for T

Source§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
Source§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
Source§

impl<T> FutureExt for T

Source§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
Source§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
Source§

impl<T> FutureExt for T

Source§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
Source§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
Source§

impl<T> FutureExt for T

Source§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
Source§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more