blob: 3c9090e6a5c9e3b429ef67747820eee1499ba118 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use {argh::FromArgs, ffx_core::ffx_command};
#[derive(FromArgs, Debug, PartialEq)]
/// Interact with the tracing subsystem
#[argh(subcommand, name = "trace")]
pub struct TraceCommand {
pub sub_cmd: TraceSubCommand,
#[derive(FromArgs, PartialEq, Debug)]
pub enum TraceSubCommand {
// More commands including `record` and `convert` to follow.
#[derive(FromArgs, PartialEq, Debug)]
/// List the target's trace providers
#[argh(subcommand, name = "list-providers")]
pub struct ListProviders {}
// Work around argh's handling of Vec. Listing categories as a comma
// separated list of values rather than a repeated keyed option
// is much more concise when dealing with a large set of categories.
pub type TraceCategories = Vec<String>;
// This list should be kept in sync with DEFAULT_CATEGORIES in
// //src/testing/sl4f/src/tracing/ as well as the help text below
static DEFAULT_CATEGORIES: &str = "app,audio,benchmark,blobfs,gfx,input,kernel:meta,kernel:sched,ledger,magma,minfs,modular,view,flutter,dart,dart:compiler,dart:dart,dart:debugger,dart:embedder,dart:gc,dart:isolate,dart:profiler,dart:vm";
#[derive(FromArgs, PartialEq, Debug)]
/// Record a trace
#[argh(subcommand, name = "record")]
pub struct Record {
/// size of per-provider trace buffer in MB. Defaults to 4.
#[argh(option, default = "4")]
pub buffer_size: u32,
/// comma-separated list of categories to enable. Defaults
/// to "app,audio,benchmark,blobfs,gfx,input,kernel:meta,
/// kernel:sched,ledger,magma,minfs,modular,view,flutter,
/// dart,dart:compiler,dart:dart,dart:debugger,dart:embedder,
/// dart:gc,dart:isolate,dart:profiler,dart:vm"
default = "parse_categories(DEFAULT_CATEGORIES).unwrap()",
pub categories: TraceCategories,
/// duration of trace capture in seconds. Defaults to 10 seconds.
#[argh(option, default = "10.0")]
pub duration: f64,
/// name of output trace file. Defaults to trace.fxt.
#[argh(option, default = "String::from(\"trace.fxt\")")]
pub output: String,
fn parse_categories(value: &str) -> Result<TraceCategories, String> {
let mut cats = Vec::new();
if value.is_empty() {
return Err("no categories specified".to_string());
for cat in value.split(",") {
if cat.is_empty() {
return Err("empty category specified".to_string());
mod tests {
use super::*;
fn test_parse_categories() {
assert_eq!(parse_categories(&"a"), Ok(vec!["a".to_string()]));
Ok(vec!["a".to_string(), "b".to_string(), "c:d".to_string()])
assert_eq!(parse_categories(&""), Err("no categories specified".to_string()));
assert_eq!(parse_categories(&"a,,b"), Err("empty category specified".to_string()));