Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 87 additions & 23 deletions crates/lambda-rs-logging/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,112 @@
![lambda-rs](https://img.shields.io/crates/d/lambda-rs-logging)
![lambda-rs](https://img.shields.io/crates/v/lambda-rs-logging)

A simple logger implementation for lamba-rs crates. Inspired by
python's [logging](https://docs.python.org/3/library/logging.html) module.
Simple, lightweight logging for lambda-rs crates. Inspired by Python’s
[logging](https://docs.python.org/3/library/logging.html) module.


# Installation
First, add the following to your `Cargo.toml`:
## Installation
Add to your `Cargo.toml`:
```toml
[dependencies]
# Option A: use the crate name in code as `lambda_rs_logging`
lambda-rs-logging = "2023.1.30"

# Option B: rename dependency so you can write `use logging;`
# logging = { package = "lambda-rs-logging", version = "2023.1.30" }
```

or run this command from your project directory:
Or from your project directory:
```bash
cargo add lambda-rs-logging
```

# Getting started
## Using the global logger
Then in code, either import with the default name:
```rust
use lambda_rs_logging as logging;
```
or, if you used the rename in Cargo.toml (Option B), simply:
```rust
use logging; // renamed in Cargo.toml
```

## Getting Started
### Global logger via macros
```rust
use logging;
use lambda_rs_logging as logging;

fn main() {
logging::trace!("Hello world");
logging::debug!("Hello world");
logging::info!("Hello world");
logging::warn!("Hello world");
logging::error!("Hello world");
logging::fatal!("Hello world");
logging::trace!("trace {}", 1);
logging::debug!("debug {}", 2);
logging::info!("info {}", 3);
logging::warn!("warn {}", 4);
logging::error!("error {}", 5);
logging::fatal!("fatal {}", 6); // note: does not exit
}
```

## Using an instance of the logger
### Custom logger instance
```rust
use logging::Logger;
use lambda_rs_logging as logging;

fn main() {
let logger = Logger::new("my-logger");
logger.trace("Hello world");
logger.debug("Hello world");
logger.info("Hello world");
logger.warn("Hello world");
logger.error("Hello world");
logger.fatal("Hello world");
let logger = logging::Logger::builder()
.name("my-app")
.level(logging::LogLevel::INFO)
.with_handler(Box::new(logging::handler::ConsoleHandler::new("my-app")))
.build();

logger.info("Hello world".to_string());
logger.warn("Be careful".to_string());
}
```

### Initialize a custom global
```rust
use lambda_rs_logging as logging;

fn main() {
let logger = logging::Logger::builder()
.name("app")
.level(logging::LogLevel::DEBUG)
.with_handler(Box::new(logging::handler::ConsoleHandler::new("app")))
.build();

// Set the global logger before any macros are used
logging::Logger::init(logger).expect("global logger can only be initialized once");

logging::debug!("from global");
}
```

### Configure level from environment
```rust
use lambda_rs_logging as logging;

fn main() {
// LAMBDA_LOG can be: trace|debug|info|warn|error|fatal
// Example: export LAMBDA_LOG=debug
logging::env::init_global_from_env().ok();

logging::info!("respects env filter");
}
```

## Notes
- Thread-safe global with `OnceLock<Arc<Logger>>`.
- Handlers are `Send + Sync` and receive a `Record` internally (phase 1 refactor).
- `fatal!` logs at FATAL level but does not exit the process. Prefer explicit exits in your app logic.
- Console handler colors only when attached to a TTY and writes WARN+ to stderr.

## Examples
This crate ships with examples. From the repository root:
```bash
cargo run -p lambda-rs-logging --example 01_global_macros
cargo run -p lambda-rs-logging --example 02_custom_logger
cargo run -p lambda-rs-logging --example 03_global_init
```

### Environment example
```bash
LAMBDA_LOG=debug cargo run -p lambda-rs-logging --example 01_global_macros
```
8 changes: 8 additions & 0 deletions crates/lambda-rs-logging/examples/01_global_macros.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
fn main() {
logging::trace!("trace example");
logging::debug!("debug example: {}", 42);
logging::info!("info example");
logging::warn!("warn example");
logging::error!("error example");
logging::fatal!("fatal example (no exit)");
}
8 changes: 8 additions & 0 deletions crates/lambda-rs-logging/examples/02_custom_logger.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
fn main() {
let logger = logging::Logger::new(logging::LogLevel::DEBUG, "custom");
logger.add_handler(Box::new(logging::handler::ConsoleHandler::new("custom")));

logger.trace("this will be filtered unless level <= TRACE".to_string());
logger.debug("debug from custom logger".to_string());
logger.info("info from custom logger".to_string());
}
9 changes: 9 additions & 0 deletions crates/lambda-rs-logging/examples/03_global_init.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
fn main() {
let logger = logging::Logger::new(logging::LogLevel::INFO, "app");
logger.add_handler(Box::new(logging::handler::ConsoleHandler::new("app")));

logging::Logger::init(logger)
.expect("global logger can only be initialized once");

logging::info!("hello from initialized global");
}
17 changes: 17 additions & 0 deletions crates/lambda-rs-logging/examples/04_builder_env.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// When building examples inside the crate, refer to the library as `logging` directly.

fn main() {
// Build a custom logger and apply env level
let logger = logging::Logger::builder()
.name("builder-env")
.level(logging::LogLevel::INFO)
.with_handler(Box::new(logging::handler::ConsoleHandler::new(
"builder-env",
)))
.build();

logging::env::apply_env_level(&logger, Some("LAMBDA_LOG"));

logger.debug("filtered unless LAMBDA_LOG=debug".to_string());
logger.info("visible at info".to_string());
}
17 changes: 17 additions & 0 deletions crates/lambda-rs-logging/examples/05_json_handler.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Inside this crate, refer to the lib as `logging` directly.

fn main() {
let path = std::env::temp_dir().join("lambda_json_example.log");
let path_s = path.to_string_lossy().to_string();

let logger = logging::Logger::builder()
.name("json-example")
.level(logging::LogLevel::TRACE)
.with_handler(Box::new(logging::handler::JsonHandler::new(path_s.clone())))
.build();

logger.info("json info".to_string());
logger.error("json error".to_string());

println!("wrote JSON to {}", path_s);
}
20 changes: 20 additions & 0 deletions crates/lambda-rs-logging/examples/06_rotating_file.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
fn main() {
let base = std::env::temp_dir().join("lambda_rotate_example.log");
let base_s = base.to_string_lossy().to_string();

let logger = logging::Logger::builder()
.name("rotate-example")
.level(logging::LogLevel::TRACE)
.with_handler(Box::new(logging::handler::RotatingFileHandler::new(
base_s.clone(),
256, // bytes
3, // keep 3 backups
)))
.build();

for i in 0..200 {
logger.info(format!("log line {:03}", i));
}

println!("rotation base: {} (check .1, .2, .3)", base_s);
}
Loading
Loading