master-log-client 0.1.0

Rust client for sending structured logs to Master Log
Documentation

Master Log Rust Client

Rust client for sending structured logs to Master Log. It mirrors the Python client’s core shape: environment configuration, a configure() function that takes precedence over env values, simple module-level logging helpers, explicit client instances, automatic host/process metadata, TTL support, background batching, flush/shutdown, backpressure, and a minimum HTTP request interval.

Environment

Linux/macOS:

export MASTER_LOG_API_KEY=dev-key
export MASTER_LOG_ENDPOINT=http://127.0.0.1:8000

Windows PowerShell:

$env:MASTER_LOG_API_KEY = "dev-key"
$env:MASTER_LOG_ENDPOINT = "http://127.0.0.1:8000"

MASTER_LOG_ENDPOINT may be the backend root, /api/v1, /api/v1/logs, or /api/v1/logs/batch.

Optional controls:

export MASTER_LOG_TIMEOUT_SECONDS=2.0
export MASTER_LOG_ECHO=false
export MASTER_LOG_ASYNC=true
export MASTER_LOG_BATCH_SIZE=100
export MASTER_LOG_FLUSH_INTERVAL_SECONDS=1.0
export MASTER_LOG_MAX_QUEUE_SIZE=10000
export MASTER_LOG_DROP_WHEN_FULL=true
export MASTER_LOG_QUEUE_TIMEOUT_SECONDS=0.25
export MASTER_LOG_BACKPRESSURE=true
export MASTER_LOG_INITIAL_SEND_SECONDS_PER_LOG=0.005
export MASTER_LOG_MAX_ENQUEUE_SLEEP_SECONDS=0.25
export MASTER_LOG_MIN_REQUEST_INTERVAL_SECONDS=0.25

Add To A Rust Project

From a local checkout:

[dependencies]
master-log-client = { path = "../master_log_clients/rust" }
serde_json = "1"

Simple Usage

use std::time::Duration;

use master_log_client::{flush, mlog, mlogf, warn};

fn main() {
    mlog("Telescope array online");
    warn("Dome slit wind threshold approaching");
    mlogf!("Captured frame {} for {}", 42, "M31");

    let result = flush(Duration::from_secs(5));
    if !result.ok {
        eprintln!("Master Log flush failed: {}", result.error.unwrap_or_default());
    }
}

Configure In Code

Values passed to configure() are used immediately and take precedence over MASTER_LOG_API_KEY and MASTER_LOG_ENDPOINT.

use std::time::Duration;

use master_log_client::{configure, flush, mlog, MasterLogConfig};

fn main() {
    configure(
        MasterLogConfig::from_env()
            .api_key("dev-key")
            .endpoint("http://127.0.0.1:8000")
            .batch_size(100)
            .flush_interval(Duration::from_secs(1))
            .min_request_interval(Duration::from_millis(250)),
    );

    mlog("Mirror cover opened");
    flush(Duration::from_secs(5));
}

Structured Fields

use std::time::Duration;

use master_log_client::{flush, log_entry, LogEntry, Severity};
use serde_json::json;

fn main() {
    log_entry(
        LogEntry::with_title("Camera cooling alert", "CCD cooling loop failed to settle")
            .severity(Severity::Error)
            .tags(["ccd", "camera"])
            .ttl_seconds(120)
            .metadata(json!({
                "setpoint_celsius": -20,
                "actual_celsius": -16.8
            })),
    );

    flush(Duration::from_secs(5));
}

Explicit Client

use std::time::Duration;

use master_log_client::{LogEntry, MasterLogClient, MasterLogConfig, Severity};

fn main() {
    let client = MasterLogClient::new(
        MasterLogConfig::from_env()
            .api_key("dev-key")
            .endpoint("http://127.0.0.1:8000"),
    );

    client.log_entry(
        LogEntry::new("Flat-field calibration completed")
            .severity(Severity::Info)
            .tags(["calibration", "ccd"]),
    );

    client.flush(Duration::from_secs(5));
}

Background Batching

The Rust client defaults to a background worker thread. Calls enqueue log events locally and wake the worker. The worker drains the queue, batches events, and sends them to /api/v1/logs/batch.

min_request_interval or MASTER_LOG_MIN_REQUEST_INTERVAL_SECONDS enforces a minimum delay between actual HTTP request starts. This is separate from flush_interval: a full batch can wake the worker immediately, but the worker still waits until the minimum request interval has elapsed.

Async enqueue is intentionally not free by default. After each queued log, the caller sleeps for the worker’s moving average send time per accepted log. The first burst uses initial_send_seconds_per_log, then successful batch sends tune the value. Use backpressure(false) only when the caller already has its own rate limit.

Use async_mode(false) when a program must block on every send or when a background thread is not appropriate.

Automatic Metadata

Every event includes a rust_client metadata block with:

  • Hostname
  • Process id
  • Process name
  • argv0
  • Current working directory
  • Library name and version

Failures are non-fatal by default. Logging calls return MasterLogResult with ok, status_code, event_id, queued, accepted, response, and error. Use try_log() or try_log_entry() on MasterLogClient when Rust Result errors are preferred.