rush_sync_server/commands/log_level/
manager.rs1use crate::core::prelude::*;
2use log::LevelFilter;
3use std::sync::Mutex;
4
5pub struct LogLevelManager;
6
7static CURRENT_LOG_LEVEL: Mutex<LevelFilter> = Mutex::new(LevelFilter::Info);
8
9impl LogLevelManager {
10 pub fn show_status() -> String {
11 let current = Self::get_current_level();
12 let current_name = Self::level_to_name(current);
13 let current_number = Self::level_to_number(current);
14
15 format!(
16 "{}\n{}",
17 get_command_translation(
18 "system.commands.log_level.current_status",
19 &[¤t_name, ¤t_number]
20 ),
21 Self::show_help_i18n()
22 )
23 }
24
25 pub fn show_help_i18n() -> String {
26 get_command_translation("system.commands.log_level.help_text", &[])
27 }
28
29 pub fn show_help() -> String {
30 Self::show_help_i18n()
31 }
32
33 pub fn set_level_persistent(level_input: &str) -> Result<String> {
34 use log::LevelFilter;
35
36 let level_filter = match level_input {
37 "1" => LevelFilter::Error,
38 "2" => LevelFilter::Warn,
39 "3" => LevelFilter::Info,
40 "4" => LevelFilter::Debug,
41 "5" => LevelFilter::Trace,
42 "error" | "ERROR" => LevelFilter::Error,
43 "warn" | "WARN" | "warning" => LevelFilter::Warn,
44 "info" | "INFO" => LevelFilter::Info,
45 "debug" | "DEBUG" => LevelFilter::Debug,
46 "trace" | "TRACE" => LevelFilter::Trace,
47 _ => {
48 return Err(AppError::Validation(get_command_translation(
49 "system.commands.log_level.invalid_level",
50 &[level_input],
51 )));
52 }
53 };
54
55 Self::init_with_level(level_filter);
56 Ok(get_command_translation(
57 "system.commands.log_level.changed",
58 &[level_input],
59 ))
60 }
61
62 pub fn set_level_runtime(level_filter: LevelFilter) {
63 if let Ok(mut current) = CURRENT_LOG_LEVEL.lock() {
64 *current = level_filter;
65 }
66 log::set_max_level(level_filter);
67 }
68
69 pub async fn load_from_config() -> LevelFilter {
70 match crate::core::config::Config::load_with_messages(false).await {
71 Ok(config) => match Self::string_to_level_filter(&config.log_level) {
72 Ok(level) => level,
73 Err(_) => {
74 log::warn!(
75 "{}",
76 get_translation(
77 "config.validation.invalid_log_level",
78 &[&config.log_level]
79 )
80 );
81 LevelFilter::Info
82 }
83 },
84 Err(_) => LevelFilter::Info,
85 }
86 }
87
88 pub fn get_current_level() -> LevelFilter {
89 if let Ok(current) = CURRENT_LOG_LEVEL.lock() {
90 *current
91 } else {
92 log::max_level()
93 }
94 }
95
96 pub fn init_with_level(level: LevelFilter) {
97 if let Ok(mut current) = CURRENT_LOG_LEVEL.lock() {
98 *current = level;
99 }
100 log::set_max_level(level);
101 }
102
103 fn string_to_level_filter(s: &str) -> std::result::Result<LevelFilter, ()> {
104 match s.to_lowercase().as_str() {
105 "error" | "1" => Ok(LevelFilter::Error),
106 "warn" | "warning" | "2" => Ok(LevelFilter::Warn),
107 "info" | "3" => Ok(LevelFilter::Info),
108 "debug" | "4" => Ok(LevelFilter::Debug),
109 "trace" | "5" => Ok(LevelFilter::Trace),
110 "off" | "0" => Ok(LevelFilter::Off),
111 _ => Err(()),
112 }
113 }
114
115 fn level_to_name(level: LevelFilter) -> String {
116 match level {
117 LevelFilter::Error => "ERROR".to_string(),
118 LevelFilter::Warn => "WARN".to_string(),
119 LevelFilter::Info => "INFO".to_string(),
120 LevelFilter::Debug => "DEBUG".to_string(),
121 LevelFilter::Trace => "TRACE".to_string(),
122 LevelFilter::Off => "OFF".to_string(),
123 }
124 }
125
126 fn level_to_number(level: LevelFilter) -> String {
127 match level {
128 LevelFilter::Error => "1".to_string(),
129 LevelFilter::Warn => "2".to_string(),
130 LevelFilter::Info => "3".to_string(),
131 LevelFilter::Debug => "4".to_string(),
132 LevelFilter::Trace => "5".to_string(),
133 LevelFilter::Off => "0".to_string(),
134 }
135 }
136}