Skip to content

Commit

Permalink
finish docs and hide some things not ready to be made public
Browse files Browse the repository at this point in the history
  • Loading branch information
mladedav committed Jun 13, 2024
1 parent 54d22de commit d0ed79a
Show file tree
Hide file tree
Showing 9 changed files with 181 additions and 10 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
- uses: Swatinem/rust-cache@v2
- name: cargo doc
env:
RUSTDOCFLAGS: "-D rustdoc::all -A rustdoc::private-doc-tests"
RUSTDOCFLAGS: "-D missing_docs -D rustdoc::all -A rustdoc::private-doc-tests"
run: cargo doc --all-features --no-deps

cargo-hack:
Expand Down
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,33 @@ This will produce log lines like for example this (without the formatting):

See the `readme-opentelemetry` example for full code.

### Custom

You can also specify custom static fields to be added to each log line, or serialize extensions provided by other `Layer`s:

```rust
#[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);
}
}

fn main() {
let foo_layer = FooLayer;

let mut layer = json_subscriber::JsonLayer::stdout();
layer.serialize_extension::<Foo>("foo");

registry().with(foo_layer).with(layer);
}
```

## Supported Rust Versions

`json-subscriber` is built against the latest stable release. The minimum supported version is 1.65.
Expand Down
2 changes: 1 addition & 1 deletion src/fields.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::{collections::BTreeMap, sync::Arc};

#[derive(Debug, Default)]
pub struct JsonFields {
pub(crate) struct JsonFields {
pub(crate) fields: BTreeMap<&'static str, serde_json::Value>,
pub(crate) version: usize,
pub(crate) serialized: Option<Arc<str>>,
Expand Down
2 changes: 2 additions & 0 deletions src/fmt/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,8 @@ impl<W, T, F> SubscriberBuilder<W, T, F> {

/// Sets whether or not [OpenTelemetry] trace ID and span ID is displayed when formatting
/// events.
///
/// [OpenTelemetry]: https://opentelemetry.io
#[cfg(feature = "opentelemetry")]
#[cfg_attr(docsrs, doc(cfg(feature = "opentelemetry")))]
pub fn with_opentelemetry_ids(self, display_opentelemetry_ids: bool) -> Self {
Expand Down
30 changes: 26 additions & 4 deletions src/fmt/layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ where

/// 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.
/// This sets the [`MakeWriter`] that the layer being built will use to write events.
///
/// # Examples
///
Expand All @@ -224,7 +224,7 @@ where
}
}

/// Configures the subscriber to support [`libtest`'s output capturing][capturing] when used in
/// Configures the layer to support [`libtest`'s output capturing][capturing] when used in
/// unit tests.
///
/// See [`TestWriter`] for additional details.
Expand Down Expand Up @@ -252,14 +252,14 @@ where
}
}

/// Borrows the [writer] for this subscriber.
/// Borrows the [writer] for this layer.
///
/// [writer]: MakeWriter
pub fn writer(&self) -> &W {
self.inner.writer()
}

/// Mutably borrows the [writer] for this subscriber.
/// Mutably borrows the [writer] for this layer.
///
/// This method is primarily expected to be used with the [`reload::Handle::modify`] method.
///
Expand Down Expand Up @@ -290,6 +290,28 @@ where
self.inner.writer_mut()
}

/// Mutably borrows the [`JsonLayer`] inside of this layer. This can be useful to add more
/// information to the output or to change the output with the [`reload::Handle::modify`]
/// method.
///
/// # Examples
/// ```rust
/// let mut layer = tracing_json::layer();
/// let mut inner = layer.inner_layer_mut();
///
/// inner.add_static_field(
/// "hostname",
/// serde_json::json!({
/// "hostname": get_hostname(),
/// }),
/// );
/// ```
///
/// [`reload::Handle::modify`]: tracing_subscriber::reload::Handle::modify
pub fn inner_layer_mut(&mut self) -> &mut JsonLayer<S, W> {
&mut self.inner
}

/// Sets whether to write errors from [`FormatEvent`] to the writer.
/// Defaults to true.
///
Expand Down
15 changes: 15 additions & 0 deletions src/fmt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,24 @@ where
Layer::default()
}

/// A type that can be used to create a [`Subscriber`](tracing::Subscriber) which collects tracing
/// spans and events and emits them in JSON.
///
/// This type is actually ZST and is only useful to call [`builder`](fn@Self::builder) to configure
/// a subscriber.
pub struct Subscriber;

