lazy static (Rust)

Here’s an example demonstrating how to use lazy_static to initialize a global logger with thread-safe access in Rust.

#![allow(unused)] // Prevent unused code warnings for demonstration
use lazy_static::lazy_static; // Import `lazy_static` for safe, lazy static initialization
use reqwest::Client; // HTTP client for making requests
use std::sync::Mutex; // Mutex ensures thread-safe access to shared data

#[derive(Debug)] // Allows us to print debug information about `Logger` and `Log`
struct Logger {
    logs: Mutex<Vec<Log>>, // Use Mutex to protect the log vector from concurrent access
    url: String,           // Example URL where logs might be sent
    client: Client,        // HTTP client instance for sending logs
}

#[derive(Debug)] // Enable debugging display for `Log`
struct Log {
    message: String, // The content of the log
    timestamp: i64,  // A placeholder timestamp (e.g., Unix epoch time)
}

// `lazy_static!` ensures that the static value is only initialized once, lazily.
// This avoids thread-safety issues while providing global accessibility.
lazy_static! {
    static ref GLOBAL_LOGGER: Logger = Logger {
        logs: Mutex::new(vec![]), // Initialize an empty, thread-safe log vector
        url: "https://example.com".to_string(), // Example log submission URL
        client: Client::default(), // Default HTTP client configuration
    };
}

fn main() {
    // Log an example message by locking the Mutex to ensure thread-safe access.
    // `.lock()` acquires the Mutex lock; `.unwrap()` handles potential lock failure.
    GLOBAL_LOGGER.logs.lock().unwrap().push(Log {
        message: "Everything's cool".to_string(), // Add an example message
        timestamp: 123124234,                    // Example timestamp
    });

    // Access and print the logs, again using `.lock()` to safely access the data.
    println!("{:#?}", GLOBAL_LOGGER.logs.lock().unwrap());
}

The code is structured to illustrate safe concurrency and the advantages of lazy initialization while remaining simple enough for a beginner to grasp.

lazy_static:

  • Ensures safe, one-time initialization of static variables at runtime.
  • Perfect for creating global state in a thread-safe manner.

Mutex for Thread Safety:

  • Protects shared resources from race conditions in multi-threaded environments.
  • Ensures only one thread can access or modify the data at a time.

Global Logger:

  • Demonstrates how to create a global, reusable logging utility.
  • Logs are stored in a Vec guarded by a Mutex.

Future Expansion:

  • With the included reqwest::Client, this logger could be extended to send logs to a remote server.
Rust Programming

Previous article

Rust BenchmarkNew!!