1LIBTRACECMD(3)                 libtracefs Manual                LIBTRACECMD(3)
2
3
4

NAME

6       tracecmd_iterate_events, tracecmd_iterate_events_multi,
7       tracecmd_follow_event, tracecmd_filter_add - Read events from a trace
8       file
9

SYNOPSIS

11       #include <trace-cmd.h>
12
13       int tracecmd_iterate_events(struct tracecmd_input *handle,
14                                   cpu_set_t *cpus, int cpu_size,
15                                   int (*callback)(struct tracecmd_input *,
16                                                   struct tep_record *,
17                                                   int, void *),
18                                   void *callback_data);
19       int tracecmd_iterate_events_multi(struct tracecmd_input **handles,
20                                         int nr_handles,
21                                         int (*callback)(struct tracecmd_input *,
22                                                                  struct tep_record *,
23                                                                  int, void *),
24                                         void *callback_data);
25       int tracecmd_follow_event(struct tracecmd_input *handle,
26                                 const char *system, const char *event_name,
27                                 int (*callback)(struct tracecmd_input *,
28                                                 struct tep_event *,
29                                                 struct tep_record *,
30                                                 int, void *),
31                                 void *callback_data);
32       struct tracecmd_filter *tracecmd_filter_add(struct tracecmd_input *handle,
33                                                   const char *filter_str, bool neg);
34

DESCRIPTION

36       This set of APIs can be used to iterate over events after opening a
37       trace file using one of the open functions like tracecmd_open(3) or
38       tracecmd_open_fd(3).
39
40       The function tracecmd_iterate_events() will iterate through all the
41       events in the trace file defined by handle, where handle is returned
42       from one of the tracecmd_open(3) functions. It will call the callback()
43       function on the events on the CPUs defined by cpus. The cpu_size must
44       be the size of cpus (see CPU_SET(3)). If cpus is NULL, then cpu_size is
45       ignored and callback() will be called for all events on all CPUs in the
46       trace file. The callback_data is passed to the callback() as its last
47       parameter. callback may be NULL, which is useful if
48       tracecmd_follow_event() is used, but note if callback is NULL, then
49       callback_data is ignored and not sent to the callback of
50       tracecmd_follow_event().
51
52       The function tracecmd_iterate_events_multi() is similar to
53       tracecmd_iterate_events() except that it allows to iterate over more
54       than one trace file. If tracecmd agent(1) is used to get a trace file
55       for both the host and guest, make sure that the host trace file is the
56       first entry in handles and tracecmd_iterate_events_multi() will do the
57       synchronization of the meta data for the guest files that come later in
58       handles. handles is an array of trace file descriptors that were opened
59       by tracecmd_open(3) and friends. Note, unlike
60       tracecmd_iterate_events(), tracecmd_iterate_events_multi() does not
61       filter on CPUs, as it will cause the API to become too complex in
62       knowing which handle to filter the CPUs on. If CPU filtering is
63       desired, then the callback should check the record→cpu to and return 0
64       if it is not the desired CPU to process. nr_handles denotes the number
65       of elements in handles. The callback_data is passed to the callback as
66       its last parameter. callback may be NULL, which is useful if
67       tracecmd_follow_event() is used, but note if callback is NULL, then
68       callback_data is ignored and not sent to the callback of
69       tracecmd_follow_event().
70
71       The callback() for both tracecmd_iterate_events() and
72       tracecmd_iterate_events_multi() is of the prototype:
73
74       int callback()(struct tracecmd_input *handle, struct tep_record
75       *record, int cpu, void *data);
76
77       The handle is the same handle passed to tracecmd_iterate_events() or
78       the current handle of handles passed to tracecmd_iterate_events_multi()
79       that the record belongs to. The record is the current event record. The
80       cpu is the current CPU being processed. Note, for
81       tracecmd_iterate_events_multi() it may not be the actual CPU of the
82       file, but the nth CPU of all the handles put together. Use record→cpu
83       to get the actual CPU that the event is on.
84
85       The tracecmd_follow_event() function will attach to a trace file
86       descriptor handle and call the callback when the event described by
87       system and name matches an event in the iteration of
88       tracecmd_iterate_events() or tracecmd_iterate_events_multi(). For
89       tracecmd_iterate_events_multi(), the callback is only called if the
90       handle matches the current trace file descriptor within handles. The
91       callback_data is passed as the last parameter to the callback()
92       function. Note, this callback() function will be called before the
93       callback() function of either tracecmd_iterate_events() or
94       tracecmd_iterate_events_multi().
95
96       The callback() prototype for *tracecmd_follow_event()_ is:
97
98       int callback()(struct tracecmd_input *handle, struct tep_event *event,
99       struct tep_record *_record, int cpu, void *data);
100
101       The tracecmd_filter_add() function, adds a filter to handle that
102       affects both tracecmd_iterate_events() and
103       tracecmd_iterate_events_multi(). The filter_str is a character string
104       defining a filter in a format that is defined by
105       tep_filter_add_filter_str(3). If neg is true, then the events that
106       match the filter will be skipped, otherwise the events that match will
107       execute the callback() function in the iterators.
108

