bugfixes 0.2.3

Rust logging client for Bugfixes with optional remote reporting
Documentation
# bugfixes

Rust logging client for Bugfixes.

It provides:

- local log output with file and line capture
- global logging macros for application code
- explicit logger instances for dependency injection
- optional remote reporting to `POST /log`
- optional panic and bug reporting to `POST /bug`
- local-only logging paths for operational noise

## Install

```toml
[dependencies]
bugfixes = "0.1.0"
```

## Environment

Remote reporting is configured through:

- `BUGFIXES_AGENT_KEY`
- `BUGFIXES_AGENT_SECRET`
- `BUGFIXES_LOG_LEVEL`
- `BUGFIXES_LOCAL_ONLY`
- `BUGFIXES_SERVER`

If the agent credentials are missing, logs still print locally and remote reporting is skipped.

## Examples

Runnable examples live in [`examples/`](examples):

- `cargo run --example app_init`
- `cargo run --example explicit_logger`
- `cargo run --example local_only`

## Recommended app setup

For most binaries, initialize the global logger once at startup and then use the macros everywhere else:

```rust
fn main() -> Result<(), Box<dyn std::error::Error>> {
    init_bugfixes()?;

    bugfixes::info!("server starting on {}", ":3000")?;
    bugfixes::warn!("slow request threshold set to {}ms", 250)?;

    Ok(())
}

fn init_bugfixes() -> Result<(), Box<dyn std::error::Error>> {
    bugfixes::init_global_from_env()?;
    bugfixes::install_global_panic_hook();
    Ok(())
}
```

That is usually all you need. You do not need a custom init function to fall back to local-only mode when credentials are absent.

## Explicit logger instances

Use explicit logger instances in library code, services built around dependency injection, or anywhere you want logging to be passed in explicitly:

```rust
use bugfixes::BugfixesLogger;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let logger = BugfixesLogger::from_env()?;
    handle_request(&logger)?;
    Ok(())
}

fn handle_request(logger: &BugfixesLogger) -> Result<(), Box<dyn std::error::Error>> {
    logger.info("request started")?;
    logger.warn("upstream latency is elevated")?;
    Ok(())
}
```

## Local-only logging

Use local-only logging when a message should never be sent remotely:

```rust
use bugfixes::{BugfixesLogger, init_global_local, local_logger};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    BugfixesLogger::local()?.info("warming cache")?;
    local_logger().warn("retry loop is still booting")?;

    init_global_local()?;
    bugfixes::local::info!("server started on {}", ":3000")?;
    bugfixes::local::warn!("health check is not ready yet")?;

    Ok(())
}
```

## API shape

The crate supports both:

- explicit logger instances for libraries and injected dependencies
- global macros for application code
- `local_logger()` for direct local-only logging
- `bugfixes::local::{...}` macros for namespaced local-only logging

Typical macro usage looks like this:

```rust
bugfixes::debug!("loaded {}", 3);
bugfixes::info!("started");
bugfixes::warn!("slow request");
bugfixes::error!("db error: {}", "timeout")?;
```

Panic capture is available either explicitly:

```rust
let logger = bugfixes::BugfixesLogger::from_env()?;
let _ = logger.report_panic_payload(&"worker crashed");
```

or through a global hook:

```rust
bugfixes::init_global_from_env()?;
bugfixes::install_global_panic_hook();
```