| Crates.io | papertrail_logger |
| lib.rs | papertrail_logger |
| version | 1.0.0 |
| created_at | 2025-07-01 12:55:45.370126+00 |
| updated_at | 2025-07-03 08:20:08.033894+00 |
| description | Async Rust logger for Papertrail |
| homepage | |
| repository | https://github.com/greemlin/rust-papertrail-lib |
| max_upload_size | |
| id | 1733193 |
| size | 53,007 |
A high-performance, fully asynchronous logger for Rust with dual output to local files and Papertrail. Integrates with the standard log macros and supports advanced features like file rotation, retention, and runtime configuration via environment variables.
.env or environmentlog macros (info!, warn!, etc.)Add to your Cargo.toml:
[dependencies]
papertrail_logger = "1.0.0" # Check crates.io for latest
log = "0.4"
dotenvy = "0.15" # For .env support (optional, but recommended)
.env file (recommended)# Enable/disable local logging
ENABLE_LOCAL_LOG=true
# Enable/disable Papertrail logging
ENABLE_PAPERTRAIL_LOG=true
# Directory for local log files
LOG_DIR=logs
# Max file size (bytes) before rotating
MAX_FILE_SIZE=1048576
# Max number of log files to keep
MAX_FILES=5
# Papertrail endpoint (host:port)
PAPERTRAIL_ENDPOINT=logsX.papertrailapp.com:XXXXX
# Hostname for syslog messages
HOSTNAME=my-app-host
use dotenvy::dotenv; // or dotenv::dotenv if you prefer
use papertrail_logger::{LoggerConfig, set_logger};
use std::path::PathBuf;
use std::env;
use log::{info, warn, error, debug};
#[tokio::main]
async fn main() {
dotenv().ok(); // Loads .env if present
let log_dir = env::var("LOG_DIR").map(PathBuf::from).unwrap_or_else(|_| PathBuf::from("logs"));
let max_file_size = env::var("MAX_FILE_SIZE").ok().and_then(|s| s.parse().ok()).unwrap_or(1024 * 1024);
let max_files = env::var("MAX_FILES").ok().and_then(|s| s.parse().ok()).unwrap_or(5);
let papertrail_endpoint = env::var("PAPERTRAIL_ENDPOINT").ok();
let hostname = env::var("HOSTNAME").unwrap_or_else(|_| "unknown-host".to_string());
let enable_local = env::var("ENABLE_LOCAL_LOG").map(|v| v == "true" || v == "1").unwrap_or(true);
let enable_papertrail = env::var("ENABLE_PAPERTRAIL_LOG").map(|v| v == "true" || v == "1").unwrap_or(true);
let config = LoggerConfig {
log_dir,
max_file_size,
max_files,
papertrail_endpoint,
hostname,
enable_local,
enable_papertrail,
};
let handle = set_logger(config).expect("Failed to set logger");
info!("This is an info message");
warn!("This is a warning message");
debug!("This is a debug message");
error!("This is an error message");
// Give the logger some time to flush
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
handle.await.unwrap();
}
| Variable | Description | Example |
|---|---|---|
ENABLE_LOCAL_LOG |
Enable local file logging | true / false |
ENABLE_PAPERTRAIL_LOG |
Enable Papertrail logging | true / false |
LOG_DIR |
Directory for local log files | logs |
MAX_FILE_SIZE |
Max file size in bytes (rotation) | 1048576 |
MAX_FILES |
Max rotated log files to keep | 5 |
PAPERTRAIL_ENDPOINT |
Papertrail endpoint host:port | logsX.papertrailapp.com:XXXXX |
HOSTNAME |
Hostname for syslog messages | my-app-host |
LoggerConfig struct directly.info!, warn!, error!, debug!, trace! from the standard log crate.MAX_FILES is exceeded.PAPERTRAIL_ENDPOINT and port.[DEBUG]/[ERROR] messages in your terminal.RUST_LOG=debug for more verbose output.LOG_DIR exists and is writable.ENABLE_LOCAL_LOG is set to true.MIT License - see LICENSE for details.
Contributions welcome! Please:
Papertrail for their logging service
Tokio for async runtime
dotenvy for .env support
You can construct a LoggerConfig manually for custom setups, or toggle logging backends at runtime:
use papertrail_logger::{LoggerConfig, set_logger};
use std::path::PathBuf;
let config = LoggerConfig {
log_dir: PathBuf::from("custom-logs"),
max_file_size: 512 * 1024, // 512KB
max_files: 10,
papertrail_endpoint: Some("logsX.papertrailapp.com:XXXXX".to_string()),
hostname: "custom-hostname".to_string(),
enable_local: true,
enable_papertrail: false, // Start with only local logging
};
let handle = set_logger(config).expect("Failed to set logger");
// ...
// You can later enable Papertrail by updating config and restarting the logger task.
| Variable | Description | Example |
|---|---|---|
ENABLE_LOCAL_LOG |
Enable local file logging | true / false |
ENABLE_PAPERTRAIL_LOG |
Enable Papertrail logging | true / false |
LOG_DIR |
Directory for local log files | logs |
MAX_FILE_SIZE |
Max file size in bytes (rotation) | 1048576 |
MAX_FILES |
Max rotated log files to keep | 5 |
PAPERTRAIL_ENDPOINT |
Papertrail endpoint host:port | logsX.papertrailapp.com:XXXXX |
HOSTNAME |
Hostname for syslog messages | my-app-host |
RUST_LOG |
Minimum log level | debug |
| Rust Level | Syslog Severity | Description |
|---|---|---|
| Error | 3 (Error) | Critical failures |
| Warn | 4 (Warning) | Potential issues |
| Info | 6 (Informational) | Normal operation |
| Debug | 7 (Debug) | Debug messages |
| Trace | 7 (Debug) | Detailed traces |
You can write async integration tests using Tokio and the logger's config-driven API. Example:
use papertrail_logger::{LoggerConfig, set_logger};
use std::path::PathBuf;
use log::info;
#[tokio::test]
async fn test_logger_init_and_log() {
let config = LoggerConfig {
log_dir: PathBuf::from("test-logs"),
max_file_size: 1024 * 1024,
max_files: 2,
papertrail_endpoint: None, // Avoid real remote logging in tests
hostname: "test-host".to_string(),
enable_local: true,
enable_papertrail: false,
};
let handle = set_logger(config).expect("Failed to set logger");
info!("Test log message");
tokio::time::sleep(std::time::Duration::from_millis(200)).await;
handle.abort(); // Stop background task
// Optionally, check that a log file was created in test-logs/
}
tokio::test for async tests.papertrail_endpoint: None to avoid sending logs remotely during tests.handle.abort() to stop the logger background task at the end of your test.Run tests with:
cargo test -- --nocapture
error! for critical failuresdebug! and trace! for troubleshootinglog::info!("User {} authenticated", user_id);
log::debug!("Processing transaction {}", transaction_id);
// NOT: log::info!("Credit card: {}", card_number);
Contributions are welcome! Please follow:
MIT License - see LICENSE for details.