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