--- embedaddon/bmon/src/out_ascii.c 2012/02/21 22:19:56 1.1.1.1 +++ embedaddon/bmon/src/out_ascii.c 2014/07/30 07:55:27 1.1.1.2 @@ -1,7 +1,8 @@ /* * out_ascii.c ASCII Output * - * Copyright (c) 2001-2005 Thomas Graf + * Copyright (c) 2001-2013 Thomas Graf + * Copyright (c) 2013 Red Hat, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -23,10 +24,13 @@ */ #include -#include #include #include -#include +#include +#include +#include +#include +#include #include typedef enum diagram_type_e { @@ -35,213 +39,185 @@ typedef enum diagram_type_e { D_DETAILS } diagram_type_t; -static int c_print_header = INT_MAX; +static struct graph_cfg graph_cfg = { + .gc_foreground = '*', + .gc_background = ' ', + .gc_noise = '.', + .gc_unknown = '?', + .gc_height = 6, +}; + static diagram_type_t c_diagram_type = D_LIST; -static int c_graph_height = 6; +static char *c_hist = "second"; static int c_quit_after = -1; -static inline int get_print_header(void) +static void print_list(struct element *e) { - static int hdr_rem; - - if (c_print_header) { - if (0 == hdr_rem) { - hdr_rem = (c_print_header - 1); - return 1; - } - - if (c_print_header != INT_MAX) - hdr_rem--; - } - - return 0; -} - -static inline void set_diagram_type(const char *t) -{ - if (tolower(*t) == 'l') - c_diagram_type = D_LIST; - else if (tolower(*t) == 'g') - c_diagram_type = D_GRAPH; - else if (tolower(*t) == 'd') - c_diagram_type = D_DETAILS; - else - quit("Unknown diagram type '%s'\n", t); -} - - -static void print_item(item_t *i) -{ - stat_attr_t *bytes, *packets; - double rx, tx, rxp, txp; - int rxprec, txprec, rxpprec, txpprec; - char *rx_u, *tx_u, *rxp_u, *txp_u; + char *rxu1 = "", *txu1 = "", *rxu2 = "", *txu2 = ""; + double rx1 = 0.0f, tx1 = 0.0f, rx2 = 0.0f, tx2 = 0.0f; + int rx1prec = 0, tx1prec = 0, rx2prec = 0, tx2prec = 0; char pad[IFNAMSIZ + 32]; - - if (get_print_header()) { - printf("Name RX Rate # %%" \ - " TX Rate # %%\n"); - } + struct attr *a; - bytes = lookup_attr(i, i->i_major_attr); - packets = lookup_attr(i, i->i_minor_attr); + if (e->e_key_attr[GT_MAJOR] && + (a = attr_lookup(e, e->e_key_attr[GT_MAJOR]->ad_id))) + attr_rate2float(a, &rx1, &rxu1, &rx1prec, + &tx1, &txu1, &tx1prec); - rx = cancel_down(attr_get_rx_rate(bytes), bytes->a_unit, &rx_u, &rxprec); - tx = cancel_down(attr_get_tx_rate(bytes), bytes->a_unit, &tx_u, &txprec); + if (e->e_key_attr[GT_MINOR] && + (a = attr_lookup(e, e->e_key_attr[GT_MINOR]->ad_id))) + attr_rate2float(a, &rx2, &rxu2, &rx2prec, + &tx2, &txu2, &tx2prec); - rxp = cancel_down(attr_get_rx_rate(packets), packets->a_unit, &rxp_u, &rxpprec); - txp = cancel_down(attr_get_tx_rate(packets), packets->a_unit, &txp_u, &txpprec); - memset(pad, 0, sizeof(pad)); - memset(pad, ' ', i->i_level < 15 ? i->i_level : 15); + memset(pad, ' ', e->e_level < 15 ? e->e_level : 15); - strncat(pad, i->i_name, sizeof(pad) - strlen(pad) - 1); + strncat(pad, e->e_name, sizeof(pad) - strlen(pad) - 1); - if (i->i_desc) { + if (e->e_description) { strncat(pad, " (", sizeof(pad) - strlen(pad) - 1); - strncat(pad, i->i_desc, sizeof(pad) - strlen(pad) - 1); + strncat(pad, e->e_description, sizeof(pad) - strlen(pad) - 1); strncat(pad, ")", sizeof(pad) - strlen(pad) - 1); } - printf("%-22s %8.*f%s %8.*f%s ", pad, rxprec, rx, rx_u, rxpprec, rxp, rxp_u); - if (i->i_rx_usage < 0) - printf(" "); - else - printf("%2d%%", i->i_rx_usage); + printf(" %-36s %8.*f%-3s %8.*f%-3s ", + pad, rx1prec, rx1, rxu1, rx2prec, rx2, rxu2); - printf(" %8.*f%s %8.*f%s ", txprec, tx, tx_u, txpprec, txp, txp_u); - if (i->i_tx_usage < 0) + if (e->e_rx_usage == FLT_MAX) printf(" "); else - printf("%2d%%", i->i_tx_usage); + printf("%2.0f%%", e->e_rx_usage); - printf("\n"); + printf(" %8.*f%-3s %8.*f%-3s ", tx1prec, tx1, txu1, tx2prec, tx2, txu2); + + if (e->e_tx_usage == FLT_MAX) + printf(" \n"); + else + printf("%2.0f%%\n", e->e_tx_usage); } - -static void handle_child(item_t *i, void *arg) +static void print_attr_detail(struct element *e, struct attr *a, void *arg) { - node_t *node = arg; + char *rx_u, *tx_u; + int rxprec, txprec; - print_item(i); - foreach_child(node, i, handle_child, node); -} + double rx = unit_value2str(a->a_rx_rate.r_total, + a->a_def->ad_unit, + &rx_u, &rxprec); + double tx = unit_value2str(a->a_tx_rate.r_total, + a->a_def->ad_unit, + &tx_u, &txprec); -static void print_list(item_t *i, node_t *node) -{ - if (i->i_flags & ITEM_FLAG_IS_CHILD) - return; - - print_item(i); - foreach_child(node, i, handle_child, node); + printf(" %-36s %12.*f%-3s %12.*f%-3s\n", + a->a_def->ad_description, rxprec, rx, rx_u, txprec, tx, tx_u); } -static void print_attr_detail(stat_attr_t *a, void *arg) +static void print_details(struct element *e) { - char *rx_u, *tx_u; - int rxprec, txprec; - double rx = cancel_down(attr_get_rx(a), a->a_unit, &rx_u, &rxprec); - double tx = cancel_down(attr_get_tx(a), a->a_unit, &tx_u, &txprec); + printf(" %s", e->e_name); - printf(" %-14s %12.*f %s %12.*f %s\n", - type2name(a->a_type), rxprec, rx, rx_u, txprec, tx, tx_u); + if (e->e_id) + printf(" (%u)", e->e_id); + + printf("\n"); + + element_foreach_attr(e, print_attr_detail, NULL); + + printf("\n"); } -static void print_details(item_t *i) +static void print_table(struct graph *g, struct graph_table *tbl, const char *hdr) { - if (i->i_handle) - printf(" %s (%u)\n", i->i_name, i->i_handle); - else - printf(" %s\n", i->i_name); + int i; - foreach_attr(i, print_attr_detail, NULL); + if (!tbl->gt_table) + return; + + printf("%s %s\n", hdr, tbl->gt_y_unit); + + for (i = (g->g_cfg.gc_height - 1); i >= 0; i--) + printf("%8.2f %s\n", tbl->gt_scale[i], + tbl->gt_table + (i * graph_row_size(&g->g_cfg))); + + printf(" 1 5 10 15 20 25 30 35 40 " \ + "45 50 55 60\n"); } -static void __print_graph(stat_attr_t *a, void *arg) +static void __print_graph(struct element *e, struct attr *a, void *arg) { - item_t *i = (item_t *) arg; - stat_attr_hist_t *h; - graph_t *g; - int w; + struct history *h; + struct graph *g; - if (!(a->a_flags & ATTR_FLAG_HISTORY)) + if (!(a->a_flags & ATTR_DOING_HISTORY)) return; - h = (stat_attr_hist_t *) a; + graph_cfg.gc_unit = a->a_def->ad_unit; - g = create_configued_graph(&h->a_hist, c_graph_height, - h->a_unit, get_x_unit()); + list_for_each_entry(h, &a->a_history_list, h_list) { + if (strcasecmp(c_hist, h->h_definition->hd_name)) + continue; - printf("Item: %s\nAttribute: %s\n", i->i_name, type2desc(a->a_type)); + g = graph_alloc(h, &graph_cfg); + graph_refill(g, h); - printf("RX %s\n", g->g_rx.t_y_unit); - - for (w = (c_graph_height - 1); w >= 0; w--) - printf("%8.2f %s\n", g->g_rx.t_y_scale[w], - (char *) g->g_rx.t_data + (w * (HISTORY_SIZE + 1))); - - printf(" 1 5 10 15 20 25 30 35 40 " \ - "45 50 55 60 %s\n", g->g_rx.t_x_unit); + printf("Interface: %s\n", e->e_name); + printf("Attribute: %s\n", a->a_def->ad_description); - printf("TX %s\n", g->g_tx.t_y_unit); - - for (w = (c_graph_height - 1); w >= 0; w--) - printf("%8.2f %s\n", g->g_tx.t_y_scale[w], - (char *) g->g_tx.t_data + (w * (HISTORY_SIZE + 1))); - - printf(" 1 5 10 15 20 25 30 35 40 " \ - "45 50 55 60 %s\n", g->g_tx.t_x_unit); + print_table(g, &g->g_rx, "RX"); + print_table(g, &g->g_tx, "TX"); - free_graph(g); + graph_free(g); + + } } -static void print_graph(item_t *i) +static void print_graph(struct element *e) { - foreach_attr(i, &__print_graph, i); + element_foreach_attr(e, __print_graph, NULL); } -static void ascii_draw_item(item_t *i, void *arg) +static void ascii_draw_element(struct element_group *g, struct element *e, + void *arg) { - node_t *node = arg; - switch (c_diagram_type) { case D_LIST: - print_list(i, node); + print_list(e); break; case D_DETAILS: - print_details(i); + print_details(e); break; case D_GRAPH: - print_graph(i); + print_graph(e); break; } } -static void ascii_draw_node(node_t *n, void *arg) +static void ascii_draw_group(struct element_group *g, void *arg) { - if (n->n_name) { - if (get_nnodes() > 1) - printf("%s:\n", n->n_name); - foreach_item(n, ascii_draw_item, n); - } + if (c_diagram_type == D_LIST) + printf("%-37s%10s %11s %%%10s %11s %%\n", + g->g_hdr->gh_title, + g->g_hdr->gh_column[0], + g->g_hdr->gh_column[1], + g->g_hdr->gh_column[2], + g->g_hdr->gh_column[3]); + else + printf("%s\n", g->g_hdr->gh_title); + + group_foreach_element(g, ascii_draw_element, NULL); } static void ascii_draw(void) { - foreach_node(ascii_draw_node, NULL); + group_foreach(ascii_draw_group, NULL); if (c_quit_after > 0) if (--c_quit_after == 0) exit(0); } -static int ascii_probe(void) -{ - return 1; -} - static void print_help(void) { printf( @@ -249,8 +225,6 @@ static void print_help(void) "\n" \ " Plain configurable ASCII output.\n" \ "\n" \ - " vmstat like: (print header every 10 lines)\n" \ - " bmon -p eth0 -o ascii:header=10\n" \ " scriptable: (output graph for eth1 10 times)\n" \ " bmon -p eth1 -o 'ascii:diagram=graph;quitafter=10'\n" \ " show details for all ethernet interfaces:\n" \ @@ -267,56 +241,59 @@ static void print_help(void) " height=NUM Height of graph (default: 6)\n" \ " xunit=UNIT X-Axis Unit (default: seconds)\n" \ " yunit=UNIT Y-Axis Unit (default: dynamic)\n" \ - " header[=NUM] Print header every NUM lines\n" \ - " noheader Do not print a header\n" \ " quitafter=NUM Quit bmon after NUM outputs\n"); } -static void ascii_set_opts(tv_t *attrs) +static void ascii_parse_opt(const char *type, const char *value) { - while (attrs) { - if (!strcasecmp(attrs->type, "diagram") && attrs->value) - set_diagram_type(attrs->value); - else if (!strcasecmp(attrs->type, "fgchar") && attrs->value) - set_fg_char(attrs->value[0]); - else if (!strcasecmp(attrs->type, "bgchar") && attrs->value) - set_bg_char(attrs->value[0]); - else if (!strcasecmp(attrs->type, "nchar") && attrs->value) - set_noise_char(attrs->value[0]); - else if (!strcasecmp(attrs->type, "uchar") && attrs->value) - set_unk_char(attrs->value[0]); - else if (!strcasecmp(attrs->type, "xunit") && attrs->value) - set_x_unit(attrs->value, 1); - else if (!strcasecmp(attrs->type, "yunit") && attrs->value) - set_y_unit(attrs->value); - else if (!strcasecmp(attrs->type, "height") && attrs->value) - c_graph_height = strtol(attrs->value, NULL, 0); - else if (!strcasecmp(attrs->type, "header")) { - if (attrs->value) - c_print_header = strtol(attrs->value, NULL, 0); - else - c_print_header = INT_MAX; - } else if (!strcasecmp(attrs->type, "noheader")) - c_print_header = 0; - else if (!strcasecmp(attrs->type, "quitafter") && attrs->value) - c_quit_after = strtol(attrs->value, NULL, 0); - else if (!strcasecmp(attrs->type, "help")) { - print_help(); - exit(0); - } - - attrs = attrs->next; - } + if (!strcasecmp(type, "diagram") && value) { + if (tolower(*value) == 'l') + c_diagram_type = D_LIST; + else if (tolower(*value) == 'g') + c_diagram_type = D_GRAPH; + else if (tolower(*value) == 'd') + c_diagram_type = D_DETAILS; + else + quit("Unknown diagram type '%s'\n", value); + } else if (!strcasecmp(type, "fgchar") && value) + graph_cfg.gc_foreground = value[0]; + else if (!strcasecmp(type, "bgchar") && value) + graph_cfg.gc_background = value[0]; + else if (!strcasecmp(type, "nchar") && value) + graph_cfg.gc_noise = value[0]; +#if 0 + else if (!strcasecmp(type, "uchar") && value) + set_unk_char(value[0]); +#endif + else if (!strcasecmp(type, "xunit") && value) + c_hist = strdup(value); +#if 0 + else if (!strcasecmp(type, "yunit") && value) { + struct unit *u; + + if (!(u = unit_lookup(value))) + quit("Unknown unit '%s'\n", value); + + graph_cfg.gc_unit = u; +#endif + else if (!strcasecmp(type, "height") && value) + graph_cfg.gc_height = strtol(value, NULL, 0); + else if (!strcasecmp(type, "quitafter") && value) + c_quit_after = strtol(value, NULL, 0); + else if (!strcasecmp(type, "help")) { + print_help(); + exit(0); + } else + quit("Unknown module option '%s'\n", type); } -static struct output_module ascii_ops = { - .om_name = "ascii", - .om_draw = ascii_draw, - .om_probe = ascii_probe, - .om_set_opts = ascii_set_opts, +static struct bmon_module ascii_ops = { + .m_name = "ascii", + .m_do = ascii_draw, + .m_parse_opt = ascii_parse_opt, }; static void __init ascii_init(void) { - register_output_module(&ascii_ops); + output_register(&ascii_ops); }