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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
use std::ops::{Deref, DerefMut};
use std::sync::Mutex;
use std::time::SystemTime;
use crate::{proxy::copy::Proxy, serialize::Serialize, write::LogWrite, Item, Severity};
pub trait Logger: Sync + Send {
fn log(&self, item: Item);
}
pub fn logger_new_from_proxy<L, P>(original: L, proxy: P) -> impl Logger
where
L: Logger,
P: Proxy + Sync + Send,
{
logger_new_from_fn(move |old: Item| {
let neo: Item = proxy.get_item(old);
original.log(neo)
})
}
struct FnLogger<L> {
internal: L,
}
impl<L> Logger for FnLogger<L>
where
L: Fn(Item) + Sync + Send,
{
fn log(&self, item: Item) {
(self.internal)(item)
}
}
pub fn logger_new_from_fn<L>(internal: L) -> impl Logger
where
L: Fn(Item) + Sync + Send,
{
FnLogger { internal }
}
struct WriteSerialized<S, W> {
serialize: S,
write: W,
}
impl<S, W> Logger for WriteSerialized<S, W>
where
S: Serialize,
W: LogWrite,
{
fn log(&self, item: Item) {
let mut buf: String = String::new();
self.serialize.serialize(&item, &mut buf);
self.write.write(buf.as_str(), item.severity)
}
}
pub fn logger_new<S, W>(serialize: S, write: W) -> impl Logger
where
S: Serialize,
W: LogWrite,
{
WriteSerialized { serialize, write }
}
static _LOGGER: Mutex<Option<&dyn Logger>> = Mutex::new(None);
impl Logger for Option<&dyn Logger> {
fn log(&self, item: Item) {
match self {
None => {}
Some(l) => l.log(item),
}
}
}
impl Logger for Mutex<Option<&dyn Logger>> {
fn log(&self, item: Item) {
match self.lock() {
Err(_) => {}
Ok(g) => {
let ro: &Option<_> = g.deref();
let o: Option<&dyn Logger> = ro.as_deref();
o.log(item)
}
}
}
}
impl Logger for Box<dyn Logger> {
fn log(&self, item: Item) {
let r = self.as_ref();
r.log(item)
}
}
fn _log(mut item: Item) {
item.timestamp = SystemTime::now();
_LOGGER.log(item)
}
pub fn log_trace(mut item: Item) {
item.severity = Severity::Trace;
_log(item)
}
pub fn log_debug(mut item: Item) {
item.severity = Severity::Debug;
_log(item)
}
pub fn log_info(mut item: Item) {
item.severity = Severity::Info;
_log(item)
}
pub fn log_warn(mut item: Item) {
item.severity = Severity::Warn;
_log(item)
}
pub fn log_error(mut item: Item) {
item.severity = Severity::Error;
_log(item)
}
pub fn log_fatal(mut item: Item) {
item.severity = Severity::Fatal;
_log(item)
}
pub fn set(neo: &'static dyn Logger) {
match _LOGGER.try_lock() {
Err(_) => {}
Ok(mut g) => {
let mo: &mut Option<_> = g.deref_mut();
mo.replace(neo);
}
}
}
pub fn set_boxed(neo: Box<dyn Logger>) {
set(Box::leak(neo))
}