-
Notifications
You must be signed in to change notification settings - Fork 721
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
subscriber: add MakeWriter::make_writer_for
#1141
Conversation
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
This would just mean writing something like |
tracing-subscriber/src/fmt/writer.rs
Outdated
/// might write some values to the writer before or after providing it to | ||
/// the caller. | ||
/// | ||
/// For example, we ight want to write data from spans and events at the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo (ight
instead of might
)
tracing-subscriber/src/fmt/writer.rs
Outdated
/// Stderr(StderrLock<'a>), | ||
/// } | ||
/// | ||
/// impl io::Write for StdioLock { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
StdioLock
needs a lifetime parameter
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
@davidbarsky et al. mind giving this a review? i have some ideas for subsequent things we can add based on this... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I genuinely thought i reviewed this thing. Sorry! Looks good to me.
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
Currently looking into hooking tracing into Android's logging system, which has dedicated interfaces for levels and source locations, and this would be amazing.
Looks like I'm absolutely awful at reading docs and after double checking this is already a thing. My bad, sorry for the noise. |
Depends on #1141. This branch adds a `MakeWriterExt` trait which adds a number of combinators for composing multiple types implementing `MakeWriter`. `MakeWriter`s can now be teed together, filtered with minimum and maximum levels, filtered with a `Metadata` predicate, and combined with a fallback for when a writer is _not_ made for a particular `Metadata`. I've also added a `MakeWriter` impl for `std::fs::File`, because `&File` implements `Write`. Ideally, we'd have a default impl of `MakeWriter` for `T where &T: Write`, but that's not possible due to the impl of `MakeWriter` for `F: Fn() -> T: Write`. We could add a generic `by_ref` adapter for any `T where &T: Write`, though... Signed-off-by: Eliza Weisman <eliza@buoyant.io>
This backports PR #1141 from `master`. subscriber: add `MakeWriter::make_writer_for` ## Motivation In some cases, it might be desirable to configure the writer used for writing out trace data based on the metadata of the span or event being written. For example, we might want to send different levels to different outputs, write logs from different targets to separate files, or wrap formatted output in ANSI color codes based on levels. Currently, it's not possible for the `MakeWriter` trait to model this kind of behavior --- it has one method, `make_writer`, which is completely unaware of *where* the data being written came from. In particular, this came up in PR #1137, when discussing a proposal that writing to syslog could be implemented as a `MakeWriter` implementation rather than as a `Subscribe` implementation, so that all the formatting logic from `tracing_subscriber::fmt` could be reused. See [here][1] for details. ## Solution This branch adds a new `make_writer_for` method to `MakeWriter`, taking a `Metadata`. Implementations can opt in to metadata-specific behavior by implementing this method. The method has a default implementation that just calls `self.make_writer()` and ignores the metadata, so it's only necessary to implement this when per-metadata behavior is required. This isn't a breaking change to existing implementations. There are a couple downsides to this approach: it's possible for callers to skip the metadata-specific behavior by calling `make_writer` rather than `make_writer_for`, and the impls for closures can't easily provide metadata-specific behavior. Since the upcoming release is going to be a breaking change anyway, we may want to just make the breaking change of having `MakeWriter::make_writer` _always_ take a `Metadata`, which solves these problems. However, that can't be backported to v0.1.x as easily. Additionally, that would mean that functions like `io::stdout` no longer implement `MakeWriter`; they would have to be wrapped in a wrapper type or closure that ignores metadata. [1]: #1137 (comment) Signed-off-by: Eliza Weisman <eliza@buoyant.io>
This backports #1274 from `master`. Depends on #1141. This branch adds a `MakeWriterExt` trait which adds a number of combinators for composing multiple types implementing `MakeWriter`. `MakeWriter`s can now be teed together, filtered with minimum and maximum levels, filtered with a `Metadata` predicate, and combined with a fallback for when a writer is _not_ made for a particular `Metadata`. I've also added a `MakeWriter` impl for `Arc<W>` when `&W` implements `Write`. This enables `File`s to be used as `MakeWriter`s similarly to how we will be able to in 0.3, with the additional overhead of having to do ref-counting because we can't return a reference from `MakeWriter` until the next breaking change. Signed-off-by: Eliza Weisman <eliza@buoyant.io>
This backports PR #1141 from `master`. subscriber: add `MakeWriter::make_writer_for` ## Motivation In some cases, it might be desirable to configure the writer used for writing out trace data based on the metadata of the span or event being written. For example, we might want to send different levels to different outputs, write logs from different targets to separate files, or wrap formatted output in ANSI color codes based on levels. Currently, it's not possible for the `MakeWriter` trait to model this kind of behavior --- it has one method, `make_writer`, which is completely unaware of *where* the data being written came from. In particular, this came up in PR #1137, when discussing a proposal that writing to syslog could be implemented as a `MakeWriter` implementation rather than as a `Subscribe` implementation, so that all the formatting logic from `tracing_subscriber::fmt` could be reused. See [here][1] for details. ## Solution This branch adds a new `make_writer_for` method to `MakeWriter`, taking a `Metadata`. Implementations can opt in to metadata-specific behavior by implementing this method. The method has a default implementation that just calls `self.make_writer()` and ignores the metadata, so it's only necessary to implement this when per-metadata behavior is required. This isn't a breaking change to existing implementations. There are a couple downsides to this approach: it's possible for callers to skip the metadata-specific behavior by calling `make_writer` rather than `make_writer_for`, and the impls for closures can't easily provide metadata-specific behavior. Since the upcoming release is going to be a breaking change anyway, we may want to just make the breaking change of having `MakeWriter::make_writer` _always_ take a `Metadata`, which solves these problems. However, that can't be backported to v0.1.x as easily. Additionally, that would mean that functions like `io::stdout` no longer implement `MakeWriter`; they would have to be wrapped in a wrapper type or closure that ignores metadata. [1]: #1137 (comment) Signed-off-by: Eliza Weisman <eliza@buoyant.io>
This backports #1274 from `master`. Depends on #1141. This branch adds a `MakeWriterExt` trait which adds a number of combinators for composing multiple types implementing `MakeWriter`. `MakeWriter`s can now be teed together, filtered with minimum and maximum levels, filtered with a `Metadata` predicate, and combined with a fallback for when a writer is _not_ made for a particular `Metadata`. I've also added a `MakeWriter` impl for `Arc<W>` when `&W` implements `Write`. This enables `File`s to be used as `MakeWriter`s similarly to how we will be able to in 0.3, with the additional overhead of having to do ref-counting because we can't return a reference from `MakeWriter` until the next breaking change. Signed-off-by: Eliza Weisman <eliza@buoyant.io>
# 0.2.19 (June 25, 2021) ### Deprecated - **registry**: `SpanRef::parents`, `SpanRef::from_root`, and `Context::scope` iterators, which are replaced by new `SpanRef::scope` and `Scope::from_root` iterators (#1413) ### Added - **registry**: `SpanRef::scope` method, which returns a leaf-to-root `Iterator` including the leaf span (#1413) - **registry**: `Scope::from_root` method, which reverses the `scope` iterator to iterate root-to-leaf (#1413) - **registry**: `Context::event_span` method, which looks up the parent span of an event (#1434) - **registry**: `Context::event_scope` method, returning a `Scope` iterator over the span scope of an event (#1434) - **fmt**: `MakeWriter::make_writer_for` method, which allows returning a different writer based on a span or event's metadata (#1141) - **fmt**: `MakeWriterExt` trait, with `with_max_level`, `with_min_level`, `with_filter`, `and`, and `or_else` combinators (#1274) - **fmt**: `MakeWriter` implementation for `Arc<W> where &W: io::Write` (#1274) Thanks to @teozkr and @Folyd for contributing to this release!
# 0.2.19 (June 25, 2021) ### Deprecated - **registry**: `SpanRef::parents`, `SpanRef::from_root`, and `Context::scope` iterators, which are replaced by new `SpanRef::scope` and `Scope::from_root` iterators (#1413) ### Added - **registry**: `SpanRef::scope` method, which returns a leaf-to-root `Iterator` including the leaf span (#1413) - **registry**: `Scope::from_root` method, which reverses the `scope` iterator to iterate root-to-leaf (#1413) - **registry**: `Context::event_span` method, which looks up the parent span of an event (#1434) - **registry**: `Context::event_scope` method, returning a `Scope` iterator over the span scope of an event (#1434) - **fmt**: `MakeWriter::make_writer_for` method, which allows returning a different writer based on a span or event's metadata (#1141) - **fmt**: `MakeWriterExt` trait, with `with_max_level`, `with_min_level`, `with_filter`, `and`, and `or_else` combinators (#1274) - **fmt**: `MakeWriter` implementation for `Arc<W> where &W: io::Write` (#1274) Thanks to @teozkr and @Folyd for contributing to this release!
This backports PR tokio-rs#1141 from `master`. subscriber: add `MakeWriter::make_writer_for` ## Motivation In some cases, it might be desirable to configure the writer used for writing out trace data based on the metadata of the span or event being written. For example, we might want to send different levels to different outputs, write logs from different targets to separate files, or wrap formatted output in ANSI color codes based on levels. Currently, it's not possible for the `MakeWriter` trait to model this kind of behavior --- it has one method, `make_writer`, which is completely unaware of *where* the data being written came from. In particular, this came up in PR tokio-rs#1137, when discussing a proposal that writing to syslog could be implemented as a `MakeWriter` implementation rather than as a `Subscribe` implementation, so that all the formatting logic from `tracing_subscriber::fmt` could be reused. See [here][1] for details. ## Solution This branch adds a new `make_writer_for` method to `MakeWriter`, taking a `Metadata`. Implementations can opt in to metadata-specific behavior by implementing this method. The method has a default implementation that just calls `self.make_writer()` and ignores the metadata, so it's only necessary to implement this when per-metadata behavior is required. This isn't a breaking change to existing implementations. There are a couple downsides to this approach: it's possible for callers to skip the metadata-specific behavior by calling `make_writer` rather than `make_writer_for`, and the impls for closures can't easily provide metadata-specific behavior. Since the upcoming release is going to be a breaking change anyway, we may want to just make the breaking change of having `MakeWriter::make_writer` _always_ take a `Metadata`, which solves these problems. However, that can't be backported to v0.1.x as easily. Additionally, that would mean that functions like `io::stdout` no longer implement `MakeWriter`; they would have to be wrapped in a wrapper type or closure that ignores metadata. [1]: tokio-rs#1137 (comment) Signed-off-by: Eliza Weisman <eliza@buoyant.io>
This backports tokio-rs#1274 from `master`. Depends on tokio-rs#1141. This branch adds a `MakeWriterExt` trait which adds a number of combinators for composing multiple types implementing `MakeWriter`. `MakeWriter`s can now be teed together, filtered with minimum and maximum levels, filtered with a `Metadata` predicate, and combined with a fallback for when a writer is _not_ made for a particular `Metadata`. I've also added a `MakeWriter` impl for `Arc<W>` when `&W` implements `Write`. This enables `File`s to be used as `MakeWriter`s similarly to how we will be able to in 0.3, with the additional overhead of having to do ref-counting because we can't return a reference from `MakeWriter` until the next breaking change. Signed-off-by: Eliza Weisman <eliza@buoyant.io>
# 0.2.19 (June 25, 2021) ### Deprecated - **registry**: `SpanRef::parents`, `SpanRef::from_root`, and `Context::scope` iterators, which are replaced by new `SpanRef::scope` and `Scope::from_root` iterators (tokio-rs#1413) ### Added - **registry**: `SpanRef::scope` method, which returns a leaf-to-root `Iterator` including the leaf span (tokio-rs#1413) - **registry**: `Scope::from_root` method, which reverses the `scope` iterator to iterate root-to-leaf (tokio-rs#1413) - **registry**: `Context::event_span` method, which looks up the parent span of an event (tokio-rs#1434) - **registry**: `Context::event_scope` method, returning a `Scope` iterator over the span scope of an event (tokio-rs#1434) - **fmt**: `MakeWriter::make_writer_for` method, which allows returning a different writer based on a span or event's metadata (tokio-rs#1141) - **fmt**: `MakeWriterExt` trait, with `with_max_level`, `with_min_level`, `with_filter`, `and`, and `or_else` combinators (tokio-rs#1274) - **fmt**: `MakeWriter` implementation for `Arc<W> where &W: io::Write` (tokio-rs#1274) Thanks to @teozkr and @Folyd for contributing to this release!
subscriber: add
MakeWriter::make_writer_for
Motivation
In some cases, it might be desirable to configure the writer used for
writing out trace data based on the metadata of the span or event being
written. For example, we might want to send different levels to
different outputs, write logs from different targets to separate files,
or wrap formatted output in ANSI color codes based on levels. Currently,
it's not possible for the
MakeWriter
trait to model this kind ofbehavior --- it has one method,
make_writer
, which is completelyunaware of where the data being written came from.
In particular, this came up in PR #1137, when discussing a proposal that
writing to syslog could be implemented as a
MakeWriter
implementationrather than as a
Subscribe
implementation, so that all the formattinglogic from
tracing_subscriber::fmt
could be reused. See here fordetails.
Solution
This branch adds a new
make_writer_for
method toMakeWriter
, takinga
Metadata
. Implementations can opt in to metadata-specific behaviorby implementing this method. The method has a default implementation
that just calls
self.make_writer()
and ignores the metadata, so it'sonly necessary to implement this when per-metadata behavior is required.
This isn't a breaking change to existing implementations.
There are a couple downsides to this approach: it's possible for callers
to skip the metadata-specific behavior by calling
make_writer
ratherthan
make_writer_for
, and the impls for closures can't easily providemetadata-specific behavior.
Since the upcoming release is going to be a breaking change anyway, we
may want to just make the breaking change of having
MakeWriter::make_writer
always take aMetadata
, which solves theseproblems. However, that can't be backported to v0.1.x as easily. Additionally,
that would mean that functions like
io::stdout
no longer implementMakeWriter
; they would have to be wrapped in a wrapper type or closurethat ignores metadata.