diff --git a/ldms/man/ldms_ls.man b/ldms/man/ldms_ls.man index b7092c639..24483dfc2 100644 --- a/ldms/man/ldms_ls.man +++ b/ldms/man/ldms_ls.man @@ -64,6 +64,11 @@ PORT of the HOST to use for the query. Default is LDMS_DEFAULT_PORT. .BR -l Display long listing. Outputs details of the metric set, including timestamp, metric names, metric types, and values. +.TP +.BR -f " " +Display output using format, which is one of 'tab' or 'json'. Other values are ignored. +Output in tab format includes header rows starting with # and has tab separated columns. + .TP .BI -a " AUTH" The name of the LDMS Authentication plugin. Please see @@ -163,25 +168,26 @@ $ldms_ls -h vm1 -x sock -p 60000 -l vm1_1/foo ldms_ls: No such file or directory ldms_ls: lookup failed for set 'vm1_1/foo' .PP -4) Display metadata: +4a) Display metadata: .nf .RS ldms_ls -h vm1 -x sock -p 60000 -v -vm1_1/meminfo: consistent, last update: Fri Dec 16 17:12:08 2016 [5091us] - METADATA -------- - Producer Name : vm1_1 - Instance Name : vm1_1/meminfo - Schema Name : meminfo - Size : 1816 - Metric Count : 43 - GN : 2 - DATA ------------ - Timestamp : Fri Dec 16 17:12:08 2016 [5091us] - Duration : [0.000072s] - Consistent : TRUE - Size : 384 - GN : 985 - ----------------- +Schema Instance Flags Msize Dsize Hsize UID GID Perm Update Duration Info +-------------- ------------------------ ------ ------ ------ ------ ------ ------ ---------- ----------------- ----------------- -------- +vmstat vm1/vmstat CL 8504 1328 0 0 0 -rw-r--r-- 1734076680.060971 0.000186 "updt_hint_us"="60000000:0" +-------------- ------------------------ ------ ------ ------ ------ ------ ------ ---------- ----------------- ----------------- -------- +Total Sets: 1, Meta Data (kB): 8.50, Data (kB) 1.33, Memory (kB): 9.83 + +.RE +4b) Display metadata tabbed: +.nf +.RS +ldms_ls -h vm1 -x sock -p 60000 -v -f tab +#schema instance flags msize dsize hsize uid gid perm update duration age_seconds age_intervals info +vmstat amber-login4/vmstat CL 8504 1328 0 0 0 -rw-r--r-- 1734076800.060615 0.000174 10.461 0 "updt_hint_us"="60000000:0" +#total_sets meta_data_kb data_kb memory_kb +1 8.50 1.33 9.83 + .RE .PP 5) Regular Expression: diff --git a/ldms/src/ldmsd/ldms_ls.c b/ldms/src/ldmsd/ldms_ls.c index cb8ab36f1..9a28aa615 100644 --- a/ldms/src/ldmsd/ldms_ls.c +++ b/ldms/src/ldmsd/ldms_ls.c @@ -80,6 +80,10 @@ #define GRP_SCHEMA_NAME "ldmsd_grp_schema" #define GRP_KEY_PREFIX " grp_member: " #define GRP_GN_NAME "ldmsd_grp_gn" +#ifndef LDMSD_SET_INFO_UPDATE_HINT_KEY +/* from ldmsd.h */ +#define LDMSD_SET_INFO_UPDATE_HINT_KEY "updt_hint_us" +#endif /* ----- */ static size_t max_mem_size; @@ -132,7 +136,26 @@ const char *auth_name = "none"; struct attr_value_list *auth_opt = NULL; const int auth_opt_max = 128; -#define FMT "h:p:x:w:m:ESIlvua:A:VPd" +enum out_format { + + sf_normal, + sf_json, + sf_tab +}; + +enum out_format format_to_enum(const char *f) { + if (!strcmp(f,"json")) + return sf_json; + if (!strcmp(f,"tab")) + return sf_tab; + printf("WARNING: format unknown: %s\n", f); + return sf_normal; +} + +enum out_format format = sf_normal; + + +#define FMT "h:p:x:w:m:ESIlvua:A:VPdf:" void usage(char *argv[]) { printf("%s -h -x [ name ... ]\n" @@ -146,6 +169,9 @@ void usage(char *argv[]) " The default is 10 seconds.\n" "\n -v Show detail information about the metric set. Specifying\n" " this option multiple times increases the verbosity.\n" + "\n -f Emit set information in a machine readable format. Detail\n" + " level is controlled by the presence of -l or -v.\n" + " Format fmt is one of 'json' and 'tab'; any other is ignored.\n" "\n -E The arguments are regular expressions.\n" "\n -S The s refers to the schema name.\n" "\n -I The s refer to the instance name (default).\n" @@ -620,6 +646,170 @@ void value_format(ldms_set_t s, enum ldms_value_type type, ldms_mval_t val, size } } +void value_format_json(ldms_set_t s, enum ldms_value_type type, ldms_mval_t val, size_t n) +{ + ldms_mval_t lval; + enum ldms_value_type ltype, prev_type; + int i; + size_t count; + printf("\"value\":"); + if (ldms_type_is_array(type) && type != LDMS_V_CHAR_ARRAY) + printf("["); + switch (type) { + case LDMS_V_CHAR_ARRAY: + printf("\"%s\"", val->a_char); + break; + case LDMS_V_CHAR: + printf("'%c'", val->v_char); + break; + case LDMS_V_U8: + printf("%hhu", val->v_u8); + break; + case LDMS_V_U8_ARRAY: + for (i = 0; i < n; i++) { + if (i) + printf(","); + printf("0x%02hhx", val->a_u8[i]); + } + break; + case LDMS_V_S8: + printf("%hhd", val->v_s8); + break; + case LDMS_V_S8_ARRAY: + for (i = 0; i < n; i++) { + if (i) + printf(","); + printf("%hhd", val->a_s8[i]); + } + break; + case LDMS_V_U16: + printf("%hu", val->v_u16); + break; + case LDMS_V_U16_ARRAY: + for (i = 0; i < n; i++) { + if (i) + printf(","); + printf("%hu", val->a_u16[i]); + } + break; + case LDMS_V_S16: + printf("%hd", val->v_s16); + break; + case LDMS_V_S16_ARRAY: + for (i = 0; i < n; i++) { + if (i) + printf(","); + printf("%hd", val->a_s16[i]); + } + break; + case LDMS_V_U32: + printf("%u", val->v_u32); + break; + case LDMS_V_U32_ARRAY: + for (i = 0; i < n; i++) { + if (i) + printf(","); + printf("%u", val->a_u32[i]); + } + break; + case LDMS_V_S32: + printf("%d", val->v_s32); + break; + case LDMS_V_S32_ARRAY: + for (i = 0; i < n; i++) { + if (i) + printf(","); + printf("%d", val->a_s32[i]); + } + break; + case LDMS_V_U64: + printf("%"PRIu64, val->v_u64); + break; + case LDMS_V_U64_ARRAY: + for (i = 0; i < n; i++) { + if (i) + printf(","); + printf("%"PRIu64, val->a_u64[i]); + } + break; + case LDMS_V_S64: + printf("%"PRId64, val->v_s64); + break; + case LDMS_V_S64_ARRAY: + for (i = 0; i < n; i++) { + if (i) + printf(","); + printf("%"PRId64, val->a_s64[i]); + } + break; + case LDMS_V_F32: + printf("%f", val->v_f); + break; + case LDMS_V_F32_ARRAY: + for (i = 0; i < n; i++) { + if (i) + printf(","); + printf("%f", val->a_f[i]); + } + break; + case LDMS_V_D64: + printf("%f", val->v_d); + break; + case LDMS_V_D64_ARRAY: + for (i = 0; i < n; i++) { + if (i) + printf(","); + printf("%f", val->a_d[i]); + } + break; + case LDMS_V_RECORD_TYPE: + printf("LDMS_V_RECORD_TYPE"); + break; + case LDMS_V_RECORD_INST: + /* + * Record instances are handled in the record array and + * list cases. + */ + assert(0); + break; + case LDMS_V_RECORD_ARRAY: + printf("\n"); + record_array_format(s, val); + break; + case LDMS_V_LIST: + prev_type = 0; + lval = ldms_list_first(s, val, <ype, &count); + if (LDMS_V_RECORD_INST == ltype) { + printf("\n"); + list_record_format(s, val); + } else { + printf("["); + for (lval = ldms_list_first(s, val, <ype, &count), prev_type=ltype, i = 0; + lval; lval = ldms_list_next(s, lval, <ype, &count), i++) { + if (i++) { + if (prev_type != ltype) { + printf("Error: A list contains entries of different types.\n"); + exit(ENOTSUP); + } + printf(","); + } + if (ldms_type_is_array(ltype) && ltype != LDMS_V_CHAR_ARRAY) + printf("["); + value_format_json(s, ltype, lval, count); + if (ldms_type_is_array(ltype) && ltype != LDMS_V_CHAR_ARRAY) + printf("]"); + } + printf("]"); + printf("\n"); + } + break; + default: + printf("Unknown metric type"); + } + if (ldms_type_is_array(type) && type != LDMS_V_CHAR_ARRAY) + printf("]"); +} + void value_printer(ldms_set_t s, int idx) { enum ldms_value_type type = ldms_metric_type_get(s, idx); @@ -628,7 +818,40 @@ void value_printer(ldms_set_t s, int idx) value_format(s, type, val, n); } +void value_printer_json(ldms_set_t s, int idx) +{ + enum ldms_value_type type = ldms_metric_type_get(s, idx); + ldms_mval_t val = ldms_metric_get(s, idx); + int n = ldms_metric_array_get_len(s, idx); + value_format_json(s, type, val, n); +} + static int user_data = 0; +void metric_printer_tab(ldms_set_t s, int i) +{ + enum ldms_value_type type = ldms_metric_type_get(s, i); + + const char *metname, *metunit; + if (type != LDMS_V_NONE) { + metname = ldms_metric_name_get(s, i); + metunit = ldms_metric_unit_get(s, i); + } else { + metname = "SET_ERROR"; + metunit = NULL; + } + + printf("%c\t%s\t%s\t", + (ldms_metric_flags_get(s, i) & LDMS_MDESC_F_DATA ? 'D' : 'M'), + ldms_metric_type_to_str(type), metname); + if (user_data) + printf("0x%" PRIx64 "\t", ldms_metric_user_data_get(s,i)); + + value_printer(s, i); + if (metunit) + printf("\t%s", metunit); + printf("\n"); +} + void metric_printer(ldms_set_t s, int i) { enum ldms_value_type type = ldms_metric_type_get(s, i); @@ -654,6 +877,33 @@ void metric_printer(ldms_set_t s, int i) printf("\n"); } +void metric_printer_json(ldms_set_t s, int i) +{ + enum ldms_value_type type = ldms_metric_type_get(s, i); + + const char *metname, *metunit; + if (type != LDMS_V_NONE) { + metname = ldms_metric_name_get(s, i); + metunit = ldms_metric_unit_get(s, i); + } else { + metname = "SET_ERROR"; + metunit = NULL; + } + if (i) + printf(","); + printf("{\"type\":\"%c\",\"kind\":\"%s\",\"name\":\"%s\",", + (ldms_metric_flags_get(s, i) & LDMS_MDESC_F_DATA ? 'D' : 'M'), + ldms_metric_type_to_str(type), metname); + if (user_data) + printf("\"userdata\":%" PRIx64 ",", ldms_metric_user_data_get(s,i)); + + value_printer_json(s, i); + if (metunit) + printf(",\"units\":\"%s\"", metunit); + printf("}"); +} + + static int is_matched(char *inst_name, char *schema_name) { if (LIST_EMPTY(&match_list)) @@ -759,6 +1009,10 @@ struct digest_entry { struct rbn rbn; }; +int format_first = 1; +int format_long_first = 1; +extern char *__ldms_format_set_for_dir(ldms_set_t s, size_t *cnt); + void print_cb(ldms_t t, ldms_set_t s, int rc, void *arg) { int err; @@ -808,24 +1062,75 @@ void print_cb(ldms_t t, ldms_set_t s, int rc, void *arg) tm = localtime(&ti); strftime(dtsz, sizeof(dtsz), "%a %b %d %H:%M:%S %Y %z", tm); - printf("%s: %s, last update: %s [%dus] ", - ldms_set_instance_name_get(s), - (consistent?"consistent":"inconsistent"), dtsz, ts->usec); - if (rc & LDMS_UPD_F_PUSH) - printf("PUSH "); - if (rc & LDMS_UPD_F_PUSH_LAST) - printf("LAST "); - printf("\n"); - if (long_format) { - int i; - for (i = 0; i < ldms_set_card_get(s); i++) - metric_printer(s, i); + char *metajson = NULL; + size_t mj_cnt = 0; + switch (format) { + case sf_normal: + printf("%s: %s, last update: %s [%dus] ", + ldms_set_instance_name_get(s), + (consistent?"consistent":"inconsistent"), dtsz, ts->usec); + if (rc & LDMS_UPD_F_PUSH) + printf("PUSH "); + if (rc & LDMS_UPD_F_PUSH_LAST) + printf("LAST "); + printf("\n"); + if (long_format) { + int i; + for (i = 0; i < ldms_set_card_get(s); i++) + metric_printer(s, i); + } + break; + case sf_json: + metajson = __ldms_format_set_for_dir(s, &mj_cnt); + if (format_long_first) { + format_long_first = 0; + printf(",\"long_sets\":["); + } else { + printf(","); + } + if (long_format) + printf("{"); + printf("\"dir_info\":%s", metajson); + free(metajson); + if (long_format) { + printf(",\"metrics\":["); + int i; + for (i = 0; i < ldms_set_card_get(s); i++) + metric_printer_json(s, i); + printf("]}"); + } + break; + case sf_tab: + printf("#instance\tconsistent\tupdate\tupdate.usec\tpush\tlast_push\n"); + printf("%s\t%d\t%s\t%d\t%d\t%d\n", + ldms_set_instance_name_get(s), + (consistent?1:0), dtsz, ts->usec, + ((rc & LDMS_UPD_F_PUSH) ? 1 : 0), + ((rc & LDMS_UPD_F_PUSH_LAST) ? 1: 0)); + if (long_format && ldms_set_card_get(s) > 0) { + printf("#type\tkind\tname"); + if (user_data) + printf("\tudata"); + printf("\tvalue\tunit\n"); + int i; + for (i = 0; i < ldms_set_card_get(s); i++) + metric_printer_tab(s, i); + } + break; } if ((rc == 0) || (rc & LDMS_UPD_F_PUSH_LAST)) ldms_set_delete(s); out: - if (!print_decomp) - printf("\n"); + switch (format) { + case sf_normal: + if (!print_decomp) + printf("\n"); + break; + case sf_tab: + break; + case sf_json: + break; + } if (last) { pthread_mutex_lock(&print_lock); print_done = 1; @@ -920,35 +1225,134 @@ long total_meta; long total_data; long total_sets; + void print_set(struct ldms_dir_set_s *set_data) { if (!verbose) { - printf("%s\n", set_data->inst_name); + switch (format) { + case sf_normal: + printf("%s\n", set_data->inst_name); + break; + case sf_tab: + if (format_first) { + printf("#instance\n"); + format_first = 0; + } + printf("%s\n", set_data->inst_name); + break; + case sf_json: + if (!format_first) { + printf(","); + } else { + format_first = 0; + } + printf("{\"instance\":\"%s\"}", set_data->inst_name); + break; + } } else { - if (verbose > 1) - printf("%-64s ", set_data->digest_str); - printf("%-14s %-24s %6s %6lu %6lu %6lu %6d %6d %10s %10d.%06d %10d.%06d ", - set_data->schema_name, - set_data->inst_name, - set_data->flags, - set_data->meta_size, - set_data->data_size, - set_data->heap_size, - set_data->uid, - set_data->gid, - set_data->perm, - set_data->timestamp.sec, - set_data->timestamp.usec, - set_data->duration.sec, - set_data->duration.usec); + double age_seconds = -1; + int age_intervals = -1; + struct timespec ts; + clock_gettime(CLOCK_REALTIME_COARSE,&ts); + struct timespec sts; + sts.tv_sec = set_data->timestamp.sec; + sts.tv_nsec = set_data->timestamp.usec*1000; + age_seconds = ldms_timespec_diff_s(&sts, &ts); + char *update_hint = ldms_dir_set_info_get(set_data, + LDMSD_SET_INFO_UPDATE_HINT_KEY); + if (update_hint) { + int interval=0, offset=0; + sscanf(update_hint,"%d:%d", &interval, &offset); + if (interval) { + age_intervals = age_seconds / (interval * 1.0e-6); + } + } + int j; + switch (format) { + case sf_normal: + if (verbose > 1) + printf("%-64s ", set_data->digest_str); + printf("%-14s %-24s %6s %6lu %6lu %6lu %6d %6d %10s %10d.%06d %10d.%06d ", + set_data->schema_name, + set_data->inst_name, + set_data->flags, + set_data->meta_size, + set_data->data_size, + set_data->heap_size, + set_data->uid, + set_data->gid, + set_data->perm, + set_data->timestamp.sec, + set_data->timestamp.usec, + set_data->duration.sec, + set_data->duration.usec); + for (j = 0; j < set_data->info_count; j++) { + printf("\"%s\"=\"%s\" ", set_data->info[j].key, set_data->info[j].value); + } + printf("\n"); + break; + case sf_json: + if (!format_first) { + printf(","); + } else { + format_first = 0; + } + if (verbose > 1) + printf("{\"schema_digest\":\"%s\",", + set_data->digest_str); + else + printf("{"); + printf("\"schema\":\"%s\",\"instance\":\"%s\",\"flags\":\"%s\"," + "\"meta_size\":%lu,\"data_size\":%lu,\"heap_size\":%lu," + "\"uid\":%d,\"gid\":%d,\"perm\":\"%s\"," + "\"update\":\"%d.%06d\",\"duration\":%d.%06d," + "\"age_seconds\":%.3f,\"age_intervals\":%d,\"info\":{", + set_data->schema_name, + set_data->inst_name, + set_data->flags, + set_data->meta_size, + set_data->data_size, + set_data->heap_size, + set_data->uid, + set_data->gid, + set_data->perm, + set_data->timestamp.sec, + set_data->timestamp.usec, + set_data->duration.sec, + set_data->duration.usec, + age_seconds, age_intervals); + for (j = 0; j < set_data->info_count-1; j++) { + printf("\"%s\":\"%s\",", set_data->info[j].key, set_data->info[j].value); + } + printf("\"%s\":\"%s\"}}", set_data->info[j].key, set_data->info[j].value); + break; + case sf_tab: + if (verbose > 1) + printf("%s\t", set_data->digest_str); + printf("%s\t%s\t%s\t%lu\t%lu\t%lu\t%d\t%d\t%s\t%d.%06d\t%d.%06d\t%.3f\t%d\t", + set_data->schema_name, + set_data->inst_name, + set_data->flags, + set_data->meta_size, + set_data->data_size, + set_data->heap_size, + set_data->uid, + set_data->gid, + set_data->perm, + set_data->timestamp.sec, + set_data->timestamp.usec, + set_data->duration.sec, + set_data->duration.usec, + age_seconds, age_intervals); + for (j = 0; j < set_data->info_count; j++) { + printf("\"%s\"=\"%s\" ", set_data->info[j].key, set_data->info[j].value); + } + printf("\n"); + break; + } total_meta += set_data->meta_size; total_data += set_data->data_size; total_sets ++; - int j; - for (j = 0; j < set_data->info_count; j++) { - printf("\"%s\"=\"%s\" ", set_data->info[j].key, set_data->info[j].value); - } - printf("\n"); } } @@ -1157,6 +1561,9 @@ int main(int argc, char *argv[]) } port_no = ptmp; break; + case 'f': + format = format_to_enum(optarg); + break; case 'l': long_format = 1; break; @@ -1266,26 +1673,75 @@ int main(int argc, char *argv[]) } if (verbose > 1) { - printf("Hostname : %s\n", hostname); char addr_buff[128]; - switch (lsa.sa.sa_family) { - case AF_INET: - inet_ntop(AF_INET, &lsa.sin.sin_addr, - addr_buff, sizeof(addr_buff)); - printf("IP Address : %s\n", addr_buff); - break; - case AF_INET6: - inet_ntop(AF_INET6, &lsa.sin6.sin6_addr, - addr_buff, sizeof(addr_buff)); - printf("IPv6 Address : %s\n", addr_buff); + switch (format) { + case sf_normal: + printf("Hostname : %s\n", hostname); + switch (lsa.sa.sa_family) { + case AF_INET: + inet_ntop(AF_INET, &lsa.sin.sin_addr, + addr_buff, sizeof(addr_buff)); + printf("IP Address : %s\n", addr_buff); + break; + case AF_INET6: + inet_ntop(AF_INET6, &lsa.sin6.sin6_addr, + addr_buff, sizeof(addr_buff)); + printf("IPv6 Address : %s\n", addr_buff); + break; + default: + printf("Address : __UNSUPPORTED__ " + "(address family: %d)\n", + lsa.sa.sa_family); + break; + } + printf("Port : %hu\n", port_no); + printf("Transport : %s\n", xprt); break; - default: - printf("Address : __UNSUPPORTED__ (address family: %d)\n", + case sf_json: + printf("{\"source\":{"); + printf("\"hostname\":\"%s\",", hostname); + switch (lsa.sa.sa_family) { + case AF_INET: + inet_ntop(AF_INET, &lsa.sin.sin_addr, + addr_buff, sizeof(addr_buff)); + printf("\"ip_address\":\"%s\",", addr_buff); + break; + case AF_INET6: + inet_ntop(AF_INET6, &lsa.sin6.sin6_addr, + addr_buff, sizeof(addr_buff)); + printf("\"ipv6_address\":\"%s\",", addr_buff); + break; + default: + printf("\"unsupported_address\":\"family_%d\",", lsa.sa.sa_family); + break; + } + printf("\"port\":%hu,", port_no); + printf("\"transport\":\"%s\"},", xprt); + printf("\"sets\":["); + break; + case sf_tab: + printf("#hostname\t"); + switch (lsa.sa.sa_family) { + case AF_INET: + inet_ntop(AF_INET, &lsa.sin.sin_addr, + addr_buff, sizeof(addr_buff)); + printf("ip_address\t"); + break; + case AF_INET6: + inet_ntop(AF_INET6, &lsa.sin6.sin6_addr, + addr_buff, sizeof(addr_buff)); + printf("ipv6_address\t"); + break; + default: + printf("unsupported_address\t"); + sprintf(addr_buff,"family_%d", lsa.sa.sa_family); + break; + } + printf("port\ttransport\n"); + printf("%s\t%s\t%hu\t%s\n", hostname, addr_buff, port_no, xprt); break; } - printf("Port : %hu\n", port_no); - printf("Transport : %s\n", xprt); } free(xprt); free(hostname); @@ -1312,20 +1768,38 @@ int main(int argc, char *argv[]) int is_filter_list = 0; if (verbose) { - if (verbose > 1) - printf("%-*s ", 64, "Schema Digest"); - printf("%-*s %-*s %-*s %-*s %-*s %-*s %-*s %-*s %-*s %-*s %-*s %-*s\n", - 14, "Schema", - 24, "Instance", - 6, "Flags", - 6, "Msize", 6, "Dsize", 6, "Hsize", - 6, "UID", 6, "GID", 10, "Perm", - 17, "Update", 17, "Duration", 8, "Info"); - if (verbose > 1) - printf("---------------------------------------------------------------- "); - printf("-------------- ------------------------ ------ ------ " - "------ ------ ------ ------ ---------- ----------------- " - "----------------- --------\n"); + switch (format) { + case sf_normal: + if (verbose > 1) + printf("%-*s ", 64, "Schema Digest"); + printf("%-*s %-*s %-*s %-*s %-*s %-*s %-*s %-*s %-*s %-*s %-*s %-*s\n", + 14, "Schema", + 24, "Instance", + 6, "Flags", + 6, "Msize", 6, "Dsize", 6, "Hsize", + 6, "UID", 6, "GID", 10, "Perm", + 17, "Update", 17, "Duration", 8, "Info"); + if (verbose > 1) + printf("---------------------------------------------------------------- "); + printf("-------------- ------------------------ ------ ------ " + "------ ------ ------ ------ ---------- ----------------- " + "----------------- --------\n"); + break; + case sf_json: + if (verbose <= 1) + printf("{\"sets\":["); + break; + case sf_tab: + printf("#"); + if (verbose > 1) + printf("schema_digest\t"); + printf("schema\tinstance\tflags\tmsize\tdsize\thsize\t" + "uid\tgid\tperm\tupdate\tduration\t" + "age_seconds\tage_intervals\tinfo\n"); + } + } else { + if (format == sf_json) + printf("{\"sets\":["); } if (optind == argc) { /* List all existing metric sets */ @@ -1395,7 +1869,16 @@ int main(int argc, char *argv[]) struct ls_set *lss; if (LIST_EMPTY(&set_list)) { if (is_filter_list) - printf("ldms_ls: No metric sets matched the given criteria\n"); + switch (format) { + case sf_normal: + printf("ldms_ls: No metric sets matched the given criteria\n"); + break; + case sf_json: + printf("]"); + break; + case sf_tab: + break; + } done = 1; goto done; } @@ -1434,14 +1917,35 @@ int main(int argc, char *argv[]) } if (verbose) { - if (verbose > 1) - printf("---------------------------------------------------------------- "); - printf("-------------- ------------------------ ------ ------ " - "------ ------ ------ ------ ---------- ----------------- " - "----------------- --------\n"); - printf("Total Sets: %ld, Meta Data (kB): %.2f, Data (kB) %.2f, Memory (kB): %.2f\n", - total_sets, (double)total_meta / 1000.0, (double)total_data / 1000.0, - (double)(total_meta + total_data) / 1000.0); + switch (format) { + case sf_normal: + if (verbose > 1) + printf("---------------------------------------------------------------- "); + printf("-------------- ------------------------ ------ ------ " + "------ ------ ------ ------ ---------- ----------------- " + "----------------- --------\n"); + printf("Total Sets: %ld, Meta Data (kB): %.2f, Data (kB) %.2f, Memory (kB): %.2f\n", + total_sets, (double)total_meta / 1000.0, (double)total_data / 1000.0, + (double)(total_meta + total_data) / 1000.0); + break; + case sf_json: + printf("],\"memory\":{"); + printf( "\"total_sets\":%ld,\"meta_data_kb\":%.2f," + "\"data_kb\":%.2f,\"memory_kb\":%2f", + total_sets, (double)total_meta / 1000.0, (double)total_data / 1000.0, + (double)(total_meta + total_data) / 1000.0); + printf("}"); + break; + case sf_tab: + printf("#total_sets\tmeta_data_kb\tdata_kb\tmemory_kb\n"); + printf("%ld\t%.2f\t %.2f\t%.2f\n", + total_sets, (double)total_meta / 1000.0, (double)total_data / 1000.0, + (double)(total_meta + total_data) / 1000.0); + break; + } + } else { + if (format == sf_json) + printf("]"); } /* @@ -1458,9 +1962,17 @@ int main(int argc, char *argv[]) goto done; } - if (verbose && long_format) - printf("\n=======================================================================\n\n"); - + if (verbose && long_format) { + switch (format) { + case sf_normal: + printf("\n=======================================================================\n\n"); + break; + case sf_tab: + break; + case sf_json: + break; + } + } if (print_decomp) { fprintf(stdout, "{\n"); fprintf(stdout, " \"type\" : \"flex\",\n"); @@ -1524,6 +2036,11 @@ int main(int argc, char *argv[]) free(dir); } + if (format == sf_json) { + if (long_format && ! format_long_first) + printf("]"); + printf("}"); + } /* gracefully close, and wait at most 2 seconds before exit */ ldms_xprt_close(ldms); struct timespec _t;