Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
hawkw authored Oct 10, 2023
2 parents 22739de + f085b89 commit 3307207
Show file tree
Hide file tree
Showing 35 changed files with 1,837 additions and 235 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ are not maintained by the `tokio` project. These include:
- [`tracing-actix-web`] provides `tracing` integration for the `actix-web` web framework.
- [`tracing-actix`] provides `tracing` integration for the `actix` actor
framework.
- [`axum-insights`] provides `tracing` integration and Application insights export for the `axum` web framework.
- [`tracing-gelf`] implements a subscriber for exporting traces in Greylog
GELF format.
- [`tracing-coz`] provides integration with the [coz] causal profiler
Expand Down Expand Up @@ -404,6 +405,7 @@ are not maintained by the `tokio` project. These include:
- [`tracing-chrome`] provides a layer that exports trace data that can be viewed in `chrome://tracing`.
- [`reqwest-tracing`] provides a middleware to trace [`reqwest`] HTTP requests.
- [`tracing-cloudwatch`] provides a layer that sends events to AWS CloudWatch Logs.
- [`clippy-tracing`] provides a tool to add, remove and check for `tracing::instrument`.

(if you're the maintainer of a `tracing` ecosystem crate not in this list,
please let us know!)
Expand All @@ -414,6 +416,7 @@ please let us know!)
[honeycomb.io]: https://www.honeycomb.io/
[`tracing-actix`]: https://crates.io/crates/tracing-actix
[`tracing-actix-web`]: https://crates.io/crates/tracing-actix-web
[`axum-insights`]: https://crates.io/crates/axum-insights
[`tracing-gelf`]: https://crates.io/crates/tracing-gelf
[`tracing-coz`]: https://crates.io/crates/tracing-coz
[coz]: https://github.com/plasma-umass/coz
Expand Down Expand Up @@ -447,6 +450,7 @@ please let us know!)
[`reqwest-tracing`]: https://crates.io/crates/reqwest-tracing
[`reqwest`]: https://crates.io/crates/reqwest
[`tracing-cloudwatch`]: https://crates.io/crates/tracing-cloudwatch
[`clippy-tracing`]: https://crates.io/crates/clippy-tracing

