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

NAME

6       tracecmd_iterate_events, tracecmd_iterate_events_multi,
7       tracecmd_follow_event, tracecmd_follow_missed_events,
8       tracecmd_filter_add - Read events from a trace 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       int tracecmd_follow_missed_events(struct tracecmd_input *handle,
33                                          int (*callback)(struct tracecmd_input *,
34                                                          struct tep_event *,
35                                                          struct tep_record *,
36                                                          int, void *),
37                                          void *callback_data);
38       struct tracecmd_filter *tracecmd_filter_add(struct tracecmd_input *handle,
39                                                   const char *filter_str, bool neg);
40

DESCRIPTION

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

RETURN VALUE

135       Both tracecmd_iterate_events() and tracecmd_iterate_events_multi()
136       return zero if they successfully iterated all events (handling the
137       follow and filters appropriately). Or an error value, which can include
138       returning a non-zero result from the callback() function.
139

EXAMPLE

141           #define _GNU_SOURCE
142           #include <sched.h>
143           #include <stdlib.h>
144           #include <getopt.h>
145           #include <trace-cmd.h>
146
147           struct private_data {
148                   int             cpu;
149                   const char      *file;
150           };
151
152           static int print_events(struct tracecmd_input *handle, struct tep_record *record, int cpu, void *data)
153           {
154                   static struct trace_seq seq;
155                   struct tep_handle *tep = tracecmd_get_tep(handle);
156                   struct private_data *pdata = tracecmd_get_private(handle);
157
158                   /* For multi handles we need this */
159                   if (pdata->cpu >= 0 && pdata->cpu != record->cpu)
160                           return 0;
161
162                   if (!seq.buffer)
163                           trace_seq_init(&seq);
164
165                   trace_seq_reset(&seq);
166                   trace_seq_printf(&seq, "%s: ", pdata->file);
167                   tep_print_event(tep, &seq, record, "%6.1000d [%03d] %s-%d %s: %s\n",
168                                   TEP_PRINT_TIME, TEP_PRINT_CPU, TEP_PRINT_COMM, TEP_PRINT_PID,
169                                   TEP_PRINT_NAME, TEP_PRINT_INFO);
170                   trace_seq_terminate(&seq);
171                   trace_seq_do_printf(&seq);
172                   return 0;
173           }
174
175           static int print_event(struct tracecmd_input *handle, struct tep_event *event,
176                                  struct tep_record *record, int cpu, void *data)
177           {
178                   return print_events(handle, record, cpu, data);
179           }
180
181           static int missed_events(struct tracecmd_input *handle, struct tep_event *event,
182                                    struct tep_record *record, int cpu, void *data)
183           {
184                   if (record->missed_events > 0)
185                           printf("CPU [%03d] has %d missed events\n",
186                                    record->cpu, record->missed_events);
187                   else
188                           printf("CPU [%03d] has missed events\n", record->cpu);
189                   return 0;
190           }
191
192           static void usage(const char *argv0)
193           {
194                   printf("usage: [-c cpu][-f filter][-e event] %s trace.dat [trace.dat ...]\n",
195                          argv0);
196                   exit(-1);
197           }
198
199           int main(int argc, char **argv)
200           {
201                   struct tracecmd_input **handles = NULL;
202                   const char *filter_str = NULL;
203                   const char *argv0 = argv[0];
204                   struct private_data *priv;
205                   cpu_set_t *cpuset = NULL;
206                   char *event = NULL;
207                   size_t cpusize = 0;
208                   int nr_handles = 0;
209                   int cpu = -1;
210                   int i;
211                   int c;
212
213                   while ((c = getopt(argc, argv, "c:f:e:")) >= 0) {
214                           switch (c) {
215                           case 'c':
216                                   /* filter all trace data to this one CPU. */
217                                   cpu = atoi(optarg);
218                                   break;
219                           case 'f':
220                                   filter_str = optarg;
221                                   break;
222                           case 'e':
223                                   event = optarg;
224                                   break;
225                           default:
226                                   usage(argv0);
227                           }
228                   }
229                   argc -= optind;
230                   argv += optind;
231
232                   if (argc == 0)
233                           usage(argv0);
234
235                   for (i = 0; i < argc; i++) {
236                           handles = realloc(handles, sizeof(*handles) * (nr_handles + 1));
237                           if (!handles)
238                                   exit(-1);
239                           handles[nr_handles] = tracecmd_open(argv[i], 0);
240                           if (!handles[nr_handles]) {
241                                   perror(argv[i]);
242                                   exit(-1);
243                           }
244                           if (filter_str) {
245                                   if (tracecmd_filter_add(handles[nr_handles], filter_str, false) == NULL) {
246                                           perror("adding filter");
247                                           exit(-1);
248                                   }
249                           }
250                           priv = calloc(1, sizeof(*priv));
251                           if (!priv)
252                                   exit(-1);
253                           priv->file = argv[i];
254                           priv->cpu = cpu;
255                           tracecmd_set_private(handles[nr_handles], priv);
256                           if (event) {
257                                   if (tracecmd_follow_event(handles[nr_handles], NULL, event, print_event, NULL) < 0) {
258                                           printf("Could not follow event %s for file %s\n", event, argv[i]);
259                                           exit(-1);
260                                   }
261                           }
262                           tracecmd_follow_missed_events(handles[nr_handles], missed_events, NULL);
263                           nr_handles++;
264                   }
265
266                   /* Shortcut */
267                   if (nr_handles == 1) {
268                           if (cpu >= 0) {
269                                   cpuset = CPU_ALLOC(cpu + 1);
270                                   if (!cpuset)
271                                           exit(-1);
272                                   cpusize = CPU_ALLOC_SIZE(cpu + 1);
273                                   CPU_SET_S(cpu, cpusize, cpuset);
274                           }
275                           if (event)
276                                   tracecmd_iterate_events(handles[0], cpuset, cpusize, NULL, NULL);
277                           else
278                                   tracecmd_iterate_events(handles[0], cpuset, cpusize, print_events, NULL);
279                   } else {
280                           if (event)
281                                   tracecmd_iterate_events_multi(handles, nr_handles, NULL, NULL);
282                           else
283                                   tracecmd_iterate_events_multi(handles, nr_handles, print_events, NULL);
284                   }
285
286                   for (i = 0; i < nr_handles; i++) {
287                           priv = tracecmd_get_private(handles[i]);
288                           free(priv);
289                           tracecmd_close(handles[i]);
290                   }
291                   free(handles);
292           }
293

