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
#![deny(missing_docs)]
mod level;
#[macro_use]
mod macros;
mod metadata;
pub mod subscriber;
use std::cell::RefCell;
use lunatic::{process_local, spawn_link, Process};
use serde::{Deserialize, Serialize};
use subscriber::Subscriber;
pub use crate::level::*;
pub use crate::metadata::*;
process_local! {
static LOGGING_PROCESS: RefCell<LoggingProcess> = RefCell::new(LoggingProcess::NotLookedUp);
}
enum LoggingProcess {
NotLookedUp,
NotPresent,
Present(Process<Event>),
}
pub fn init(subscriber: impl Subscriber) -> Process<Event> {
if Process::<Event>::lookup("lunatic::logger").is_some() {
panic!("logger already initialized");
}
let process = spawn_subscriber(subscriber);
process.register("lunatic::logger");
LOGGING_PROCESS.with_borrow_mut(|mut proc| *proc = LoggingProcess::Present(process.clone()));
process
}
pub fn spawn_subscriber(subscriber: impl Subscriber) -> Process<Event> {
spawn_link!(|subscriber, mailbox: Mailbox<Event>| {
loop {
let event = mailbox.receive();
if subscriber.enabled(event.metadata()) {
subscriber.event(&event);
}
}
})
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Event {
message: String,
metadata: Metadata,
}
impl Event {
pub const fn new(message: String, metadata: Metadata) -> Self {
Event { metadata, message }
}
pub fn message(&self) -> &String {
&self.message
}
pub fn metadata(&self) -> &Metadata {
&self.metadata
}
}
#[doc(hidden)]
pub fn __lookup_logging_process() -> Option<Process<Event>> {
LOGGING_PROCESS.with(|proc| match &*proc.borrow() {
LoggingProcess::NotLookedUp => match Process::<Event>::lookup("lunatic::logger") {
Some(process) => {
*proc.borrow_mut() = LoggingProcess::Present(process.clone());
Some(process)
}
None => {
*proc.borrow_mut() = LoggingProcess::NotPresent;
None
}
},
LoggingProcess::NotPresent => None,
LoggingProcess::Present(process) => Some(process.clone()),
})
}