File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / bmon / src / in_proc.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jul 30 07:55:27 2014 UTC (9 years, 11 months ago) by misho
Branches: bmon, MAIN
CVS tags: v3_3, HEAD
bmon 3.3

    1: /*
    2:  * in_proc.c		       /proc/net/dev Input (Linux)
    3:  *
    4:  * Copyright (c) 2001-2013 Thomas Graf <tgraf@suug.ch>
    5:  * Copyright (c) 2013 Red Hat, Inc.
    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/input.h>
   28: #include <bmon/element.h>
   29: #include <bmon/group.h>
   30: #include <bmon/attr.h>
   31: #include <bmon/utils.h>
   32: 
   33: static const char *c_path = "/proc/net/dev";
   34: static const char *c_group = DEFAULT_GROUP;
   35: static struct element_group *grp;
   36: 
   37: enum {
   38: 	PROC_BYTES,
   39: 	PROC_PACKETS,
   40: 	PROC_ERRORS,
   41: 	PROC_DROP,
   42: 	PROC_COMPRESSED,
   43: 	PROC_FIFO,
   44: 	PROC_FRAME,
   45: 	PROC_MCAST,
   46: 	NUM_PROC_VALUE,
   47: };
   48: 
   49: static struct attr_map link_attrs[NUM_PROC_VALUE] = {
   50: {
   51: 	.name		= "bytes",
   52: 	.type		= ATTR_TYPE_COUNTER,
   53: 	.unit		= UNIT_BYTE,
   54: 	.description	= "Bytes",
   55: },
   56: {
   57: 	.name		= "packets",
   58: 	.type		= ATTR_TYPE_COUNTER,
   59: 	.unit		= UNIT_NUMBER,
   60: 	.description	= "Packets",
   61: },
   62: {
   63: 	.name		= "errors",
   64: 	.type		= ATTR_TYPE_COUNTER,
   65: 	.unit		= UNIT_NUMBER,
   66: 	.description	= "Errors",
   67: },
   68: {
   69: 	.name		= "drop",
   70: 	.type		= ATTR_TYPE_COUNTER,
   71: 	.unit		= UNIT_NUMBER,
   72: 	.description	= "Dropped",
   73: },
   74: {
   75: 	.name		= "compressed",
   76: 	.type		= ATTR_TYPE_COUNTER,
   77: 	.unit		= UNIT_NUMBER,
   78: 	.description	= "Compressed",
   79: },
   80: {
   81: 	.name		= "fifoerr",
   82: 	.type		= ATTR_TYPE_COUNTER,
   83: 	.unit		= UNIT_NUMBER,
   84: 	.description	= "FIFO Error",
   85: },
   86: {
   87: 	.name		= "frameerr",
   88: 	.type		= ATTR_TYPE_COUNTER,
   89: 	.unit		= UNIT_NUMBER,
   90: 	.description	= "Frame Error",
   91: },
   92: {
   93: 	.name		= "mcast",
   94: 	.type		= ATTR_TYPE_COUNTER,
   95: 	.unit		= UNIT_NUMBER,
   96: 	.description	= "Multicast",
   97: }
   98: };
   99: 
  100: static void proc_read(void)
  101: {
  102: 	struct element *e;
  103: 	FILE *fd;
  104: 	char buf[512], *p, *s;
  105: 	int w;
  106: 	
  107: 	if (!(fd = fopen(c_path, "r")))
  108: 		quit("Unable to open file %s: %s\n", c_path, strerror(errno));
  109: 
  110: 	/* Ignore header */
  111: 	fgets(buf, sizeof(buf), fd);
  112: 	fgets(buf, sizeof(buf), fd);
  113: 	
  114: 	for (; fgets(buf, sizeof(buf), fd);) {
  115: 		uint64_t data[NUM_PROC_VALUE][2];
  116: 		int i;
  117: 		
  118: 		if (buf[0] == '\r' || buf[0] == '\n')
  119: 			continue;
  120: 
  121: 		if (!(p = strchr(buf, ':')))
  122: 			continue;
  123: 		*p = '\0';
  124: 		s = (p + 1);
  125: 		
  126: 		for (p = &buf[0]; *p == ' '; p++);
  127: 
  128: 		w = sscanf(s, "%" SCNu64 " %" SCNu64 " %" SCNu64 " %" SCNu64 " "
  129: 			      "%" SCNu64 " %" SCNu64 " %" SCNu64 " %" SCNu64 " "
  130: 			      "%" SCNu64 " %" SCNu64 " %" SCNu64 " %" SCNu64 " "
  131: 			      "%" SCNu64 " %" SCNu64 " %" SCNu64 " %" SCNu64
  132: 			      "\n",
  133: 			      &data[PROC_BYTES][0],
  134: 			      &data[PROC_PACKETS][0],
  135: 			      &data[PROC_ERRORS][0],
  136: 			      &data[PROC_DROP][0],
  137: 			      &data[PROC_FIFO][0],
  138: 			      &data[PROC_FRAME][0],
  139: 			      &data[PROC_COMPRESSED][0],
  140: 			      &data[PROC_MCAST][0],
  141: 			      &data[PROC_BYTES][1],
  142: 			      &data[PROC_PACKETS][1],
  143: 			      &data[PROC_ERRORS][1],
  144: 			      &data[PROC_DROP][1],
  145: 			      &data[PROC_FIFO][1],
  146: 			      &data[PROC_FRAME][1],
  147: 			      &data[PROC_COMPRESSED][1],
  148: 			      &data[PROC_MCAST][1]);
  149: 
  150: 		if (w != 16)
  151: 			continue;
  152: 
  153: 		if (!(e = element_lookup(grp, p, 0, NULL, ELEMENT_CREAT)))
  154: 			return;
  155: 
  156: 		if (e->e_flags & ELEMENT_FLAG_CREATED) {
  157: 			if (element_set_key_attr(e, "bytes", "packets") ||
  158: 			    element_set_usage_attr(e, "bytes"))
  159: 				BUG();
  160: 
  161: 			e->e_flags &= ~ELEMENT_FLAG_CREATED;
  162: 		}
  163: 
  164: 		for (i = 0; i < ARRAY_SIZE(link_attrs); i++) {
  165: 			struct attr_map *m = &link_attrs[i];
  166: 
  167: 			attr_update(e, m->attrid, data[i][0], data[i][1],
  168: 				    UPDATE_FLAG_RX | UPDATE_FLAG_TX);
  169: 		}
  170: 
  171: 		element_notify_update(e, NULL);
  172: 		element_lifesign(e, 1);
  173: 	}
  174: 	
  175: 	fclose(fd);
  176: }
  177: 
  178: static void print_help(void)
  179: {
  180: 	printf(
  181: 	"proc - procfs statistic collector for Linux" \
  182: 	"\n" \
  183: 	"  Reads statistics from procfs (/proc/net/dev)\n" \
  184: 	"  Author: Thomas Graf <tgraf@suug.ch>\n" \
  185: 	"\n" \
  186: 	"  Options:\n" \
  187: 	"    file=PATH	    Path to statistics file (default: /proc/net/dev)\n"
  188: 	"    group=NAME     Name of group\n");
  189: }
  190: 
  191: static void proc_parse_opt(const char *type, const char *value)
  192: {
  193: 	if (!strcasecmp(type, "file") && value)
  194: 		c_path = value;
  195: 	else if (!strcasecmp(type, "group") && value)
  196: 		c_group = value;
  197: 	else if (!strcasecmp(type, "help")) {
  198: 		print_help();
  199: 		exit(0);
  200: 	}
  201: }
  202: 
  203: static int proc_do_init(void)
  204: {
  205: 	if (attr_map_load(link_attrs, ARRAY_SIZE(link_attrs)) ||
  206: 	    !(grp = group_lookup(c_group, GROUP_CREATE)))
  207: 		BUG();
  208: 
  209: 	return 0;
  210: }
  211: 
  212: static int proc_probe(void)
  213: {
  214: 	FILE *fd = fopen(c_path, "r");
  215: 
  216: 	if (fd) {
  217: 		fclose(fd);
  218: 		return 1;
  219: 	}
  220: 	return 0;
  221: }
  222: 
  223: static struct bmon_module proc_ops = {
  224: 	.m_name		= "proc",
  225: 	.m_do		= proc_read,
  226: 	.m_parse_opt	= proc_parse_opt,
  227: 	.m_probe	= proc_probe,
  228: 	.m_init		= proc_do_init,
  229: };
  230: 
  231: static void __init proc_init(void)
  232: {
  233: 	input_register(&proc_ops);
  234: }

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