version 1.1, 2012/02/21 22:19:56
|
version 1.1.1.3, 2019/10/21 14:58:35
|
Line 1
|
Line 1
|
/* |
/* |
* in_proc.c /proc/net/dev Input (Linux) |
* in_proc.c /proc/net/dev Input (Linux) |
* |
* |
* Copyright (c) 2001-2004 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 24
|
Line 25
|
|
|
#include <bmon/bmon.h> |
#include <bmon/bmon.h> |
#include <bmon/input.h> |
#include <bmon/input.h> |
#include <bmon/node.h> | #include <bmon/element.h> |
#include <bmon/item.h> | #include <bmon/group.h> |
| #include <bmon/attr.h> |
#include <bmon/utils.h> |
#include <bmon/utils.h> |
#include <inttypes.h> |
|
|
|
static char *c_path = "/proc/net/dev"; | static const char *c_path = "/proc/net/dev"; |
| static const char *c_group = DEFAULT_GROUP; |
| static struct element_group *grp; |
|
|
|
enum { |
|
PROC_BYTES, |
|
PROC_PACKETS, |
|
PROC_ERRORS, |
|
PROC_DROP, |
|
PROC_COMPRESSED, |
|
PROC_FIFO, |
|
PROC_FRAME, |
|
PROC_MCAST, |
|
NUM_PROC_VALUE, |
|
}; |
|
|
|
static struct attr_map link_attrs[NUM_PROC_VALUE] = { |
|
{ |
|
.name = "bytes", |
|
.type = ATTR_TYPE_COUNTER, |
|
.unit = UNIT_BYTE, |
|
.description = "Bytes", |
|
}, |
|
{ |
|
.name = "packets", |
|
.type = ATTR_TYPE_COUNTER, |
|
.unit = UNIT_NUMBER, |
|
.description = "Packets", |
|
}, |
|
{ |
|
.name = "errors", |
|
.type = ATTR_TYPE_COUNTER, |
|
.unit = UNIT_NUMBER, |
|
.description = "Errors", |
|
}, |
|
{ |
|
.name = "drop", |
|
.type = ATTR_TYPE_COUNTER, |
|
.unit = UNIT_NUMBER, |
|
.description = "Dropped", |
|
}, |
|
{ |
|
.name = "compressed", |
|
.type = ATTR_TYPE_COUNTER, |
|
.unit = UNIT_NUMBER, |
|
.description = "Compressed", |
|
}, |
|
{ |
|
.name = "fifoerr", |
|
.type = ATTR_TYPE_COUNTER, |
|
.unit = UNIT_NUMBER, |
|
.description = "FIFO Error", |
|
}, |
|
{ |
|
.name = "frameerr", |
|
.type = ATTR_TYPE_COUNTER, |
|
.unit = UNIT_NUMBER, |
|
.description = "Frame Error", |
|
}, |
|
{ |
|
.name = "mcast", |
|
.type = ATTR_TYPE_COUNTER, |
|
.unit = UNIT_NUMBER, |
|
.description = "Multicast", |
|
} |
|
}; |
|
|
static void proc_read(void) |
static void proc_read(void) |
{ |
{ |
FILE * fd; | struct element *e; |
char buf[512], *p, *s; | FILE *fd; |
int w; | char buf[512], *p, *s, *unused __unused__; |
item_t *it; | int w; |
|
|
if (!(fd = fopen(c_path, "r"))) |
if (!(fd = fopen(c_path, "r"))) |
quit("Unable to open file %s: %s\n", c_path, strerror(errno)); |
quit("Unable to open file %s: %s\n", c_path, strerror(errno)); |
|
|
|
/* Ignore header */ |
|
unused = fgets(buf, sizeof(buf), fd); |
|
unused = fgets(buf, sizeof(buf), fd); |
|
|
fgets(buf, sizeof(buf), fd); |
|
fgets(buf, sizeof(buf), fd); |
|
|
|
for (; fgets(buf, sizeof(buf), fd);) { |
for (; fgets(buf, sizeof(buf), fd);) { |
b_cnt_t rx_errors, rx_drop, rx_fifo, rx_frame, rx_compressed; | uint64_t data[NUM_PROC_VALUE][2]; |
b_cnt_t rx_multicast, tx_errors, tx_drop, tx_fifo, tx_frame; | int i; |
b_cnt_t tx_compressed, tx_multicast, rx_bytes, tx_bytes; | |
b_cnt_t rx_packets, tx_packets; | |
|
|
if (buf[0] == '\r' || buf[0] == '\n') |
if (buf[0] == '\r' || buf[0] == '\n') |
continue; |
continue; |
| |
if (!(p = strchr(buf, ':'))) |
if (!(p = strchr(buf, ':'))) |
continue; |
continue; |
*p = '\0'; |
*p = '\0'; |
Line 60 static void proc_read(void)
|
Line 125 static void proc_read(void)
|
|
|
for (p = &buf[0]; *p == ' '; p++); |
for (p = &buf[0]; *p == ' '; p++); |
|
|
/* |
|
* XXX: get_show_only_running |
|
*/ |
|
|
|
if ((it = lookup_item(get_local_node(), p, 0, 0)) == NULL) |
|
continue; |
|
|
|
w = sscanf(s, "%" SCNu64 " %" SCNu64 " %" SCNu64 " %" SCNu64 " " |
w = sscanf(s, "%" SCNu64 " %" SCNu64 " %" SCNu64 " %" SCNu64 " " |
"%" SCNu64 " %" SCNu64 " %" SCNu64 " %" SCNu64 " " |
"%" SCNu64 " %" SCNu64 " %" SCNu64 " %" SCNu64 " " |
"%" SCNu64 " %" SCNu64 " %" SCNu64 " %" SCNu64 " " |
"%" SCNu64 " %" SCNu64 " %" SCNu64 " %" SCNu64 " " |
"%" SCNu64 " %" SCNu64 " %" SCNu64 " %" SCNu64 "\n", | "%" SCNu64 " %" SCNu64 " %" SCNu64 " %" SCNu64 |
&rx_bytes, &rx_packets, &rx_errors, &rx_drop, &rx_fifo, | "\n", |
&rx_frame, &rx_compressed, &rx_multicast, &tx_bytes, | &data[PROC_BYTES][0], |
&tx_packets, &tx_errors, &tx_drop, &tx_fifo, | &data[PROC_PACKETS][0], |
&tx_frame, &tx_compressed, &tx_multicast); | &data[PROC_ERRORS][0], |
| &data[PROC_DROP][0], |
| &data[PROC_FIFO][0], |
| &data[PROC_FRAME][0], |
| &data[PROC_COMPRESSED][0], |
| &data[PROC_MCAST][0], |
| &data[PROC_BYTES][1], |
| &data[PROC_PACKETS][1], |
| &data[PROC_ERRORS][1], |
| &data[PROC_DROP][1], |
| &data[PROC_FIFO][1], |
| &data[PROC_FRAME][1], |
| &data[PROC_COMPRESSED][1], |
| &data[PROC_MCAST][1]); |
| |
if (w != 16) |
if (w != 16) |
continue; |
continue; |
|
|
it->i_major_attr = BYTES; |
|
it->i_minor_attr = PACKETS; |
|
|
|
update_attr(it, BYTES, rx_bytes, tx_bytes, RX_PROVIDED|TX_PROVIDED); |
|
update_attr(it, PACKETS, rx_packets, tx_packets, RX_PROVIDED|TX_PROVIDED); |
|
update_attr(it, ERRORS, rx_errors, tx_errors, RX_PROVIDED|TX_PROVIDED); |
|
update_attr(it, DROP, rx_drop, tx_drop, RX_PROVIDED|TX_PROVIDED); |
|
update_attr(it, FIFO, rx_fifo, tx_fifo, RX_PROVIDED|TX_PROVIDED); |
|
update_attr(it, FRAME, rx_frame, tx_frame, RX_PROVIDED|TX_PROVIDED); |
|
update_attr(it, COMPRESSED, rx_compressed, tx_compressed, RX_PROVIDED|TX_PROVIDED); |
|
update_attr(it, MULTICAST, rx_multicast, tx_multicast, RX_PROVIDED|TX_PROVIDED); |
|
|
|
notify_update(it, NULL); | if (!(e = element_lookup(grp, p, 0, NULL, ELEMENT_CREAT))) |
increase_lifetime(it, 1); | goto skip; |
| |
| if (e->e_flags & ELEMENT_FLAG_CREATED) { |
| if (element_set_key_attr(e, "bytes", "packets") || |
| element_set_usage_attr(e, "bytes")) |
| BUG(); |
| |
| e->e_flags &= ~ELEMENT_FLAG_CREATED; |
| } |
| |
| for (i = 0; i < ARRAY_SIZE(link_attrs); i++) { |
| struct attr_map *m = &link_attrs[i]; |
| |
| attr_update(e, m->attrid, data[i][0], data[i][1], |
| UPDATE_FLAG_RX | UPDATE_FLAG_TX); |
| } |
| |
| element_notify_update(e, NULL); |
| element_lifesign(e, 1); |
} |
} |
| skip: |
fclose(fd); |
fclose(fd); |
} |
} |
|
|
Line 107 static void print_help(void)
|
Line 184 static void print_help(void)
|
" Author: Thomas Graf <tgraf@suug.ch>\n" \ |
" Author: Thomas Graf <tgraf@suug.ch>\n" \ |
"\n" \ |
"\n" \ |
" Options:\n" \ |
" Options:\n" \ |
" file=PATH Path to statistics file (default: /proc/net/dev)\n"); | " file=PATH Path to statistics file (default: /proc/net/dev)\n" |
| " group=NAME Name of group\n"); |
} |
} |
|
|
static void proc_set_opts(tv_t *attrs) | static void proc_parse_opt(const char *type, const char *value) |
{ |
{ |
while (attrs) { | if (!strcasecmp(type, "file") && value) |
if (!strcasecmp(attrs->type, "file") && attrs->value) | c_path = value; |
c_path = attrs->value; | else if (!strcasecmp(type, "group") && value) |
else if (!strcasecmp(attrs->type, "help")) { | c_group = value; |
print_help(); | else if (!strcasecmp(type, "help")) { |
exit(0); | print_help(); |
} | exit(0); |
attrs = attrs->next; | |
} |
} |
} |
} |
|
|
|
static int proc_do_init(void) |
|
{ |
|
if (attr_map_load(link_attrs, ARRAY_SIZE(link_attrs)) || |
|
!(grp = group_lookup(c_group, GROUP_CREATE))) |
|
BUG(); |
|
|
|
return 0; |
|
} |
|
|
static int proc_probe(void) |
static int proc_probe(void) |
{ |
{ |
FILE *fd = fopen(c_path, "r"); |
FILE *fd = fopen(c_path, "r"); |
Line 134 static int proc_probe(void)
|
Line 220 static int proc_probe(void)
|
return 0; |
return 0; |
} |
} |
|
|
static struct input_module proc_ops = { | static struct bmon_module proc_ops = { |
.im_name = "proc", | .m_name = "proc", |
.im_read = proc_read, | .m_do = proc_read, |
.im_set_opts = proc_set_opts, | .m_parse_opt = proc_parse_opt, |
.im_probe = proc_probe, | .m_probe = proc_probe, |
| .m_init = proc_do_init, |
}; |
}; |
|
|
static void __init proc_init(void) |
static void __init proc_init(void) |
{ |
{ |
register_input_module(&proc_ops); | input_register(&proc_ops); |
} |
} |