flwrs_plugin/plugin/
logger.rs1use crate::plugin::msg_client::MSG_CLIENT;
2use crate::schema::common::log_level::Enum;
3use crate::schema::common::{
4 log_level::Enum as LogLevel, plugin_type::Enum as PluginType, LogEvent,
5};
6use lazy_static::lazy_static;
7use log::{Level, Metadata, Record, SetLoggerError};
8use prost::Message;
9use std::sync::{Arc, RwLock};
10
11lazy_static! {
12 pub(crate) static ref LOGGER: Arc<RwLock<PluginLogger>> =
13 Arc::new(RwLock::new(PluginLogger::default()));
14 pub(crate) static ref LOG_WRAPPER: Arc<LogWrapper> = Arc::new(LogWrapper::default());
15}
16
17pub(crate) struct PluginLogger {
18 plugin_id: String,
19 plugin_type: PluginType,
20 level: Level,
21}
22
23impl PluginLogger {
24 pub(crate) fn set_plugin_id(&mut self, plugin_id: String) {
25 self.plugin_id = plugin_id;
26 }
27
28 pub(crate) fn set_plugin_type(&mut self, plugin_type: PluginType) {
29 self.plugin_type = plugin_type;
30 }
31
32 pub(crate) fn set_level(&mut self, level: Level) {
33 self.level = level;
34 }
35
36 pub(crate) fn initialize(id: &str, log_level: Level) -> Result<(), SetLoggerError> {
37 let mut logger = LOGGER.write().expect("Was expecting to lock");
38 logger.set_plugin_id(id.into());
39 logger.set_plugin_type(PluginType::Sink);
40 logger.set_level(log_level.into());
41 log::set_logger(LOG_WRAPPER.as_ref())?;
42 Ok(())
43 }
44}
45
46impl log::Log for PluginLogger {
47 fn enabled(&self, metadata: &Metadata) -> bool {
48 metadata.level() <= self.level
49 }
50
51 fn log(&self, record: &Record) {
52 let log_level: LogLevel = self.level.into();
53 let msg = LogEvent {
54 plugin_id: self.plugin_id.to_string(),
55 plugin_type: self.plugin_type as i32,
56 log_level: log_level as i32,
57 message: record.args().as_str().unwrap_or("<no message>").to_string(),
58 details: vec![],
59 };
60
61 tokio::task::spawn(async move {
62 match MSG_CLIENT
63 .read()
64 .await
65 .send(msg.encode_to_vec().as_slice())
66 .await
67 {
68 Ok(_) => {}
69 Err(e) => {
70 println!("Failed to send log message: {}", e); println!("Message: {}", msg.message);
72 println!("Details: {:?}", msg.details);
73 println!("Log level: {:?}", log_level);
74 println!("Plugin type: {:?}", msg.plugin_type);
75 println!("Plugin ID: {:?}", msg.plugin_id);
76 }
77 };
78 });
79 }
80
81 fn flush(&self) {
82 }
84}
85
86impl Default for PluginLogger {
87 fn default() -> Self {
88 Self {
89 plugin_id: "<no-ID>".to_string(),
90 level: Level::Warn,
91 plugin_type: PluginType::Undefined,
92 }
93 }
94}
95
96impl Into<LogLevel> for Level {
97 fn into(self) -> LogLevel {
98 match self {
99 Level::Error => LogLevel::Error,
100 Level::Warn => LogLevel::Warn,
101 Level::Info => LogLevel::Info,
102 Level::Debug => LogLevel::Debug,
103 Level::Trace => LogLevel::Trace,
104 }
105 }
106}
107
108impl From<LogLevel> for Level {
109 fn from(value: LogLevel) -> Self {
110 match value {
111 Enum::Undefined => Self::Warn,
112 Enum::Trace => Self::Trace,
113 Enum::Debug => Self::Debug,
114 Enum::Info => Self::Info,
115 Enum::Warn => Self::Warn,
116 Enum::Error => Self::Error,
117 }
118 }
119}
120
121#[derive(Default)]
122pub(crate) struct LogWrapper;
123
124impl log::Log for LogWrapper {
125 fn enabled(&self, metadata: &Metadata) -> bool {
126 let logger = LOGGER.read();
127 match logger {
128 Ok(logger) => logger.enabled(metadata),
129 Err(err) => {
130 println!("Failed to read logger: {}", err);
131 false
132 }
133 }
134 }
135
136 fn log(&self, record: &Record) {
137 let logger = LOGGER.read();
138 match logger {
139 Ok(logger) => logger.log(record),
140 Err(err) => {
141 println!("Failed to read logger: {}", err);
142 }
143 };
144 }
145
146 fn flush(&self) {
147 let logger = LOGGER.read();
148 match logger {
149 Ok(logger) => logger.flush(),
150 Err(err) => {
151 println!("Failed to read logger: {}", err);
152 }
153 };
154 }
155}