Babeltrace 2 C API  2.0.0
Open-source trace manipulation framework
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:

A sink.epitome.output component does not 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 uptream 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);

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
bt_self_component_sink_configuration
struct bt_self_component_sink_configuration bt_self_component_sink_configuration
Self sink component configuration.
Definition: types.h:97
bt_message_iterator_create_from_sink_component
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_value
struct bt_value bt_value
Value.
Definition: types.h:107
BT_PLUGIN_SINK_COMPONENT_CLASS_INITIALIZE_METHOD
#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:2332
bt_self_component_sink_borrow_input_port_by_index
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.
BT_PLUGIN_SINK_COMPONENT_CLASS_FINALIZE_METHOD
#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:2194
bt_self_component_set_data
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.
BT_MESSAGE_ITERATOR_NEXT_STATUS_AGAIN
Try again.
Definition: message-iterator.h:400
bt_self_component_get_data
void * bt_self_component_get_data(const bt_self_component *self_component)
Returns the user data of the component self_component.
bt_component_class_initialize_method_status
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:881
BT_PLUGIN_SINK_COMPONENT_CLASS
#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:904
bt_message_iterator
struct bt_message_iterator bt_message_iterator
Message iterator.
Definition: types.h:72
BT_PLUGIN_MODULE
#define BT_PLUGIN_MODULE()
Defines a plugin module.
Definition: plugin-dev.h:338
BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK
Success.
Definition: component-class-dev.h:833
bt_event_borrow_payload_field_const
const bt_field * bt_event_borrow_payload_field_const(const bt_event *event)
Borrows the payload field of the event event (const version).
BT_MESSAGE_TYPE_EVENT
Event message.
Definition: message.h:997
bt_message_array_const
const bt_message ** bt_message_array_const
Array of constant messages.
Definition: types.h:196
BT_MESSAGE_ITERATOR_NEXT_STATUS_MEMORY_ERROR
Out of memory.
Definition: message-iterator.h:406
bt_component_class_sink_graph_is_configured_method_status
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:828
bt_message_iterator_next
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_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_AGAIN
Try again.
Definition: component-class-dev.h:520
bt_message_iterator_put_ref
void bt_message_iterator_put_ref(const bt_message_iterator *message_iterator)
Decrements the reference count of the message iterator message_iterator.
bt_event_class_get_name
const char * bt_event_class_get_name(const bt_event_class *event_class)
Returns the name of the event class event_class.
bt_event_borrow_class_const
const bt_event_class * bt_event_borrow_class_const(const bt_event *event)
Borrows the class of the event event (const version).
bt_self_component_sink
struct bt_self_component_sink bt_self_component_sink
Self sink component.
Definition: types.h:96
bt_event
struct bt_event bt_event
Event.
Definition: types.h:50
bt_message_event_borrow_event_const
const bt_event * bt_message_event_borrow_event_const(const bt_message *message)
Borrows the event of the event message message (const version).
bt_self_component_sink_add_input_port
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...
bt_component_class_sink_consume_method_status
bt_component_class_sink_consume_method_status
Status codes for bt_component_class_sink_consume_method.
Definition: component-class-dev.h:503
bt_field
struct bt_field bt_field
Field.
Definition: types.h:53
BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK
Success.
Definition: component-class-dev.h:886
bt_event_class
struct bt_event_class bt_event_class
Event class.
Definition: types.h:51
bt_message_iterator_next_status
bt_message_iterator_next_status
Status code for bt_message_iterator_next().
Definition: message-iterator.h:383
BT_MESSAGE_ITERATOR_NEXT_STATUS_ERROR
Other error.
Definition: message-iterator.h:412
bt_field_class_structure_get_member_count
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.
BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_END
Sink component is finished processing.
Definition: component-class-dev.h:514
bt_message_put_ref
void bt_message_put_ref(const bt_message *message)
Decrements the reference count of the message message.
BT_MESSAGE_ITERATOR_NEXT_STATUS_END
End of iteration.
Definition: message-iterator.h:394
BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK
Success.
Definition: component-class-dev.h:508
BT_PLUGIN
#define BT_PLUGIN(_name)
Alias of BT_PLUGIN_WITH_ID() with the _id parameter set to auto.
Definition: plugin-dev.h:426
bt_field_borrow_class_const
const bt_field_class * bt_field_borrow_class_const(const bt_field *field)
Borrows the class of the field field (const version).
bt_message_get_type
bt_message_type bt_message_get_type(const bt_message *message)
Returns the type enumerator of the message message.
BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_MEMORY_ERROR
Out of memory.
Definition: component-class-dev.h:526
bt_self_component_port_input
struct bt_self_component_port_input bt_self_component_port_input
Self component input port.
Definition: types.h:93
bt_message
struct bt_message bt_message
Message.
Definition: types.h:71
BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR
User error.
Definition: component-class-dev.h:532
BT_PLUGIN_SINK_COMPONENT_CLASS_GRAPH_IS_CONFIGURED_METHOD
#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:2287
bt_self_component_sink_as_self_component
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:869