@@ -6,7 +6,9 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH};
6
6
7
7
use analyzeme:: { ProfilingData , Timestamp } ;
8
8
9
+ use serde:: ser:: SerializeSeq ;
9
10
use serde:: { Serialize , Serializer } ;
11
+ use serde_json:: json;
10
12
use std:: cmp;
11
13
use structopt:: StructOpt ;
12
14
@@ -42,7 +44,7 @@ struct Event {
42
44
43
45
#[ derive( StructOpt , Debug ) ]
44
46
struct Opt {
45
- file_prefix : PathBuf ,
47
+ file_prefix : Vec < PathBuf > ,
46
48
/// collapse threads without overlapping events
47
49
#[ structopt( long = "collapse-threads" ) ]
48
50
collapse_threads : bool ,
@@ -113,45 +115,78 @@ fn generate_thread_to_collapsed_thread_mapping(
113
115
fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
114
116
let opt = Opt :: from_args ( ) ;
115
117
116
- let data = ProfilingData :: new ( & opt. file_prefix ) ?;
117
-
118
118
let chrome_file = BufWriter :: new ( fs:: File :: create ( "chrome_profiler.json" ) ?) ;
119
-
120
119
let mut serializer = serde_json:: Serializer :: new ( chrome_file) ;
121
- let thread_to_collapsed_thread = generate_thread_to_collapsed_thread_mapping ( & opt, & data) ;
122
- let mut event_iterator = data. iter ( ) ;
123
-
124
- //create an iterator so we can avoid allocating a Vec with every Event for serialization
125
- let json_event_iterator = std:: iter:: from_fn ( || {
126
- while let Some ( event) = event_iterator. next ( ) {
127
- // Chrome does not seem to like how many QueryCacheHit events we generate
128
- // only handle startStop events for now
129
- if let Timestamp :: Interval { start, end } = event. timestamp {
130
- let duration = end. duration_since ( start) . unwrap ( ) ;
131
- if let Some ( minimum_duration) = opt. minimum_duration {
132
- if duration. as_micros ( ) < minimum_duration {
133
- continue ;
134
- }
120
+
121
+ let mut seq = serializer. serialize_seq ( None ) ?;
122
+
123
+ for file_prefix in opt. file_prefix . iter ( ) {
124
+ let data = ProfilingData :: new ( & file_prefix) ?;
125
+
126
+ let thread_to_collapsed_thread = generate_thread_to_collapsed_thread_mapping ( & opt, & data) ;
127
+
128
+ // Chrome does not seem to like how many QueryCacheHit events we generate
129
+ // only handle Interval events for now
130
+ for event in data. iter ( ) . filter ( |e| !e. timestamp . is_instant ( ) ) {
131
+ let duration = event. duration ( ) . unwrap ( ) ;
132
+ if let Some ( minimum_duration) = opt. minimum_duration {
133
+ if duration. as_micros ( ) < minimum_duration {
134
+ continue ;
135
135
}
136
- return Some ( Event {
137
- name : event. label . clone ( ) . into_owned ( ) ,
138
- category : event. event_kind . clone ( ) . into_owned ( ) ,
139
- event_type : EventType :: Complete ,
140
- timestamp : start. duration_since ( UNIX_EPOCH ) . unwrap ( ) ,
141
- duration,
142
- process_id : data. meta_data . process_id ,
143
- thread_id : * thread_to_collapsed_thread
144
- . get ( & event. thread_id )
145
- . unwrap_or ( & event. thread_id ) ,
146
- args : None ,
147
- } ) ;
148
136
}
137
+ let crox_event = Event {
138
+ name : event. label . clone ( ) . into_owned ( ) ,
139
+ category : event. event_kind . clone ( ) . into_owned ( ) ,
140
+ event_type : EventType :: Complete ,
141
+ timestamp : event. timestamp . start ( ) . duration_since ( UNIX_EPOCH ) . unwrap ( ) ,
142
+ duration,
143
+ process_id : data. meta_data . process_id ,
144
+ thread_id : * thread_to_collapsed_thread
145
+ . get ( & event. thread_id )
146
+ . unwrap_or ( & event. thread_id ) ,
147
+ args : None ,
148
+ } ;
149
+ seq. serialize_element ( & crox_event) ?;
149
150
}
151
+ // add crate name for the process_id
152
+ let index_of_crate_name = data
153
+ . meta_data
154
+ . cmd
155
+ . find ( " --crate-name " )
156
+ . map ( |index| index + 14 ) ;
157
+ if let Some ( index) = index_of_crate_name {
158
+ let ( _, last) = data. meta_data . cmd . split_at ( index) ;
159
+ let ( crate_name, _) = last. split_at ( last. find ( " " ) . unwrap_or ( last. len ( ) ) ) ;
160
+
161
+ let process_name = json ! ( {
162
+ "name" : "process_name" ,
163
+ "ph" : "M" ,
164
+ "ts" : 0 ,
165
+ "tid" : 0 ,
166
+ "cat" : "" ,
167
+ "pid" : data. meta_data. process_id,
168
+ "args" : {
169
+ "name" : crate_name
170
+ }
171
+ } ) ;
172
+ seq. serialize_element ( & process_name) ?;
173
+ }
174
+ // sort the processes after start time
175
+ let process_name = json ! ( {
176
+ "name" : "process_sort_index" ,
177
+ "ph" : "M" ,
178
+ "ts" : 0 ,
179
+ "tid" : 0 ,
180
+ "cat" : "" ,
181
+ "pid" : data. meta_data. process_id,
182
+ "args" : {
183
+ "sort_index" : data. meta_data. start_time. duration_since( UNIX_EPOCH ) . unwrap( ) . as_micros( ) as u64
184
+ }
185
+ } ) ;
186
+ seq. serialize_element ( & process_name) ?;
187
+ }
150
188
151
- None
152
- } ) ;
153
-
154
- serializer. collect_seq ( json_event_iterator) ?;
189
+ seq. end ( ) ?;
155
190
156
191
Ok ( ( ) )
157
192
}
0 commit comments