sjl - Simple JSON Logger
📦 crates.io | 📚 docs.rs
Why?
I mostly need JSON logging without the quirks: enums that serialize correctly and clean output out of the box, not escaped strings.
I built this because the tracing crate's valuable support has been behind an unstable feature flag for over three years and the slog crate also doesn't seem to provide this..
If you want a simple JSON logger, this might be useful for you too.
Installation
cargo add sjl
Usage
use sjl::{debug, error, info, warn, LogLevel, Logger, RGB};
use serde::Serialize;
use serde_json::json;
#[derive(Serialize)]
struct User {
id: u64,
name: String,
verified: bool,
}
#[derive(Serialize)]
enum Status {
Active,
Inactive,
RateLimited { retry_after: u32 },
}
#[derive(Serialize)]
struct Address {
street: String,
city: String,
country: String,
}
#[derive(Serialize)]
struct OrderItem {
sku: String,
name: String,
quantity: u32,
price: f64,
status: Status,
}
#[derive(Serialize)]
struct Order {
order_id: String,
user: User,
status: Status,
shipping_address: Address,
items: Vec<OrderItem>,
metadata: Metadata,
}
#[derive(Serialize)]
struct Metadata {
tags: Vec<String>,
priority: u8,
notes: Option<String>,
}
fn main() {
Logger::init()
.min_level(LogLevel::Debug) .batch_size(100) .batch_duration_ms(100) .buffer_size(5000) .timestamp_format("%Y-%m-%dT%H:%M:%S%.3fZ") .debug_color(RGB::new(38, 45, 56)) .info_color(RGB::new(15, 115, 255))
.warn_color(RGB::new(247, 155, 35))
.error_color(RGB::new(255, 0, 0))
.build();
debug!("Application started");
info!("Server listening", "0.0.0.0:8080");
info!(User {
id: 1,
name: "Alice".into(),
verified: true
});
info!("User authenticated", User {
id: 1,
name: "Alice".into(),
verified: true
});
warn!(Status::Active);
warn!(Status::RateLimited { retry_after: 60 });
error!(json!({
"error": "connection_failed",
"host": "db.example.com",
"port": 5432
}));
error!("Database connection failed", json!({
"host": "db.example.com",
"port": 5432,
"retry_count": 3
}));
info!(
"Order processed",
Order {
order_id: "ORD-2024-001".into(),
user: User {
id: 42,
name: "John Doe".into(),
verified: true,
},
status: Status::Active,
shipping_address: Address {
street: "123 Main St".into(),
city: "San Francisco".into(),
country: "USA".into(),
},
items: vec![
OrderItem {
sku: "WIDGET-001".into(),
name: "Premium Widget".into(),
quantity: 2,
price: 29.99,
status: Status::Active,
},
OrderItem {
sku: "GADGET-002".into(),
name: "Super Gadget".into(),
quantity: 1,
price: 49.99,
status: Status::RateLimited { retry_after: 30 },
},
],
metadata: Metadata {
tags: vec!["express".into(), "gift".into()],
priority: 1,
notes: Some("Handle with care".into()),
},
}
);
}
Output
{"level":"DEBUG","timestamp":"2025-10-28T10:14:41.229Z","data":"Application started"}
{"level":"INFO","timestamp":"2025-10-28T10:14:41.229Z", "message": "Server listening","data":"0.0.0.0:8080"}
{"level":"INFO","timestamp":"2025-10-28T10:14:41.229Z","data":{"id":1,"name":"Alice","verified":true}}
{"level":"INFO","timestamp":"2025-10-28T10:14:41.229Z", "message": "User authenticated","data":{"id":1,"name":"Alice","verified":true}}
{"level":"WARN","timestamp":"2025-10-28T10:14:41.229Z","data":"Active"}
{"level":"WARN","timestamp":"2025-10-28T10:14:41.229Z","data":{"RateLimited":{"retry_after":60}}}
{"level":"ERROR","timestamp":"2025-10-28T10:14:41.229Z","data":{"error":"connection_failed","host":"db.example.com","port":5432}}
{"level":"ERROR","timestamp":"2025-10-28T10:14:41.229Z", "message": "Database connection failed","data":{"host":"db.example.com","port":5432,"retry_count":3}}
{"level":"INFO","timestamp":"2025-10-28T10:14:41.229Z", "message": "Order processed","data":{"items":[{"name":"Premium Widget","price":29.99,"quantity":2,"sku":"WIDGET-001","status":"Active"},{"name":"Super Gadget","price":49.99,"quantity":1,"sku":"GADGET-002","status":{"RateLimited":{"retry_after":30}}}],"metadata":{"notes":"Handle with care","priority":1,"tags":["express","gift"]},"order_id":"ORD-2024-001","shipping_address":{"city":"San Francisco","country":"USA","street":"123 Main St"},"status":"Active","user":{"id":42,"name":"John Doe","verified":true}}}