Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Impl Layer for Option<T:Layer> #910

Merged
merged 7 commits into from
Aug 14, 2020
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ This directory contains a collection of examples that demonstrate the use of the
debug a server under load in production.
+ `journald`: Demonstrates how to use `fmt` and `journald` layers to output to
both the terminal and the system journal.
+ `toggle-layers` : Demonstrates how Layers can be wrapped with an `Option` allowing
them to be dynamically toggled.
- **tracing-futures**:
+ `spawny-thing`: Demonstrates the use of the `#[instrument]` attribute macro
asynchronous functions.
Expand Down
47 changes: 47 additions & 0 deletions examples/examples/toggle-layers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#![deny(rust_2018_idioms)]
Pothulapati marked this conversation as resolved.
Show resolved Hide resolved
/// This is a example showing how `Layer` can be enabled or disabled by
/// by wrapping them with an `Option`. This example shows `fmt` and `json`
/// being toggled based on the `json` command line flag.
///
/// You can run this example by running the following command in a terminal
///
/// ```
/// cargo run --example toggle-layers -- json
/// ```
///
use clap::{App, Arg};
use tracing::info;
use tracing_subscriber::{prelude::__tracing_subscriber_SubscriberExt, util::SubscriberInitExt};

#[path = "fmt/yak_shave.rs"]
mod yak_shave;

fn main() {
let matches = App::new("fmt optional Example")
.version("1.0")
.arg(
Arg::with_name("json")
.help("Enabling json formatting of logs")
.required(false)
.takes_value(false),
)
.get_matches();

let (json, plain) = if matches.is_present("json") {
(Some(tracing_subscriber::fmt::layer().json()), None)
} else {
(None, Some(tracing_subscriber::fmt::layer()))
};

tracing_subscriber::registry().with(json).with(plain).init();
Comment on lines +30 to +36
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to have an abbreviated version of this example in the docs for the Layer trait. Maybe also a version showing runtime reloading in the layer::reload docs.


let number_of_yaks = 3;
// this creates a new event, outside of any spans.
info!(number_of_yaks, "preparing to shave yaks");

let number_shaved = yak_shave::shave_all(number_of_yaks);
info!(
all_yaks_shaved = number_shaved == number_of_yaks,
"yak shaving completed."
);
}
98 changes: 98 additions & 0 deletions tracing-subscriber/src/layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -808,6 +808,104 @@ where
}
}

impl<L, S> Layer<S> for Option<L>
where
L: Layer<S>,
S: Subscriber,
{
#[inline]
fn new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, ctx: Context<'_, S>) {
if let Some(ref inner) = self {
inner.new_span(attrs, id, ctx)
}
}

#[inline]
fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest {
match self {
Some(ref inner) => inner.register_callsite(metadata),
None => Interest::always(),
hawkw marked this conversation as resolved.
Show resolved Hide resolved
}
}

#[inline]
fn enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, S>) -> bool {
match self {
Some(ref inner) => inner.enabled(metadata, ctx),
None => true,
Pothulapati marked this conversation as resolved.
Show resolved Hide resolved
}
}

#[inline]
fn max_level_hint(&self) -> Option<LevelFilter> {
match self {
Some(ref inner) => inner.max_level_hint(),
None => None,
}
Comment on lines +841 to +844
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit, take it or leave it: this could also be expressed using Option::and_then, like this:

Suggested change
match self {
Some(ref inner) => inner.max_level_hint(),
None => None,
}
self.and_then(Layer::max_level_hint)

}

#[inline]
fn on_record(&self, span: &span::Id, values: &span::Record<'_>, ctx: Context<'_, S>) {
if let Some(ref inner) = self {
inner.on_record(span, values, ctx);
}
}

#[inline]
fn on_follows_from(&self, span: &span::Id, follows: &span::Id, ctx: Context<'_, S>) {
if let Some(ref inner) = self {
inner.on_follows_from(span, follows, ctx);
}
}

#[inline]
fn on_event(&self, event: &Event<'_>, ctx: Context<'_, S>) {
if let Some(ref inner) = self {
inner.on_event(event, ctx);
}
}

#[inline]
fn on_enter(&self, id: &span::Id, ctx: Context<'_, S>) {
if let Some(ref inner) = self {
inner.on_enter(id, ctx);
}
}

#[inline]
fn on_exit(&self, id: &span::Id, ctx: Context<'_, S>) {
if let Some(ref inner) = self {
inner.on_exit(id, ctx);
}
}

#[inline]
fn on_close(&self, id: span::Id, ctx: Context<'_, S>) {
if let Some(ref inner) = self {
inner.on_close(id, ctx);
}
}

#[inline]
Pothulapati marked this conversation as resolved.
Show resolved Hide resolved
fn on_id_change(&self, old: &span::Id, new: &span::Id, ctx: Context<'_, S>) {
if let Some(ref inner) = self {
inner.on_id_change(old, new, ctx)
}
}

#[doc(hidden)]
hawkw marked this conversation as resolved.
Show resolved Hide resolved
unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> {
if id == TypeId::of::<Self>() {
Some(self as *const _ as *const ())
} else {
match self {
Some(inner) => inner.downcast_raw(id),
None => None,
}
hawkw marked this conversation as resolved.
Show resolved Hide resolved
}
}
Pothulapati marked this conversation as resolved.
Show resolved Hide resolved
}

#[cfg(feature = "registry")]
#[cfg_attr(docsrs, doc(cfg(feature = "registry")))]
impl<'a, L, S> LookupSpan<'a> for Layered<L, S>
Expand Down