apple-log 0.2.0

Safe Rust bindings for Apple's os_log — structured logging that integrates with Console.app + the log CLI on macOS
docs.rs failed to build apple-log-0.2.0
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.

apple-log

Safe Rust bindings for Apple's os_log on macOS — structured logging that integrates with Console.app and the log CLI.

Status: experimental. v0.1 ships per-subsystem Logger, free-function logging via OS_LOG_DEFAULT, all 5 standard levels (Default / Info / Debug / Error / Fault). v0.2 adds os_signpost for performance tracing, OSLogStore for reading back logs, and log crate facade impl.

Pure C (with a tiny shim file built via cc) — zero Swift bridge.

Quick start

use apple_log::prelude::*;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Free-function logging via OS_LOG_DEFAULT (no subsystem).
    log(Level::Info, "starting up");

    // Per-subsystem Logger (filter via `log stream --predicate ...`).
    let logger = Logger::new("fish.doom.myapp", "net")?;
    logger.info("opening port 8080");
    logger.debug("tcp socket fd=7");
    logger.error("connection refused");
    Ok(())
}

Then in another terminal:

log stream --predicate 'subsystem == "fish.doom.myapp"'
log show --info --debug --predicate 'subsystem == "fish.doom.myapp"' --last 1m

Or open Console.app and filter by subsystem.

Why os_log over log/tracing?

  • System-integrated: visible in Console.app, log CLI, system-wide log archives — even after your binary exits.
  • Persistent: error+ entries survive log rotation.
  • Privacy-aware: format specifiers (%{public}s vs %{private}s) control redaction.
  • No I/O cost: the kernel buffers log records; expensive-to-format messages are skipped when no subscriber is active.
  • Free for the user: integrates with existing macOS log infrastructure (sysdiagnose, MDM exports, etc.).

You can still wire log/tracing on top — both crates support pluggable backends.

your-app ──► apple-log ──► /private/var/db/diagnostics
                                  │
                                  ├──► Console.app
                                  ├──► `log` CLI
                                  └──► sysdiagnose archives

Roadmap

  • Logger::new(subsystem, category)
  • Logger::{info, debug, error, fault} + log(level, msg) shortcut
  • log() free function via OS_LOG_DEFAULT
  • All 5 levels (Default / Info / Debug / Error / Fault)
  • Send + Sync Logger
  • os_signpost for performance tracing
  • OSLogStore to read back past logs from Rust
  • log + tracing crate facade backends
  • Format-string redaction control (%{private}s selector)

License

Licensed under either of Apache-2.0 or MIT at your option.