|
| 1 | +# Libraries for Linux Tracepoints and user_events |
| 2 | + |
| 3 | +This repository contains C/C++ libraries for collecting and decoding |
| 4 | +[Linux Tracepoint](https://www.kernel.org/doc/html/latest/trace/tracepoints.html) |
| 5 | +events and for generating Tracepoint events from user mode using the |
| 6 | +[user_events](https://docs.kernel.org/trace/user_events.html) facility. |
| 7 | + |
| 8 | +Related repositories: |
| 9 | + |
| 10 | +- [LinuxTracepoints-Net](https://github.com/microsoft/LinuxTracepoints-Net) - |
| 11 | + .NET libraries and tools for decoding perf.data files, including `eventheader` |
| 12 | + events. |
| 13 | +- [LinuxTracepoints-Rust](https://github.com/microsoft/LinuxTracepoints-Rust) - |
| 14 | + Rust libraries for generating Tracepoint events from user mode using the |
| 15 | + [user_events](https://docs.kernel.org/trace/user_events.html) facility |
| 16 | + |
| 17 | +## Overview |
| 18 | + |
| 19 | +- [libtracepoint](libtracepoint) - |
| 20 | + low-level C/C++ tracing interface. Designed to support replacement at |
| 21 | + link-time if a different implementation is needed (e.g. for testing). |
| 22 | + |
| 23 | + - [tracepoint-provider.h](libtracepoint/include/tracepoint/tracepoint-provider.h) - |
| 24 | + a developer-friendly C/C++ API for writing tracepoint events to any |
| 25 | + implementation of the `tracepoint.h` interface. |
| 26 | + - [tracepoint.h](libtracepoint/include/tracepoint/tracepoint-provider.h) - |
| 27 | + low-level interface for writing tracepoint events. |
| 28 | + - [libtracepoint.a](libtracepoint/src/tracepoint.c) - |
| 29 | + default implementation that writes directly to the Linux `user_events` facility. |
| 30 | + |
| 31 | +- [libtracepoint-control-cpp](libtracepoint-control-cpp) - |
| 32 | + C++ library for controlling a tracepoint event collection session. |
| 33 | + |
| 34 | + - `TracingSession.h` implements an event collection session that can |
| 35 | + collect tracepoint events and enumerate the events that the session has |
| 36 | + collected. Supports real-time and circular-buffer modes. |
| 37 | + - `TracingPath.h` has functions for finding the `/sys/kernel/tracing` |
| 38 | + mount point and reading `format` files. |
| 39 | + - `TracepointSpec.h` parses tracepoint event specifications for configuring |
| 40 | + a tracepoint collection session. |
| 41 | + - `TracingCache.h` implements a cache for tracking parsed `format` files |
| 42 | + based on system+name or by `common_type` id. |
| 43 | + |
| 44 | +- [libtracepoint-decode-cpp](libtracepoint-decode-cpp) - |
| 45 | + C++ library for decoding tracepoints. Works on both Linux and Windows. |
| 46 | + |
| 47 | + - `PerfDataFile.h` defines the `PerfDataFile` class that decodes |
| 48 | + `perf.data` files. |
| 49 | + - `PerfEventInfo.h` defines the `PerfSampleEventInfo` and |
| 50 | + `PerfNonSampleEventInfo` structures for raw event information. |
| 51 | + - `PerfEventMetadata.h` defines classes for parsing ftrace event metadata |
| 52 | + information. |
| 53 | + |
| 54 | +- [libeventheader-tracepoint](libeventheader-tracepoint) - |
| 55 | + `eventheader` envelope that supports extended attributes including severity |
| 56 | + level and optional field information (field types and field names). |
| 57 | + |
| 58 | + - [TraceLoggingProvider.h](libeventheader-tracepoint/include/eventheader/TraceLoggingProvider.h) - |
| 59 | + a developer-friendly C/C++ API for writing `eventheader`-encapsulated |
| 60 | + events to any implementation of the tracepoint interface. |
| 61 | + - [EventHeaderDynamic.h](libeventheader-tracepoint/include/eventheader/EventHeaderDynamic.h) - |
| 62 | + C++ API for writing runtime-defined `eventheader`-encapsulated events, |
| 63 | + intended for use as an implementation layer for a higher-level API like |
| 64 | + OpenTelemetry. |
| 65 | + |
| 66 | +- [libeventheader-decode-cpp](libeventheader-decode-cpp) - |
| 67 | + C++ library for decoding events that use the `eventheader` envelope. |
| 68 | + - `EventEnumerator` class parses an event into fields. |
| 69 | + - `EventFormatter` class converts event data into a string. |
| 70 | + - `decode-perf` tool that decodes `perf.data` files to JSON. |
| 71 | + |
| 72 | +## General Usage |
| 73 | + |
| 74 | +- Configure a Linux system with the `user_events` feature enabled. |
| 75 | + |
| 76 | + - Supported on Linux kernel 6.4 and later. |
| 77 | + - Kernel must be built with `user_events` support (`CONFIG_USER_EVENTS=y`). |
| 78 | + - Must have either `tracefs` or `debugfs` mounted. For example, you might add |
| 79 | + the following line to your `/etc/fstab` file: |
| 80 | + `tracefs /sys/kernel/tracing tracefs defaults 0 0` |
| 81 | + - The user that will generate events must have `x` access to the `tracing` |
| 82 | + directory and `w` access to the `tracing/user_events_data` file. One |
| 83 | + possible implementation is to create a `tracers` group, then: |
| 84 | + - `chgrp tracers /sys/kernel/tracing` |
| 85 | + - `chgrp tracers /sys/kernel/tracing/user_events_data` |
| 86 | + - `chmod g+x /sys/kernel/tracing` |
| 87 | + - `chmod g+w /sys/kernel/tracing/user_events_data` |
| 88 | + |
| 89 | +- Use one of the event generation APIs to write a program that generates events. |
| 90 | + |
| 91 | + - C/C++ programs can use |
| 92 | + [tracepoint-provider.h](libtracepoint/include/tracepoint/tracepoint-provider.h) |
| 93 | + to generate regular Linux Tracepoint events that are defined at compile-time. |
| 94 | + (Link with `libtracepoint`.) |
| 95 | + - C/C++ programs can use |
| 96 | + [TraceLoggingProvider.h](libeventheader-tracepoint/include/eventheader/TraceLoggingProvider.h) |
| 97 | + to generate eventheader-enabled Tracepoint events that are defined at |
| 98 | + compile-time. (Link with `libtracepoint` and `libeventheader-tracepoint`.) |
| 99 | + - C++ middle-layer APIs (e.g. an OpenTelemetry exporter) can use |
| 100 | + [EventHeaderDynamic.h](libeventheader-tracepoint/include/eventheader/EventHeaderDynamic.h) |
| 101 | + to generate eventheader-enabled Tracepoint events that are runtime-dynamic. |
| 102 | + (Link with `libtracepoint` and `libeventheader-tracepoint`.) |
| 103 | + - Rust programs can use |
| 104 | + [LinuxTracepoints-Rust](https://github.com/microsoft/LinuxTracepoints-Rust) |
| 105 | + to generate eventheader-enabled Tracepoint events. |
| 106 | + |
| 107 | +- To collect events in a C++ program, use |
| 108 | + [libtracepoint-control-cpp](libtracepoint-control-cpp). Note that your |
| 109 | + program must run as a privileged user (`CAP_PERFMON` capability plus read access to |
| 110 | + `/sys/kernel/tracing/events`) because access to the event collection system is |
| 111 | + restricted by default. |
| 112 | + |
| 113 | +- To collect events without writing C++ code, use the included |
| 114 | + [tracepoint-collect](libtracepoint-control-cpp/tools/tracepoint-collect.cpp) tool |
| 115 | + or the Linux [`perf`](https://www.man7.org/linux/man-pages/man1/perf.1.html) tool |
| 116 | + to collect events to a `perf.data` file, e.g. |
| 117 | + `tracepoint-collect -o File.perf user_events:MyEvent1 user_events:MyEvent2` or |
| 118 | + `perf record -o File.perf -k monotonic -e user_events:MyEvent1,user_events:MyEvent2`. |
| 119 | + Note that you must run the tool as a privileged user to collect events (`CAP_PERFMON` |
| 120 | + capability plus read access to `/sys/kernel/tracing/events`). |
| 121 | + |
| 122 | + - The `perf` tool binary is typically available as part of the `linux-perf` |
| 123 | + package (e.g. can be installed by `apt install linux-perf`). However, this |
| 124 | + package installs a `perf_VERSION` binary rather than a `perf` binary, so |
| 125 | + you will need to add an appropriate VERSION suffix to your `perf` commands |
| 126 | + or use a wrapper script. |
| 127 | + - To capture tracepoints using `perf`, you'll also need to install |
| 128 | + `libtraceevent`, e.g. `apt install libtraceevent1`. |
| 129 | + - The `linux-base` package installs a `perf` wrapper script that redirects to |
| 130 | + the version of `perf` that matches your current kernel (if present) so that |
| 131 | + you can run the appropriate version of `perf` without the VERSION suffix. |
| 132 | + This frequently doesn't work because the latest `perf` binary from `apt` |
| 133 | + doesn't always match the running kernel, so you may want to make your own |
| 134 | + wrapper script instead. |
| 135 | + - Note that for purposes of collecting events, it is usually not important |
| 136 | + for the version of the `perf` tool to match the kernel version, so it's |
| 137 | + ok to use e.g. `perf_5.10` even if you are running a newer kernel. |
| 138 | + |
| 139 | +- Note that tracepoints must be registered before you can start collecting |
| 140 | + them. The `tracepoint-collect` tool has facilities to pre-register a user_events |
| 141 | + tracepoint. The `perf` command will report an error if the tracepoint is not yet |
| 142 | + registered. |
| 143 | + |
| 144 | + - You can usually register tracepoints by starting the program that generates |
| 145 | + them. Most programs will register all of their tracepoints when they start |
| 146 | + running. (They will usually unregister when they stop running.) |
| 147 | + - You can also use the |
| 148 | + [`tracepoint-register`](libtracepoint/tools/tracepoint-register.cpp) |
| 149 | + tool to pre-register an event so you can start collecting it before |
| 150 | + starting the program that generates it. |
| 151 | + - If writing your own event collection tool, you might do something similar |
| 152 | + in your tool to pre-register the events that you need to collect. For |
| 153 | + example, you might use the `PreregisterTracepoint` or |
| 154 | + `PreregisterEventHeaderTracepoint` methods of the `TracepointCache` class |
| 155 | + in [`libtracepoint=control`](libtracepoint-control-cpp). |
| 156 | + |
| 157 | +- Use the [`decode-perf`](libeventheader-decode-cpp/tools/decode-perf.cpp) |
| 158 | + tool to decode the `perf.data` file to JSON text, or write your own decoding |
| 159 | + tool using [libtracepoint-decode-cpp](libtracepoint-decode-cpp) and |
| 160 | + `libeventheader-decode-cpp`. |
| 161 | + |
| 162 | +## Contributing |
| 163 | + |
| 164 | +This project welcomes contributions and suggestions. Most contributions require you to agree to a |
| 165 | +Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us |
| 166 | +the rights to use your contribution. For details, visit [https://cla.opensource.microsoft.com](https://cla.opensource.microsoft.com). |
| 167 | + |
| 168 | +When you submit a pull request, a CLA bot will automatically determine whether you need to provide |
| 169 | +a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions |
| 170 | +provided by the bot. You will only need to do this once across all repos using our CLA. |
| 171 | + |
| 172 | +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). |
| 173 | +For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or |
| 174 | +contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. |
| 175 | + |
| 176 | +## Trademarks |
| 177 | + |
| 178 | +This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft |
| 179 | +trademarks or logos is subject to and must follow |
| 180 | +[Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/legal/intellectualproperty/trademarks/usage/general). |
| 181 | +Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. |
| 182 | +Any use of third-party trademarks or logos are subject to those third-party's policies. |
0 commit comments