Skip to main content

browser_protocol/tracing/
mod.rs

1use serde::{Serialize, Deserialize};
2use serde_json::Value as JsonValue;
3use std::borrow::Cow;
4
5/// Configuration for memory dump. Used only when "memory-infra" category is enabled.
6
7pub type MemoryDumpConfig = serde_json::Map<String, JsonValue>;
8
9
10#[derive(Debug, Clone, Serialize, Deserialize, Default)]
11#[serde(rename_all = "camelCase")]
12pub struct TraceConfig<'a> {
13    /// Controls how the trace buffer stores data. The default is 'recordUntilFull'.
14    #[serde(skip_serializing_if = "Option::is_none")]
15    recordMode: Option<Cow<'a, str>>,
16    /// Size of the trace buffer in kilobytes. If not specified or zero is passed, a default value
17    /// of 200 MB would be used.
18    #[serde(skip_serializing_if = "Option::is_none")]
19    traceBufferSizeInKb: Option<f64>,
20    /// Turns on JavaScript stack sampling.
21    #[serde(skip_serializing_if = "Option::is_none")]
22    enableSampling: Option<bool>,
23    /// Turns on system tracing.
24    #[serde(skip_serializing_if = "Option::is_none")]
25    enableSystrace: Option<bool>,
26    /// Turns on argument filter.
27    #[serde(skip_serializing_if = "Option::is_none")]
28    enableArgumentFilter: Option<bool>,
29    /// Included category filters.
30    #[serde(skip_serializing_if = "Option::is_none")]
31    includedCategories: Option<Vec<Cow<'a, str>>>,
32    /// Excluded category filters.
33    #[serde(skip_serializing_if = "Option::is_none")]
34    excludedCategories: Option<Vec<Cow<'a, str>>>,
35    /// Configuration to synthesize the delays in tracing.
36    #[serde(skip_serializing_if = "Option::is_none")]
37    syntheticDelays: Option<Vec<Cow<'a, str>>>,
38    /// Configuration for memory dump triggers. Used only when "memory-infra" category is enabled.
39    #[serde(skip_serializing_if = "Option::is_none")]
40    memoryDumpConfig: Option<MemoryDumpConfig>,
41}
42
43impl<'a> TraceConfig<'a> {
44    pub fn builder() -> TraceConfigBuilder<'a> {
45        TraceConfigBuilder {
46            recordMode: None,
47            traceBufferSizeInKb: None,
48            enableSampling: None,
49            enableSystrace: None,
50            enableArgumentFilter: None,
51            includedCategories: None,
52            excludedCategories: None,
53            syntheticDelays: None,
54            memoryDumpConfig: None,
55        }
56    }
57    pub fn recordMode(&self) -> Option<&str> { self.recordMode.as_deref() }
58    pub fn traceBufferSizeInKb(&self) -> Option<f64> { self.traceBufferSizeInKb }
59    pub fn enableSampling(&self) -> Option<bool> { self.enableSampling }
60    pub fn enableSystrace(&self) -> Option<bool> { self.enableSystrace }
61    pub fn enableArgumentFilter(&self) -> Option<bool> { self.enableArgumentFilter }
62    pub fn includedCategories(&self) -> Option<&[Cow<'a, str>]> { self.includedCategories.as_deref() }
63    pub fn excludedCategories(&self) -> Option<&[Cow<'a, str>]> { self.excludedCategories.as_deref() }
64    pub fn syntheticDelays(&self) -> Option<&[Cow<'a, str>]> { self.syntheticDelays.as_deref() }
65    pub fn memoryDumpConfig(&self) -> Option<&MemoryDumpConfig> { self.memoryDumpConfig.as_ref() }
66}
67
68#[derive(Default)]
69pub struct TraceConfigBuilder<'a> {
70    recordMode: Option<Cow<'a, str>>,
71    traceBufferSizeInKb: Option<f64>,
72    enableSampling: Option<bool>,
73    enableSystrace: Option<bool>,
74    enableArgumentFilter: Option<bool>,
75    includedCategories: Option<Vec<Cow<'a, str>>>,
76    excludedCategories: Option<Vec<Cow<'a, str>>>,
77    syntheticDelays: Option<Vec<Cow<'a, str>>>,
78    memoryDumpConfig: Option<MemoryDumpConfig>,
79}
80
81impl<'a> TraceConfigBuilder<'a> {
82    /// Controls how the trace buffer stores data. The default is 'recordUntilFull'.
83    pub fn recordMode(mut self, recordMode: impl Into<Cow<'a, str>>) -> Self { self.recordMode = Some(recordMode.into()); self }
84    /// Size of the trace buffer in kilobytes. If not specified or zero is passed, a default value
85    /// of 200 MB would be used.
86    pub fn traceBufferSizeInKb(mut self, traceBufferSizeInKb: f64) -> Self { self.traceBufferSizeInKb = Some(traceBufferSizeInKb); self }
87    /// Turns on JavaScript stack sampling.
88    pub fn enableSampling(mut self, enableSampling: bool) -> Self { self.enableSampling = Some(enableSampling); self }
89    /// Turns on system tracing.
90    pub fn enableSystrace(mut self, enableSystrace: bool) -> Self { self.enableSystrace = Some(enableSystrace); self }
91    /// Turns on argument filter.
92    pub fn enableArgumentFilter(mut self, enableArgumentFilter: bool) -> Self { self.enableArgumentFilter = Some(enableArgumentFilter); self }
93    /// Included category filters.
94    pub fn includedCategories(mut self, includedCategories: Vec<Cow<'a, str>>) -> Self { self.includedCategories = Some(includedCategories); self }
95    /// Excluded category filters.
96    pub fn excludedCategories(mut self, excludedCategories: Vec<Cow<'a, str>>) -> Self { self.excludedCategories = Some(excludedCategories); self }
97    /// Configuration to synthesize the delays in tracing.
98    pub fn syntheticDelays(mut self, syntheticDelays: Vec<Cow<'a, str>>) -> Self { self.syntheticDelays = Some(syntheticDelays); self }
99    /// Configuration for memory dump triggers. Used only when "memory-infra" category is enabled.
100    pub fn memoryDumpConfig(mut self, memoryDumpConfig: MemoryDumpConfig) -> Self { self.memoryDumpConfig = Some(memoryDumpConfig); self }
101    pub fn build(self) -> TraceConfig<'a> {
102        TraceConfig {
103            recordMode: self.recordMode,
104            traceBufferSizeInKb: self.traceBufferSizeInKb,
105            enableSampling: self.enableSampling,
106            enableSystrace: self.enableSystrace,
107            enableArgumentFilter: self.enableArgumentFilter,
108            includedCategories: self.includedCategories,
109            excludedCategories: self.excludedCategories,
110            syntheticDelays: self.syntheticDelays,
111            memoryDumpConfig: self.memoryDumpConfig,
112        }
113    }
114}
115
116/// Data format of a trace. Can be either the legacy JSON format or the
117/// protocol buffer format. Note that the JSON format will be deprecated soon.
118
119#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
120pub enum StreamFormat {
121    #[default]
122    #[serde(rename = "json")]
123    Json,
124    #[serde(rename = "proto")]
125    Proto,
126}
127
128/// Compression type to use for traces returned via streams.
129
130#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
131pub enum StreamCompression {
132    #[default]
133    #[serde(rename = "none")]
134    None,
135    #[serde(rename = "gzip")]
136    Gzip,
137}
138
139/// Details exposed when memory request explicitly declared.
140/// Keep consistent with memory_dump_request_args.h and
141/// memory_instrumentation.mojom
142
143#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
144pub enum MemoryDumpLevelOfDetail {
145    #[default]
146    #[serde(rename = "background")]
147    Background,
148    #[serde(rename = "light")]
149    Light,
150    #[serde(rename = "detailed")]
151    Detailed,
152}
153
154/// Backend type to use for tracing. 'chrome' uses the Chrome-integrated
155/// tracing service and is supported on all platforms. 'system' is only
156/// supported on Chrome OS and uses the Perfetto system tracing service.
157/// 'auto' chooses 'system' when the perfettoConfig provided to Tracing.start
158/// specifies at least one non-Chrome data source; otherwise uses 'chrome'.
159
160#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
161pub enum TracingBackend {
162    #[default]
163    #[serde(rename = "auto")]
164    Auto,
165    #[serde(rename = "chrome")]
166    Chrome,
167    #[serde(rename = "system")]
168    System,
169}
170
171#[derive(Debug, Clone, Serialize, Deserialize, Default)]
172pub struct EndParams {}
173
174impl EndParams { pub const METHOD: &'static str = "Tracing.end"; }
175
176impl<'a> crate::CdpCommand<'a> for EndParams {
177    const METHOD: &'static str = "Tracing.end";
178    type Response = crate::EmptyReturns;
179}
180
181/// Gets supported tracing categories.
182
183#[derive(Debug, Clone, Serialize, Deserialize, Default)]
184#[serde(rename_all = "camelCase")]
185pub struct GetCategoriesReturns<'a> {
186    /// A list of supported tracing categories.
187    categories: Vec<Cow<'a, str>>,
188}
189
190impl<'a> GetCategoriesReturns<'a> {
191    pub fn builder(categories: Vec<Cow<'a, str>>) -> GetCategoriesReturnsBuilder<'a> {
192        GetCategoriesReturnsBuilder {
193            categories: categories,
194        }
195    }
196    pub fn categories(&self) -> &[Cow<'a, str>] { &self.categories }
197}
198
199
200pub struct GetCategoriesReturnsBuilder<'a> {
201    categories: Vec<Cow<'a, str>>,
202}
203
204impl<'a> GetCategoriesReturnsBuilder<'a> {
205    pub fn build(self) -> GetCategoriesReturns<'a> {
206        GetCategoriesReturns {
207            categories: self.categories,
208        }
209    }
210}
211
212#[derive(Debug, Clone, Serialize, Deserialize, Default)]
213pub struct GetCategoriesParams {}
214
215impl GetCategoriesParams { pub const METHOD: &'static str = "Tracing.getCategories"; }
216
217impl<'a> crate::CdpCommand<'a> for GetCategoriesParams {
218    const METHOD: &'static str = "Tracing.getCategories";
219    type Response = GetCategoriesReturns<'a>;
220}
221
222/// Return a descriptor for all available tracing categories.
223
224#[derive(Debug, Clone, Serialize, Deserialize, Default)]
225#[serde(rename_all = "camelCase")]
226pub struct GetTrackEventDescriptorReturns<'a> {
227    /// Base64-encoded serialized perfetto.protos.TrackEventDescriptor protobuf message. (Encoded as a base64 string when passed over JSON)
228    descriptor: Cow<'a, str>,
229}
230
231impl<'a> GetTrackEventDescriptorReturns<'a> {
232    pub fn builder(descriptor: impl Into<Cow<'a, str>>) -> GetTrackEventDescriptorReturnsBuilder<'a> {
233        GetTrackEventDescriptorReturnsBuilder {
234            descriptor: descriptor.into(),
235        }
236    }
237    pub fn descriptor(&self) -> &str { self.descriptor.as_ref() }
238}
239
240
241pub struct GetTrackEventDescriptorReturnsBuilder<'a> {
242    descriptor: Cow<'a, str>,
243}
244
245impl<'a> GetTrackEventDescriptorReturnsBuilder<'a> {
246    pub fn build(self) -> GetTrackEventDescriptorReturns<'a> {
247        GetTrackEventDescriptorReturns {
248            descriptor: self.descriptor,
249        }
250    }
251}
252
253#[derive(Debug, Clone, Serialize, Deserialize, Default)]
254pub struct GetTrackEventDescriptorParams {}
255
256impl GetTrackEventDescriptorParams { pub const METHOD: &'static str = "Tracing.getTrackEventDescriptor"; }
257
258impl<'a> crate::CdpCommand<'a> for GetTrackEventDescriptorParams {
259    const METHOD: &'static str = "Tracing.getTrackEventDescriptor";
260    type Response = GetTrackEventDescriptorReturns<'a>;
261}
262
263/// Record a clock sync marker in the trace.
264
265#[derive(Debug, Clone, Serialize, Deserialize, Default)]
266#[serde(rename_all = "camelCase")]
267pub struct RecordClockSyncMarkerParams<'a> {
268    /// The ID of this clock sync marker
269    syncId: Cow<'a, str>,
270}
271
272impl<'a> RecordClockSyncMarkerParams<'a> {
273    pub fn builder(syncId: impl Into<Cow<'a, str>>) -> RecordClockSyncMarkerParamsBuilder<'a> {
274        RecordClockSyncMarkerParamsBuilder {
275            syncId: syncId.into(),
276        }
277    }
278    pub fn syncId(&self) -> &str { self.syncId.as_ref() }
279}
280
281
282pub struct RecordClockSyncMarkerParamsBuilder<'a> {
283    syncId: Cow<'a, str>,
284}
285
286impl<'a> RecordClockSyncMarkerParamsBuilder<'a> {
287    pub fn build(self) -> RecordClockSyncMarkerParams<'a> {
288        RecordClockSyncMarkerParams {
289            syncId: self.syncId,
290        }
291    }
292}
293
294impl<'a> RecordClockSyncMarkerParams<'a> { pub const METHOD: &'static str = "Tracing.recordClockSyncMarker"; }
295
296impl<'a> crate::CdpCommand<'a> for RecordClockSyncMarkerParams<'a> {
297    const METHOD: &'static str = "Tracing.recordClockSyncMarker";
298    type Response = crate::EmptyReturns;
299}
300
301/// Request a global memory dump.
302
303#[derive(Debug, Clone, Serialize, Deserialize, Default)]
304#[serde(rename_all = "camelCase")]
305pub struct RequestMemoryDumpParams {
306    /// Enables more deterministic results by forcing garbage collection
307    #[serde(skip_serializing_if = "Option::is_none")]
308    deterministic: Option<bool>,
309    /// Specifies level of details in memory dump. Defaults to "detailed".
310    #[serde(skip_serializing_if = "Option::is_none")]
311    levelOfDetail: Option<MemoryDumpLevelOfDetail>,
312}
313
314impl RequestMemoryDumpParams {
315    pub fn builder() -> RequestMemoryDumpParamsBuilder {
316        RequestMemoryDumpParamsBuilder {
317            deterministic: None,
318            levelOfDetail: None,
319        }
320    }
321    pub fn deterministic(&self) -> Option<bool> { self.deterministic }
322    pub fn levelOfDetail(&self) -> Option<&MemoryDumpLevelOfDetail> { self.levelOfDetail.as_ref() }
323}
324
325#[derive(Default)]
326pub struct RequestMemoryDumpParamsBuilder {
327    deterministic: Option<bool>,
328    levelOfDetail: Option<MemoryDumpLevelOfDetail>,
329}
330
331impl RequestMemoryDumpParamsBuilder {
332    /// Enables more deterministic results by forcing garbage collection
333    pub fn deterministic(mut self, deterministic: bool) -> Self { self.deterministic = Some(deterministic); self }
334    /// Specifies level of details in memory dump. Defaults to "detailed".
335    pub fn levelOfDetail(mut self, levelOfDetail: MemoryDumpLevelOfDetail) -> Self { self.levelOfDetail = Some(levelOfDetail); self }
336    pub fn build(self) -> RequestMemoryDumpParams {
337        RequestMemoryDumpParams {
338            deterministic: self.deterministic,
339            levelOfDetail: self.levelOfDetail,
340        }
341    }
342}
343
344/// Request a global memory dump.
345
346#[derive(Debug, Clone, Serialize, Deserialize, Default)]
347#[serde(rename_all = "camelCase")]
348pub struct RequestMemoryDumpReturns<'a> {
349    /// GUID of the resulting global memory dump.
350    dumpGuid: Cow<'a, str>,
351    /// True iff the global memory dump succeeded.
352    success: bool,
353}
354
355impl<'a> RequestMemoryDumpReturns<'a> {
356    pub fn builder(dumpGuid: impl Into<Cow<'a, str>>, success: bool) -> RequestMemoryDumpReturnsBuilder<'a> {
357        RequestMemoryDumpReturnsBuilder {
358            dumpGuid: dumpGuid.into(),
359            success: success,
360        }
361    }
362    pub fn dumpGuid(&self) -> &str { self.dumpGuid.as_ref() }
363    pub fn success(&self) -> bool { self.success }
364}
365
366
367pub struct RequestMemoryDumpReturnsBuilder<'a> {
368    dumpGuid: Cow<'a, str>,
369    success: bool,
370}
371
372impl<'a> RequestMemoryDumpReturnsBuilder<'a> {
373    pub fn build(self) -> RequestMemoryDumpReturns<'a> {
374        RequestMemoryDumpReturns {
375            dumpGuid: self.dumpGuid,
376            success: self.success,
377        }
378    }
379}
380
381impl RequestMemoryDumpParams { pub const METHOD: &'static str = "Tracing.requestMemoryDump"; }
382
383impl<'a> crate::CdpCommand<'a> for RequestMemoryDumpParams {
384    const METHOD: &'static str = "Tracing.requestMemoryDump";
385    type Response = RequestMemoryDumpReturns<'a>;
386}
387
388/// Start trace events collection.
389
390#[derive(Debug, Clone, Serialize, Deserialize, Default)]
391#[serde(rename_all = "camelCase")]
392pub struct StartParams<'a> {
393    /// Category/tag filter
394    #[serde(skip_serializing_if = "Option::is_none")]
395    categories: Option<Cow<'a, str>>,
396    /// Tracing options
397    #[serde(skip_serializing_if = "Option::is_none")]
398    options: Option<Cow<'a, str>>,
399    /// If set, the agent will issue bufferUsage events at this interval, specified in milliseconds
400    #[serde(skip_serializing_if = "Option::is_none")]
401    bufferUsageReportingInterval: Option<f64>,
402    /// Whether to report trace events as series of dataCollected events or to save trace to a
403    /// stream (defaults to 'ReportEvents').
404    #[serde(skip_serializing_if = "Option::is_none")]
405    transferMode: Option<Cow<'a, str>>,
406    /// Trace data format to use. This only applies when using 'ReturnAsStream'
407    /// transfer mode (defaults to 'json').
408    #[serde(skip_serializing_if = "Option::is_none")]
409    streamFormat: Option<StreamFormat>,
410    /// Compression format to use. This only applies when using 'ReturnAsStream'
411    /// transfer mode (defaults to 'none')
412    #[serde(skip_serializing_if = "Option::is_none")]
413    streamCompression: Option<StreamCompression>,
414    #[serde(skip_serializing_if = "Option::is_none")]
415    traceConfig: Option<TraceConfig<'a>>,
416    /// Base64-encoded serialized perfetto.protos.TraceConfig protobuf message
417    /// When specified, the parameters 'categories', 'options', 'traceConfig'
418    /// are ignored. (Encoded as a base64 string when passed over JSON)
419    #[serde(skip_serializing_if = "Option::is_none")]
420    perfettoConfig: Option<Cow<'a, str>>,
421    /// Backend type (defaults to 'auto')
422    #[serde(skip_serializing_if = "Option::is_none")]
423    tracingBackend: Option<TracingBackend>,
424}
425
426impl<'a> StartParams<'a> {
427    pub fn builder() -> StartParamsBuilder<'a> {
428        StartParamsBuilder {
429            categories: None,
430            options: None,
431            bufferUsageReportingInterval: None,
432            transferMode: None,
433            streamFormat: None,
434            streamCompression: None,
435            traceConfig: None,
436            perfettoConfig: None,
437            tracingBackend: None,
438        }
439    }
440    pub fn categories(&self) -> Option<&str> { self.categories.as_deref() }
441    pub fn options(&self) -> Option<&str> { self.options.as_deref() }
442    pub fn bufferUsageReportingInterval(&self) -> Option<f64> { self.bufferUsageReportingInterval }
443    pub fn transferMode(&self) -> Option<&str> { self.transferMode.as_deref() }
444    pub fn streamFormat(&self) -> Option<&StreamFormat> { self.streamFormat.as_ref() }
445    pub fn streamCompression(&self) -> Option<&StreamCompression> { self.streamCompression.as_ref() }
446    pub fn traceConfig(&self) -> Option<&TraceConfig<'a>> { self.traceConfig.as_ref() }
447    pub fn perfettoConfig(&self) -> Option<&str> { self.perfettoConfig.as_deref() }
448    pub fn tracingBackend(&self) -> Option<&TracingBackend> { self.tracingBackend.as_ref() }
449}
450
451#[derive(Default)]
452pub struct StartParamsBuilder<'a> {
453    categories: Option<Cow<'a, str>>,
454    options: Option<Cow<'a, str>>,
455    bufferUsageReportingInterval: Option<f64>,
456    transferMode: Option<Cow<'a, str>>,
457    streamFormat: Option<StreamFormat>,
458    streamCompression: Option<StreamCompression>,
459    traceConfig: Option<TraceConfig<'a>>,
460    perfettoConfig: Option<Cow<'a, str>>,
461    tracingBackend: Option<TracingBackend>,
462}
463
464impl<'a> StartParamsBuilder<'a> {
465    /// Category/tag filter
466    pub fn categories(mut self, categories: impl Into<Cow<'a, str>>) -> Self { self.categories = Some(categories.into()); self }
467    /// Tracing options
468    pub fn options(mut self, options: impl Into<Cow<'a, str>>) -> Self { self.options = Some(options.into()); self }
469    /// If set, the agent will issue bufferUsage events at this interval, specified in milliseconds
470    pub fn bufferUsageReportingInterval(mut self, bufferUsageReportingInterval: f64) -> Self { self.bufferUsageReportingInterval = Some(bufferUsageReportingInterval); self }
471    /// Whether to report trace events as series of dataCollected events or to save trace to a
472    /// stream (defaults to 'ReportEvents').
473    pub fn transferMode(mut self, transferMode: impl Into<Cow<'a, str>>) -> Self { self.transferMode = Some(transferMode.into()); self }
474    /// Trace data format to use. This only applies when using 'ReturnAsStream'
475    /// transfer mode (defaults to 'json').
476    pub fn streamFormat(mut self, streamFormat: StreamFormat) -> Self { self.streamFormat = Some(streamFormat); self }
477    /// Compression format to use. This only applies when using 'ReturnAsStream'
478    /// transfer mode (defaults to 'none')
479    pub fn streamCompression(mut self, streamCompression: StreamCompression) -> Self { self.streamCompression = Some(streamCompression); self }
480    pub fn traceConfig(mut self, traceConfig: TraceConfig<'a>) -> Self { self.traceConfig = Some(traceConfig); self }
481    /// Base64-encoded serialized perfetto.protos.TraceConfig protobuf message
482    /// When specified, the parameters 'categories', 'options', 'traceConfig'
483    /// are ignored. (Encoded as a base64 string when passed over JSON)
484    pub fn perfettoConfig(mut self, perfettoConfig: impl Into<Cow<'a, str>>) -> Self { self.perfettoConfig = Some(perfettoConfig.into()); self }
485    /// Backend type (defaults to 'auto')
486    pub fn tracingBackend(mut self, tracingBackend: TracingBackend) -> Self { self.tracingBackend = Some(tracingBackend); self }
487    pub fn build(self) -> StartParams<'a> {
488        StartParams {
489            categories: self.categories,
490            options: self.options,
491            bufferUsageReportingInterval: self.bufferUsageReportingInterval,
492            transferMode: self.transferMode,
493            streamFormat: self.streamFormat,
494            streamCompression: self.streamCompression,
495            traceConfig: self.traceConfig,
496            perfettoConfig: self.perfettoConfig,
497            tracingBackend: self.tracingBackend,
498        }
499    }
500}
501
502impl<'a> StartParams<'a> { pub const METHOD: &'static str = "Tracing.start"; }
503
504impl<'a> crate::CdpCommand<'a> for StartParams<'a> {
505    const METHOD: &'static str = "Tracing.start";
506    type Response = crate::EmptyReturns;
507}