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
mod macros;
mod mongo_backend;
mod stdout_backend;
use chrono::{DateTime, Utc};
use potatonet::*;
use rmpv::Value;
use std::collections::HashMap;
#[doc(hidden)]
pub use chrono;
pub use mongo_backend::{MongoBackend, MongoBackendConfig};
pub use stdout_backend::StdoutBackend;
#[message]
#[derive(Copy, Clone, Eq, PartialEq)]
pub enum Level {
Trace,
Debug,
Info,
Warn,
Error,
}
impl Level {
pub fn as_str(&self) -> &'static str {
match self {
Level::Trace => "TRACE",
Level::Debug => "DEBUG",
Level::Info => "INFO",
Level::Warn => "WARN",
Level::Error => "ERROR",
}
}
}
pub type KvsHashMap = HashMap<String, Value>;
#[message]
pub struct Item {
pub time: DateTime<Utc>,
pub service: String,
pub level: Level,
pub message: String,
pub kvs: Option<KvsHashMap>,
}
pub trait Backend: Sync + Send + 'static {
fn append(&self, item: Item) -> Result<()>;
fn query_latest(&self, limit: usize) -> Result<Vec<Item>>;
}
pub struct Logger {
backend: Box<dyn Backend>,
}
impl Logger {
pub fn new<B: Backend>(backend: B) -> Self {
Self {
backend: Box::new(backend),
}
}
}
#[service]
impl Logger {
#[notify]
async fn log(&self, item: Item) {
self.backend.append(item).ok();
}
#[call]
async fn query_latest(&self, limit: usize) -> Result<Vec<Item>> {
self.backend.query_latest(limit)
}
}