Babeltrace 2 C API 2.1.0
Open-source trace manipulation framework
Loading...
Searching...
No Matches
Simple sink component class

This example shows a basic sink component class packaged as a shared object plugin.

The name of the plugin is epitome and the name of the sink component class is output. Therefore the component class is identified in the babeltrace2 command-line tool as sink.epitome.output.

A sink.epitome.output component prints one text line to the standard output for each event message it consumes, for example:

#1: kmem_kmalloc (5 payload members)
#2: kmem_kfree (2 payload members)
#3: sched_waking (4 payload members)
#4: sched_migrate_task (5 payload members)
#5: sched_stat_runtime (4 payload members)
#6: sched_wakeup (4 payload members)
#7: rcu_utilization (1 payload member)
#8: rcu_utilization (1 payload member)
#9: sched_switch (7 payload members)
#10: syscall_entry_write (3 payload members)
...

For each line, there is:

  • The index of the event message (simple counter).
  • The event class name of the event message.
  • The number of members in the payload field of the event of the event message.

A sink.epitome.output component doesn't need any initialization parameter: it just prints to the standard output.

A sink.epitome.output component creates a single input port named in.

To simplify this example, a sink.epitome.output component doesn't check the return status codes of API functions, but you must check them in production code.

The sink component class implementation and the shared object plugin macros are in the same file, epitome.c:

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <string.h>
#include <babeltrace2/babeltrace.h>
/* Sink component's private data */
struct epitome_out {
/* Upstream message iterator (owned by this) */
bt_message_iterator *message_iterator;
/* Current event message index */
uint64_t index;
};
/*
* Initializes the sink component.
*/
static
bt_self_component_sink *self_component_sink,
const bt_value *params, void *initialize_method_data)
{
/* Allocate a private data structure */
struct epitome_out *epitome_out = malloc(sizeof(*epitome_out));
/* Initialize the first event message's index */
epitome_out->index = 1;
/* Set the component's user data to our private data structure */
epitome_out);
/*
* Add an input port named `in` to the sink component.
*
* This is needed so that this sink component can be connected to a
* filter or a source component. With a connected upstream
* component, this sink component can create a message iterator
* to consume messages.
*/
"in", NULL, NULL);
}
/*
* Finalizes the sink component.
*/
static
void epitome_out_finalize(bt_self_component_sink *self_component_sink)
{
/* Retrieve our private data from the component's user data */
struct epitome_out *epitome_out = bt_self_component_get_data(
/* Free the allocated structure */
free(epitome_out);
}
/*
* Called when the trace processing graph containing the sink component
* is configured.
*
* This is where we can create our upstream message iterator.
*/
static
epitome_out_graph_is_configured(bt_self_component_sink *self_component_sink)
{
/* Retrieve our private data from the component's user data */
struct epitome_out *epitome_out = bt_self_component_get_data(
/* Borrow our unique port */
self_component_sink, 0);
/* Create the upstream message iterator */
in_port, &epitome_out->message_iterator);
}
/*
* Prints a line for `message`, if it's an event message, to the
* standard output.
*/
static
void print_message(struct epitome_out *epitome_out, const bt_message *message)
{
/* Discard if it's not an event message */
goto end;
}
/* Borrow the event message's event and its class */
const bt_event *event =
const bt_event_class *event_class = bt_event_borrow_class_const(event);
/* Get the number of payload field members */
const bt_field *payload_field =
bt_field_borrow_class_const(payload_field));
/* Write a corresponding line to the standard output */
printf("#%" PRIu64 ": %s (%" PRIu64 " payload member%s)\n",
epitome_out->index, bt_event_class_get_name(event_class),
member_count, member_count == 1 ? "" : "s");
/* Increment the current event message's index */
epitome_out->index++;
end:
return;
}
/*
* Consumes a batch of messages and writes the corresponding lines to
* the standard output.
*/
bt_self_component_sink *self_component_sink)
{
/* Retrieve our private data from the component's user data */
struct epitome_out *epitome_out = bt_self_component_get_data(
/* Consume a batch of messages from the upstream message iterator */
uint64_t message_count;
bt_message_iterator_next(epitome_out->message_iterator, &messages,
&message_count);
switch (next_status) {
/* End of iteration: put the message iterator's reference */
bt_message_iterator_put_ref(epitome_out->message_iterator);
goto end;
goto end;
goto end;
goto end;
default:
break;
}
/* For each consumed message */
for (uint64_t i = 0; i < message_count; i++) {
/* Current message */
const bt_message *message = messages[i];
/* Print line for current message if it's an event message */
print_message(epitome_out, message);
/* Put this message's reference */
}
end:
return status;
}
/* Mandatory */
/* Define the `epitome` plugin */
BT_PLUGIN(epitome);
/* Define the `output` sink component class */
BT_PLUGIN_SINK_COMPONENT_CLASS(output, epitome_out_consume);
/* Set some of the `output` sink component class's optional methods */
epitome_out_initialize);
BT_PLUGIN_SINK_COMPONENT_CLASS_FINALIZE_METHOD(output, epitome_out_finalize);
epitome_out_graph_is_configured);
bt_message const ** bt_message_array_const
Array of constant messages.
Definition types.h:182
bt_component_class_sink_consume_method_status
Status codes for bt_component_class_sink_consume_method.
Definition component-class-dev.h:511
bt_component_class_sink_graph_is_configured_method_status
Status codes for bt_component_class_sink_graph_is_configured_method.
Definition component-class-dev.h:838
bt_component_class_initialize_method_status
Status codes for bt_component_class_source_initialize_method, bt_component_class_filter_initialize_me...
Definition component-class-dev.h:891
@ BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR
User error.
Definition component-class-dev.h:540
@ BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_END
Sink component is finished processing.
Definition component-class-dev.h:522
@ BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_AGAIN
Try again.
Definition component-class-dev.h:528
@ BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_MEMORY_ERROR
Out of memory.
Definition component-class-dev.h:534
@ BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK
Success.
Definition component-class-dev.h:516
@ BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK
Success.
Definition component-class-dev.h:843
@ BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK
Success.
Definition component-class-dev.h:896
void bt_message_iterator_put_ref(const bt_message_iterator *message_iterator)
Decrements the reference count of the message iterator message_iterator.
bt_message_iterator_next_status bt_message_iterator_next(bt_message_iterator *message_iterator, bt_message_array_const *messages, uint64_t *count)
Returns the next messages of the message iterator message_iterator into the *messages array of size *...
bt_message_iterator_next_status
Status code for bt_message_iterator_next().
Definition message-iterator.h:371
struct bt_message_iterator bt_message_iterator
Message iterator.
Definition types.h:59
bt_message_iterator_create_from_sink_component_status bt_message_iterator_create_from_sink_component(bt_self_component_sink *self_component_sink, bt_self_component_port_input *port, bt_message_iterator **message_iterator)
Creates a message iterator on the input port port from the sink component self_component_sink,...
@ BT_MESSAGE_ITERATOR_NEXT_STATUS_END
End of iteration.
Definition message-iterator.h:382
@ BT_MESSAGE_ITERATOR_NEXT_STATUS_MEMORY_ERROR
Out of memory.
Definition message-iterator.h:394
@ BT_MESSAGE_ITERATOR_NEXT_STATUS_ERROR
Other error.
Definition message-iterator.h:400
@ BT_MESSAGE_ITERATOR_NEXT_STATUS_AGAIN
Try again.
Definition message-iterator.h:388
struct bt_message bt_message
Message.
Definition types.h:58
const bt_event * bt_message_event_borrow_event_const(const bt_message *message)
Borrows the event of the event message message (const version).
bt_message_type bt_message_get_type(const bt_message *message)
Returns the type enumerator of the message message.
void bt_message_put_ref(const bt_message *message)
Decrements the reference count of the message message.
@ BT_MESSAGE_TYPE_EVENT
Event message.
Definition message.h:993
#define BT_PLUGIN_MODULE()
Defines a plugin module.
Definition plugin-dev.h:335
#define BT_PLUGIN_SINK_COMPONENT_CLASS(_name, _consume_method)
Alias of BT_PLUGIN_SINK_COMPONENT_CLASS_WITH_ID() with the _plugin_id parameter set to auto,...
Definition plugin-dev.h:905
#define BT_PLUGIN(_name)
Alias of BT_PLUGIN_WITH_ID() with the _id parameter set to auto.
Definition plugin-dev.h:423
#define BT_PLUGIN_SINK_COMPONENT_CLASS_INITIALIZE_METHOD(_name, _method)
Alias of BT_PLUGIN_SINK_COMPONENT_CLASS_INITIALIZE_METHOD_WITH_ID() with the _plugin_id parameter set...
Definition plugin-dev.h:2335
#define BT_PLUGIN_SINK_COMPONENT_CLASS_FINALIZE_METHOD(_name, _method)
Alias of BT_PLUGIN_SINK_COMPONENT_CLASS_FINALIZE_METHOD_WITH_ID() with the _plugin_id parameter set t...
Definition plugin-dev.h:2197
#define BT_PLUGIN_SINK_COMPONENT_CLASS_GRAPH_IS_CONFIGURED_METHOD(_name, _method)
Alias of BT_PLUGIN_SINK_COMPONENT_CLASS_GRAPH_IS_CONFIGURED_METHOD_WITH_ID() with the _plugin_id para...
Definition plugin-dev.h:2290
struct bt_self_component_port_input bt_self_component_port_input
Self component input port.
Definition types.h:79
bt_self_component_add_port_status bt_self_component_sink_add_input_port(bt_self_component_sink *self_component, const char *name, void *user_data, bt_self_component_port_input **self_component_port)
Adds an input port named name and having the user data user_data to the sink component self_component...
struct bt_self_component_sink_configuration bt_self_component_sink_configuration
Self sink component configuration.
Definition types.h:83
static bt_self_component * bt_self_component_sink_as_self_component(bt_self_component_sink *self_component)
Upcasts the self sink component self_component to the common bt_self_component type.
Definition self-component.h:857
void * bt_self_component_get_data(const bt_self_component *self_component)
Returns the user data of the component self_component.
bt_self_component_port_input * bt_self_component_sink_borrow_input_port_by_index(bt_self_component_sink *self_component, uint64_t index)
Borrows the self component input port at index index from the sink component self_component.
void bt_self_component_set_data(bt_self_component *self_component, void *user_data)
Sets the user data of the component self_component to data.
struct bt_self_component_sink bt_self_component_sink
Self sink component.
Definition types.h:82
const char * bt_event_class_get_name(const bt_event_class *event_class)
Returns the name of the event class event_class.
struct bt_event_class bt_event_class
Event class.
Definition types.h:37
const bt_event_class * bt_event_borrow_class_const(const bt_event *event)
Borrows the class of the event event (const version).
const bt_field * bt_event_borrow_payload_field_const(const bt_event *event)
Borrows the payload field of the event event (const version).
struct bt_event bt_event
Event.
Definition types.h:36
uint64_t bt_field_class_structure_get_member_count(const bt_field_class *field_class)
Returns the number of members contained in the structure field class field_class.
const bt_field_class * bt_field_borrow_class_const(const bt_field *field)
Borrows the class of the field field (const version).
struct bt_field bt_field
Field.
Definition types.h:38
struct bt_value bt_value
Value.
Definition types.h:93

As per the Compile and link a Babeltrace 2 shared object plugin guide, you can build the shared object plugin as such:

$ cc epitome.c -fPIC -c $(pkg-config --cflags babeltrace2)
$ ld epitome.o -o epitome.so -shared $(pkg-config --libs babeltrace2)

With the babeltrace2 tool, you can use a sink.epitome.output component, reading a CTF trace (see babeltrace2-source.ctf.fs(7)) for example:

$ babeltrace2 --plugin-path=. /path/to/ctf/trace --component=sink.epitome.output