| 1 | /*! |
| 2 | @page examples Examples |
| 3 | |
| 4 | The examples of this section apply the different parts of the |
| 5 | libbabeltrace2 API to accomplish real tasks. |
| 6 | |
| 7 | The available examples are: |
| 8 | |
| 9 | - \subpage example-simple-plugin-def-file |
| 10 | - \subpage example-simple-src-cmp-cls |
| 11 | - \subpage example-simple-flt-cmp-cls |
| 12 | - \subpage example-simple-sink-cmp-cls |
| 13 | |
| 14 | @page example-simple-plugin-def-file Simple shared object plugin definition C file |
| 15 | |
| 16 | This example shows a basic \bt_name |
| 17 | \ref api-plugin-dev "shared object plugin" definition C file. |
| 18 | |
| 19 | The shared object plugin's name is <code>vestige</code>. Therefore |
| 20 | the \c input and \c output \bt_p_comp_cls would be identified in the |
| 21 | \bt_cli command-line tool as \c source.vestige.input and |
| 22 | <code>sink.vestige.output</code>. |
| 23 | |
| 24 | Assume that \c vestige.c contains the actual source and sink component |
| 25 | classes's code, and that \c vestige.h contains its declarations. |
| 26 | |
| 27 | <code>vestige-plugin.c</code>: |
| 28 | |
| 29 | @include vestige-plugin.c |
| 30 | |
| 31 | See \ref guide-comp-link-plugin-so to learn how you could compile and |
| 32 | link those files as a \bt_name shared object plugin. |
| 33 | |
| 34 | @page example-simple-src-cmp-cls Simple source component class |
| 35 | |
| 36 | This example shows a basic \bt_src_comp_cls packaged as a |
| 37 | \ref api-plugin-dev "shared object plugin". |
| 38 | |
| 39 | The name of the plugin is <code>dust</code> and the name of the source |
| 40 | component class is <code>input</code>. Therefore the |
| 41 | component class is identified in the \bt_cli |
| 42 | command-line tool as <code>source.dust.input</code>. |
| 43 | |
| 44 | A <code>source.dust.input</code> \bt_comp reads a text file having this |
| 45 | fictitious format: |
| 46 | |
| 47 | @verbinclude dust |
| 48 | |
| 49 | That is: |
| 50 | |
| 51 | - Each line represents an event record. |
| 52 | - For a given line: |
| 53 | - The first token is the |
| 54 | <a href="https://en.wikipedia.org/wiki/Unix_time">Unix timestamp</a> |
| 55 | (seconds since the Unix epoch) of the record. |
| 56 | - The second token is a number of microseconds to add to the Unix |
| 57 | timestamp. |
| 58 | - The third token is the event record's name: only \c send-msg and |
| 59 | \c recv-msg are possible. |
| 60 | - The remaining characters form the event record's message (payload). |
| 61 | |
| 62 | A <code>source.dust.input</code> component accepts a single |
| 63 | \ref api-comp-cls-dev-meth-init "initialization parameter", |
| 64 | <code>path</code>, which is the path of the file to open and read. |
| 65 | |
| 66 | A <code>source.dust.input</code> component creates a single |
| 67 | \bt_oport named <code>out</code>. |
| 68 | |
| 69 | For each line of the input file, a <code>source.dust.input</code> |
| 70 | component's \bt_msg_iter emits an \bt_ev_msg. |
| 71 | |
| 72 | To simplify this example, a <code>source.dust.input</code> component is |
| 73 | not resilient and needs a valid input and valid initialization |
| 74 | parameters. The code also doesn't check the return status codes of API |
| 75 | functions for simplicity, but you must check them in production code. |
| 76 | |
| 77 | The source component class implementation and the shared object plugin |
| 78 | macros are in the same file, <code>dust.c</code>: |
| 79 | |
| 80 | @include dust.c |
| 81 | |
| 82 | As per the \ref guide-comp-link-plugin-so guide, you can build the |
| 83 | shared object plugin as such: |
| 84 | |
| 85 | @code{.unparsed} |
| 86 | $ cc dust.c -fPIC -c $(pkg-config --cflags babeltrace2) |
| 87 | $ ld dust.o -o dust.so -shared $(pkg-config --libs babeltrace2) |
| 88 | @endcode |
| 89 | |
| 90 | With the \bt_cli tool, assuming you have a valid input file named |
| 91 | <code>dust</code>, you can view the event messages that a |
| 92 | <code>source.dust.input</code> message iterator emits: |
| 93 | |
| 94 | @code{.unparsed} |
| 95 | $ babeltrace2 --plugin-path=. --component=source.dust.input --params='path="dust"' |
| 96 | @endcode |
| 97 | |
| 98 | The output is similar to: |
| 99 | |
| 100 | @code{.unparsed} |
| 101 | [17:10:37.154215000] (+?.?????????) send-msg: { msg = "Jowl pig filet mignon, turducken capicola." } |
| 102 | [17:10:37.200774000] (+0.046559000) recv-msg: { msg = "Pork belly pig burgdoggen venison bacon." } |
| 103 | [17:10:41.001831000] (+3.801057000) send-msg: { msg = "Bacon ipsum dolor amet strip steak." } |
| 104 | [17:10:41.944187000] (+0.942356000) send-msg: { msg = "Spare ribs filet mignon boudin bresaola." } |
| 105 | [17:10:45.115406000] (+3.171219000) recv-msg: { msg = "Rump cow t-bone hamburger short tenderloin." } |
| 106 | @endcode |
| 107 | |
| 108 | You can also view more details with |
| 109 | |
| 110 | @code{.unparsed} |
| 111 | $ babeltrace2 --plugin-path=. --component=source.dust.input --params='path="dust"' \ |
| 112 | --component=sink.text.details |
| 113 | @endcode |
| 114 | |
| 115 | @page example-simple-flt-cmp-cls Simple filter component class |
| 116 | |
| 117 | This example shows a basic \bt_flt_comp_cls packaged as a |
| 118 | \ref api-plugin-dev "shared object plugin". |
| 119 | |
| 120 | The name of the plugin is <code>distill</code> and the name of the |
| 121 | filter component class is <code>theone</code>. Therefore the |
| 122 | component class is identified in the \bt_cli |
| 123 | command-line tool as <code>filter.distill.theone</code>. |
| 124 | |
| 125 | A <code>filter.distill.theone</code> \bt_comp removes specific |
| 126 | \bt_p_ev_msg from a \bt_stream based on their \bt_ev_cls's name. |
| 127 | |
| 128 | A <code>filter.distill.theone</code> component accepts a single |
| 129 | \ref api-comp-cls-dev-meth-init "initialization parameter", |
| 130 | <code>names</code>, which is an \bt_array_val of string values. The |
| 131 | array value contains the names of the classes of the events to discard. |
| 132 | |
| 133 | A <code>filter.distill.theone</code> component creates a single |
| 134 | \bt_iport named <code>in</code> and a single \bt_oport named |
| 135 | <code>out</code>. |
| 136 | |
| 137 | To simplify this example, a <code>filter.distill.theone</code> component |
| 138 | is not resilient and needs a valid input and valid initialization |
| 139 | parameters. The code also doesn't check the return status codes of API |
| 140 | functions for simplicity, but you must check them in production code. |
| 141 | |
| 142 | The filter component class implementation and the shared object plugin |
| 143 | macros are in the same file, <code>distill.c</code>: |
| 144 | |
| 145 | @include distill.c |
| 146 | |
| 147 | As per the \ref guide-comp-link-plugin-so guide, you can build the |
| 148 | shared object plugin as such: |
| 149 | |
| 150 | @code{.unparsed} |
| 151 | $ cc distill.c -fPIC -c $(pkg-config --cflags babeltrace2) |
| 152 | $ ld distill.o -o distill.so -shared $(pkg-config --libs babeltrace2) |
| 153 | @endcode |
| 154 | |
| 155 | With the \bt_cli tool, you can use a |
| 156 | <code>filter.distill.theone</code> component, reading a |
| 157 | <a href="https://diamon.org/ctf/">CTF</a> trace |
| 158 | (see \bt_man{babeltrace2-source.ctf.fs,7}) for example: |
| 159 | |
| 160 | @code{.unparsed} |
| 161 | $ babeltrace2 --plugin-path=. /path/to/ctf/trace \ |
| 162 | --component=filter.distill.theone \ |
| 163 | --params='names=["sched_switch", "rcu_utilization", "kmem_kfree"]' |
| 164 | @endcode |
| 165 | |
| 166 | @page example-simple-sink-cmp-cls Simple sink component class |
| 167 | |
| 168 | This example shows a basic \bt_sink_comp_cls packaged as a |
| 169 | \ref api-plugin-dev "shared object plugin". |
| 170 | |
| 171 | The name of the plugin is <code>epitome</code> and the name of the |
| 172 | sink component class is <code>output</code>. Therefore the component |
| 173 | class is identified in the \bt_cli |
| 174 | command-line tool as <code>sink.epitome.output</code>. |
| 175 | |
| 176 | A <code>sink.epitome.output</code> \bt_comp prints one text line to |
| 177 | the standard output for each \bt_ev_msg it consumes, for |
| 178 | example: |
| 179 | |
| 180 | @code{.unparsed} |
| 181 | #1: kmem_kmalloc (5 payload members) |
| 182 | #2: kmem_kfree (2 payload members) |
| 183 | #3: sched_waking (4 payload members) |
| 184 | #4: sched_migrate_task (5 payload members) |
| 185 | #5: sched_stat_runtime (4 payload members) |
| 186 | #6: sched_wakeup (4 payload members) |
| 187 | #7: rcu_utilization (1 payload member) |
| 188 | #8: rcu_utilization (1 payload member) |
| 189 | #9: sched_switch (7 payload members) |
| 190 | #10: syscall_entry_write (3 payload members) |
| 191 | ... |
| 192 | @endcode |
| 193 | |
| 194 | For each line, there is: |
| 195 | |
| 196 | - The event message's index (simple counter). |
| 197 | - The event message's \bt_ev_cls \ref api-tir-ev-cls-prop-name "name". |
| 198 | - The number of members in the event message's \bt_ev's |
| 199 | \ref api-tir-ev-prop-payload "payload field". |
| 200 | |
| 201 | A <code>sink.epitome.output</code> component does not need any |
| 202 | \ref api-comp-cls-dev-meth-init "initialization parameter": it just |
| 203 | prints to the standard output. |
| 204 | |
| 205 | A <code>sink.epitome.output</code> component creates a single |
| 206 | \bt_iport named <code>in</code>. |
| 207 | |
| 208 | To simplify this example, a <code>sink.epitome.output</code> component |
| 209 | doesn't check the return status codes of API functions, |
| 210 | but you must check them in production code. |
| 211 | |
| 212 | The sink component class implementation and the shared object plugin |
| 213 | macros are in the same file, <code>epitome.c</code>: |
| 214 | |
| 215 | @include epitome.c |
| 216 | |
| 217 | As per the \ref guide-comp-link-plugin-so guide, you can build the |
| 218 | shared object plugin as such: |
| 219 | |
| 220 | @code{.unparsed} |
| 221 | $ cc epitome.c -fPIC -c $(pkg-config --cflags babeltrace2) |
| 222 | $ ld epitome.o -o epitome.so -shared $(pkg-config --libs babeltrace2) |
| 223 | @endcode |
| 224 | |
| 225 | With the \bt_cli tool, you can use a |
| 226 | <code>sink.epitome.output</code> component, reading a |
| 227 | <a href="https://diamon.org/ctf/">CTF</a> trace |
| 228 | (see \bt_man{babeltrace2-source.ctf.fs,7}) for example: |
| 229 | |
| 230 | @code{.unparsed} |
| 231 | $ babeltrace2 --plugin-path=. /path/to/ctf/trace --component=sink.epitome.output |
| 232 | @endcode |
| 233 | */ |