1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use crate::log::log_def::VibeLogInfo;
use crate::log::log_level::LogLevel;
impl VibeLogInfo {
/// Creates a structured log record.
///
/// # Returns
///
/// A [`VibeLogInfo`] containing the provided level, tag, content, and timestamp.
///
/// # Examples
///
/// ```
/// use vibe_ready::{VibeLogInfo, VibeLogLevel};
///
/// let info = VibeLogInfo::new(VibeLogLevel::Info, "startup".into(), "ready".into(), 1);
/// assert_eq!(info.tag(), "startup");
/// ```
pub fn new(level: LogLevel, tag: String, content: String, create_time: i64) -> VibeLogInfo {
VibeLogInfo {
level,
tag,
content,
create_time,
}
}
/// Returns the log severity.
///
/// # Returns
///
/// The [`LogLevel`] stored in the record.
pub fn level(&self) -> LogLevel {
self.level
}
/// Returns the log tag.
///
/// # Returns
///
/// A cloned tag string.
pub fn tag(&self) -> String {
self.tag.clone()
}
/// Returns the log content.
///
/// # Returns
///
/// A cloned content string.
pub fn content(&self) -> String {
self.content.clone()
}
/// Returns the creation timestamp.
///
/// # Returns
///
/// Unix timestamp in milliseconds.
pub fn create_time(&self) -> i64 {
self.create_time
}
/// Splits oversized log content into smaller log records.
///
/// # Returns
///
/// One record for normal content, or multiple records for content larger
/// than the internal CSV chunk size.
pub fn slice(&self) -> Vec<VibeLogInfo> {
let size = self.to_csv().len();
if size <= 1024 * 1024 {
return vec![self.clone()];
}
let mut ret = vec![];
let chars = self.content.chars().collect::<Vec<_>>();
for (_, chunk) in chars.chunks(1024 * 1024 / 4).enumerate() {
let content = chunk.iter().collect::<String>();
ret.push(Self {
content,
..self.clone()
})
}
ret
}
/// Serializes the log record as a CSV row.
///
/// # Returns
///
/// A CSV-formatted string ending with a newline.
pub fn to_csv(&self) -> String {
format!(
"{},{},{},\"{}\"\n",
self.create_time,
self.level as i16,
self.tag,
self.content.replace('"', "\"\"")
)
}
}
#[cfg(test)]
mod strict_tests {
use super::*;
include!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/test/unit/log/models_impl_tests.rs"
));
}