1use once_cell::sync::Lazy;
9use parking_lot::Mutex;
10use serde::{Deserialize, Serialize};
11use serde_json::{self, value as json};
12use std::{
13 collections::VecDeque,
14 convert::TryInto,
15 time::{SystemTime, UNIX_EPOCH},
16};
17
18#[derive(Serialize, Deserialize, Clone)]
19pub struct JsonLogEntry {
20 pub name: String,
21 pub timestamp: u64,
22 pub json: json::Value,
23}
24
25const MAX_EVENTS_IN_QUEUE: usize = 10_000;
26
27#[macro_export]
32macro_rules! event {
33 ($name:expr, $($json:tt)*) => {
34 $crate::json_log::send_json_log($crate::json_log::JsonLogEntry::new(
35 $name,
36 serde_json::json!({$($json)+}),
37 ));
38 };
39}
40
41static JSON_LOG_ENTRY_QUEUE: Lazy<Mutex<VecDeque<JsonLogEntry>>> =
44 Lazy::new(|| Mutex::new(VecDeque::with_capacity(MAX_EVENTS_IN_QUEUE)));
45
46impl JsonLogEntry {
47 pub fn new(name: &'static str, json: json::Value) -> Self {
48 let timestamp = SystemTime::now()
49 .duration_since(UNIX_EPOCH)
50 .expect("System time is before UNIX_EPOCH")
51 .as_millis()
52 .try_into()
53 .expect("Unable to convert u128 into u64");
54 JsonLogEntry {
55 name: name.into(),
56 timestamp,
57 json,
58 }
59 }
60}
61
62pub fn send_json_log(entry: JsonLogEntry) {
69 let mut queue = JSON_LOG_ENTRY_QUEUE.lock();
70 if queue.len() >= MAX_EVENTS_IN_QUEUE {
71 queue.pop_front();
72 }
73 queue.push_back(entry);
74}
75
76pub fn pop_last_entries() -> Vec<JsonLogEntry> {
78 let mut queue = JSON_LOG_ENTRY_QUEUE.lock();
79 queue.drain(..).collect()
80}