async_profiler_agent/reporter/
local.rs1use async_trait::async_trait;
7use chrono::SecondsFormat;
8use std::path::PathBuf;
9use std::time::SystemTime;
10use thiserror::Error;
11
12use crate::metadata::ReportMetadata;
13
14use super::Reporter;
15
16#[derive(Error, Debug)]
17enum LocalReporterError {
18 #[error("{0}")]
19 IoError(#[from] std::io::Error),
20}
21
22#[derive(Debug)]
50pub struct LocalReporter {
51 directory: PathBuf,
52}
53
54impl LocalReporter {
55 pub fn new(directory: impl Into<PathBuf>) -> Self {
57 LocalReporter {
58 directory: directory.into(),
59 }
60 }
61
62 async fn report_profiling_data(
64 &self,
65 jfr: Vec<u8>,
66 _metadata_obj: &ReportMetadata<'_>,
67 ) -> Result<(), std::io::Error> {
68 let time: chrono::DateTime<chrono::Utc> = SystemTime::now().into();
69 let time = time
70 .to_rfc3339_opts(SecondsFormat::Secs, true)
71 .replace(":", "-");
72 tracing::debug!("reporting {time}.jfr");
73 let file_name = format!("{time}.jfr");
74 tokio::fs::write(self.directory.join(file_name), jfr).await?;
75 Ok(())
76 }
77}
78
79#[async_trait]
80impl Reporter for LocalReporter {
81 async fn report(
82 &self,
83 jfr: Vec<u8>,
84 metadata: &ReportMetadata,
85 ) -> Result<(), Box<dyn std::error::Error + Send>> {
86 self.report_profiling_data(jfr, metadata)
87 .await
88 .map_err(|e| Box::new(LocalReporterError::IoError(e)) as _)
89 }
90}
91
92#[cfg(test)]
93mod test {
94 use std::path::Path;
95
96 use crate::{
97 metadata::DUMMY_METADATA,
98 reporter::{Reporter, local::LocalReporter},
99 };
100
101 #[tokio::test]
102 async fn test_local_reporter() {
103 let dir = tempfile::tempdir().unwrap();
104 let reporter = LocalReporter::new(dir.path());
105 reporter
106 .report(b"JFR".into(), &DUMMY_METADATA)
107 .await
108 .unwrap();
109 let jfr_file = std::fs::read_dir(dir.path())
110 .unwrap()
111 .flat_map(|f| f.ok())
112 .filter(|f| {
113 Path::new(&f.file_name())
114 .extension()
115 .is_some_and(|e| e == "jfr")
116 })
117 .next()
118 .unwrap();
119 assert_eq!(tokio::fs::read(jfr_file.path()).await.unwrap(), b"JFR");
120 }
121}