LTTNG_UST_TRACELOG(3)

πŸ’… LTTNG_UST_TRACELOG(3) β€” the LTTng Manual, but make it group chat ✨

okay so bestie, buckle up β€” this is the LTTng-UST page for lttng_ust_tracelog and lttng_ust_vtracelog, straight out of the LTTng Manual. it's giving "printf but make it tracy" and honestly? iconic. πŸŽ€


✨ NAME ✨

lttng_ust_tracelog, lttng_ust_vtracelog β€” the LTTng-UST printf(3)-like interface, but with a log level attached. yes bestie, you get to say how bad the vibe is. πŸ’…


🌸 SYNOPSIS 🌸

#include <lttng/tracelog.h>

#define lttng_ust_tracelog(level, fmt, ...)
#define lttng_ust_vtracelog(level, fmt, ap)

and then you gotta link with:

  • -llttng-ust
  • and if you define _LGPL_SOURCE before including <lttng/tracelog.h> (directly or indirectly): -llttng-ust-common

like, both of them. don't skip the second one, i'm literally begging. 🫢


πŸ¦‹ DESCRIPTION πŸ¦‹

so the LTTng-UST lttng_ust_tracelog() and lttng_ust_vtracelog() API lets you trace your app using cute little printf(3)-like and vprintf(3)-like macros, with one extra parameter for the log level you want. that's it, that's the whole vibe.

