hyperlane_log/log/
fn.rs

1use crate::*;
2
3/// Extracts the second element (index number) from log filenames in a directory.
4///
5/// # Arguments
6///
7/// - `&str` - The directory path to scan for log files.
8///
9/// # Returns
10///
11/// - `usize` - The extracted index number or default start index.
12pub(crate) fn get_second_element_from_filename(dir_path: &str) -> usize {
13    let mut res_idx: usize = DEFAULT_LOG_FILE_START_IDX;
14    if let Ok(entries) = read_dir(dir_path) {
15        for entry in entries.filter_map(Result::ok) {
16            let file_name: String = entry.file_name().to_string_lossy().to_string();
17            let parts: Vec<&str> = file_name.split(POINT).collect();
18            if parts.len() > 1
19                && let Ok(second_element) = parts[1].parse::<usize>()
20            {
21                res_idx = second_element.max(res_idx);
22            }
23        }
24    }
25    res_idx.max(DEFAULT_LOG_FILE_START_IDX)
26}
27
28/// Generates a log filename with given index using current date.
29///
30/// # Arguments
31///
32/// - `usize` - The index number for the log file.
33///
34/// # Returns
35///
36/// - `String` - The formatted log filename with path.
37#[inline(always)]
38pub(crate) fn get_file_name(idx: usize) -> String {
39    format!(
40        "{}{}{}{}{}{}",
41        ROOT_PATH,
42        date(),
43        POINT,
44        idx,
45        POINT,
46        LOG_EXTENSION
47    )
48}
49
50/// Generates directory name for current date's logs.
51///
52/// # Returns
53///
54/// - `String` - The directory name based on current date.
55#[inline(always)]
56pub(crate) fn get_file_dir_name() -> String {
57    format!("{}{}", ROOT_PATH, date())
58}
59
60/// Constructs appropriate log file path considering size limits.
61///
62/// # Arguments
63///
64/// - `&str` - The system directory path.
65/// - `&str` - The base path for logs.
66/// - `&usize` - The maximum allowed file size in bytes.
67///
68/// # Returns
69///
70/// - `String` - The full path to appropriate log file.
71pub(crate) fn get_log_path(system_dir: &str, base_path: &str, limit_file_size: &usize) -> String {
72    let mut combined_path: String = base_path.trim_end_matches(ROOT_PATH).to_string();
73    if !system_dir.starts_with(ROOT_PATH) {
74        combined_path.push_str(ROOT_PATH);
75    }
76    combined_path.push_str(
77        system_dir
78            .trim_start_matches(ROOT_PATH)
79            .trim_end_matches(ROOT_PATH),
80    );
81    combined_path.push_str(&get_file_dir_name());
82    let idx: usize = get_second_element_from_filename(&combined_path);
83    let mut combined_path_clone: String = combined_path.clone();
84    combined_path.push_str(&get_file_name(idx));
85    let file_size: usize = get_file_size(&combined_path).unwrap_or_default() as usize;
86    if &file_size <= limit_file_size {
87        return combined_path;
88    }
89    combined_path_clone.push_str(&get_file_name(idx + 1));
90    combined_path_clone
91}
92
93/// Formats log data with timestamp for each line.
94///
95/// # Arguments
96///
97/// - `AsRef<str>` - The data to be logged, which will be converted to string slice.
98///
99/// # Returns
100///
101/// - `String` - The formatted log string with timestamps.
102#[inline(always)]
103pub fn common_log<T: AsRef<str>>(data: T) -> String {
104    let mut log_string: String = String::new();
105    for line in data.as_ref().lines() {
106        let line_string: String = format!("{}: {}{}", time(), line, BR);
107        log_string.push_str(&line_string);
108    }
109    log_string
110}
111
112/// Handles log data formatting by delegating to common_log.
113///
114/// # Arguments
115///
116/// - `AsRef<str>` - The data to be logged, which will be converted to string slice.
117///
118/// # Returns
119///
120/// - `String` - The formatted log string.
121#[inline(always)]
122pub fn log_handler<T: AsRef<str>>(log_data: T) -> String {
123    common_log(log_data)
124}