Annotation of embedaddon/bmon/src/out_ascii.c, revision 1.1.1.2
1.1 misho 1: /*
2: * out_ascii.c ASCII Output
3: *
1.1.1.2 ! misho 4: * Copyright (c) 2001-2013 Thomas Graf <tgraf@suug.ch>
! 5: * Copyright (c) 2013 Red Hat, Inc.
1.1 misho 6: *
7: * Permission is hereby granted, free of charge, to any person obtaining a
8: * copy of this software and associated documentation files (the "Software"),
9: * to deal in the Software without restriction, including without limitation
10: * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11: * and/or sell copies of the Software, and to permit persons to whom the
12: * Software is furnished to do so, subject to the following conditions:
13: *
14: * The above copyright notice and this permission notice shall be included
15: * in all copies or substantial portions of the Software.
16: *
17: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18: * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22: * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23: * DEALINGS IN THE SOFTWARE.
24: */
25:
26: #include <bmon/bmon.h>
27: #include <bmon/conf.h>
28: #include <bmon/output.h>
1.1.1.2 ! misho 29: #include <bmon/group.h>
! 30: #include <bmon/element.h>
! 31: #include <bmon/attr.h>
! 32: #include <bmon/graph.h>
! 33: #include <bmon/history.h>
1.1 misho 34: #include <bmon/utils.h>
35:
36: typedef enum diagram_type_e {
37: D_LIST,
38: D_GRAPH,
39: D_DETAILS
40: } diagram_type_t;
41:
1.1.1.2 ! misho 42: static struct graph_cfg graph_cfg = {
! 43: .gc_foreground = '*',
! 44: .gc_background = ' ',
! 45: .gc_noise = '.',
! 46: .gc_unknown = '?',
! 47: .gc_height = 6,
! 48: };
! 49:
1.1 misho 50: static diagram_type_t c_diagram_type = D_LIST;
1.1.1.2 ! misho 51: static char *c_hist = "second";
1.1 misho 52: static int c_quit_after = -1;
53:
1.1.1.2 ! misho 54: static void print_list(struct element *e)
1.1 misho 55: {
1.1.1.2 ! misho 56: char *rxu1 = "", *txu1 = "", *rxu2 = "", *txu2 = "";
! 57: double rx1 = 0.0f, tx1 = 0.0f, rx2 = 0.0f, tx2 = 0.0f;
! 58: int rx1prec = 0, tx1prec = 0, rx2prec = 0, tx2prec = 0;
1.1 misho 59: char pad[IFNAMSIZ + 32];
1.1.1.2 ! misho 60: struct attr *a;
1.1 misho 61:
1.1.1.2 ! misho 62: if (e->e_key_attr[GT_MAJOR] &&
! 63: (a = attr_lookup(e, e->e_key_attr[GT_MAJOR]->ad_id)))
! 64: attr_rate2float(a, &rx1, &rxu1, &rx1prec,
! 65: &tx1, &txu1, &tx1prec);
! 66:
! 67: if (e->e_key_attr[GT_MINOR] &&
! 68: (a = attr_lookup(e, e->e_key_attr[GT_MINOR]->ad_id)))
! 69: attr_rate2float(a, &rx2, &rxu2, &rx2prec,
! 70: &tx2, &txu2, &tx2prec);
1.1 misho 71:
72: memset(pad, 0, sizeof(pad));
1.1.1.2 ! misho 73: memset(pad, ' ', e->e_level < 15 ? e->e_level : 15);
1.1 misho 74:
1.1.1.2 ! misho 75: strncat(pad, e->e_name, sizeof(pad) - strlen(pad) - 1);
1.1 misho 76:
1.1.1.2 ! misho 77: if (e->e_description) {
1.1 misho 78: strncat(pad, " (", sizeof(pad) - strlen(pad) - 1);
1.1.1.2 ! misho 79: strncat(pad, e->e_description, sizeof(pad) - strlen(pad) - 1);
1.1 misho 80: strncat(pad, ")", sizeof(pad) - strlen(pad) - 1);
81: }
82:
1.1.1.2 ! misho 83: printf(" %-36s %8.*f%-3s %8.*f%-3s ",
! 84: pad, rx1prec, rx1, rxu1, rx2prec, rx2, rxu2);
1.1 misho 85:
1.1.1.2 ! misho 86: if (e->e_rx_usage == FLT_MAX)
1.1 misho 87: printf(" ");
88: else
1.1.1.2 ! misho 89: printf("%2.0f%%", e->e_rx_usage);
1.1 misho 90:
1.1.1.2 ! misho 91: printf(" %8.*f%-3s %8.*f%-3s ", tx1prec, tx1, txu1, tx2prec, tx2, txu2);
1.1 misho 92:
1.1.1.2 ! misho 93: if (e->e_tx_usage == FLT_MAX)
! 94: printf(" \n");
! 95: else
! 96: printf("%2.0f%%\n", e->e_tx_usage);
! 97: }
1.1 misho 98:
1.1.1.2 ! misho 99: static void print_attr_detail(struct element *e, struct attr *a, void *arg)
1.1 misho 100: {
1.1.1.2 ! misho 101: char *rx_u, *tx_u;
! 102: int rxprec, txprec;
1.1 misho 103:
1.1.1.2 ! misho 104: double rx = unit_value2str(a->a_rx_rate.r_total,
! 105: a->a_def->ad_unit,
! 106: &rx_u, &rxprec);
! 107: double tx = unit_value2str(a->a_tx_rate.r_total,
! 108: a->a_def->ad_unit,
! 109: &tx_u, &txprec);
1.1 misho 110:
1.1.1.2 ! misho 111: printf(" %-36s %12.*f%-3s %12.*f%-3s\n",
! 112: a->a_def->ad_description, rxprec, rx, rx_u, txprec, tx, tx_u);
1.1 misho 113: }
114:
1.1.1.2 ! misho 115: static void print_details(struct element *e)
1.1 misho 116: {
1.1.1.2 ! misho 117: printf(" %s", e->e_name);
! 118:
! 119: if (e->e_id)
! 120: printf(" (%u)", e->e_id);
! 121:
! 122: printf("\n");
! 123:
! 124: element_foreach_attr(e, print_attr_detail, NULL);
1.1 misho 125:
1.1.1.2 ! misho 126: printf("\n");
1.1 misho 127: }
128:
1.1.1.2 ! misho 129: static void print_table(struct graph *g, struct graph_table *tbl, const char *hdr)
1.1 misho 130: {
1.1.1.2 ! misho 131: int i;
1.1 misho 132:
1.1.1.2 ! misho 133: if (!tbl->gt_table)
! 134: return;
! 135:
! 136: printf("%s %s\n", hdr, tbl->gt_y_unit);
! 137:
! 138: for (i = (g->g_cfg.gc_height - 1); i >= 0; i--)
! 139: printf("%8.2f %s\n", tbl->gt_scale[i],
! 140: tbl->gt_table + (i * graph_row_size(&g->g_cfg)));
! 141:
! 142: printf(" 1 5 10 15 20 25 30 35 40 " \
! 143: "45 50 55 60\n");
1.1 misho 144: }
145:
1.1.1.2 ! misho 146: static void __print_graph(struct element *e, struct attr *a, void *arg)
1.1 misho 147: {
1.1.1.2 ! misho 148: struct history *h;
! 149: struct graph *g;
1.1 misho 150:
1.1.1.2 ! misho 151: if (!(a->a_flags & ATTR_DOING_HISTORY))
1.1 misho 152: return;
153:
1.1.1.2 ! misho 154: graph_cfg.gc_unit = a->a_def->ad_unit;
1.1 misho 155:
1.1.1.2 ! misho 156: list_for_each_entry(h, &a->a_history_list, h_list) {
! 157: if (strcasecmp(c_hist, h->h_definition->hd_name))
! 158: continue;
1.1 misho 159:
1.1.1.2 ! misho 160: g = graph_alloc(h, &graph_cfg);
! 161: graph_refill(g, h);
1.1 misho 162:
1.1.1.2 ! misho 163: printf("Interface: %s\n", e->e_name);
! 164: printf("Attribute: %s\n", a->a_def->ad_description);
1.1 misho 165:
1.1.1.2 ! misho 166: print_table(g, &g->g_rx, "RX");
! 167: print_table(g, &g->g_tx, "TX");
! 168:
! 169: graph_free(g);
1.1 misho 170:
1.1.1.2 ! misho 171: }
1.1 misho 172: }
173:
1.1.1.2 ! misho 174: static void print_graph(struct element *e)
1.1 misho 175: {
1.1.1.2 ! misho 176: element_foreach_attr(e, __print_graph, NULL);
1.1 misho 177: }
178:
1.1.1.2 ! misho 179: static void ascii_draw_element(struct element_group *g, struct element *e,
! 180: void *arg)
1.1 misho 181: {
182: switch (c_diagram_type) {
183: case D_LIST:
1.1.1.2 ! misho 184: print_list(e);
1.1 misho 185: break;
186:
187: case D_DETAILS:
1.1.1.2 ! misho 188: print_details(e);
1.1 misho 189: break;
190:
191: case D_GRAPH:
1.1.1.2 ! misho 192: print_graph(e);
1.1 misho 193: break;
194: }
195: }
196:
1.1.1.2 ! misho 197: static void ascii_draw_group(struct element_group *g, void *arg)
1.1 misho 198: {
1.1.1.2 ! misho 199: if (c_diagram_type == D_LIST)
! 200: printf("%-37s%10s %11s %%%10s %11s %%\n",
! 201: g->g_hdr->gh_title,
! 202: g->g_hdr->gh_column[0],
! 203: g->g_hdr->gh_column[1],
! 204: g->g_hdr->gh_column[2],
! 205: g->g_hdr->gh_column[3]);
! 206: else
! 207: printf("%s\n", g->g_hdr->gh_title);
! 208:
! 209: group_foreach_element(g, ascii_draw_element, NULL);
1.1 misho 210: }
211:
212: static void ascii_draw(void)
213: {
1.1.1.2 ! misho 214: group_foreach(ascii_draw_group, NULL);
1.1 misho 215:
216: if (c_quit_after > 0)
217: if (--c_quit_after == 0)
218: exit(0);
219: }
220:
221: static void print_help(void)
222: {
223: printf(
224: "ascii - ASCII Output\n" \
225: "\n" \
226: " Plain configurable ASCII output.\n" \
227: "\n" \
228: " scriptable: (output graph for eth1 10 times)\n" \
229: " bmon -p eth1 -o 'ascii:diagram=graph;quitafter=10'\n" \
230: " show details for all ethernet interfaces:\n" \
231: " bmon -p 'eth*' -o 'ascii:diagram=details;quitafter=1'\n" \
232: "\n" \
233: " Author: Thomas Graf <tgraf@suug.ch>\n" \
234: "\n" \
235: " Options:\n" \
236: " diagram=TYPE Diagram type\n" \
237: " fgchar=CHAR Foreground character (default: '*')\n" \
238: " bgchar=CHAR Background character (default: '.')\n" \
239: " nchar=CHAR Noise character (default: ':')\n" \
240: " uchar=CHAR Unknown character (default: '?')\n" \
241: " height=NUM Height of graph (default: 6)\n" \
242: " xunit=UNIT X-Axis Unit (default: seconds)\n" \
243: " yunit=UNIT Y-Axis Unit (default: dynamic)\n" \
244: " quitafter=NUM Quit bmon after NUM outputs\n");
245: }
246:
1.1.1.2 ! misho 247: static void ascii_parse_opt(const char *type, const char *value)
1.1 misho 248: {
1.1.1.2 ! misho 249: if (!strcasecmp(type, "diagram") && value) {
! 250: if (tolower(*value) == 'l')
! 251: c_diagram_type = D_LIST;
! 252: else if (tolower(*value) == 'g')
! 253: c_diagram_type = D_GRAPH;
! 254: else if (tolower(*value) == 'd')
! 255: c_diagram_type = D_DETAILS;
! 256: else
! 257: quit("Unknown diagram type '%s'\n", value);
! 258: } else if (!strcasecmp(type, "fgchar") && value)
! 259: graph_cfg.gc_foreground = value[0];
! 260: else if (!strcasecmp(type, "bgchar") && value)
! 261: graph_cfg.gc_background = value[0];
! 262: else if (!strcasecmp(type, "nchar") && value)
! 263: graph_cfg.gc_noise = value[0];
! 264: #if 0
! 265: else if (!strcasecmp(type, "uchar") && value)
! 266: set_unk_char(value[0]);
! 267: #endif
! 268: else if (!strcasecmp(type, "xunit") && value)
! 269: c_hist = strdup(value);
! 270: #if 0
! 271: else if (!strcasecmp(type, "yunit") && value) {
! 272: struct unit *u;
! 273:
! 274: if (!(u = unit_lookup(value)))
! 275: quit("Unknown unit '%s'\n", value);
! 276:
! 277: graph_cfg.gc_unit = u;
! 278: #endif
! 279: else if (!strcasecmp(type, "height") && value)
! 280: graph_cfg.gc_height = strtol(value, NULL, 0);
! 281: else if (!strcasecmp(type, "quitafter") && value)
! 282: c_quit_after = strtol(value, NULL, 0);
! 283: else if (!strcasecmp(type, "help")) {
! 284: print_help();
! 285: exit(0);
! 286: } else
! 287: quit("Unknown module option '%s'\n", type);
! 288: }
! 289:
! 290: static struct bmon_module ascii_ops = {
! 291: .m_name = "ascii",
! 292: .m_do = ascii_draw,
! 293: .m_parse_opt = ascii_parse_opt,
1.1 misho 294: };
295:
296: static void __init ascii_init(void)
297: {
1.1.1.2 ! misho 298: output_register(&ascii_ops);
1.1 misho 299: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>