rsiot_extra_components/
cmp_logger.rs

1//! Компонент для логгирования сообщений
2
3use async_trait::async_trait;
4use tracing::{debug, error, info, trace, warn, Level};
5
6use rsiot_component_core::{CmpInOut, Component, ComponentError, IComponentProcess};
7use rsiot_messages_core::{AuthPermissions, MsgDataBound};
8
9/// Настройки компонента логгирования
10#[derive(Clone, Debug)]
11pub struct Config {
12    /// Уровень логгирования
13    pub level: Level,
14    /// Добавляется в начале каждого сообщения
15    pub header: String,
16}
17
18#[cfg_attr(not(feature = "single-thread"), async_trait)]
19#[cfg_attr(feature = "single-thread", async_trait(?Send))]
20impl<TMessage> IComponentProcess<Config, TMessage> for Component<Config, TMessage>
21where
22    TMessage: MsgDataBound,
23{
24    async fn process(
25        &self,
26        config: Config,
27        in_out: CmpInOut<TMessage>,
28    ) -> Result<(), ComponentError> {
29        process(
30            config,
31            in_out.clone_with_new_id("cmp_logger", AuthPermissions::FullAccess),
32        )
33        .await
34    }
35}
36
37async fn process<TMessage>(
38    config: Config,
39    mut in_out: CmpInOut<TMessage>,
40) -> Result<(), ComponentError>
41where
42    TMessage: MsgDataBound,
43{
44    let header = match config.header.as_str() {
45        "" => "".to_string(),
46        _ => format!("{}: ", config.header),
47    };
48    while let Ok(msg) = in_out.recv_input().await {
49        match config.level {
50            Level::TRACE => trace!("{}{:?}", header, msg),
51            Level::DEBUG => debug!("{}{:?}", header, msg),
52            Level::INFO => info!("{}{:?}", header, msg),
53            Level::WARN => warn!("{}{:?}", header, msg),
54            Level::ERROR => error!("{}{:?}", header, msg),
55        }
56    }
57    Ok(())
58}
59
60pub type Cmp<TMessage> = Component<Config, TMessage>;