linux-perf-users.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: David Ahern <daahern@cisco.com>
To: linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: acme@ghostprotocols.net, mingo@elte.hu, peterz@infradead.org,
	fweisbec@gmail.com, paulus@samba.org, tglx@linutronix.de,
	David Ahern <daahern@cisco.com>
Subject: [PATCH 4/6] perf script: support custom field selection for output
Date: Wed,  9 Mar 2011 22:23:26 -0700	[thread overview]
Message-ID: <1299734608-5223-5-git-send-email-daahern@cisco.com> (raw)
In-Reply-To: <1299734608-5223-1-git-send-email-daahern@cisco.com>

Allow a user to select which fields to print to stdout for event data.
Options include comm (command name), tid (thread id), pid (process id),
time (perf timestamp), cpu, event (for event name), and trace (for
trace data).

Default is set to maintain compatibility with current output; this
feature does alter output format slightly -- no '-' between command
and pid/tid.

Thanks to Frederic Weisbecker for detailed suggestions on this approach.

Examples (output compressed)

1. trace, default format

perf record -ga -e sched:sched_switch
perf script

swapper    0 [000] 537.037184: sched_switch: prev_comm=swapper prev_pid=0...
   sshd 1675 [000] 537.037309: sched_switch: prev_comm=sshd prev_pid=1675...
netstat 1692 [001] 537.038664: sched_switch: prev_comm=netstat prev_pid=1692...

2. trace, custom format

perf record -ga -e sched:sched_switch
perf script -f comm,pid,time,trace     <--- omitting cpu and event name

swapper    0 537.037184: prev_comm=swapper prev_pid=0 prev_prio=120 ...
   sshd 1675 537.037309: prev_comm=sshd prev_pid=1675 prev_prio=120 ...
netstat 1692 537.038664: prev_comm=netstat prev_pid=1692 prev_prio=120 ...

Signed-off-by: David Ahern <daahern@cisco.com>
---
 tools/perf/Documentation/perf-script.txt |    5 +
 tools/perf/builtin-script.c              |  141 ++++++++++++++++++++++++++----
 2 files changed, 130 insertions(+), 16 deletions(-)

diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt
index 29ad942..b73cf58 100644
--- a/tools/perf/Documentation/perf-script.txt
+++ b/tools/perf/Documentation/perf-script.txt
@@ -112,6 +112,11 @@ OPTIONS
 --debug-mode::
         Do various checks like samples ordering and lost events.
 
+-f::
+--fields
+        Comma separated list of fields to print. Options are:
+        comm, tid, pid, time, cpu, event, trace
+
 SEE ALSO
 --------
 linkperf:perf-record[1], linkperf:perf-script-perl[1],
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 0a79da2..c046e6e 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -20,6 +20,38 @@ static u64			last_timestamp;
 static u64			nr_unordered;
 extern const struct option	record_options[];
 
+enum perf_output_field {
+	PERF_OUTPUT_COMM            = 1U << 0,
+	PERF_OUTPUT_TID             = 1U << 1,
+	PERF_OUTPUT_PID             = 1U << 2,
+	PERF_OUTPUT_TIME            = 1U << 3,
+	PERF_OUTPUT_CPU             = 1U << 4,
+	PERF_OUTPUT_EVNAME          = 1U << 5,
+	PERF_OUTPUT_TRACE           = 1U << 6,
+};
+
+struct output_option {
+	const char *str;
+	enum perf_output_field field;
+} all_output_options[] = {
+	{.str = "comm",  .field = PERF_OUTPUT_COMM},
+	{.str = "tid",   .field = PERF_OUTPUT_TID},
+	{.str = "pid",   .field = PERF_OUTPUT_PID},
+	{.str = "time",  .field = PERF_OUTPUT_TIME},
+	{.str = "cpu",   .field = PERF_OUTPUT_CPU},
+	{.str = "event", .field = PERF_OUTPUT_EVNAME},
+	{.str = "trace", .field = PERF_OUTPUT_TRACE},
+};
+
+/* default set to maintain compatibility with current format */
+static u64 output_fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | \
+			   PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | \
+			   PERF_OUTPUT_EVNAME | PERF_OUTPUT_TRACE;
+
+static bool output_set_by_user;
+
+#define PRINT_FIELD(x)  (output_fields & PERF_OUTPUT_##x)
+
 static void print_sample_start(struct perf_sample *sample,
 			       struct thread *thread)
 {
@@ -28,24 +60,45 @@ static void print_sample_start(struct perf_sample *sample,
 	const char *evname = NULL;
 	unsigned long secs;
 	unsigned long usecs;
-	unsigned long long nsecs = sample->time;
+	unsigned long long nsecs;
+
+	if (PRINT_FIELD(COMM)) {
+		if (latency_format)
+			printf("%8.8s ", thread->comm);
+		else
+			printf("%16s ", thread->comm);
+	}
 
-	if (latency_format)
-		printf("%8.8s-%-5d %3d", thread->comm, sample->tid, sample->cpu);
-	else
-		printf("%16s-%-5d [%03d]", thread->comm, sample->tid, sample->cpu);
+	if (PRINT_FIELD(PID) && PRINT_FIELD(TID))
+		printf("%5d/%-5d ", sample->pid, sample->tid);
+	else if (PRINT_FIELD(PID))
+		printf("%5d ", sample->pid);
+	else if (PRINT_FIELD(TID))
+		printf("%5d ", sample->tid);
+
+	if (PRINT_FIELD(CPU)) {
+		if (latency_format)
+			printf("%3d ", sample->cpu);
+		else
+			printf("[%03d] ", sample->cpu);
+	}
 
-	secs = nsecs / NSECS_PER_SEC;
-	nsecs -= secs * NSECS_PER_SEC;
-	usecs = nsecs / NSECS_PER_USEC;
-	printf(" %5lu.%06lu: ", secs, usecs);
+	if (PRINT_FIELD(TIME)) {
+		nsecs = sample->time;
+		secs = nsecs / NSECS_PER_SEC;
+		nsecs -= secs * NSECS_PER_SEC;
+		usecs = nsecs / NSECS_PER_USEC;
+		printf("%5lu.%06lu: ", secs, usecs);
+	}
 
-	type = trace_parse_common_type(sample->raw_data);
-	event = trace_find_event(type);
-	if (event)
-		evname = event->name;
+	if (PRINT_FIELD(EVNAME)) {
+		type = trace_parse_common_type(sample->raw_data);
+		event = trace_find_event(type);
+		if (event)
+			evname = event->name;
 
-	printf("%s: ", evname ? evname : "(unknown)");
+		printf("%s: ", evname ? evname : "(unknown)");
+	}
 }
 
 static void process_event(union perf_event *event __unused,
@@ -54,7 +107,11 @@ static void process_event(union perf_event *event __unused,
 			  struct thread *thread)
 {
 	print_sample_start(sample, thread);
-	print_trace_event(sample->cpu, sample->raw_data, sample->raw_size);
+
+	if (PRINT_FIELD(TRACE))
+		print_trace_event(sample->cpu, sample->raw_data,
+				  sample->raw_size);
+
 	printf("\n");
 }
 
@@ -311,6 +368,48 @@ static int parse_scriptname(const struct option *opt __used,
 	return 0;
 }
 
+static int parse_output_fields(const struct option *opt __used,
+			    const char *arg, int unset __used)
+{
+	char *tok;
+	int i, imax = sizeof(all_output_options) / sizeof(struct output_option);
+	int rc = 0;
+	char *str = strdup(arg);
+
+	if (!str)
+		return -ENOMEM;
+
+	tok = strtok(str, ",");
+	if (!tok) {
+		fprintf(stderr, "Invalid field string.");
+		return -EINVAL;
+	}
+
+	output_fields = 0;
+	while (1) {
+		for (i = 0; i < imax; ++i) {
+			if (strcmp(tok, all_output_options[i].str) == 0) {
+				output_fields |= all_output_options[i].field;
+				break;
+			}
+		}
+		if (i == imax) {
+			fprintf(stderr, "Invalid field requested.");
+			rc = -EINVAL;
+			break;
+		}
+
+		tok = strtok(NULL, ",");
+		if (!tok)
+			break;
+	}
+
+	output_set_by_user = true;
+
+	free(str);
+	return rc;
+}
+
 /* Helper function for filesystems that return a dent->d_type DT_UNKNOWN */
 static int is_directory(const char *base_path, const struct dirent *dent)
 {
@@ -623,6 +722,9 @@ static const struct option options[] = {
 		    "input file name"),
 	OPT_BOOLEAN('d', "debug-mode", &debug_mode,
 		   "do various checks like samples ordering and lost events"),
+	OPT_CALLBACK('f', "fields", NULL, "str",
+		     "comma separated output fields. Options: comm,tid,pid,time,cpu,event,trace",
+		     parse_output_fields),
 
 	OPT_END()
 };
@@ -809,8 +911,15 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
 
 	if (generate_script_lang) {
 		struct stat perf_stat;
+		int input;
+
+		if (output_set_by_user) {
+			fprintf(stderr,
+				"custom fields not supported for generated scripts");
+			return -1;
+		}
 
-		int input = open(input_name, O_RDONLY);
+		input = open(input_name, O_RDONLY);
 		if (input < 0) {
 			perror("failed to open file");
 			exit(-1);
-- 
1.7.4

  parent reply	other threads:[~2011-03-10  5:23 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-03-10  5:23 [PATCH 0/6 v4] perf script: add support for dumping events other than trace David Ahern
2011-03-10  5:23 ` [PATCH 1/6] perf script: change process_event prototype David Ahern
2011-03-10  5:23 ` [PATCH 2/6] perf: remove print_graph_cpu and print_graph_proc from trace-event-parse David Ahern
2011-03-10  5:23 ` [PATCH 3/6] perf script: move printing of 'common' data from print_event and rename David Ahern
2011-03-10 15:20   ` Steven Rostedt
2011-03-10 15:51     ` Arnaldo Carvalho de Melo
2011-03-10 16:05       ` Steven Rostedt
2011-03-10 16:20         ` Arnaldo Carvalho de Melo
2011-03-10 16:45           ` David Ahern
2011-03-10 17:07             ` Steven Rostedt
2011-03-11  0:28       ` Frederic Weisbecker
2011-03-10  5:23 ` David Ahern [this message]
2011-03-10  5:23 ` [PATCH 5/6] perf script: add support for dumping symbols David Ahern
2011-03-10  5:23 ` [PATCH 6/6] perf script: add support for H/W and S/W events David Ahern

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1299734608-5223-5-git-send-email-daahern@cisco.com \
    --to=daahern@cisco.com \
    --cc=acme@ghostprotocols.net \
    --cc=fweisbec@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=paulus@samba.org \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).