Commit 462f4353 authored by Thomas Applencourt's avatar Thomas Applencourt
Browse files

Add timeline

parent 46ca2835
......@@ -20,6 +20,30 @@ void *init_clinterval_callbacks_state() {
| | (/_ _> _> (_| (_| (/_ \_ | (/_ (_| |_ | (_) | |
_|
%>
/*
Utils function
*/
static
const hostname_t borrow_hostname(const bt_event *event){
const bt_stream *stream = bt_event_borrow_stream_const(event);
const bt_trace *trace = bt_stream_borrow_trace_const(stream);
const bt_value *host_name_str = bt_trace_borrow_environment_entry_value_by_name_const(trace, "hostname");
return bt_value_string_get(host_name_str);
}
static
process_id_t borrow_process_id(const bt_event *event){
const bt_field *common_context_field = bt_event_borrow_common_context_field_const(event);
const bt_field *field = bt_field_structure_borrow_member_field_by_index_const(common_context_field, 0);
return bt_field_integer_signed_get_value(field);
}
static
thread_id_t borrow_thread_id(const bt_event *event){
const bt_field *common_context_field = bt_event_borrow_common_context_field_const(event);
const bt_field *field = bt_field_structure_borrow_member_field_by_index_const(common_context_field, 1);
return bt_field_integer_unsigned_get_value(field);
}
static void create_and_enqueue_host_message(const char* hostname, const process_id_t process_id, const thread_id_t thread_id, const char* name,
const uint64_t ts, const uint64_t duration, const bool err) {
......
......@@ -76,25 +76,3 @@ namespace std{
};
}
/*
Utils function
*/
const hostname_t borrow_hostname(const bt_event *event){
const bt_stream *stream = bt_event_borrow_stream_const(event);
const bt_trace *trace = bt_stream_borrow_trace_const(stream);
const bt_value *host_name_str = bt_trace_borrow_environment_entry_value_by_name_const(trace, "hostname");
return bt_value_string_get(host_name_str);
}
process_id_t borrow_process_id(const bt_event *event){
const bt_field *common_context_field = bt_event_borrow_common_context_field_const(event);
const bt_field *field = bt_field_structure_borrow_member_field_by_index_const(common_context_field, 0);
return bt_field_integer_signed_get_value(field);
}
thread_id_t borrow_thread_id(const bt_event *event){
const bt_field *common_context_field = bt_event_borrow_common_context_field_const(event);
const bt_field *field = bt_field_structure_borrow_member_field_by_index_const(common_context_field, 1);
return bt_field_integer_unsigned_get_value(field);
}
......@@ -25,9 +25,12 @@ nodist_libXProf_la_SOURCES = \
# File to compiled
libXProf_la_SOURCES = \
xprof.c \
tally_callbacks_state.h \
tally_state.h \
tally.h \
tally.cpp
tally.cpp \
timeline_state.h \
timeline.h \
timeline.cpp
# Compiler flags
libXProf_la_CPPFLAGS = -I$(top_srcdir)/utils -I$(srcdir)/include -I./
......
#include "tally.h"
#include "xprof_utils.h" //Typedef and hashtuple
#include "tally_utils.h"
#include "tally_callbacks_state.h"
#include "tally_state.h"
#include <stdlib.h> // calloc
#include <stdio.h> // printf
#include <string.h> // strcmp
bt_component_class_sink_consume_method_status tally_dispatch_consume(
bt_self_component_sink *self_component_sink)
......
#include "timeline.h"
#include "timeline_state.h"
#include "xprof_utils.h" // typedef
#include <iomanip> // set precision
#include <iostream> // stdcout
#include <stdio.h> // printf
#include <string.h> // strcmp
bt_component_class_sink_consume_method_status timeline_dispatch_consume(
bt_self_component_sink *self_component_sink)
{
bt_component_class_sink_consume_method_status status =
BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK;
/* Retrieve our private data from the component's user data */
struct timeline_dispatch *dispatch = (timeline_dispatch*) bt_self_component_get_data(
bt_self_component_sink_as_self_component(self_component_sink));
/* Consume a batch of messages from the upstream message iterator */
bt_message_array_const messages;
uint64_t message_count;
bt_message_iterator_next_status next_status =
bt_message_iterator_next(dispatch->message_iterator, &messages,
&message_count);
switch (next_status) {
case BT_MESSAGE_ITERATOR_NEXT_STATUS_END:
/* End of iteration: put the message iterator's reference */
bt_message_iterator_put_ref(dispatch->message_iterator);
status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_END;
goto end;
case BT_MESSAGE_ITERATOR_NEXT_STATUS_AGAIN:
status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_AGAIN;
goto end;
case BT_MESSAGE_ITERATOR_NEXT_STATUS_MEMORY_ERROR:
status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_MEMORY_ERROR;
goto end;
case BT_MESSAGE_ITERATOR_NEXT_STATUS_ERROR:
status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
goto end;
default:
break;
}
/* For each consumed message */
for (uint64_t i = 0; i < message_count; i++) {
const bt_message *message = messages[i];
if (bt_message_get_type(message) == BT_MESSAGE_TYPE_EVENT) {
const bt_event *event = bt_message_event_borrow_event_const(message);
//const bt_event_class *event_class = bt_event_borrow_class_const(event);
//const char * class_name = bt_event_class_get_name(event_class);
//Common context field
const bt_field *common_context_field = bt_event_borrow_common_context_field_const(event);
const bt_field *hostname_field = bt_field_structure_borrow_member_field_by_index_const(common_context_field, 0);
const hostname_t hostname = std::string{bt_field_string_get_value(hostname_field)};
const bt_field *process_id_field = bt_field_structure_borrow_member_field_by_index_const(common_context_field, 1);
const process_id_t process_id = bt_field_integer_signed_get_value(process_id_field);
const bt_field *thread_id_field = bt_field_structure_borrow_member_field_by_index_const(common_context_field, 2);
const thread_id_t thread_id = bt_field_integer_unsigned_get_value(thread_id_field);
const bt_field *ts_field = bt_field_structure_borrow_member_field_by_index_const(common_context_field, 3);
const long ts = bt_field_integer_unsigned_get_value(ts_field);
//Payload
const bt_field *payload_field = bt_event_borrow_payload_field_const(event);
const bt_field *name_field = bt_field_structure_borrow_member_field_by_index_const(payload_field, 0);
const std::string name = std::string{bt_field_string_get_value(name_field)};
const bt_field *dur_field = bt_field_structure_borrow_member_field_by_index_const(payload_field, 1);
const long dur = bt_field_integer_unsigned_get_value(dur_field);
std::cout << "{\"pid\": " << process_id
<< ",\"tid\":" << thread_id
<< std::fixed << std::setprecision(2) << ",\"ts\":" << ts*1.E-3
<< ",\"dur\":" << dur*1.E-3
<< ",\"name\":" << "\"" << name << "\""
<< ",\"ph\":\"X\""
<< "}," << std::endl;
}
bt_message_put_ref(message);
}
end:
return status;
}
/*
* Initializes the sink component.
*/
bt_component_class_initialize_method_status timeline_dispatch_initialize(
bt_self_component_sink *self_component_sink,
bt_self_component_sink_configuration *configuration,
const bt_value *params, void *initialize_method_data)
{
/* Allocate a private data structure */
struct timeline_dispatch *dispatch = new timeline_dispatch;
/* Set the component's user data to our private data structure */
bt_self_component_set_data(
bt_self_component_sink_as_self_component(self_component_sink),
dispatch);
/*
* 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.
*/
bt_self_component_sink_add_input_port(self_component_sink,
"in", NULL, NULL);
/* Print the begining of the json */
std::cout << "{\"traceEvents\":[" << std::endl;
return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK;
}
/*
* Finalizes the sink component.
*/
void timeline_dispatch_finalize(bt_self_component_sink *self_component_sink)
{
// JSTON is stupornd, it doesn't allow trailling comma.
// To avoid creating yet anothing state, we will create a dummy/empty object at the end.
// This only work because chrome::tracing doesn't parse such event.
std::cout << "{}]}" << std::endl;
}
/*
* Called when the trace processing graph containing the sink component
* is configured.
*
* This is where we can create our upstream message iterator.
*/
bt_component_class_sink_graph_is_configured_method_status
timeline_dispatch_graph_is_configured(bt_self_component_sink *self_component_sink)
{
/* Retrieve our private data from the component's user data */
struct timeline_dispatch *dispatch = (timeline_dispatch*) bt_self_component_get_data(
bt_self_component_sink_as_self_component(self_component_sink));
/* Borrow our unique port */
bt_self_component_port_input *in_port =
bt_self_component_sink_borrow_input_port_by_index(
self_component_sink, 0);
/* Create the uptream message iterator */
bt_message_iterator_create_from_sink_component(self_component_sink,
in_port, &dispatch->message_iterator);
return BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK;
}
#pragma once
#include <babeltrace2/babeltrace.h>
#ifdef __cplusplus
extern "C" {
#endif
bt_component_class_sink_consume_method_status timeline_dispatch_consume(
bt_self_component_sink *self_component_sink);
bt_component_class_initialize_method_status timeline_dispatch_initialize(
bt_self_component_sink *self_component_sink,
bt_self_component_sink_configuration *configuration,
const bt_value *params, void *initialize_method_data);
void timeline_dispatch_finalize(bt_self_component_sink *self_component_sink);
bt_component_class_sink_graph_is_configured_method_status
timeline_dispatch_graph_is_configured(bt_self_component_sink *self_component_sink);
#ifdef __cplusplus
}
#endif
#pragma once
/* Sink component's private data */
struct timeline_dispatch {
bt_message_iterator *message_iterator;
};
#include <babeltrace2/babeltrace.h>
#include "tally.h"
#include "timeline.h"
/* Mandatory */
BT_PLUGIN_MODULE();
/* Define the `clprof` plugin */
/* Define the `xprof` plugin */
BT_PLUGIN(xprof);
//~ ~ ~
......@@ -17,3 +17,13 @@ BT_PLUGIN_SINK_COMPONENT_CLASS_INITIALIZE_METHOD(tally, tally_dispatch_initializ
BT_PLUGIN_SINK_COMPONENT_CLASS_FINALIZE_METHOD(tally, tally_dispatch_finalize);
BT_PLUGIN_SINK_COMPONENT_CLASS_GRAPH_IS_CONFIGURED_METHOD(tally, tally_dispatch_graph_is_configured);
//~ ~ ~
// Sink Timeline
//~ ~ ~
BT_PLUGIN_SINK_COMPONENT_CLASS(timeline, timeline_dispatch_consume);
BT_PLUGIN_SINK_COMPONENT_CLASS_INITIALIZE_METHOD(timeline, timeline_dispatch_initialize);
BT_PLUGIN_SINK_COMPONENT_CLASS_FINALIZE_METHOD(timeline, timeline_dispatch_finalize);
BT_PLUGIN_SINK_COMPONENT_CLASS_GRAPH_IS_CONFIGURED_METHOD(timeline, timeline_dispatch_graph_is_configured);
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment