Commit | Line | Data |
---|---|---|
7704a0af PP |
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 | */ |