FILES

295           trace-cmd.h
296                   Header file to include in order to have access to the library APIs.
297           -ltracecmd
298                   Linker switch to add when building a program that uses the library.
299

SEE ALSO

301       libtracefs(3), libtraceevent(3), trace-cmd(1) trace-cmd.dat(5)
302

AUTHOR

304           Steven Rostedt <rostedt@goodmis.org[1]>
305           Tzvetomir Stoyanov <tz.stoyanov@gmail.com[2]>
306

REPORTING BUGS

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

LICENSE

311       libtracecmd is Free Software licensed under the GNU LGPL 2.1
312

RESOURCES

314       https://git.kernel.org/pub/scm/utils/trace-cmd/trace-cmd.git/
315

COPYING

317       Copyright (C) 2020 VMware, Inc. Free use of this software is granted
318       under the terms of the GNU Public License (GPL).
319

NOTES

321        1. rostedt@goodmis.org
322           mailto:rostedt@goodmis.org
323
324        2. tz.stoyanov@gmail.com
325           mailto:tz.stoyanov@gmail.com
326
327        3. linux-trace-devel@vger.kernel.org
328           mailto:linux-trace-devel@vger.kernel.org
329
330
331
332libtracefs                        07/20/2023                    LIBTRACECMD(3)
Impressum