From 11ac667403ca915f51cc5981fa4bb8bd443fb606 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Mon, 30 Jan 2012 10:38:19 -0500 Subject: [PATCH] clock: show as time of day - todo: implement offset at trace collection level. Signed-off-by: Mathieu Desnoyers --- converter/babeltrace.c | 48 +++++++++++ formats/ctf-text/ctf-text.c | 82 +++++++++++++++++-- .../metadata/ctf-visitor-generate-io-struct.c | 11 +++ include/babeltrace/babeltrace-internal.h | 9 +- include/babeltrace/ctf-ir/metadata.h | 1 + 5 files changed, 143 insertions(+), 8 deletions(-) diff --git a/converter/babeltrace.c b/converter/babeltrace.c index 03b9d2f2..3824547f 100644 --- a/converter/babeltrace.c +++ b/converter/babeltrace.c @@ -64,6 +64,11 @@ enum { OPT_NAMES, OPT_FIELDS, OPT_NO_DELTA, + OPT_CLOCK_OFFSET, + OPT_CLOCK_RAW, + OPT_CLOCK_SECONDS, + OPT_CLOCK_DATE, + OPT_CLOCK_GMT, }; static struct poptOption long_options[] = { @@ -77,6 +82,11 @@ static struct poptOption long_options[] = { { "names", 'n', POPT_ARG_STRING, NULL, OPT_NAMES, NULL, NULL }, { "fields", 'f', POPT_ARG_STRING, NULL, OPT_FIELDS, NULL, NULL }, { "no-delta", 0, POPT_ARG_NONE, NULL, OPT_NO_DELTA, NULL, NULL }, + { "clock-offset", 0, POPT_ARG_STRING, NULL, OPT_CLOCK_OFFSET, NULL, NULL }, + { "clock-raw", 0, POPT_ARG_NONE, NULL, OPT_CLOCK_RAW, NULL, NULL }, + { "clock-seconds", 0, POPT_ARG_NONE, NULL, OPT_CLOCK_SECONDS, NULL, NULL }, + { "clock-date", 0, POPT_ARG_NONE, NULL, OPT_CLOCK_DATE, NULL, NULL }, + { "clock-gmt", 0, POPT_ARG_NONE, NULL, OPT_CLOCK_GMT, NULL, NULL }, { NULL, 0, 0, NULL, 0, NULL, NULL }, }; @@ -111,6 +121,12 @@ static void usage(FILE *fp) fprintf(fp, " -f, --fields name1<,name2,...> Print additional fields:\n"); fprintf(fp, " all, trace, trace:domain, trace:procname,\n"); fprintf(fp, " trace:vpid, loglevel.\n"); + fprintf(fp, " --clock-raw Disregard internal clock offset (use raw value)\n"); + fprintf(fp, " --clock-offset seconds Clock offset in seconds\n"); + fprintf(fp, " --clock-seconds Print the timestamps as [sec.ns]\n"); + fprintf(fp, " (default is: [hh:mm:ss.ns])\n"); + fprintf(fp, " --clock-date Print clock date\n"); + fprintf(fp, " --clock-gmt Print clock in GMT time zone (default: local time zone)\n"); list_formats(fp); fprintf(fp, "\n"); } @@ -226,6 +242,38 @@ static int parse_options(int argc, char **argv) case OPT_NO_DELTA: opt_delta_field = 0; break; + case OPT_CLOCK_RAW: + opt_clock_raw = 1; + break; + case OPT_CLOCK_OFFSET: + { + char *str, *endptr; + + str = poptGetOptArg(pc); + if (!str) { + fprintf(stderr, "[error] Missing --clock-offset argument\n"); + ret = -EINVAL; + goto end; + } + errno = 0; + opt_clock_offset = strtoull(str, &endptr, 0); + if (*endptr != '\0' || str == endptr || errno != 0) { + fprintf(stderr, "[error] Incorrect --clock-offset argument: %s\n", str); + ret = -EINVAL; + goto end; + } + break; + } + case OPT_CLOCK_SECONDS: + opt_clock_seconds = 1; + break; + case OPT_CLOCK_DATE: + opt_clock_date = 1; + break; + case OPT_CLOCK_GMT: + opt_clock_gmt = 1; + break; + default: ret = -EINVAL; goto end; diff --git a/formats/ctf-text/ctf-text.c b/formats/ctf-text/ctf-text.c index a837f914..35b26235 100644 --- a/formats/ctf-text/ctf-text.c +++ b/formats/ctf-text/ctf-text.c @@ -47,7 +47,13 @@ int opt_all_field_names, opt_trace_procname_field, opt_trace_vpid_field, opt_loglevel_field, - opt_delta_field = 1; + opt_delta_field = 1, + opt_clock_raw, + opt_clock_seconds, + opt_clock_date, + opt_clock_gmt; + +uint64_t opt_clock_offset; enum field_item { ITEM_SCOPE, @@ -151,6 +157,73 @@ void set_field_names_print(struct ctf_text_stream_pos *pos, enum field_item item } } +static +void ctf_text_print_timestamp(struct ctf_text_stream_pos *pos, + struct ctf_stream *stream) +{ + uint64_t ts_sec = 0, ts_nsec; + //need to get the clock offset at trace collection level. TODO + //struct ctf_trace *trace = stream->stream_class->trace; + + ts_nsec = stream->timestamp; + + /* Add offsets */ + if (!opt_clock_raw) { + //ts_sec += pos->clock_offset_s; + //ts_nsec += pos->clock_offset; + } + ts_sec += opt_clock_offset; + + ts_sec += ts_nsec / NSEC_PER_SEC; + ts_nsec = ts_nsec % NSEC_PER_SEC; + + if (!opt_clock_seconds) { + struct tm tm; + time_t time_s = (time_t) ts_sec; + + if (!opt_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 (opt_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(pos->fp, "%s", timestr); + } + /* Print time in HH:MM:SS.ns */ + fprintf(pos->fp, "%02d:%02d:%02d.%09" PRIu64, + tm.tm_hour, tm.tm_min, tm.tm_sec, ts_nsec); + goto end; + } +seconds: + fprintf(pos->fp, "%3" PRIu64 ".%09" PRIu64, + ts_sec, ts_nsec); + +end: + return; +} + static int ctf_text_write_event(struct stream_pos *ppos, struct ctf_stream *stream) @@ -183,17 +256,12 @@ int ctf_text_write_event(struct stream_pos *ppos, } if (stream->has_timestamp) { - uint64_t ts_sec, ts_nsec; - - ts_sec = stream->timestamp / NSEC_PER_SEC; - ts_nsec = stream->timestamp % NSEC_PER_SEC; set_field_names_print(pos, ITEM_HEADER); if (pos->print_names) fprintf(pos->fp, "timestamp = "); else fprintf(pos->fp, "["); - fprintf(pos->fp, "%3" PRIu64 ".%09" PRIu64, - ts_sec, ts_nsec); + ctf_text_print_timestamp(pos, stream); if (!pos->print_names) fprintf(pos->fp, "]"); diff --git a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c index a8aebf91..dee8384d 100644 --- a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c +++ b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c @@ -2241,6 +2241,17 @@ int ctf_clock_declaration_visit(FILE *fd, int depth, struct ctf_node *node, ret = -EINVAL; goto error; } + } else if (!strcmp(left, "absolute")) { + struct ctf_node *right; + + right = _cds_list_first_entry(&node->u.ctf_expression.right, struct ctf_node, siblings); + ret = get_boolean(fd, depth, right); + if (ret < 0) { + fprintf(fd, "[error] %s: unexpected \"absolute\" right member\n", __func__); + ret = -EINVAL; + goto error; + } + clock->absolute = ret; } else { fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in clock declaration.\n", __func__, left); } diff --git a/include/babeltrace/babeltrace-internal.h b/include/babeltrace/babeltrace-internal.h index ebeb048e..01a7abaa 100644 --- a/include/babeltrace/babeltrace-internal.h +++ b/include/babeltrace/babeltrace-internal.h @@ -3,6 +3,7 @@ #include #include +#include extern int babeltrace_verbose, babeltrace_debug; @@ -37,6 +38,12 @@ extern int opt_all_field_names, opt_trace_procname_field, opt_trace_vpid_field, opt_loglevel_field, - opt_delta_field; + opt_delta_field, + opt_clock_raw, + opt_clock_seconds, + opt_clock_date, + opt_clock_gmt; + +extern uint64_t opt_clock_offset; #endif diff --git a/include/babeltrace/ctf-ir/metadata.h b/include/babeltrace/ctf-ir/metadata.h index 2cae4630..bf68c328 100644 --- a/include/babeltrace/ctf-ir/metadata.h +++ b/include/babeltrace/ctf-ir/metadata.h @@ -82,6 +82,7 @@ struct ctf_clock { uint64_t offset_s; /* Fine clock offset from Epoch, in (1/freq) units. */ uint64_t offset; + int absolute; enum { /* Fields populated mask */ CTF_CLOCK_name = (1U << 0), -- 2.34.1