@@ -6,7 +6,12 @@ use pyroscope::{
66 } ,
77 error:: { PyroscopeError , Result } ,
88} ;
9- use std:: { collections:: HashMap , ffi:: OsStr } ;
9+ use std:: {
10+ collections:: HashMap ,
11+ ffi:: OsStr ,
12+ ops:: Deref ,
13+ sync:: { Arc , Mutex } ,
14+ } ;
1015
1116pub fn pprof_backend ( config : PprofConfig ) -> BackendImpl < BackendUninitialized > {
1217 BackendImpl :: new ( Box :: new ( Pprof :: new ( config) ) )
@@ -37,9 +42,15 @@ impl PprofConfig {
3742/// Pprof Backend
3843#[ derive( Default ) ]
3944pub struct Pprof < ' a > {
45+ /// Profling buffer
46+ buffer : Arc < Mutex < StackBuffer > > ,
47+ /// pprof-rs Configuration
4048 config : PprofConfig ,
41- inner_builder : Option < ProfilerGuardBuilder > ,
42- guard : Option < ProfilerGuard < ' a > > ,
49+ /// pprof-rs profiler Guard Builder
50+ inner_builder : Arc < Mutex < Option < ProfilerGuardBuilder > > > ,
51+ /// pprof-rs profiler Guard
52+ guard : Arc < Mutex < Option < ProfilerGuard < ' a > > > > ,
53+ /// Ruleset
4354 ruleset : Ruleset ,
4455}
4556
@@ -52,9 +63,10 @@ impl std::fmt::Debug for Pprof<'_> {
5263impl < ' a > Pprof < ' a > {
5364 pub fn new ( config : PprofConfig ) -> Self {
5465 Pprof {
66+ buffer : Arc :: new ( Mutex :: new ( StackBuffer :: default ( ) ) ) ,
5567 config,
56- inner_builder : None ,
57- guard : None ,
68+ inner_builder : Arc :: new ( Mutex :: new ( None ) ) ,
69+ guard : Arc :: new ( Mutex :: new ( None ) ) ,
5870 ruleset : Ruleset :: default ( ) ,
5971 }
6072 }
@@ -78,11 +90,13 @@ impl Backend for Pprof<'_> {
7890 fn initialize ( & mut self ) -> Result < ( ) > {
7991 // Construct a ProfilerGuardBuilder
8092 let profiler = ProfilerGuardBuilder :: default ( ) . frequency ( self . config . sample_rate as i32 ) ;
93+
8194 // Set inner_builder field
82- self . inner_builder = Some ( profiler) ;
95+ * self . inner_builder . lock ( ) ? = Some ( profiler) ;
8396
84- self . guard = Some (
97+ * self . guard . lock ( ) ? = Some (
8598 self . inner_builder
99+ . lock ( ) ?
86100 . as_ref ( )
87101 . ok_or_else ( || PyroscopeError :: new ( "pprof-rs: ProfilerGuardBuilder error" ) ) ?
88102 . clone ( )
@@ -94,8 +108,44 @@ impl Backend for Pprof<'_> {
94108 }
95109
96110 fn report ( & mut self ) -> Result < Vec < Report > > {
111+ self . dump_report ( ) ?;
112+
113+ let buffer = self . buffer . clone ( ) ;
114+
115+ let report: StackBuffer = buffer. lock ( ) ?. deref ( ) . to_owned ( ) ;
116+
117+ let reports: Vec < Report > = report. into ( ) ;
118+
119+ buffer. lock ( ) ?. clear ( ) ;
120+
121+ Ok ( reports)
122+ }
123+
124+ fn add_rule ( & self , rule : Rule ) -> Result < ( ) > {
125+ if self . guard . lock ( ) ?. as_ref ( ) . is_some ( ) {
126+ self . dump_report ( ) ?;
127+ }
128+
129+ self . ruleset . add_rule ( rule) ?;
130+
131+ Ok ( ( ) )
132+ }
133+ fn remove_rule ( & self , rule : Rule ) -> Result < ( ) > {
134+ if self . guard . lock ( ) ?. as_ref ( ) . is_some ( ) {
135+ self . dump_report ( ) ?;
136+ }
137+
138+ self . ruleset . remove_rule ( rule) ?;
139+
140+ Ok ( ( ) )
141+ }
142+ }
143+
144+ impl Pprof < ' _ > {
145+ pub fn dump_report ( & self ) -> Result < ( ) > {
97146 let report = self
98147 . guard
148+ . lock ( ) ?
99149 . as_ref ( )
100150 . ok_or_else ( || PyroscopeError :: new ( "pprof-rs: ProfilerGuard report error" ) ) ?
101151 . report ( )
@@ -105,43 +155,32 @@ impl Backend for Pprof<'_> {
105155 let stack_buffer = Into :: < StackBuffer > :: into ( Into :: < StackBufferWrapper > :: into ( report) ) ;
106156
107157 // apply ruleset to stack_buffer
108- let data = stack_buffer
158+ let data: HashMap < StackTrace , usize > = stack_buffer
109159 . data
110160 . iter ( )
111161 . map ( |( stacktrace, ss) | {
112162 let stacktrace = stacktrace. to_owned ( ) + & self . ruleset ;
113163 ( stacktrace, ss. to_owned ( ) )
114164 } )
115165 . collect ( ) ;
116- let stack_buffer = StackBuffer :: new ( data) ;
117166
118- let reports = stack_buffer. into ( ) ;
119- //let new_report = Into::<Report>::into(Into::<ReportWrapper>::into(report));
120- //let reports = vec![new_report];
121-
122- self . reset ( ) ?;
123-
124- Ok ( reports)
125- }
167+ let buffer = self . buffer . clone ( ) ;
126168
127- fn add_rule ( & self , rule : Rule ) -> Result < ( ) > {
128- self . ruleset . add_rule ( rule) ?;
169+ for ( stacktrace, count) in data {
170+ buffer. lock ( ) ?. record_with_count ( stacktrace, count) ?;
171+ }
129172
130- Ok ( ( ) )
131- }
132- fn remove_rule ( & self , rule : Rule ) -> Result < ( ) > {
133- self . ruleset . remove_rule ( rule) ?;
173+ self . reset ( ) ?;
134174
135175 Ok ( ( ) )
136176 }
137- }
138177
139- impl Pprof < ' _ > {
140- pub fn reset ( & mut self ) -> Result < ( ) > {
141- drop ( self . guard . take ( ) ) ;
178+ pub fn reset ( & self ) -> Result < ( ) > {
179+ drop ( self . guard . lock ( ) ?. take ( ) ) ;
142180
143- self . guard = Some (
181+ * self . guard . lock ( ) ? = Some (
144182 self . inner_builder
183+ . lock ( ) ?
145184 . as_ref ( )
146185 . ok_or_else ( || PyroscopeError :: new ( "pprof-rs: ProfilerGuardBuilder error" ) ) ?
147186 . clone ( )
0 commit comments