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