Skip to content

Commit

Permalink
Use a visitor pattern instead of FormattedFields (#12)
Browse files Browse the repository at this point in the history
This changes a lot of the insides of the crate, but the API is mostly
the same. While the visitor pattern is a bit more verbose, it's also
more flexible and allows for more customization in the future.
  • Loading branch information
cmackenzie1 authored Oct 20, 2023
1 parent b1dd04d commit ca110b6
Show file tree
Hide file tree
Showing 14 changed files with 386 additions and 681 deletions.
15 changes: 7 additions & 8 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,20 @@ name: Rust

on:
push:
branches: [ "main" ]
branches: ["main"]
pull_request:
branches: [ "main" ]
branches: ["main"]

env:
CARGO_TERM_COLOR: always

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Build
run: cargo build --verbose
- name: Run tests
run: cargo test --verbose
- uses: actions/checkout@v3
- name: Build
run: cargo build --verbose
- name: Run tests
run: cargo test --verbose
3 changes: 3 additions & 0 deletions .rustfmt.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# rustup install nightly
group_imports = "StdExternalCrate"
format_code_in_doc_comments = true
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "tracing-ndjson"
version = "0.1.3"
version = "0.2.0"
edition = "2021"
license = "MIT"
authors = ["Cole Mackenzie"]
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
fmt:
@cargo fmt
@cargo +nightly fmt || cargo fmt

build:
@cargo build
Expand All @@ -8,7 +8,7 @@ clean:
@cargo clean

test:
@cargo test
@cargo test -- --nocapture

lint: fmt
@cargo clippy --all-targets -- -D warnings
Expand Down
29 changes: 20 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,25 @@
[![Rust](https://github.com/cmackenzie1/tracing-ndjson/actions/workflows/rust.yml/badge.svg)](https://github.com/cmackenzie1/tracing-ndjson/actions/workflows/rust.yml)
[![docs.rs](https://img.shields.io/docsrs/tracing-ndjson)](https://docs.rs/tracing-ndjson/latest/tracing_ndjson)


A simple library for tracing in new-line delimited JSON format. This library is meant to be used with [tracing](https://github.com/tokio-rs/tracing) as an alternative to the `tracing_subscriber::fmt::json` formatter.

The goal of this crate is to provide a flattend JSON event, comprising of fields from the span attributes and event fields, with customizeable field names and timestamp formats.

## Features

- Configurable field names for `target`, `message`, `level`, and `timestamp`.
- Configurable timestamp formats such as RFC3339, UNIX timestamp, or any custom chrono format.
- Captures all span attributes and event fields in the root of the JSON object.
- Configurable timestamp formats
- RFC3339 (`2023-10-08T03:30:52Z`),
- RFC339Nanos (`2023-10-08T03:30:52.123456789Z`)
- Unix timestamp (`1672535452`)
- UnixMills (`1672535452123`)
- Captures all span attributes and event fields in the root of the JSON object. Collisions will result in overwriting the existing field.

## Limitations

- When flattening span attributes and event fields, the library will overwrite any existing fields with the same name, including the built-in fields such as `target`, `message`, `level`, `timestamp`, `file`, and `line`.
- Non-determistic ordering of fields in the JSON object. ([JSON objects are unordered](https://www.json.org/json-en.html))
- Currently only logs to stdout. (PRs welcome!)

## Usage

Expand All @@ -20,24 +31,24 @@ Add this to your `Cargo.toml`:
```toml
[dependencies]
tracing = "0.1"
tracing-ndjson = "0.1"
tracing-ndjson = "0.2"
```

```rust
use tracing_subscriber::prelude::*;

fn main() {
tracing_subscriber::registry()
.with(tracing_ndjson::builder().layer())
.init();
let subscriber = tracing_subscriber::registry().with(tracing_ndjson::layer());

tracing::subscriber::set_global_default(subscriber).unwrap();

tracing::info!(life = 42, "Hello, world!");
// {"level":"info","timestamp":"2023-10-10T20:35:26Z","target":"defaults","message":"Hello, world!","life":42}
// {"level":"info","target":"default","life":42,"timestamp":"2023-10-20T21:17:49Z","message":"Hello, world!"}

let span = tracing::info_span!("hello", "request.uri" = "https://example.com");
span.in_scope(|| {
tracing::info!("Hello, world!");
// {"level":"info","timestamp":"2023-10-10T20:35:26Z","target":"defaults","message":"Hello, world!","request.uri":"https://example.com"}
// {"message":"Hello, world!","request.uri":"https://example.com","level":"info","target":"default","timestamp":"2023-10-20T21:17:49Z"}
});
}
```
Expand Down
8 changes: 1 addition & 7 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,11 @@
## Defaults

```bash
cargo run --example defaults

{"level":"info","timestamp":"2023-10-08T03:35:11Z","target":"defaults","message":"Hello, world!","life":42}
{"level":"info","timestamp":"2023-10-08T03:35:11Z","target":"defaults","message":"Hello, world!","request.uri":"https://example.com"}
cargo run --example default
```

## Customized

```bash
cargo run --example customize

{"severity":"info","ts":1696736208,"target":"customize","message":"Hello, world!","life":42}
{"severity":"info","ts":1696736208,"target":"customize","message":"Hello, world!","request.uri":"https://example.com"}
```
28 changes: 15 additions & 13 deletions examples/customize.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
use tracing_subscriber::prelude::*;

fn main() {
tracing_subscriber::registry()
.with(
tracing_ndjson::builder()
.with_level_name("severity")
.with_message_name("msg")
.with_timestamp_name("ts")
.with_timestamp_format(tracing_ndjson::TimestampFormat::Unix)
.layer(),
)
.init();
let subscriber = tracing_subscriber::registry().with(
tracing_ndjson::builder()
.with_level_name("severity")
.with_level_value_casing(tracing_ndjson::Casing::Uppercase)
.with_timestamp_name("ts")
.with_timestamp_format(tracing_ndjson::TimestampFormat::UnixMillis)
.with_message_name("msg")
.with_line_numbers(true)
.with_file_names(true)
.layer(),
);

tracing::subscriber::set_global_default(subscriber).unwrap();

tracing::info!(life = 42, "Hello, world!");
// {"level":"info","timestamp":"2023-10-08T03:30:52Z","target":"default","message":"Hello, world!"}
// {"life":42,"msg":"Hello, world!","target":"customize","ts":1697836630814,"file":"examples/customize.rs","line":17,"severity":"INFO"}

let span = tracing::info_span!("hello", "request.uri" = "https://example.com");
span.in_scope(|| {
tracing::info!("Hello, world!");
// {"level":"info","timestamp":"2023-10-08T03:34:33Z","target":"defaults","message":"Hello, world!","request.uri":"https://example.com"}
// {"severity":"INFO","target":"customize","file":"examples/customize.rs","msg":"Hello, world!","ts":1697836630814,"line":22,"request.uri":"https://example.com"}
});
}
15 changes: 15 additions & 0 deletions examples/default.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use tracing_subscriber::prelude::*;
fn main() {
let subscriber = tracing_subscriber::registry().with(tracing_ndjson::layer());

tracing::subscriber::set_global_default(subscriber).unwrap();

tracing::info!(life = 42, "Hello, world!");
// {"level":"info","target":"default","life":42,"timestamp":"2023-10-20T21:17:49Z","message":"Hello, world!"}

let span = tracing::info_span!("hello", "request.uri" = "https://example.com");
span.in_scope(|| {
tracing::info!("Hello, world!");
// {"message":"Hello, world!","request.uri":"https://example.com","level":"info","target":"default","timestamp":"2023-10-20T21:17:49Z"}
});
}
16 changes: 0 additions & 16 deletions examples/defaults.rs

This file was deleted.

Loading

0 comments on commit ca110b6

Please sign in to comment.