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>,
impl<S> JsonLayer<S>where
S: Subscriber + for<'lookup> LookupSpan<'lookup>,
Source§impl<S, W> JsonLayer<S, W>where
S: Subscriber + for<'lookup> LookupSpan<'lookup>,
impl<S, W> JsonLayer<S, W>where
S: Subscriber + for<'lookup> LookupSpan<'lookup>,
Sourcepub fn with_writer<W2>(self, make_writer: W2) -> JsonLayer<S, W2>where
W2: for<'writer> MakeWriter<'writer> + 'static,
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);
Sourcepub fn writer_mut(&mut self) -> &mut W
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");
Sourcepub fn with_test_writer(self) -> JsonLayer<S, TestWriter>
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();
Sourcepub fn log_internal_errors(&mut self, log_internal_errors: bool) -> &mut Self
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.
Sourcepub fn map_writer<W2>(self, f: impl FnOnce(W) -> W2) -> JsonLayer<S, W2>where
W2: for<'writer> MakeWriter<'writer> + 'static,
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));
Sourcepub fn add_static_field(&mut self, key: impl Into<String>, value: Value)
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()),
);
Sourcepub fn remove_field(&mut self, key: impl Into<String>)
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");
Sourcepub fn add_dynamic_field<Fun, Res>(
&mut self,
key: impl Into<String>,
mapper: Fun,
)
pub fn add_dynamic_field<Fun, Res>( &mut self, key: impl Into<String>, mapper: Fun, )
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()))
});
Sourcepub fn add_multiple_dynamic_fields<Fun, Res>(&mut self, mapper: Fun)
pub fn add_multiple_dynamic_fields<Fun, Res>(&mut self, mapper: Fun)
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()))]
}
});
Sourcepub fn add_from_span<Fun, Res>(&mut self, key: impl Into<String>, mapper: Fun)
pub fn add_from_span<Fun, Res>(&mut self, key: impl Into<String>, mapper: Fun)
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())
);
Sourcepub fn serialize_extension<Ext: Serialize + 'static>(
&mut self,
key: impl Into<String>,
)
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 Layer
s 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);
Sourcepub fn add_from_extension_ref<Ext, Fun, Res>(
&mut self,
key: impl Into<String>,
mapper: Fun,
)
pub fn add_from_extension_ref<Ext, Fun, Res>( &mut self, key: impl Into<String>, mapper: Fun, )
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);
Sourcepub fn add_from_extension<Ext, Fun, Res>(
&mut self,
key: impl Into<String>,
mapper: Fun,
)
pub fn add_from_extension<Ext, Fun, Res>( &mut self, key: impl Into<String>, mapper: Fun, )
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);
Sourcepub fn with_event(&mut self, key: impl Into<String>) -> &mut Self
pub fn with_event(&mut self, key: impl Into<String>) -> &mut Self
Print all event fields in an object with the key as specified.
Sourcepub fn with_top_level_flattened_current_span(&mut self) -> &mut Self
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.
Sourcepub fn with_top_level_flattened_span_list(&mut self) -> &mut Self
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.
Sourcepub fn with_flattened_event(&mut self) -> &mut Self
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.
Sourcepub fn with_current_span(&mut self, key: impl Into<String>) -> &mut Self
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.
Sourcepub fn with_span_list(&mut self, key: impl Into<String>) -> &mut Self
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.
Sourcepub fn with_flattened_span_fields(
&mut self,
key: impl Into<String>,
) -> &mut Self
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.
Sourcepub fn with_timer<T: FormatTime + Send + Sync + 'static>(
&mut self,
key: impl Into<String>,
timer: T,
) -> &mut Self
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.
Sourcepub fn with_target(&mut self, key: impl Into<String>) -> &mut Self
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.
Sourcepub fn with_file(&mut self, key: impl Into<String>) -> &mut Self
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.
Sourcepub fn with_line_number(&mut self, key: impl Into<String>) -> &mut Self
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.
Sourcepub fn with_level(&mut self, key: impl Into<String>) -> &mut Self
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.
Sourcepub fn with_thread_names(&mut self, key: impl Into<String>) -> &mut Self
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.
Sourcepub fn with_thread_ids(&mut self, key: impl Into<String>) -> &mut Self
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.
Sourcepub 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.
pub fn with_opentelemetry_ids( &mut self, display_opentelemetry_ids: bool, ) -> &mut Self
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,
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>)
fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>)
Attributes
and Id
.Source§fn on_record(&self, id: &Id, values: &Record<'_>, ctx: Context<'_, S>)
fn on_record(&self, id: &Id, values: &Record<'_>, ctx: Context<'_, S>)
Id
recorded the given
values
.Source§fn on_enter(&self, _id: &Id, _ctx: Context<'_, S>)
fn on_enter(&self, _id: &Id, _ctx: Context<'_, S>)
Source§fn on_exit(&self, _id: &Id, _ctx: Context<'_, S>)
fn on_exit(&self, _id: &Id, _ctx: Context<'_, S>)
Source§fn on_close(&self, _id: Id, _ctx: Context<'_, S>)
fn on_close(&self, _id: Id, _ctx: Context<'_, S>)
Source§fn on_event(&self, event: &Event<'_>, ctx: Context<'_, S>)
fn on_event(&self, event: &Event<'_>, ctx: Context<'_, S>)
Source§fn on_register_dispatch(&self, subscriber: &Dispatch)
fn on_register_dispatch(&self, subscriber: &Dispatch)
Subscriber
. Read moreSource§fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest
fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest
Subscriber::register_callsite
. Read moreSource§fn enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, S>) -> bool
fn enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, S>) -> bool
true
if this layer is interested in a span or event with the
given metadata
in the current Context
, similarly to
Subscriber::enabled
. Read moreSource§fn on_follows_from(&self, _span: &Id, _follows: &Id, _ctx: Context<'_, S>)
fn on_follows_from(&self, _span: &Id, _follows: &Id, _ctx: Context<'_, S>)
span
recorded that it
follows from the span with the ID follows
.Source§fn on_id_change(&self, _old: &Id, _new: &Id, _ctx: Context<'_, S>)
fn on_id_change(&self, _old: &Id, _new: &Id, _ctx: Context<'_, S>)
Source§fn and_then<L>(self, layer: L) -> Layered<L, Self, S>
fn and_then<L>(self, layer: L) -> Layered<L, Self, S>
Layer
, returning a Layered
struct implementing Layer
. Read moreSource§fn with_subscriber(self, inner: S) -> Layered<Self, S>where
Self: Sized,
fn with_subscriber(self, inner: S) -> Layered<Self, S>where
Self: Sized,
Layer
with the given Subscriber
, returning a
Layered
struct that implements Subscriber
. Read more