the fmt argument gets passed straight through as the fmt parameter of vasprintf(3), plus:

  • for lttng_ust_tracelog() β€” the optional parameters that come after fmt.
  • for lttng_ust_vtracelog() β€” the ap parameter, used as the ap parameter of vasprintf(3) (it's va_list type, iykyk).

the whole point of lttng_ust_tracelog() and lttng_ust_vtracelog() is to make migrating from logging to tracing so much easier. glow-up, but for your instrumentation. ✨

πŸ’œ the level values you can pick from

  • LTTNG_UST_TRACEPOINT_LOGLEVEL_EMERG β€” the system is unusable. like, everything is on fire. πŸ”₯
  • LTTNG_UST_TRACEPOINT_LOGLEVEL_ALERT β€” action must be taken immediately.
  • LTTNG_UST_TRACEPOINT_LOGLEVEL_CRIT β€” critical conditions.
  • LTTNG_UST_TRACEPOINT_LOGLEVEL_ERR β€” error conditions.
  • LTTNG_UST_TRACEPOINT_LOGLEVEL_WARNING β€” warning conditions.
  • LTTNG_UST_TRACEPOINT_LOGLEVEL_NOTICE β€” a normal, but significant, condition.
  • LTTNG_UST_TRACEPOINT_LOGLEVEL_INFO β€” informational message.
  • LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_SYSTEM β€” debug info with system-level scope (set of programs).
  • LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_PROGRAM β€” debug info with program-level scope (set of processes).
  • LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_PROCESS β€” debug info with process-level scope (set of modules).
  • LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_MODULE β€” debug info with module (executable/library) scope (set of units).
  • LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_UNIT β€” debug info with compilation unit scope (set of functions).
  • LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_FUNCTION β€” debug info with function-level scope.
  • LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_LINE β€” debug info with line-level scope (this one's the default log level, fyi πŸ‘€).
  • LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG β€” debug-level message.

🧚 how to actually use it

to use lttng_ust_tracelog() or lttng_ust_vtracelog(), just include <lttng/tracelog.h> wherever you need it, and link your app with liblttng-ust and liblttng-ust-common. there's a whole complete usage example in the EXAMPLE section below if you want the full recipe. πŸ“

once your app is instrumented with lttng_ust_tracelog() and/or lttng_ust_vtracelog() calls and is ready to run, use lttng-enable-event(1) to enable the lttng_ust_tracelog:* event. you can isolate specific log levels with the --loglevel and --loglevel-only options of that command. slay. πŸ‘‘

πŸŽ€ the fields in your events

the lttng_ust_tracelog() and lttng_ust_vtracelog() events contain these fields:

  • line β€” the line in the source file where lttng_ust_tracelog() was called.
  • file β€” the source file from which lttng_ust_tracelog() was called.
  • func β€” the function name from which lttng_ust_tracelog() was called.
  • msg β€” the formatted string output.

if you don't need to attach a specific log level to a lttng_ust_tracelog()/lttng_ust_vtracelog() call, use lttng_ust_tracef(3) instead. less work, same vibe.

⚠️ also pls pls pls read the LIMITATIONS section below β€” there are some genuinely important limitations to consider when using lttng_ust_tracelog() or lttng_ust_vtracelog(). i'm not being dramatic, it's real.

πŸ”₯ EXAMPLE πŸ”₯

here's a usage example of lttng_ust_tracelog(), enjoy bestie:

#include <stdlib.h>
#include <lttng/tracelog.h>

int main(int argc, char *argv[])
{
    int i;

    if (argc < 2) {
        lttng_ust_tracelog(LTTNG_UST_TRACEPOINT_LOGLEVEL_CRIT,
                           "Not enough arguments: %d", argc);
        return EXIT_FAILURE;
    }

    lttng_ust_tracelog(LTTNG_UST_TRACEPOINT_LOGLEVEL_INFO,
                       "Starting app with %d arguments", argc);

    for (i = 0; i < argc; i++) {
        lttng_ust_tracelog(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG,
                           "Argument %d: %s", i, argv[i]);
    }

    lttng_ust_tracelog(LTTNG_UST_TRACEPOINT_LOGLEVEL_INFO,
                       "Exiting app");
    return EXIT_SUCCESS;
}

this C source file, saved as app.c, can be compiled into a program like this:

$ cc -o app app.c -llttng-ust -llttng-ust-common

then you can create an LTTng tracing session, enable all the lttng_ust_tracelog() events, and start the created tracing session like this:

$ lttng create my-session
$ lttng enable-event --userspace 'lttng_ust_tracelog:*'
$ lttng start

or β€” and this is the fancy option β€” you can enable lttng_ust_tracelog() events matching a log level at least as severe as a given log level:

$ lttng enable-event --userspace 'lttng_ust_tracelog:*' \
                     --loglevel=INFO

next, start the program to be traced:

$ ./app a few arguments passed to this application

finally, stop the tracing session, and inspect the recorded events:

$ lttng stop
$ lttng view

ate. no crumbs. πŸ’€βœ¨


πŸ’€ LIMITATIONS πŸ’€

ngl, the lttng_ust_tracelog() and lttng_ust_vtracelog() utility macros were developed to make user space tracing super simple β€” but with notable disadvantages compared to custom, full-fledged tracepoint providers. trade-offs, bestie. 😭

  • all generated events have the same provider/event names.
  • there's no static type checking.
  • the only event field with user data you actually get, named msg, is a string potentially containing the values you passed to the macro using your own format. this also means you cannot use filtering using a custom expression at run time, because there are no isolated fields.
  • since lttng_ust_tracelog() and lttng_ust_vtracelog() use the C standard library's vasprintf(3) function in the background to format the strings at run time, their expected performance is lower than using custom tracepoint providers with typed fields, which do not require a conversion to a string. yeah. it's the conversion, that's the cost. πŸ’Έ
  • generally, a string containing the textual representation of the user data fields is not as compact as binary fields in the resulting trace.

so basically: lttng_ust_tracelog()/lttng_ust_vtracelog() are useful for quick prototyping and debugging, but should not be considered for any permanent/serious application instrumentation. read that again. i'll wait. 🫢

also β€” lttng_ust_vtracelog() does not have a STAP_PROBEV() call, because STAP_PROBEV() does not support va_list. if you need it, you should emit this call yourself. nobody's doing it for you, main character. πŸ‘‘

see lttng-ust(3) to learn more about custom tracepoint providers.


🌈 BUGS 🌈

if you encounter any issue or usability problem, please report it on the LTTng bug tracker <https://bugs.lttng.org/projects/lttng-ust>. don't suffer in silence babe, file the bug. πŸ™ˆ


🌸 RESOURCES 🌸


πŸ‘‘ COPYRIGHTS πŸ‘‘

this macro is part of the LTTng-UST project.

this macro is distributed under the GNU Lesser General Public License, version 2.1 <http://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html>. see the COPYING <https://github.com/lttng/lttng-ust/blob/v2.16/COPYING> file for more details.


🫢 THANKS 🫢

thanks to Ericsson for funding this work, providing real-life use cases, and testing. genuinely so real of them. πŸ’–

special thanks to Michel Dagenais and the DORSAL laboratory <http://www.dorsal.polymtl.ca/> at Γ‰cole Polytechnique de MontrΓ©al for the LTTng journey. 🧚


⭐ AUTHORS ⭐

LTTng-UST was originally written by Mathieu Desnoyers, with additional contributions from various other people. it is currently maintained by Mathieu Desnoyers <mailto:mathieu.desnoyers@efficios.com>.


πŸŽ€ SEE ALSO πŸŽ€

lttng_ust_tracef(3), lttng_ust_vtracef(3), lttng-ust(3), lttng(1), printf(3)


okay that's the whole page bestie, you're officially tracelog-pilled πŸ’… this was LTTng 2.16.0, dated 08/31/2026 β€” go forth and lttng_ust_tracelog() responsibly (or at least adorably). πŸ¦‹βœ¨πŸ’–

πŸ“¦ where this page comes from
  • arch rolling: lttng-ust 2.16.0-1 Β· LGPL-2.1-only AND MIT AND GPL-2.0-only AND BSD-3-Clause AND BSD-2-Clause AND GPL-3.0-or-later
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms