• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Writers for logging events and spans
2 //!
3 //! # Overview
4 //!
5 //! [`tracing`][tracing] is a framework for structured, event-based diagnostic information.
6 //! `tracing-appender` allows events and spans to be recorded in a non-blocking manner through
7 //! a dedicated logging thread. It also provides a [`RollingFileAppender`][file_appender] that can
8 //! be used with _or_ without the non-blocking writer.
9 //!
10 //! *Compiler support: [requires `rustc` 1.53+][msrv]*
11 //!
12 //! [msrv]: #supported-rust-versions
13 //! [file_appender]: rolling::RollingFileAppender
14 //! [tracing]: https://docs.rs/tracing/
15 //!
16 //! # Usage
17 //!
18 //! Add the following to your `Cargo.toml`:
19 //! ```toml
20 //! tracing-appender = "0.2"
21 //! ```
22 //!
23 //! This crate can be used in a few ways to record spans/events:
24 //!  - Using a [`RollingFileAppender`][rolling_struct] to perform writes to a log file. This will block on writes.
25 //!  - Using *any* type implementing [`std::io::Write`][write] in a non-blocking fashion.
26 //!  - Using a combination of [`NonBlocking`][non_blocking] and [`RollingFileAppender`][rolling_struct] to allow writes to a log file
27 //! without blocking.
28 //!
29 //! ## Rolling File Appender
30 //!
31 //! ```rust
32 //! # fn docs() {
33 //! let file_appender = tracing_appender::rolling::hourly("/some/directory", "prefix.log");
34 //! # }
35 //! ```
36 //! This creates an hourly rotating file appender that writes to `/some/directory/prefix.log.YYYY-MM-DD-HH`.
37 //! [`Rotation::DAILY`](rolling::Rotation::DAILY) and [`Rotation::NEVER`](rolling::Rotation::NEVER) are the other available options.
38 //!
39 //! The file appender implements [`std::io::Write`][write]. To be used with [`tracing_subscriber::FmtSubscriber`][fmt_subscriber],
40 //! it must be combined with a [`MakeWriter`][make_writer] implementation to be able to record tracing spans/event.
41 //!
42 //! The [`rolling` module][rolling]'s documentation provides more detail on how to use this file appender.
43 //!
44 //! ## Non-Blocking Writer
45 //!
46 //! The example below demonstrates the construction of a `non_blocking` writer with `std::io::stdout()`,
47 //! which implements [`MakeWriter`][make_writer].
48 //!
49 //! ```rust
50 //! # fn doc() {
51 //! let (non_blocking, _guard) = tracing_appender::non_blocking(std::io::stdout());
52 //! tracing_subscriber::fmt()
53 //!     .with_writer(non_blocking)
54 //!     .init();
55 //! # }
56 //! ```
57 //! **Note:** `_guard` is a [`WorkerGuard`][guard] which is returned by [`tracing_appender::non_blocking`][non_blocking]
58 //! to ensure buffered logs are flushed to their output in the case of abrupt terminations of a process.
59 //! See [`WorkerGuard` module][guard] for more details.
60 //!
61 //! The example below demonstrates the construction of a [`tracing_appender::non_blocking`][non_blocking]
62 //! writer constructed with a [`std::io::Write`][write]:
63 //!
64 //! ```rust
65 //! use std::io::Error;
66 //!
67 //! struct TestWriter;
68 //!
69 //! impl std::io::Write for TestWriter {
70 //!     fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
71 //!         let buf_len = buf.len();
72 //!         println!("{:?}", buf);
73 //!         Ok(buf_len)
74 //!     }
75 //!
76 //!     fn flush(&mut self) -> std::io::Result<()> {
77 //!         Ok(())
78 //!     }
79 //! }
80 //!
81 //! # fn doc() {
82 //! let (non_blocking, _guard) = tracing_appender::non_blocking(TestWriter);
83 //! tracing_subscriber::fmt()
84 //!     .with_writer(non_blocking)
85 //!     .init();
86 //! # }
87 //! ```
88 //!
89 //! The [`non_blocking` module][non_blocking]'s documentation provides more detail on how to use `non_blocking`.
90 //!
91 //! [non_blocking]: mod@non_blocking
92 //! [write]: std::io::Write
93 //! [guard]: non_blocking::WorkerGuard
94 //! [make_writer]: tracing_subscriber::fmt::MakeWriter
95 //! [rolling_struct]: rolling::RollingFileAppender
96 //! [fmt_subscriber]: tracing_subscriber::fmt::Subscriber
97 //!
98 //! ## Non-Blocking Rolling File Appender
99 //!
100 //! ```rust
101 //! # fn docs() {
102 //! let file_appender = tracing_appender::rolling::hourly("/some/directory", "prefix.log");
103 //! let (non_blocking, _guard) = tracing_appender::non_blocking(file_appender);
104 //! tracing_subscriber::fmt()
105 //!     .with_writer(non_blocking)
106 //!     .init();
107 //! # }
108 //! ```
109 //!
110 //! ## Supported Rust Versions
111 //!
112 //! `tracing-appender` is built against the latest stable release. The minimum supported
113 //! version is 1.53. The current `tracing-appender` version is not guaranteed to build on
114 //! Rust versions earlier than the minimum supported version.
115 //!
116 //! Tracing follows the same compiler support policies as the rest of the Tokio
117 //! project. The current stable Rust compiler and the three most recent minor
118 //! versions before it will always be supported. For example, if the current
119 //! stable compiler version is 1.45, the minimum supported version will not be
120 //! increased past 1.42, three minor versions prior. Increasing the minimum
121 //! supported compiler version is not considered a semver breaking change as
122 //! long as doing so complies with this policy.
123 //!
124 #![doc(html_root_url = "https://docs.rs/tracing-appender/0.2.2")]
125 #![doc(
126     html_logo_url = "https://raw.githubusercontent.com/tokio-rs/tracing/master/assets/logo-type.png",
127     issue_tracker_base_url = "https://github.com/tokio-rs/tracing/issues/"
128 )]
129 #![cfg_attr(docsrs, deny(rustdoc::broken_intra_doc_links))]
130 #![warn(
131     missing_debug_implementations,
132     missing_docs,
133     rust_2018_idioms,
134     unreachable_pub,
135     bad_style,
136     const_err,
137     dead_code,
138     improper_ctypes,
139     non_shorthand_field_patterns,
140     no_mangle_generic_items,
141     overflowing_literals,
142     path_statements,
143     patterns_in_fns_without_body,
144     private_in_public,
145     unconditional_recursion,
146     unused,
147     unused_allocation,
148     unused_comparisons,
149     unused_parens,
150     while_true
151 )]
152 use crate::non_blocking::{NonBlocking, WorkerGuard};
153 
154 use std::io::Write;
155 
156 pub mod non_blocking;
157 
158 pub mod rolling;
159 
160 mod worker;
161 
162 pub(crate) mod sync;
163 
164 /// Convenience function for creating a non-blocking, off-thread writer.
165 ///
166 /// See the [`non_blocking` module's docs][non_blocking]'s for more details.
167 ///
168 /// [non_blocking]: mod@non_blocking
169 ///
170 /// # Examples
171 ///
172 /// ``` rust
173 /// # fn docs() {
174 /// let (non_blocking, _guard) = tracing_appender::non_blocking(std::io::stdout());
175 /// let subscriber = tracing_subscriber::fmt().with_writer(non_blocking);
176 /// tracing::subscriber::with_default(subscriber.finish(), || {
177 ///    tracing::event!(tracing::Level::INFO, "Hello");
178 /// });
179 /// # }
180 /// ```
non_blocking<T: Write + Send + Sync + 'static>(writer: T) -> (NonBlocking, WorkerGuard)181 pub fn non_blocking<T: Write + Send + Sync + 'static>(writer: T) -> (NonBlocking, WorkerGuard) {
182     NonBlocking::new(writer)
183 }
184 
185 #[derive(Debug)]
186 pub(crate) enum Msg {
187     Line(Vec<u8>),
188     Shutdown,
189 }
190