lnstat: add json output format
This commit is contained in:
parent
ec3e625c41
commit
a4f9e8df37
171
misc/lnstat.c
171
misc/lnstat.c
|
|
@ -41,7 +41,8 @@
|
||||||
static struct option opts[] = {
|
static struct option opts[] = {
|
||||||
{ "version", 0, NULL, 'V' },
|
{ "version", 0, NULL, 'V' },
|
||||||
{ "count", 1, NULL, 'c' },
|
{ "count", 1, NULL, 'c' },
|
||||||
{ "dump", 1, NULL, 'd' },
|
{ "dump", 0, NULL, 'd' },
|
||||||
|
{ "json", 0, NULL, 'j' },
|
||||||
{ "file", 1, NULL, 'f' },
|
{ "file", 1, NULL, 'f' },
|
||||||
{ "help", 0, NULL, 'h' },
|
{ "help", 0, NULL, 'h' },
|
||||||
{ "interval", 1, NULL, 'i' },
|
{ "interval", 1, NULL, 'i' },
|
||||||
|
|
@ -63,6 +64,8 @@ static int usage(char *name, int exit_code)
|
||||||
"Print <count> number of intervals\n");
|
"Print <count> number of intervals\n");
|
||||||
fprintf(stderr, "\t-d --dump\t\t"
|
fprintf(stderr, "\t-d --dump\t\t"
|
||||||
"Dump list of available files/keys\n");
|
"Dump list of available files/keys\n");
|
||||||
|
fprintf(stderr, "\t-j --json\t\t"
|
||||||
|
"Display in JSON format\n");
|
||||||
fprintf(stderr, "\t-f --file <file>\tStatistics file to use\n");
|
fprintf(stderr, "\t-f --file <file>\tStatistics file to use\n");
|
||||||
fprintf(stderr, "\t-h --help\t\tThis help message\n");
|
fprintf(stderr, "\t-h --help\t\tThis help message\n");
|
||||||
fprintf(stderr, "\t-i --interval <intv>\t"
|
fprintf(stderr, "\t-i --interval <intv>\t"
|
||||||
|
|
@ -94,7 +97,7 @@ static void print_line(FILE *of, const struct lnstat_file *lnstat_files,
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < fp->num; i++) {
|
for (i = 0; i < fp->num; i++) {
|
||||||
struct lnstat_field *lf = fp->params[i].lf;
|
const struct lnstat_field *lf = fp->params[i].lf;
|
||||||
char formatbuf[255];
|
char formatbuf[255];
|
||||||
|
|
||||||
snprintf(formatbuf, sizeof(formatbuf)-1, "%%%ulu|",
|
snprintf(formatbuf, sizeof(formatbuf)-1, "%%%ulu|",
|
||||||
|
|
@ -104,6 +107,30 @@ static void print_line(FILE *of, const struct lnstat_file *lnstat_files,
|
||||||
fputc('\n', of);
|
fputc('\n', of);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void print_json(FILE *of, const struct lnstat_file *lnstat_files,
|
||||||
|
const struct field_params *fp)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const char *sep;
|
||||||
|
const char *base = NULL;
|
||||||
|
|
||||||
|
fputs("{\n", of);
|
||||||
|
for (i = 0; i < fp->num; i++) {
|
||||||
|
const struct lnstat_field *lf = fp->params[i].lf;
|
||||||
|
|
||||||
|
if (!base || lf->file->basename != base) {
|
||||||
|
if (base) fputs("},\n", of);
|
||||||
|
base = lf->file->basename;
|
||||||
|
sep = "\n\t";
|
||||||
|
fprintf(of, " \"%s\":{", base);
|
||||||
|
}
|
||||||
|
fprintf(of, "%s\"%s\":%lu", sep,
|
||||||
|
lf->name, lf->result);
|
||||||
|
sep = ",\n\t";
|
||||||
|
}
|
||||||
|
fputs("}\n}\n", of);
|
||||||
|
}
|
||||||
|
|
||||||
/* find lnstat_field according to user specification */
|
/* find lnstat_field according to user specification */
|
||||||
static int map_field_params(struct lnstat_file *lnstat_files,
|
static int map_field_params(struct lnstat_file *lnstat_files,
|
||||||
struct field_params *fps, int interval)
|
struct field_params *fps, int interval)
|
||||||
|
|
@ -218,15 +245,16 @@ int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct lnstat_file *lnstat_files;
|
struct lnstat_file *lnstat_files;
|
||||||
const char *basename;
|
const char *basename;
|
||||||
int c;
|
int i, c;
|
||||||
int interval = DEFAULT_INTERVAL;
|
int interval = DEFAULT_INTERVAL;
|
||||||
int hdr = 2;
|
int hdr = 2;
|
||||||
enum {
|
enum {
|
||||||
MODE_DUMP,
|
MODE_DUMP,
|
||||||
|
MODE_JSON,
|
||||||
MODE_NORMAL,
|
MODE_NORMAL,
|
||||||
} mode = MODE_NORMAL;
|
} mode = MODE_NORMAL;
|
||||||
|
|
||||||
unsigned long count = 1;
|
unsigned long count = 1;
|
||||||
|
struct table_hdr *header;
|
||||||
static struct field_params fp;
|
static struct field_params fp;
|
||||||
int num_req_files = 0;
|
int num_req_files = 0;
|
||||||
char *req_files[LNSTAT_MAX_FILES];
|
char *req_files[LNSTAT_MAX_FILES];
|
||||||
|
|
@ -248,70 +276,73 @@ int main(int argc, char **argv)
|
||||||
num_req_files = 1;
|
num_req_files = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((c = getopt_long(argc, argv,"Vc:df:h?i:k:s:w:",
|
while ((c = getopt_long(argc, argv,"Vc:djf:h?i:k:s:w:",
|
||||||
opts, NULL)) != -1) {
|
opts, NULL)) != -1) {
|
||||||
int i, len = 0;
|
int len = 0;
|
||||||
char *tmp, *tok;
|
char *tmp, *tok;
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'c':
|
case 'c':
|
||||||
count = strtoul(optarg, NULL, 0);
|
count = strtoul(optarg, NULL, 0);
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
mode = MODE_DUMP;
|
||||||
|
break;
|
||||||
|
case 'j':
|
||||||
|
mode = MODE_JSON;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
req_files[num_req_files++] = strdup(optarg);
|
||||||
|
break;
|
||||||
|
case '?':
|
||||||
|
case 'h':
|
||||||
|
usage(argv[0], 0);
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
sscanf(optarg, "%u", &interval);
|
||||||
|
break;
|
||||||
|
case 'k':
|
||||||
|
tmp = strdup(optarg);
|
||||||
|
if (!tmp)
|
||||||
break;
|
break;
|
||||||
case 'd':
|
for (tok = strtok(tmp, ",");
|
||||||
mode = MODE_DUMP;
|
tok;
|
||||||
break;
|
tok = strtok(NULL, ",")) {
|
||||||
case 'f':
|
if (fp.num >= MAX_FIELDS) {
|
||||||
req_files[num_req_files++] = strdup(optarg);
|
fprintf(stderr,
|
||||||
break;
|
"WARN: too many keys"
|
||||||
case '?':
|
" requested: (%d max)\n",
|
||||||
case 'h':
|
MAX_FIELDS);
|
||||||
usage(argv[0], 0);
|
|
||||||
break;
|
|
||||||
case 'i':
|
|
||||||
sscanf(optarg, "%u", &interval);
|
|
||||||
break;
|
|
||||||
case 'k':
|
|
||||||
tmp = strdup(optarg);
|
|
||||||
if (!tmp)
|
|
||||||
break;
|
break;
|
||||||
for (tok = strtok(tmp, ",");
|
|
||||||
tok;
|
|
||||||
tok = strtok(NULL, ",")) {
|
|
||||||
if (fp.num >= MAX_FIELDS) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"WARN: too many keys"
|
|
||||||
" requested: (%d max)\n",
|
|
||||||
MAX_FIELDS);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
fp.params[fp.num++].name = tok;
|
|
||||||
}
|
}
|
||||||
|
fp.params[fp.num++].name = tok;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
sscanf(optarg, "%u", &hdr);
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
|
tmp = strdup(optarg);
|
||||||
|
if (!tmp)
|
||||||
break;
|
break;
|
||||||
case 's':
|
i = 0;
|
||||||
sscanf(optarg, "%u", &hdr);
|
for (tok = strtok(tmp, ",");
|
||||||
break;
|
tok;
|
||||||
case 'w':
|
tok = strtok(NULL, ",")) {
|
||||||
tmp = strdup(optarg);
|
len = strtoul(tok, NULL, 0);
|
||||||
if (!tmp)
|
if (len > FIELD_WIDTH_MAX)
|
||||||
break;
|
len = FIELD_WIDTH_MAX;
|
||||||
i = 0;
|
fp.params[i].print.width = len;
|
||||||
for (tok = strtok(tmp, ",");
|
i++;
|
||||||
tok;
|
}
|
||||||
tok = strtok(NULL, ",")) {
|
if (i == 1) {
|
||||||
len = strtoul(tok, NULL, 0);
|
for (i = 0; i < MAX_FIELDS; i++)
|
||||||
if (len > FIELD_WIDTH_MAX)
|
|
||||||
len = FIELD_WIDTH_MAX;
|
|
||||||
fp.params[i].print.width = len;
|
fp.params[i].print.width = len;
|
||||||
i++;
|
}
|
||||||
}
|
break;
|
||||||
if (i == 1) {
|
default:
|
||||||
for (i = 0; i < MAX_FIELDS; i++)
|
usage(argv[0], 1);
|
||||||
fp.params[i].print.width = len;
|
break;
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
usage(argv[0], 1);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -319,13 +350,12 @@ int main(int argc, char **argv)
|
||||||
(const char **) req_files);
|
(const char **) req_files);
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
int i;
|
|
||||||
struct table_hdr *header;
|
|
||||||
case MODE_DUMP:
|
case MODE_DUMP:
|
||||||
lnstat_dump(stderr, lnstat_files);
|
lnstat_dump(stderr, lnstat_files);
|
||||||
break;
|
break;
|
||||||
case MODE_NORMAL:
|
|
||||||
|
|
||||||
|
case MODE_NORMAL:
|
||||||
|
case MODE_JSON:
|
||||||
if (!map_field_params(lnstat_files, &fp, interval))
|
if (!map_field_params(lnstat_files, &fp, interval))
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
||||||
|
|
@ -334,16 +364,23 @@ int main(int argc, char **argv)
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
||||||
if (interval < 1 )
|
if (interval < 1 )
|
||||||
interval=1;
|
interval = 1;
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
if ((hdr > 1 && (! (i % 20))) || (hdr == 1 && i == 0))
|
|
||||||
print_hdr(stdout, header);
|
|
||||||
lnstat_update(lnstat_files);
|
lnstat_update(lnstat_files);
|
||||||
print_line(stdout, lnstat_files, &fp);
|
if (mode == MODE_JSON)
|
||||||
|
print_json(stdout, lnstat_files, &fp);
|
||||||
|
else {
|
||||||
|
if ((hdr > 1 &&
|
||||||
|
(! (i % 20))) || (hdr == 1 && i == 0))
|
||||||
|
print_hdr(stdout, header);
|
||||||
|
print_line(stdout, lnstat_files, &fp);
|
||||||
|
}
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
sleep(interval);
|
if (i < count - 1)
|
||||||
|
sleep(interval);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue