Crate ice_age[][src]

Simple logging kit

Project


Design

It uses synchronous channels for communication. Log records are stored in RAM, and will be flushed to disk based on some configurable conditions: a period of time, or when maximum number of records reached.

Backends: either SQLite or Binn format. There's binary kit which can port .ice-age files to .sqlite files.

The crate's own log messages are prefixed with TAG.

Usage

Default features use SQLite via rusqlite crate.

Currently, flushing log records to SQLite database is via a prepared cached statement, inside a transaction. However, from my experiences, Binn backend is often twice as fast. I don't keep the number for SQLite backend, but with Binn backend, some numbers are:

Records Time to flush
1879 3.220934ms
1839 4.975739ms
1932 3.313327ms
1873 5.222861ms
1732 4.771375ms
1957 5.312771ms
2017 3.550235ms
3226 5.561279ms
3137 5.451346ms
2816 8.097975ms

To use Binn backend, you have to turn default features off:

[dependencies]
ice-age = { version = "x.y.z", default-features = false, features = ["with-binn-ir"] }

Examples

use std::{
    path::PathBuf,
    thread,
    time::{UNIX_EPOCH, Duration, SystemTime},
};
use ice_age::{Config, Cmd, Log, Logger};

let config = Config {
    // Directory to save log files
    work_dir: PathBuf::from("/tmp/"),
    // For this example, max file length is 1 MiB
    max_file_len: 1024 * 1024,
    // Keep log files at most 3 days
    log_files_reserved: Duration::from_secs(3 * 24 * 60 * 60),
    // Maximum log records to be kept in RAM
    buf_len: 5_000,
    // Flush to disk every 30 minutes
    disk_flush_interval: Duration::from_secs(30 * 60),
};

let logger = Logger::make(config).unwrap();
for _ in 0..3 {
    let logger = logger.clone();
    thread::spawn(move || {
        let log = Log {
            time: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(),
            remote_ip: String::from("127.0.0.1"),
            url: String::from("/api/statistics"),
            response_size: Some(512),
            code: 200,
            runtime: Duration::from_secs(1),
            notes: None,
        };

        // Use ::try_send() to not block the thread.
        // This example's strategy is to discard failed calls.
        if let Err(_) = logger.try_send(Cmd::StoreLog(log)) {
            eprintln!("Failed to store log, discarding...");
        }
    });
}

Structs

Config

Config

Log

Log

Logger

Logger

Enums

Cmd

Commands

Constants

CODE_NAME

Crate code name

NAME

Crate name

RELEASE_DATE

Crate release date (year/month/day)

TAG

Tag, which can be used for logging...

UUID

Unique universally identifier of this crate

VERSION

Crate version

Type Definitions

CmdSender

Command sender