impl Subscriber {
/// Creates a [`SubscriberBuilder`] which can be used to configure a [`Subscriber`].
///
/// # Examples
///
/// ```rust
/// let subscriber = Subscriber::builder()
/// .with_max_level(tracing::Level::INFO)
/// .with_target(false)
/// .finish();
/// ```
pub fn builder() -> SubscriberBuilder {
SubscriberBuilder::default()
}
Expand Down
11 changes: 10 additions & 1 deletion src/layer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,19 @@ use event::EventRef;

use crate::{cached::Cached, fields::JsonFields, visitor::JsonVisitor};

/// 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`](crate::fmt::Layer) for an alternative especially if you're migrating from
/// `tracing_subscriber`.
pub struct JsonLayer<S = Registry, W = fn() -> io::Stdout> {
make_writer: W,
log_internal_errors: bool,
pub(crate) schema: BTreeMap<SchemaKey, JsonValue<S>>,
}

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum SchemaKey {
enum SchemaKey {
Static(Cow<'static, str>),
}

Expand Down Expand Up @@ -183,14 +188,18 @@ impl<S> JsonLayer<S>
where
S: Subscriber + for<'lookup> LookupSpan<'lookup>,
{
/// Creates an empty [`JsonLayer`] which will output logs to stdout.
pub fn stdout() -> JsonLayer<S, fn() -> io::Stdout> {
JsonLayer::new(io::stdout)
}

/// Creates an empty [`JsonLayer`] which will output logs to stderr.
pub fn stderr() -> JsonLayer<S, fn() -> io::Stderr> {
JsonLayer::new(io::stderr)
}

/// Creates an empty [`JsonLayer`] which will output logs to the configured
/// [`Writer`](io::Write).
pub fn new<W>(make_writer: W) -> JsonLayer<S, W>
where
W: for<'writer> MakeWriter<'writer> + 'static,
Expand Down
98 changes: 97 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,102 @@
//! # `json-subscriber`
//!
//! `json-subscriber` is (mostly) a drop-in replacement for `tracing_subscriber::fmt().json()`.
//!
//! It provides helpers to be as compatible as possible with `tracing_subscriber` while also
//! allowing for simple extensions to the format to include custom data in the log lines.
//!
//! The end goal is for each user to be able to define the structure of their JSON log lines as they
//! wish. Currently, the library only allows what `tracing-subscriber` plus OpenTelemetry trace and
//! span IDs.
//!
//! ## Compatibility
//!
//! However you created your `FmtSubscriber` or `fmt::Layer`, the same thing should work in this
//! crate.
//!
//! For example in `README.md` in Tracing, you can see an yak-shaving example where if you just
//! change `tracing_subscriber` to `json_subscriber`, everything will work the same, except the logs
//! will be in JSON.
//!
//! ```rust
//! use tracing::info;
//! use json_subscriber;
//!
//! fn main() {
//! // install global collector configured based on RUST_LOG env var.
//! json_subscriber::fmt::init();
//!
//! 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."
//! );
//! }
//! ```
//!
//! Most configuration under `tracing_subscriber::fmt` should work equivalently. For example one can
//! create a layer like this:
//!
//! ```rust
//! json_subscriber::fmt()
//! // .json()
//! .with_max_level(tracing::Level::TRACE)
//! .with_current_span(false)
//! .init();
//! ```
//!
//! Calling `.json()` is not needed and the method does nothing and is marked as deprecated. It is
//! kept around for simpler migration from `tracing-subscriber` though.
//!
//! Trying to call `.pretty()` or `.compact()` will however result in an error. `json-tracing` does
//! not support any output other than JSON.
//!
//! ## Extensions
//!
//! ### OpenTelemetry
//!
//! To include trace ID and span ID from opentelemetry in log lines, simply call
//! `with_opentelemetry_ids`. This will have no effect if you don't also configure a
//! `tracing-opentelemetry` layer.
//!
//! ```rust
//! let tracer = todo!();
//! let opentelemetry = tracing_opentelemetry::layer().with_tracer(tracer);
//! let json = json_subscriber::layer()
//! .with_current_span(false)
//! .with_span_list(false)
//! .with_opentelemetry_ids(true);
//!
//! tracing_subscriber::registry()
//! .with(opentelemetry)
//! .with(json)
//! .init();
//! ```
//!
//! This will produce log lines like for example this (without the formatting):
//!
//! ```json
//! {
//! "fields": {
//! "message": "shaving yaks"
//! },
//! "level": "INFO",
//! "openTelemetry": {
//! "spanId": "35249d86bfbcf774",
//! "traceId": "fb4b6ae1fa52d4aaf56fa9bda541095f"
//! },
//! "target": "readme_opentelemetry::yak_shave",
//! "timestamp": "2024-06-06T23:09:07.620167Z"
//! }
//! ```

mod cached;
mod cursor;
pub mod fields;
mod fields;
pub mod fmt;
mod layer;
mod serde;
Expand Down

0 comments on commit d0ed79a

Please sign in to comment.