**Note:** that some of the ecosystem crates are currently unreleased and
undergoing active development. They may be less stable than `tracing` and
Expand Down
1 change: 1 addition & 0 deletions netlify.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
[build.environment]
RUSTDOCFLAGS="""
-D warnings \
--force-warn rustdoc::redundant-explicit-links \
--force-warn renamed-and-removed-lints \
--cfg docsrs \
--html-before-content /opt/build/repo/assets/warning.html \
Expand Down
26 changes: 20 additions & 6 deletions tracing-appender/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,34 @@
//! - Using a combination of [`NonBlocking`] and [`RollingFileAppender`] to allow writes to a log file
//! without blocking.
//!
//! ## Rolling File Appender
//! ## File Appender
//!
//! The [`rolling` module][rolling] provides functions to create rolling and non-rolling file
//! appenders.
//!
//! Rolling file appender rotation options are [`Rotation::MINUTELY`](rolling::Rotation::MINUTELY),
//! [`Rotation::HOURLY`](rolling::Rotation::HOURLY), and
//! [`Rotation::DAILY`](rolling::Rotation::DAILY).
//!
//! To create a non-rolling file appender, use
//! [`tracing_appender::rolling::never(/*...*/)`](rolling::never) or
//! [`Rotation::NEVER`](rolling::Rotation::NEVER).
//!
//! The following example creates an hourly rotating file appender that writes to
//! `/some/directory/prefix.log.YYYY-MM-DD-HH`:
//!
//! ```rust
//! # fn docs() {
//! let file_appender = tracing_appender::rolling::hourly("/some/directory", "prefix.log");
//! # }
//! ```
//! This creates an hourly rotating file appender that writes to `/some/directory/prefix.log.YYYY-MM-DD-HH`.
//! [`Rotation::DAILY`](rolling::Rotation::DAILY) and [`Rotation::NEVER`](rolling::Rotation::NEVER) are the other available options.
//!
//! The file appender implements [`std::io::Write`][write]. To be used with [`tracing_subscriber::FmtSubscriber`][fmt_subscriber],
//! it must be combined with a [`MakeWriter`][make_writer] implementation to be able to record tracing spans/event.
//! The file appender implements [`std::io::Write`][write]. To be used with
//! [`tracing_subscriber::FmtSubscriber`][fmt_subscriber], it must be combined with a
//! [`MakeWriter`][make_writer] implementation to be able to record tracing spans/event.
//!
//! The [`rolling` module][rolling]'s documentation provides more detail on how to use this file appender.
//! See the [`rolling` module][rolling]'s documentation for more detail on how to use this file
//! appender.
//!
//! ## Non-Blocking Writer
//!
Expand Down
10 changes: 5 additions & 5 deletions tracing-appender/src/rolling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ impl fmt::Debug for RollingFileAppender {
}
}

/// Creates a minutely, rolling file appender. This will rotate the log file once per minute.
/// Creates a minutely-rotating file appender. This will rotate the log file once per minute.
///
/// The appender returned by `rolling::minutely` can be used with `non_blocking` to create
/// a non-blocking, minutely file appender.
Expand Down Expand Up @@ -299,7 +299,7 @@ pub fn minutely(
RollingFileAppender::new(Rotation::MINUTELY, directory, file_name_prefix)
}

/// Creates an hourly, rolling file appender.
/// Creates an hourly-rotating file appender.
///
/// The appender returned by `rolling::hourly` can be used with `non_blocking` to create
/// a non-blocking, hourly file appender.
Expand Down Expand Up @@ -334,7 +334,7 @@ pub fn hourly(
RollingFileAppender::new(Rotation::HOURLY, directory, file_name_prefix)
}

/// Creates a file appender that rotates daily.
/// Creates a daily-rotating file appender.
///
/// The appender returned by `rolling::daily` can be used with `non_blocking` to create
/// a non-blocking, daily file appender.
Expand Down Expand Up @@ -370,13 +370,13 @@ pub fn daily(
RollingFileAppender::new(Rotation::DAILY, directory, file_name_prefix)
}

/// Creates a non-rolling, file appender
/// Creates a non-rolling file appender.
///
/// The appender returned by `rolling::never` can be used with `non_blocking` to create
/// a non-blocking, non-rotating appender.
///
/// The location of the log file will be specified the `directory` passed in.
/// `file_name` specifies the prefix of the log file. No date or time is appended.
/// `file_name` specifies the complete name of the log file (no date or time is appended).
///
/// # Examples
///
Expand Down
2 changes: 1 addition & 1 deletion tracing-attributes/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ rust-version = "1.56.0"
proc-macro = true

[dependencies]
proc-macro2 = "1.0.40"
proc-macro2 = "1.0.60"
syn = { version = "2.0", default-features = false, features = ["full", "parsing", "printing", "visit-mut", "clone-impls", "extra-traits", "proc-macro"] }
quote = "1.0.20"

Expand Down
8 changes: 4 additions & 4 deletions tracing-attributes/src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ pub(crate) fn gen_function<'a, B: ToTokens + 'a>(
let fake_return_edge = quote_spanned! {return_span=>
#[allow(
unknown_lints, unreachable_code, clippy::diverging_sub_expression,
clippy::let_unit_value, clippy::unreachable, clippy::let_with_type_underscore
clippy::let_unit_value, clippy::unreachable, clippy::let_with_type_underscore,
clippy::empty_loop
)]
if false {
let __tracing_attr_fake_return: #return_type =
unreachable!("this is just for type inference, and is unreachable code");
let __tracing_attr_fake_return: #return_type = loop {};
return __tracing_attr_fake_return;
}
};
Expand Down Expand Up @@ -343,7 +343,7 @@ fn gen_block<B: ToTokens>(
// regression in case the level is enabled.
let __tracing_attr_span;
let __tracing_attr_guard;
if tracing::level_enabled!(#level) {
if tracing::level_enabled!(#level) || tracing::if_log_enabled!(#level, {true} else {false}) {
__tracing_attr_span = #span;
#follows_from
__tracing_attr_guard = __tracing_attr_span.enter();
Expand Down
1 change: 0 additions & 1 deletion tracing-attributes/tests/async_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ async fn test_async_fn(polls: usize) -> Result<(), ()> {
#[allow(dead_code)] // this is just here to test whether it compiles.
#[instrument]
async fn test_ret_impl_trait(n: i32) -> Result<impl Iterator<Item = i32>, ()> {
let n = n;
Ok((0..10).filter(move |x| *x < n))
}

Expand Down
48 changes: 18 additions & 30 deletions tracing-core/src/field.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! Span and `Event` key-value data.
//!
//! Spans and events may be annotated with key-value data, referred to as known
//! as _fields_. These fields consist of a mapping from a key (corresponding to
//! a `&str` but represented internally as an array index) to a [`Value`].
//! Spans and events may be annotated with key-value data, known as _fields_.
//! These fields consist of a mapping from a key (corresponding to a `&str` but
//! represented internally as an array index) to a [`Value`].
//!
//! # `Value`s and `Collect`s
//!
Expand Down Expand Up @@ -373,6 +373,10 @@ macro_rules! impl_one_value {
impl $crate::sealed::Sealed for $value_ty {}
impl $crate::field::Value for $value_ty {
fn record(&self, key: &$crate::field::Field, visitor: &mut dyn $crate::field::Visit) {
// `op` is always a function; the closure is used because
// sometimes there isn't a real function corresponding to that
// operation. the clippy warning is not that useful here.
#[allow(clippy::redundant_closure_call)]
visitor.$record(key, $op(*self))
}
}
Expand All @@ -388,6 +392,10 @@ macro_rules! impl_one_value {
impl $crate::sealed::Sealed for ty_to_nonzero!($value_ty) {}
impl $crate::field::Value for ty_to_nonzero!($value_ty) {
fn record(&self, key: &$crate::field::Field, visitor: &mut dyn $crate::field::Visit) {
// `op` is always a function; the closure is used because
// sometimes there isn't a real function corresponding to that
// operation. the clippy warning is not that useful here.
#[allow(clippy::redundant_closure_call)]
visitor.$record(key, $op(self.get()))
}
}
Expand Down Expand Up @@ -748,9 +756,6 @@ impl FieldSet {
}

/// Returns a new `ValueSet` with entries for this `FieldSet`'s values.
///
/// Note that a `ValueSet` may not be constructed with arrays of over 32
/// elements.
#[doc(hidden)]
pub fn value_set<'v, V>(&'v self, values: &'v V) -> ValueSet<'v>
where
Expand Down Expand Up @@ -949,37 +954,20 @@ impl<'a> fmt::Display for ValueSet<'a> {
mod private {
use super::*;

/// Marker trait implemented by arrays which are of valid length to
/// construct a `ValueSet`.
///
/// `ValueSet`s may only be constructed from arrays containing 32 or fewer
/// elements, to ensure the array is small enough to always be allocated on the
/// stack. This trait is only implemented by arrays of an appropriate length,
/// ensuring that the correct size arrays are used at compile-time.
/// Restrictions on `ValueSet` lengths were removed in #2508 but this type remains for backwards compatibility.
pub trait ValidLen<'a>: Borrow<[(&'a Field, Option<&'a (dyn Value + 'a)>)]> {}
}

macro_rules! impl_valid_len {
( $( $len:tt ),+ ) => {
$(
impl<'a> private::ValidLen<'a> for
[(&'a Field, ::core::option::Option<&'a (dyn Value + 'a)>); $len] {}
)+
}
}

impl_valid_len! {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32
impl<'a, const N: usize> ValidLen<'a> for [(&'a Field, Option<&'a (dyn Value + 'a)>); N] {}
}

#[cfg(test)]
mod test {
use super::*;
use crate::metadata::{Kind, Level, Metadata};

struct TestCallsite1;
static TEST_CALLSITE_1: TestCallsite1 = TestCallsite1;
// Make sure TEST_CALLSITE_* have non-zero size, so they can't be located at the same address.
struct TestCallsite1(u8);
static TEST_CALLSITE_1: TestCallsite1 = TestCallsite1(0);
static TEST_META_1: Metadata<'static> = metadata! {
name: "field_test1",
target: module_path!(),
Expand All @@ -999,8 +987,8 @@ mod test {
}
}

struct TestCallsite2;
static TEST_CALLSITE_2: TestCallsite2 = TestCallsite2;
struct TestCallsite2(u8);
static TEST_CALLSITE_2: TestCallsite2 = TestCallsite2(0);
static TEST_META_2: Metadata<'static> = metadata! {
name: "field_test2",
target: module_path!(),
Expand Down
6 changes: 3 additions & 3 deletions tracing-flame/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ impl Default for Config {
empty_samples: true,
threads_collapsed: false,
module_path: true,
file_and_line: true,
file_and_line: false,
}
}
}
Expand Down Expand Up @@ -404,7 +404,7 @@ where

if let Some(second) = first.parent() {
for parent in second.scope().from_root() {
stack += "; ";
stack += ";";
write(&mut stack, parent, &self.config)
.expect("expected: write to String never fails");
}
Expand Down Expand Up @@ -446,7 +446,7 @@ where
}

for parent in first.scope().from_root() {
stack += "; ";
stack += ";";
expect!(
write(&mut stack, parent, &self.config),
"expected: write to String never fails"
Expand Down
39 changes: 38 additions & 1 deletion tracing-journald/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ pub struct Subscriber {
socket: UnixDatagram,
field_prefix: Option<String>,
syslog_identifier: String,
additional_fields: Vec<u8>,
}

#[cfg(unix)]
Expand All @@ -108,7 +109,8 @@ impl Subscriber {
.and_then(|p| p.file_name())
.map(|n| n.to_string_lossy().into_owned())
// If we fail to get the name of the current executable fall back to an empty string.
.unwrap_or_else(String::new),
.unwrap_or_default(),
additional_fields: Vec::new(),
};
// Check that we can talk to journald, by sending empty payload which journald discards.
// However if the socket didn't exist or if none listened we'd get an error here.
Expand Down Expand Up @@ -150,6 +152,40 @@ impl Subscriber {
self
}

/// Adds fields that will get be passed to journald with every log entry.
///
/// The input values of this function are interpreted as `(field, value)` pairs.
///
/// This can for example be used to configure the syslog facility.
/// See [Journal Fields](https://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html)
/// and [journalctl](https://www.freedesktop.org/software/systemd/man/journalctl.html)
/// for more information.
///
/// Fields specified using this method will be added to the journald
/// message alongside fields generated from the event's fields, its
/// metadata, and the span context. If the name of a field provided using
/// this method is the same as the name of a field generated by the
/// subscriber, both fields will be sent to journald.
///
/// ```no_run
/// # use tracing_journald::Subscriber;
/// let sub = Subscriber::new()
/// .unwrap()
/// .with_custom_fields([("SYSLOG_FACILITY", "17")]);
/// ```
///
pub fn with_custom_fields<T: AsRef<str>, U: AsRef<[u8]>>(
mut self,
fields: impl IntoIterator<Item = (T, U)>,
) -> Self {
for (name, value) in fields {
put_field_length_encoded(&mut self.additional_fields, name.as_ref(), |buf| {
buf.extend_from_slice(value.as_ref())
})
}
self
}

/// Returns the syslog identifier in use.
pub fn syslog_identifier(&self) -> &str {
&self.syslog_identifier
Expand Down Expand Up @@ -257,6 +293,7 @@ where
put_field_length_encoded(&mut buf, "SYSLOG_IDENTIFIER", |buf| {
write!(buf, "{}", self.syslog_identifier).unwrap()
});
buf.extend_from_slice(&self.additional_fields);

event.record(&mut EventVisitor::new(
&mut buf,
Expand Down
22 changes: 22 additions & 0 deletions tracing-journald/tests/journal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,28 @@ fn simple_metadata() {
});
}

#[test]
fn journal_fields() {
let sub = Subscriber::new()
.unwrap()
.with_field_prefix(None)
.with_custom_fields([("SYSLOG_FACILITY", "17")])
.with_custom_fields([("ABC", "dEf"), ("XYZ", "123")]);
with_journald_subscriber(sub, || {
info!(test.name = "journal_fields", "Hello World");

let message = retry_read_one_line_from_journal("journal_fields");
assert_eq!(message["MESSAGE"], "Hello World");
assert_eq!(message["PRIORITY"], "5");
assert_eq!(message["TARGET"], "journal");
assert_eq!(message["SYSLOG_FACILITY"], "17");
assert_eq!(message["ABC"], "dEf");
assert_eq!(message["XYZ"], "123");
assert!(message["CODE_FILE"].as_text().is_some());
assert!(message["CODE_LINE"].as_text().is_some());
});
}

#[test]
fn span_metadata() {
with_journald(|| {
Expand Down
Loading

0 comments on commit 3307207

Please sign in to comment.