X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=plugins%2Ftext%2Fprint.c;h=b227e399d219fa9510c16cd558822f995d95d05c;hb=f504043cde2c53406808a400a5e5e7d84cba3c04;hp=472c29c81a4fc8d9fbfaf10c8b50fe2790967e3f;hpb=2cbb04c0187b488719252f570d711804175c4117;p=babeltrace.git diff --git a/plugins/text/print.c b/plugins/text/print.c index 472c29c8..b227e399 100644 --- a/plugins/text/print.c +++ b/plugins/text/print.c @@ -4,6 +4,7 @@ * Babeltrace CTF Text Output Plugin Event Printing * * Copyright 2016 Jérémie Galarneau + * Copyright 2016 Mathieu Desnoyers * * Author: Jérémie Galarneau * @@ -34,10 +35,13 @@ #include #include #include +#include #include #include #include "text.h" +#define NSEC_PER_SEC 1000000000LL + static inline const char *rem_(const char *str) { @@ -61,7 +65,23 @@ void print_timestamp_cycles(struct text_component *text, struct bt_ctf_clock *clock, struct bt_ctf_event *event) { - fputs("00000000000000000000", text->out); + int ret; + struct bt_ctf_clock_value *clock_value; + uint64_t cycles; + + clock_value = bt_ctf_event_get_clock_value(event, clock); + if (!clock_value) { + fputs("????????????????????", text->out); + return; + } + + ret = bt_ctf_clock_value_get_value(clock_value, &cycles); + bt_put(clock_value); + if (ret) { + fprintf(text->out, "Error"); + return; + } + fprintf(text->out, "%020" PRIu64, cycles); } static @@ -69,26 +89,114 @@ void print_timestamp_wall(struct text_component *text, struct bt_ctf_clock *clock, struct bt_ctf_event *event) { - fputs("??:??:??.?????????", text->out); -} + int ret; + struct bt_ctf_clock_value *clock_value; + int64_t ts_nsec = 0; /* add configurable offset */ + int64_t ts_sec = 0; /* add configurable offset */ + uint64_t ts_sec_abs, ts_nsec_abs; + bool is_negative; + + clock_value = bt_ctf_event_get_clock_value(event, clock); + if (!clock_value) { + fputs("??:??:??.?????????", text->out); + return; + } + + ret = bt_ctf_clock_value_get_value_ns_from_epoch(clock_value, &ts_nsec); + bt_put(clock_value); + if (ret) { + fprintf(text->out, "Error"); + return; + } + + ts_sec += ts_nsec / NSEC_PER_SEC; + ts_nsec = ts_nsec % NSEC_PER_SEC; + if (ts_sec >= 0 && ts_nsec >= 0) { + is_negative = false; + ts_sec_abs = ts_sec; + ts_nsec_abs = ts_nsec; + } else if (ts_sec > 0 && ts_nsec < 0) { + is_negative = false; + ts_sec_abs = ts_sec - 1; + ts_nsec_abs = NSEC_PER_SEC + ts_nsec; + } else if (ts_sec == 0 && ts_nsec < 0) { + is_negative = true; + ts_sec_abs = ts_sec; + ts_nsec_abs = -ts_nsec; + } else if (ts_sec < 0 && ts_nsec > 0) { + is_negative = true; + ts_sec_abs = -(ts_sec + 1); + ts_nsec_abs = NSEC_PER_SEC - ts_nsec; + } else if (ts_sec < 0 && ts_nsec == 0) { + is_negative = true; + ts_sec_abs = -ts_sec; + ts_nsec_abs = ts_nsec; + } else { /* (ts_sec < 0 && ts_nsec < 0) */ + is_negative = true; + ts_sec_abs = -ts_sec; + ts_nsec_abs = -ts_nsec; + } + + if (!text->options.clock_seconds) { + struct tm tm; + time_t time_s = (time_t) ts_sec_abs; + + if (is_negative) { + fprintf(stderr, "[warning] Fallback to [sec.ns] to print negative time value. Use --clock-seconds.\n"); + goto seconds; + } -static -enum bt_component_status get_event_timestamp(struct bt_ctf_event *event) -{ -/* int ret; - uint64_t value, frequency; - int64_t offset_s, offset; -*/ - return BT_COMPONENT_STATUS_OK; + if (!text->options.clock_gmt) { + struct tm *res; + + res = localtime_r(&time_s, &tm); + if (!res) { + fprintf(stderr, "[warning] Unable to get localtime.\n"); + goto seconds; + } + } else { + struct tm *res; + + res = gmtime_r(&time_s, &tm); + if (!res) { + fprintf(stderr, "[warning] Unable to get gmtime.\n"); + goto seconds; + } + } + if (text->options.clock_date) { + char timestr[26]; + size_t res; + + /* Print date and time */ + res = strftime(timestr, sizeof(timestr), + "%F ", &tm); + if (!res) { + fprintf(stderr, "[warning] Unable to print ascii time.\n"); + goto seconds; + } + fprintf(text->out, "%s", timestr); + } + /* Print time in HH:MM:SS.ns */ + fprintf(text->out, "%02d:%02d:%02d.%09" PRIu64, + tm.tm_hour, tm.tm_min, tm.tm_sec, ts_nsec_abs); + goto end; + } +seconds: + fprintf(text->out, "%s%" PRId64 ".%09" PRIu64, + is_negative ? "-" : "", ts_sec_abs, ts_nsec_abs); +end: + return; } static enum bt_component_status print_event_timestamp(struct text_component *text, - struct bt_ctf_event *event) + struct bt_ctf_event *event, bool *start_line) { bool print_names = text->options.print_header_field_names; enum bt_component_status ret = BT_COMPONENT_STATUS_OK; struct bt_ctf_stream *stream = NULL; + struct bt_ctf_stream_class *stream_class = NULL; + struct bt_ctf_trace *trace = NULL; struct bt_ctf_clock *clock = NULL; FILE *out = text->out; FILE *err = text->err; @@ -100,11 +208,20 @@ enum bt_component_status print_event_timestamp(struct text_component *text, goto end; } - clock = bt_ctf_event_get_clock(event); + stream_class = bt_ctf_stream_get_class(stream); + if (!stream_class) { + ret = BT_COMPONENT_STATUS_ERROR; + goto end; + } + trace = bt_ctf_stream_class_get_trace(stream_class); + if (!trace) { + ret = BT_COMPONENT_STATUS_ERROR; + goto end; + } + clock = bt_ctf_trace_get_clock(trace, 0); if (!clock) { - /* Stream has no timestamp. */ - //puts("no_timestamp!"); - //goto end; + ret = BT_COMPONENT_STATUS_ERROR; + goto end; } fputs(print_names ? "timestamp = " : "[", out); @@ -114,13 +231,21 @@ enum bt_component_status print_event_timestamp(struct text_component *text, print_timestamp_wall(text, clock, event); } - fputs(print_names ? ", " : "] ", out); + if (!print_names) + fputs("] ", out); + *start_line = !print_names; + if (!text->options.print_delta_field) { goto end; } + + //TODO delta + end: bt_put(stream); bt_put(clock); + bt_put(stream_class); + bt_put(trace); return ret; } @@ -131,25 +256,209 @@ enum bt_component_status print_event_header(struct text_component *text, bool print_names = text->options.print_header_field_names; enum bt_component_status ret = BT_COMPONENT_STATUS_OK; struct bt_ctf_event_class *event_class = NULL; + struct bt_ctf_stream_class *stream_class = NULL; + struct bt_ctf_trace *trace_class = NULL; event_class = bt_ctf_event_get_class(event); if (!event_class) { ret = BT_COMPONENT_STATUS_ERROR; goto end; } + stream_class = bt_ctf_event_class_get_stream_class(event_class); + if (!stream_class) { + ret = BT_COMPONENT_STATUS_ERROR; + goto end; + } + trace_class = bt_ctf_stream_class_get_trace(stream_class); + if (!trace_class) { + ret = BT_COMPONENT_STATUS_ERROR; + goto end; + } if (!text->start_line) { fputs(", ", text->out); } text->start_line = false; - ret = print_event_timestamp(text, event); + ret = print_event_timestamp(text, event, &text->start_line); if (ret != BT_COMPONENT_STATUS_OK) { goto end; } + if (text->options.print_trace_field) { + const char *name; + + name = bt_ctf_trace_get_name(trace_class); + if (name) { + if (!text->start_line) { + fputs(", ", text->out); + } + text->start_line = false; + if (print_names) { + fputs("trace = ", text->out); + } + fprintf(text->out, "%s", name); + } + } + if (text->options.print_trace_hostname_field) { + struct bt_value *hostname_str; + + hostname_str = bt_ctf_trace_get_environment_field_value_by_name(trace_class, + "hostname"); + if (hostname_str) { + const char *str; + + if (!text->start_line) { + fputs(", ", text->out); + } + text->start_line = false; + if (print_names) { + fputs("trace:hostname = ", text->out); + } + if (bt_value_string_get(hostname_str, &str) + == BT_VALUE_STATUS_OK) { + fprintf(text->out, "%s", str); + } + bt_put(hostname_str); + } + } + if (text->options.print_trace_domain_field) { + struct bt_value *domain_str; + + domain_str = bt_ctf_trace_get_environment_field_value_by_name(trace_class, + "domain"); + if (domain_str) { + const char *str; + + if (!text->start_line) { + fputs(", ", text->out); + } + text->start_line = false; + if (print_names) { + fputs("trace:domain = ", text->out); + } + if (bt_value_string_get(domain_str, &str) + == BT_VALUE_STATUS_OK) { + fprintf(text->out, "%s", str); + } + bt_put(domain_str); + } + } + if (text->options.print_trace_procname_field) { + struct bt_value *procname_str; + + procname_str = bt_ctf_trace_get_environment_field_value_by_name(trace_class, + "procname"); + if (procname_str) { + const char *str; + + if (!text->start_line) { + fputs(", ", text->out); + } + text->start_line = false; + if (print_names) { + fputs("trace:procname = ", text->out); + } + if (bt_value_string_get(procname_str, &str) + == BT_VALUE_STATUS_OK) { + fprintf(text->out, "%s", str); + } + bt_put(procname_str); + } + } + if (text->options.print_trace_vpid_field) { + struct bt_value *vpid_value; + + vpid_value = bt_ctf_trace_get_environment_field_value_by_name(trace_class, + "vpid"); + if (vpid_value) { + int64_t value; + + if (!text->start_line) { + fputs(", ", text->out); + } + text->start_line = false; + if (print_names) { + fputs("trace:vpid = ", text->out); + } + if (bt_value_integer_get(vpid_value, &value) + == BT_VALUE_STATUS_OK) { + fprintf(text->out, "(%" PRId64 ")", value); + } + bt_put(vpid_value); + } + } + if (text->options.print_loglevel_field) { + struct bt_value *loglevel_str, *loglevel_value; + + loglevel_str = bt_ctf_event_class_get_attribute_value_by_name(event_class, + "loglevel_string"); + loglevel_value = bt_ctf_event_class_get_attribute_value_by_name(event_class, + "loglevel"); + if (loglevel_str || loglevel_value) { + bool has_str = false; + + if (!text->start_line) { + fputs(", ", text->out); + } + text->start_line = false; + if (print_names) { + fputs("loglevel = ", text->out); + } + if (loglevel_str) { + const char *str; + + if (bt_value_string_get(loglevel_str, &str) + == BT_VALUE_STATUS_OK) { + fprintf(text->out, "%s", str); + has_str = true; + } + } + if (loglevel_value) { + int64_t value; + + if (bt_value_integer_get(loglevel_value, &value) + == BT_VALUE_STATUS_OK) { + fprintf(text->out, "%s(%" PRId64 ")", + has_str ? " " : "", value); + } + } + bt_put(loglevel_str); + bt_put(loglevel_value); + } + } + if (text->options.print_emf_field) { + struct bt_value *uri_str; + + uri_str = bt_ctf_event_class_get_attribute_value_by_name(event_class, + "model.emf.uri"); + if (uri_str) { + if (!text->start_line) { + fputs(", ", text->out); + } + text->start_line = false; + if (print_names) { + fputs("model.emf.uri = ", text->out); + } + if (uri_str) { + const char *str; + + if (bt_value_string_get(uri_str, &str) + == BT_VALUE_STATUS_OK) { + fprintf(text->out, "%s", str); + } + } + bt_put(uri_str); + } + } + if (!text->start_line) { + fputs(", ", text->out); + } + text->start_line = false; if (print_names) { fputs("name = ", text->out); } fputs(bt_ctf_event_class_get_name(event_class), text->out); end: + bt_put(trace_class); + bt_put(stream_class); bt_put(event_class); return ret; }