RETURN VALUE

110       Both tracecmd_iterate_events() and tracecmd_iterate_events_multi()
111       return zero if they successfully iterated all events (handling the
112       follow and filters appropriately). Or an error value, which can include
113       returning a non-zero result from the callback() function.
114

EXAMPLE

116           #define _GNU_SOURCE
117           #include <sched.h>
118           #include <stdlib.h>
119           #include <getopt.h>
120           #include <trace-cmd.h>
121
122           struct private_data {
123                   int             cpu;
124                   const char      *file;
125           };
126
127           static int print_events(struct tracecmd_input *handle, struct tep_record *record, int cpu, void *data)
128           {
129                   static struct trace_seq seq;
130                   struct tep_handle *tep = tracecmd_get_tep(handle);
131                   struct private_data *pdata = tracecmd_get_private(handle);
132
133                   /* For multi handles we need this */
134                   if (pdata->cpu >= 0 && pdata->cpu != record->cpu)
135                           return 0;
136
137                   if (!seq.buffer)
138                           trace_seq_init(&seq);
139
140                   trace_seq_reset(&seq);
141                   trace_seq_printf(&seq, "%s: ", pdata->file);
142                   tep_print_event(tep, &seq, record, "%6.1000d [%03d] %s-%d %s: %s\n",
143                                   TEP_PRINT_TIME, TEP_PRINT_CPU, TEP_PRINT_COMM, TEP_PRINT_PID,
144                                   TEP_PRINT_NAME, TEP_PRINT_INFO);
145                   trace_seq_terminate(&seq);
146                   trace_seq_do_printf(&seq);
147                   return 0;
148           }
149
150           static int print_event(struct tracecmd_input *handle, struct tep_event *event,
151                                  struct tep_record *record, int cpu, void *data)
152           {
153                   return print_events(handle, record, cpu, data);
154           }
155
156           static void usage(const char *argv0)
157           {
158                   printf("usage: [-c cpu][-f filter][-e event] %s trace.dat [trace.dat ...]\n",
159                          argv0);
160                   exit(-1);
161           }
162
163           int main(int argc, char **argv)
164           {
165                   struct tracecmd_input **handles = NULL;
166                   const char *filter_str = NULL;
167                   const char *argv0 = argv[0];
168                   struct private_data *priv;
169                   cpu_set_t *cpuset = NULL;
170                   char *event = NULL;
171                   size_t cpusize = 0;
172                   int nr_handles = 0;
173                   int cpu = -1;
174                   int i;
175                   int c;
176
177                   while ((c = getopt(argc, argv, "c:f:e:")) >= 0) {
178                           switch (c) {
179                           case 'c':
180                                   /* filter all trace data to this one CPU. */
181                                   cpu = atoi(optarg);
182                                   break;
183                           case 'f':
184                                   filter_str = optarg;
185                                   break;
186                           case 'e':
187                                   event = optarg;
188                                   break;
189                           default:
190                                   usage(argv0);
191                           }
192                   }
193                   argc -= optind;
194                   argv += optind;
195
196                   if (argc == 0)
197                           usage(argv0);
198
199                   for (i = 0; i < argc; i++) {
200                           handles = realloc(handles, sizeof(*handles) * (nr_handles + 1));
201                           if (!handles)
202                                   exit(-1);
203                           handles[nr_handles] = tracecmd_open(argv[i], 0);
204                           if (!handles[nr_handles]) {
205                                   perror(argv[i]);
206                                   exit(-1);
207                           }
208                           if (filter_str) {
209                                   if (tracecmd_filter_add(handles[nr_handles], filter_str, false) == NULL) {
210                                           perror("adding filter");
211                                           exit(-1);
212                                   }
213                           }
214                           priv = calloc(1, sizeof(*priv));
215                           if (!priv)
216                                   exit(-1);
217                           priv->file = argv[i];
218                           priv->cpu = cpu;
219                           tracecmd_set_private(handles[nr_handles], priv);
220                           if (event) {
221                                   if (tracecmd_follow_event(handles[nr_handles], NULL, event, print_event, NULL) < 0) {
222                                           printf("Could not follow event %s for file %s\n", event, argv[i]);
223                                           exit(-1);
224                                   }
225                           }
226                           nr_handles++;
227                   }
228
229                   /* Shortcut */
230                   if (nr_handles == 1) {
231                           if (cpu >= 0) {
232                                   cpuset = CPU_ALLOC(cpu + 1);
233                                   if (!cpuset)
234                                           exit(-1);
235                                   cpusize = CPU_ALLOC_SIZE(cpu + 1);
236                                   CPU_SET_S(cpu, cpusize, cpuset);
237                           }
238                           if (event)
239                                   tracecmd_iterate_events(handles[0], cpuset, cpusize, NULL, NULL);
240                           else
241                                   tracecmd_iterate_events(handles[0], cpuset, cpusize, print_events, NULL);
242                   } else {
243                           if (event)
244                                   tracecmd_iterate_events_multi(handles, nr_handles, NULL, NULL);
245                           else
246                                   tracecmd_iterate_events_multi(handles, nr_handles, print_events, NULL);
247                   }
248
249                   for (i = 0; i < nr_handles; i++) {
250                           priv = tracecmd_get_private(handles[i]);
251                           free(priv);
252                           tracecmd_close(handles[i]);
253                   }
254                   free(handles);
255           }
256

FILES

258           trace-cmd.h
259                   Header file to include in order to have access to the library APIs.
260           -ltracecmd
261                   Linker switch to add when building a program that uses the library.
262

SEE ALSO

264       libtracefs(3), libtraceevent(3), trace-cmd(1) trace-cmd.dat(5)
265

AUTHOR

267           Steven Rostedt <rostedt@goodmis.org[1]>
268           Tzvetomir Stoyanov <tz.stoyanov@gmail.com[2]>
269

REPORTING BUGS

271       Report bugs to <linux-trace-devel@vger.kernel.org[3]>
272

LICENSE

274       libtracecmd is Free Software licensed under the GNU LGPL 2.1
275

RESOURCES

277       https://git.kernel.org/pub/scm/utils/trace-cmd/trace-cmd.git/
278

COPYING

280       Copyright (C) 2020 VMware, Inc. Free use of this software is granted
281       under the terms of the GNU Public License (GPL).
282

NOTES

284        1. rostedt@goodmis.org
285           mailto:rostedt@goodmis.org
286
287        2. tz.stoyanov@gmail.com
288           mailto:tz.stoyanov@gmail.com
289
290        3. linux-trace-devel@vger.kernel.org
291           mailto:linux-trace-devel@vger.kernel.org
292
293
294
295libtracefs                        10/11/2022                    LIBTRACECMD(3)
Impressum