Diff for /embedaddon/bmon/src/out_ascii.c between versions 1.1.1.1 and 1.1.1.2

version 1.1.1.1, 2012/02/21 22:19:56 version 1.1.1.2, 2014/07/30 07:55:27
Line 1 Line 1
 /*  /*
  * out_ascii.c           ASCII Output   * out_ascii.c           ASCII Output
  *   *
 * Copyright (c) 2001-2005 Thomas Graf <tgraf@suug.ch> * Copyright (c) 2001-2013 Thomas Graf <tgraf@suug.ch>
  * Copyright (c) 2013 Red Hat, Inc.
  *   *
  * Permission is hereby granted, free of charge, to any person obtaining a   * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),   * copy of this software and associated documentation files (the "Software"),
Line 23 Line 24
  */   */
   
 #include <bmon/bmon.h>  #include <bmon/bmon.h>
 #include <bmon/graph.h>  
 #include <bmon/conf.h>  #include <bmon/conf.h>
 #include <bmon/output.h>  #include <bmon/output.h>
#include <bmon/node.h>#include <bmon/group.h>
 #include <bmon/element.h>
 #include <bmon/attr.h>
 #include <bmon/graph.h>
 #include <bmon/history.h>
 #include <bmon/utils.h>  #include <bmon/utils.h>
   
 typedef enum diagram_type_e {  typedef enum diagram_type_e {
Line 35  typedef enum diagram_type_e { Line 39  typedef enum diagram_type_e {
         D_DETAILS          D_DETAILS
 } diagram_type_t;  } 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 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 int c_quit_after = -1;
   
static inline int get_print_header(void)static void print_list(struct element *e)
 {  {
        static int hdr_rem;        char *rxu1 = "", *txu1 = "", *rxu2 = "", *txu2 = "";
        double rx1 = 0.0f, tx1 = 0.0f, rx2 = 0.0f, tx2 = 0.0f;
        if (c_print_header) {        int rx1prec = 0, tx1prec = 0, rx2prec = 0, tx2prec = 0;
                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 pad[IFNAMSIZ + 32];          char pad[IFNAMSIZ + 32];
                struct attr *a;
        if (get_print_header()) { 
                printf("Name                      RX Rate         #   %%" \ 
                       "     TX Rate         #   %%\n"); 
        } 
   
        bytes = lookup_attr(i, i->i_major_attr);        if (e->e_key_attr[GT_MAJOR] &&
        packets = lookup_attr(i, i->i_minor_attr);            (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);        if (e->e_key_attr[GT_MINOR] &&
        tx = cancel_down(attr_get_tx_rate(bytes), bytes->a_unit, &tx_u, &txprec);            (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, 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, " (", 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);                  strncat(pad, ")", sizeof(pad) - strlen(pad) - 1);
         }          }
   
        printf("%-22s %8.*f%s %8.*f%s ", pad, rxprec, rx, rx_u, rxpprec, rxp, rxp_u);        printf("  %-36s %8.*f%-3s %8.*f%-3s ",
        if (i->i_rx_usage < 0)               pad, rx1prec, rx1, rxu1, rx2prec, rx2, rxu2);
                printf("   "); 
        else 
                printf("%2d%%", i->i_rx_usage); 
   
        printf(" %8.*f%s %8.*f%s ", txprec, tx, tx_u, txpprec, txp, txp_u);        if (e->e_rx_usage == FLT_MAX)
        if (i->i_tx_usage < 0) 
                 printf("   ");                  printf("   ");
         else          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 print_attr_detail(struct element *e, struct attr *a, void *arg)
static void handle_child(item_t *i, void *arg) 
 {  {
        node_t *node = arg;        char *rx_u, *tx_u;
         int rxprec, txprec;
   
        print_item(i);        double rx = unit_value2str(a->a_rx_rate.r_total,
        foreach_child(node, i, handle_child, node);                                   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)        printf("  %-36s %12.*f%-3s %12.*f%-3s\n",
{               a->a_def->ad_description, rxprec, rx, rx_u, txprec, tx, tx_u);
        if (i->i_flags & ITEM_FLAG_IS_CHILD) 
                return; 
         
        print_item(i); 
        foreach_child(node, i, handle_child, node); 
 }  }
   
static void print_attr_detail(stat_attr_t *a, void *arg)static void print_details(struct element *e)
 {  {
        char *rx_u, *tx_u;        printf(" %s", e->e_name);
        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("  %-14s %12.*f %s %12.*f %s\n",        if (e->e_id)
            type2name(a->a_type), rxprec, rx, rx_u, txprec, tx, tx_u);                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)        int i;
                printf(" %s (%u)\n", i->i_name, i->i_handle); 
        else 
                printf(" %s\n", i->i_name); 
   
        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;        struct history *h;
        stat_attr_hist_t *h;        struct graph *g;
        graph_t *g; 
        int w; 
   
        if (!(a->a_flags & ATTR_FLAG_HISTORY))        if (!(a->a_flags & ATTR_DOING_HISTORY))
                 return;                  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,        list_for_each_entry(h, &a->a_history_list, h_list) {
                                    h->a_unit, get_x_unit());                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);                printf("Interface: %s\n", e->e_name);
                        printf("Attribute: %s\n", a->a_def->ad_description);
        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("TX   %s\n", g->g_tx.t_y_unit);                print_table(g, &g->g_rx, "RX");
                        print_table(g, &g->g_tx, "TX");
        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); 
   
        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) {          switch (c_diagram_type) {
                 case D_LIST:                  case D_LIST:
                        print_list(i, node);                        print_list(e);
                         break;                          break;
   
                 case D_DETAILS:                  case D_DETAILS:
                        print_details(i);                        print_details(e);
                         break;                          break;
   
                 case D_GRAPH:                  case D_GRAPH:
                        print_graph(i);                        print_graph(e);
                         break;                          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 (c_diagram_type == D_LIST)
                if (get_nnodes() > 1)                printf("%-37s%10s %11s      %%%10s %11s      %%\n",
                        printf("%s:\n", n->n_name);                       g->g_hdr->gh_title,
                foreach_item(n, ascii_draw_item, n);                       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)  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)
                 if (--c_quit_after == 0)                  if (--c_quit_after == 0)
                         exit(0);                          exit(0);
 }  }
   
 static int ascii_probe(void)  
 {  
         return 1;  
 }  
   
 static void print_help(void)  static void print_help(void)
 {  {
         printf(          printf(
Line 249  static void print_help(void) Line 225  static void print_help(void)
         "\n" \          "\n" \
         "  Plain configurable ASCII output.\n" \          "  Plain configurable ASCII output.\n" \
         "\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" \          "  scriptable: (output graph for eth1 10 times)\n" \
         "      bmon -p eth1 -o 'ascii:diagram=graph;quitafter=10'\n" \          "      bmon -p eth1 -o 'ascii:diagram=graph;quitafter=10'\n" \
         "  show details for all ethernet interfaces:\n" \          "  show details for all ethernet interfaces:\n" \
Line 267  static void print_help(void) Line 241  static void print_help(void)
         "    height=NUM     Height of graph (default: 6)\n" \          "    height=NUM     Height of graph (default: 6)\n" \
         "    xunit=UNIT     X-Axis Unit (default: seconds)\n" \          "    xunit=UNIT     X-Axis Unit (default: seconds)\n" \
         "    yunit=UNIT     Y-Axis Unit (default: dynamic)\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");          "    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(type, "diagram") && value) {
                if (!strcasecmp(attrs->type, "diagram") && attrs->value)                if (tolower(*value) == 'l')
                        set_diagram_type(attrs->value);                        c_diagram_type = D_LIST;
                else if (!strcasecmp(attrs->type, "fgchar") && attrs->value)                else if (tolower(*value) == 'g')
                        set_fg_char(attrs->value[0]);                        c_diagram_type = D_GRAPH;
                else if (!strcasecmp(attrs->type, "bgchar") && attrs->value)                else if (tolower(*value) == 'd')
                        set_bg_char(attrs->value[0]);                        c_diagram_type = D_DETAILS;
                else if (!strcasecmp(attrs->type, "nchar") && attrs->value)                else
                        set_noise_char(attrs->value[0]);                        quit("Unknown diagram type '%s'\n", value);
                else if (!strcasecmp(attrs->type, "uchar") && attrs->value)        } else if (!strcasecmp(type, "fgchar") && value)
                        set_unk_char(attrs->value[0]);                graph_cfg.gc_foreground = value[0];
                else if (!strcasecmp(attrs->type, "xunit") && attrs->value)        else if (!strcasecmp(type, "bgchar") && value)
                        set_x_unit(attrs->value, 1);                graph_cfg.gc_background = value[0];
                else if (!strcasecmp(attrs->type, "yunit") && attrs->value)        else if (!strcasecmp(type, "nchar") && value)
                        set_y_unit(attrs->value);                graph_cfg.gc_noise = value[0];
                else if (!strcasecmp(attrs->type, "height") && attrs->value)#if 0
                        c_graph_height = strtol(attrs->value, NULL, 0);        else if (!strcasecmp(type, "uchar") && value)
                else if (!strcasecmp(attrs->type, "header")) {                set_unk_char(value[0]);
                        if (attrs->value)#endif
                                c_print_header = strtol(attrs->value, NULL, 0);        else if (!strcasecmp(type, "xunit") && value)
                        else                c_hist = strdup(value);
                                c_print_header = INT_MAX;#if 0
                } else if (!strcasecmp(attrs->type, "noheader"))        else if (!strcasecmp(type, "yunit") && value) {
                        c_print_header = 0;                struct unit *u;
                else if (!strcasecmp(attrs->type, "quitafter") && attrs->value)
                        c_quit_after = strtol(attrs->value, NULL, 0);                if (!(u = unit_lookup(value)))
                else if (!strcasecmp(attrs->type, "help")) {                        quit("Unknown unit '%s'\n", value);
                        print_help();
                        exit(0);                graph_cfg.gc_unit = u;
                }#endif
                        else if (!strcasecmp(type, "height") && value)
                attrs = attrs->next;                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 = {static struct bmon_module ascii_ops = {
        .om_name = "ascii",        .m_name          = "ascii",
        .om_draw = ascii_draw,        .m_do                = ascii_draw,
        .om_probe = ascii_probe,        .m_parse_opt        = ascii_parse_opt,
        .om_set_opts = ascii_set_opts, 
 };  };
   
 static void __init ascii_init(void)  static void __init ascii_init(void)
 {  {
        register_output_module(&ascii_ops);        output_register(&ascii_ops);
 }  }

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>