1 // Copyright © 2021 Intel Corporation 2 // 3 // SPDX-License-Identifier: Apache-2.0 4 // 5 6 use serde::Serialize; 7 use std::borrow::Cow; 8 use std::collections::HashMap; 9 use std::fs::File; 10 use std::io::Write; 11 use std::os::unix::io::AsRawFd; 12 use std::time::{Duration, Instant}; 13 14 static mut MONITOR: Option<(File, Instant)> = None; 15 16 /// This function must only be called once from the main process before any threads 17 /// are created to avoid race conditions 18 pub fn set_monitor(file: File) -> Result<(), std::io::Error> { 19 assert!(unsafe { MONITOR.is_none() }); 20 let fd = file.as_raw_fd(); 21 let ret = unsafe { 22 let mut flags = libc::fcntl(fd, libc::F_GETFL); 23 flags |= libc::O_NONBLOCK; 24 libc::fcntl(fd, libc::F_SETFL, flags) 25 }; 26 if ret < 0 { 27 return Err(std::io::Error::last_os_error()); 28 } 29 unsafe { 30 MONITOR = Some((file, Instant::now())); 31 }; 32 Ok(()) 33 } 34 35 #[derive(Serialize)] 36 struct Event<'a> { 37 timestamp: Duration, 38 source: &'a str, 39 event: &'a str, 40 properties: Option<&'a HashMap<Cow<'a, str>, Cow<'a, str>>>, 41 } 42 43 pub fn event_log(source: &str, event: &str, properties: Option<&HashMap<Cow<str>, Cow<str>>>) { 44 if let Some((file, start)) = unsafe { MONITOR.as_ref() } { 45 let e = Event { 46 timestamp: start.elapsed(), 47 source, 48 event, 49 properties, 50 }; 51 serde_json::to_writer_pretty(file, &e).ok(); 52 53 let mut file = file; 54 file.write_all(b"\n\n").ok(); 55 } 56 } 57 58 /* 59 Through the use of Cow<'a, str> it is possible to use String as well as 60 &str as the parameters: 61 e.g. 62 event!("cpu_manager", "create_vcpu", "id", cpu_id.to_string()); 63 */ 64 #[macro_export] 65 macro_rules! event { 66 ($source:expr, $event:expr) => { 67 $crate::event_log($source, $event, None) 68 }; 69 ($source:expr, $event:expr, $($key:expr, $value:expr),*) => { 70 { 71 let mut properties = ::std::collections::HashMap::new(); 72 $( 73 properties.insert($key.into(), $value.into()); 74 )+ 75 $crate::event_log($source, $event, Some(&properties)) 76 } 77 }; 78 79 } 80