1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#[macro_use]
extern crate wascc_codec as codec;
use codec::capabilities::{CapabilityProvider, Dispatcher, NullDispatcher};
use codec::core::{CapabilityConfiguration, OP_BIND_ACTOR, OP_REMOVE_ACTOR};
use codec::{
deserialize,
logging::{WriteLogRequest, OP_LOG},
};
#[macro_use]
extern crate log;
use std::error::Error;
use std::sync::RwLock;
#[cfg(not(feature = "static_plugin"))]
capability_provider!(LoggingProvider, LoggingProvider::new);
const CAPABILITY_ID: &str = "wascc:logging";
const SYSTEM_ACTOR: &str = "system";
const ERROR: u32 = 1;
const WARN: u32 = 2;
const INFO: u32 = 3;
const DEBUG: u32 = 4;
const TRACE: u32 = 5;
pub struct LoggingProvider {
dispatcher: RwLock<Box<dyn Dispatcher>>,
}
impl Default for LoggingProvider {
fn default() -> Self {
match env_logger::try_init() {
Ok(_) => {}
Err(_) => {}
}
LoggingProvider {
dispatcher: RwLock::new(Box::new(NullDispatcher::new())),
}
}
}
impl LoggingProvider {
pub fn new() -> Self {
Self::default()
}
}
impl CapabilityProvider for LoggingProvider {
fn capability_id(&self) -> &'static str {
CAPABILITY_ID
}
fn configure_dispatch(&self, dispatcher: Box<dyn Dispatcher>) -> Result<(), Box<dyn Error>> {
let mut lock = self.dispatcher.write().unwrap();
*lock = dispatcher;
Ok(())
}
fn name(&self) -> &'static str {
"waSCC Logging Provider"
}
fn handle_call(&self, actor: &str, op: &str, msg: &[u8]) -> Result<Vec<u8>, Box<dyn Error>> {
if op == OP_BIND_ACTOR && actor == SYSTEM_ACTOR {
Ok(vec![])
} else if op == OP_REMOVE_ACTOR && actor == SYSTEM_ACTOR {
let cfg_vals = deserialize::<CapabilityConfiguration>(msg)?;
info!("Removing actor configuration for {}", cfg_vals.module);
Ok(vec![])
} else if op == OP_LOG {
let log_msg = deserialize::<WriteLogRequest>(msg)?;
match log_msg.level {
ERROR => error!("[{}] {}", actor, log_msg.body),
WARN => warn!("[{}] {}", actor, log_msg.body),
INFO => info!("[{}] {}", actor, log_msg.body),
DEBUG => debug!("[{}] {}", actor, log_msg.body),
TRACE => trace!("[{}] {}", actor, log_msg.body),
_ => error!("Unknown log level: {}", log_msg.level),
}
Ok(vec![])
} else {
Err(format!("Unknown operation: {}", op).into())
}
}
}