LIBTRACEFS(3)
π NAME π
okay so bestie, welcome to the libtracefs manual β this is page LIBTRACEFS(3), and it's all about event filters: adding them, checking them, applying them, and clearing them. The whole crew is here: tracefs_filter_string_append, tracefs_filter_string_verify, tracefs_event_filter_apply, and tracefs_event_filter_clear. filter girlies, rise π
β¨
β¨ SYNOPSIS β¨
#include <tracefs.h>
int tracefs_filter_string_append(struct tep_event *event, char **filter,
struct tracefs_filter type, const char *field,
enum tracefs_synth_compare compare, const char *val);
int tracefs_filter_string_verify(struct tep_event *event, const char *filter, char **err);
int tracefs_event_filter_apply(struct tracefs_instance *instance, struct tep_event *event, const char *filter);
int tracefs_event_filter_clear(struct tracefs_instance *instance, struct tep_event *event);
π¦ DESCRIPTION π¦
π tracefs_filter_string_append()
tracefs_filter_string_append() is the little function that helps you create and verify event filters for a given event. It verifies that field belongs to the event, that the compare option you're using is valid for the type of the field, as well as val. For a type that is not TRACEFS_FILTER_COMPARE, it builds the logical string and also makes sure the syntax is correct β like, no more close parenthesis than open parenthesis, an AND (&&) or OR (||) isn't misplaced, etc. syntax check slay π₯
πΈ tracefs_synth_append_start_filter()
The page also brings up tracefs_synth_append_start_filter(): it creates a filter or appends to it for the starting event. Depending on type, it will build a string of tokens for parenthesis or logic statements, or it may add a comparison of field to val based on compare.
π§ the type tokens
If type is one of these, here's what gets appended to the filter:
TRACEFS_FILTER_COMPAREβ see below πTRACEFS_FILTER_ANDβ append"&&"to the filterTRACEFS_FILTER_ORβ append"||"to the filterTRACEFS_FILTER_NOTβ append"!"to the filterTRACEFS_FILTER_OPEN_PARENβ append"("to the filterTRACEFS_FILTER_CLOSE_PARENβ append")"to the filter
π field, compare, and val
field, compare, and val are ignored unless type is equal to TRACEFS_FILTER_COMPARE. When it is compare time, _compare will be used for the following:
TRACEFS_COMPARE_EQβfield == valTRACEFS_COMPARE_NEβfield != valTRACEFS_COMPARE_GTβfield > valTRACEFS_COMPARE_GEβfield >= valTRACEFS_COMPARE_LTβfield < valTRACEFS_COMPARE_LEβfield <= valTRACEFS_COMPARE_REβfield ~ "val": wherefieldis a string.TRACEFS_COMPARE_ANDβfield & val: wherefieldis a flags field.
π¦ tracefs_filter_string_verify()
tracefs_filter_string_verify() will parse filter to make sure that the fields are for the event, and that the syntax is correct. If there's an error in the syntax, and err is not NULL, then it will be allocated with an error message stating what was found wrong with the filter.
bestie,errmust be freed withfree(). no leaky vibes, okay? π«Ά
π tracefs_event_filter_apply()
tracefs_event_filter_apply() applies the given filter string on event in the given instance. doing the thing π
β tracefs_event_filter_clear()
tracefs_event_filter_clear() clears all filters on event in the given instance. bye-bye filters, iconic behavior π
π₯ RETURN VALUE π₯
tracefs_filter_string_append()β returns0on success and-1on error.tracefs_filter_string_verify()β returns0on success and-1on error. if there is an error, anderrnois notENOMEM, thenerris allocated and will contain a string describing what was found wrong withfilter.errmust be freed withfree().tracefs_event_filter_apply()β returns0on success and-1on error.tracefs_event_filter_clear()β returns0on success and-1on error.
πΈ EXAMPLE πΈ
okay bestie, this one's a whole main character example β a little program that takes a filter string, checks it with the library, re-parses it into a shiny new filter, and applies it to an event. it's giving "I read the whole manpage and now I'm dangerous" π
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <tracefs.h>
static void usage(char **argv)
{
fprintf(stderr, "usage: %s [system] event filter\n", argv[0]);
exit(-1);
}
int main (int argc, char **argv)
{
struct tep_handle *tep;
struct tep_event *event;
const char *system = NULL;
const char *event_name;
const char *filter;
char *new_filter = NULL;
char *err = NULL;
int i;
if (argc < 3)
usage(argv);
if (argc < 4) {
event_name = argv[1];
filter = argv[2];
} else {
system = argv[1];
event_name = argv[2];
filter = argv[3];
}
/* Load all events from the system */
tep = tracefs_local_events(NULL);
if (!tep) {
perror("tep");
exit(-1);
}
event = tep_find_event_by_name(tep, system, event_name);
if (!event) {
fprintf(stderr, "Event %s%s%s not found\n",
system ? system : "" , system ? " " : "",
event_name);
exit(-1);
}
if (tracefs_filter_string_verify(event, filter, &err) < 0) {
perror("tracecfs_event_verify_filter");
if (err)
fprintf(stderr, "%s", err);
free(err);
exit(-1);
}
for (i = 0; filter[i]; i++) {
char buf[strlen(filter)];
char *field = NULL;
char *val = NULL;
enum tracefs_filter type;
enum tracefs_compare compare = 0;
int start_i, n;
int quote;
bool backslash;
while (isspace(filter[i]))
i++;
switch(filter[i]) {
case '(':
type = TRACEFS_FILTER_OPEN_PAREN;
break;
case ')':
type = TRACEFS_FILTER_CLOSE_PAREN;
break;
case '!':
type = TRACEFS_FILTER_NOT;
break;
case '&':
type = TRACEFS_FILTER_AND;
i++;
break;
case '|':
type = TRACEFS_FILTER_OR;
i++;
break;
default:
type = TRACEFS_FILTER_COMPARE;
while (isspace(filter[i]))
i++;
start_i = i;
for (; filter[i]; i++) {
switch(filter[i]) {
case 'a' ... 'z':
case 'A' ... 'Z':
case '0' ... '9':
case '_':
continue;
}
break;
}
n = i - start_i;
field = buf;
strncpy(field, filter + start_i, n);
field[n++] = '\0';
val = buf + n;
while (isspace(filter[i]))
i++;
start_i = i;
switch(filter[i++]) {
case '>':
compare = TRACEFS_COMPARE_GT;
if (filter[i] == '=') {
i++;
compare = TRACEFS_COMPARE_GE;
}
break;
case '<':
compare = TRACEFS_COMPARE_LT;
if (filter[i] == '=') {
i++;
compare = TRACEFS_COMPARE_LE;
}
break;
case '=':
compare = TRACEFS_COMPARE_EQ;
i++;
break;
case '!':
compare = TRACEFS_COMPARE_NE;
i++;
break;
case '~':
compare = TRACEFS_COMPARE_RE;
break;
case '&':
compare = TRACEFS_COMPARE_AND;
break;
}
while (isspace(filter[i]))
i++;
quote = 0;
backslash = false;
start_i = i;
for (; filter[i]; i++) {
if (quote) {
if (backslash)
backslash = false;
else if (filter[i] == '\\')
backslash = true;
else if (filter[i] == quote)
quote = 0;
continue;
}
switch(filter[i]) {
case '"': case '\'':
quote = filter[i];
continue;
case 'a' ... 'z':
case 'A' ... 'Z':
case '0' ... '9':
case '_':
continue;
}
break;
}
n = i - start_i;
strncpy(val, filter + start_i, n);
val[n] = '\0';
break;
}
n = tracefs_filter_string_append(event, &new_filter, type,
field, compare, val);
if (n < 0) {
fprintf(stderr, "Failed making new filter:\n'%s'\n",
new_filter ? new_filter : "(null)");
exit(-1);
}
}
if (tracefs_event_filter_apply(NULL, event, new_filter))
fprintf(stderr, "Failed to apply filter on event");
tep_free(tep);
printf("Created new filter: '%s'\n", new_filter);
free(new_filter);
exit(0);
}
no cap, that's the whole thing β copy it, build it, run it, feel iconic π
π FILES π
the receipts, bestie β here's what you actually touch:
tracefs.hβ the header file you include so you get access to all the library APIs. like, the whole personality lives in here β¨-ltracefsβ the linker switch you add when building a program that uses the library. yes, you have to actually link it, she doesn't come free π
π SEE ALSO π
go read these next, i'm obsessed with the cross-references:
libtracefs(3), libtraceevent(3), trace-cmd(1), tracefs_hist_alloc(3), tracefs_hist_alloc_2d(3), tracefs_hist_alloc_nd(3), tracefs_hist_free(3), tracefs_hist_add_key(3), tracefs_hist_add_value(3), tracefs_hist_add_name(3), tracefs_hist_start(3), tracefs_hist_destory(3), tracefs_hist_add_sort_key(3), tracefs_hist_sort_key_direction(3)
(and yes, tracefs_hist_destory(3) is spelled exactly like that in the original β she's got a typo and we love her for it π)
β¨ AUTHOR β¨
the legends behind this:
- Steven Rostedt <rostedt@goodmis.org[1]>
- Tzvetomir Stoyanov <tz.stoyanov@gmail.com[2]>
- sameeruddin shaik <sameeruddin.shaik8@gmail.com[3]>
π REPORTING BUGS π
found a bug? don't suffer in silence, bestie β report it to <linux-trace-devel@vger.kernel.org[4]> and let the maintainers slay π«Ά
π LICENSE π
libtracefs is Free Software licensed under the GNU LGPL 2.1. periodt. π
π RESOURCES π
the mothership, go touch grass (the kernel kind):
https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git/
Β©οΈ COPYING Β©οΈ
Copyright (C) 2020 VMware, Inc. Free use of this software is granted under the terms of the GNU Public License (GPL).
π NOTES π
the link footnotes, preserved in all their glory π
rostedt@goodmis.orgmailto:rostedt@goodmis.orgtz.stoyanov@gmail.commailto:tz.stoyanov@gmail.comsameeruddin.shaik8@gmail.commailto:sameeruddin.shaik8@gmail.comlinux-trace-devel@vger.kernel.orgmailto:linux-trace-devel@vger.kernel.org
and that's a wrap on the whole page, bestie π¦ this was libtracefs 1.8.4, dated 10/21/2026 β screenshot it, memorise it, go write some iconic filters. ily, bye πβ¨
π¦ where this page comes from
- arch rolling: libtracefs 1.8.4-1 Β· GPL-2.0-only AND LGPL-2.1-only
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms