Skip to main content

ice_age/
lib.rs

1// License: see LICENSE file at root directory of `master` branch
2
3//! # Simple logging kit
4//!
5//! ## Project
6//!
7//! - Repository: <https://bitbucket.org/haibison/ice-age>
8//! - License: Nice License 1.0.0 _(see LICENSE file at root directory of `master` branch)_
9//! - _This project follows [Semantic Versioning 2.0.0]_
10//!
11//! ---
12//!
13//! ## Design
14//!
15//! It uses [synchronous channels][r::sync_channel] for communication. Log records are stored in RAM, and will be flushed to
16//! disk based on some configurable conditions: a period of time, or when maximum number of records reached.
17//!
18//! Backends: SQLite.
19//!
20//! The crate's own log messages are prefixed with [`TAG`][::TAG].
21//!
22//! ## Examples
23//!
24//! ```
25//! use std::{
26//!     env,
27//!     sync::mpsc::TrySendError,
28//!     thread,
29//!     time::{UNIX_EPOCH, Duration, SystemTime},
30//! };
31//! use ice_age::{Config, Cmd, Log, Logger};
32//!
33//! let config = Config {
34//!     // Directory to save log files
35//!     work_dir: env::temp_dir(),
36//!     // For this example, max file length is 1 MiB
37//!     max_file_len: 1024 * 1024,
38//!     // Keep log files at most 3 days
39//!     log_files_reserved: Duration::from_secs(3 * 24 * 60 * 60),
40//!     // Maximum log records to be kept in RAM
41//!     buf_len: 5_000,
42//!     // Flush to disk every 30 minutes
43//!     disk_flush_interval: Duration::from_secs(30 * 60),
44//! };
45//!
46//! let logger = Logger::make(config).unwrap();
47//! for _ in 0..3 {
48//!     let logger = logger.clone();
49//!     thread::spawn(move || {
50//!         let log = Log {
51//!             time: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(),
52//!             remote_ip: String::from("127.0.0.1"),
53//!             url: String::from("/api/statistics"),
54//!             response_size: Some(512),
55//!             code: 200,
56//!             runtime: Duration::from_secs(1),
57//!             notes: None,
58//!         };
59//!
60//!         // Use ::try_send() to not block the thread.
61//!         // This example's strategy is to discard failed calls.
62//!         match logger.try_send(Cmd::StoreLog(log)) {
63//!             Ok(()) => (),
64//!             Err(TrySendError::Full(_)) =>
65//!                 eprintln!("Log buffer is full, discarding..."),
66//!             Err(TrySendError::Disconnected(_)) =>
67//!                 eprintln!("Failed to store log. Perhaps log server is down."),
68//!         };
69//!     });
70//! }
71//! ```
72//!
73//! [Semantic Versioning 2.0.0]: https://semver.org/spec/v2.0.0.html
74//! [::TAG]: constant.TAG.html
75//! [r::sync_channel]: https://doc.rust-lang.org/std/sync/mpsc/fn.sync_channel.html
76
77#[macro_use]
78#[allow(unused_macros)]
79mod __;
80mod root;
81
82pub mod version_info;
83
84pub use root::*;
85
86// ╔═════════════════╗
87// ║   IDENTIFIERS   ║
88// ╚═════════════════╝
89
90macro_rules! code_name  { () => { "ice-age" }}
91macro_rules! version    { () => { "0.16.0" }}
92
93/// # Crate name
94pub const NAME: &str = "Ice Age";
95
96/// # Crate code name
97pub const CODE_NAME: &str = code_name!();
98
99/// # ID of this crate
100pub const ID: &str = concat!(
101    "025f3a9e-9bc88f1d-8a8a6b9a-9a00e3d5-10b76338-67eb660c-10560cf2-d8049819-",
102    "bebdff98-b9883fd2-17155b4f-b85e3ccd-02b818ac-18f9bcbc-e76c778a-53a0e376",
103);
104
105/// # Crate version
106pub const VERSION: &str = version!();
107
108/// # Crate release date (year/month/day)
109pub const RELEASE_DATE: (u16, u8, u8) = (2020, 5, 3);
110
111/// # Tag, which can be used for logging...
112pub const TAG: &str = concat!(code_name!(), "::025f3a9e::", version!());
113
114// ╔════════════════════╗
115// ║   IMPLEMENTATION   ║
116// ╚════════════════════╝
117
118#[test]
119fn test_crate_version() {
120    assert_eq!(VERSION, env!("CARGO_PKG_VERSION"));
121}