The tiny daemon that creates the server graph(s) for mirror.csclub. Will add documentation and a makefile later, right now I'm committing this before I invariably forget again for who-knows-how-many months.

This commit is contained in:
Peter Barfuss 2012-03-14 17:11:42 -04:00
parent f6b0c01148
commit 83f969bb98
6 changed files with 280 additions and 0 deletions

102
rrdtool/mirror-nl-glue.c Normal file
View File

@ -0,0 +1,102 @@
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <libgen.h>
#include <netlink/route/class.h>
#include <netlink/route/link.h>
#include <netlink/cache-api.h>
#include <netlink/object.h>
#include "mirror-nl-glue.h"
static struct nl_cache *link_cache, *class_cache;
static struct rtnl_link *eth;
static int ifindex;
struct class_info cogent_class = { "cogent", "01:02", };
struct class_info orion_class = { "orion", "01:03", };
struct class_info campus_class = { "campus", "01:04", };
static struct nl_handle *nl_handle;
void die(const char *message) {
fprintf(stderr, "fatal: %s\n", message);
exit(1);
}
static void match_obj(struct nl_object *obj, void *arg) {
struct nl_object *needle = *(struct nl_object **)arg;
struct nl_object **ret = (struct nl_object **)arg + 1;
if (!*ret && nl_object_identical(obj, needle)) {
nl_object_get(obj);
*ret = obj;
}
}
static struct rtnl_class *get_class_by_id(char *id, int ifindex) {
uint32_t handle;
struct rtnl_class *needle;
struct nl_object *magic[2];
if (rtnl_tc_str2handle(id, &handle))
die("invalid id");
needle = rtnl_class_alloc();
rtnl_class_set_ifindex(needle, ifindex);
rtnl_class_set_handle(needle, handle);
magic[0] = (struct nl_object *)needle;
magic[1] = (struct nl_object *)NULL;
nl_cache_foreach(class_cache, match_obj, magic);
rtnl_class_put(needle);
return (struct rtnl_class *)magic[1];
}
uint64_t get_class_byte_count(struct class_info *info) {
struct rtnl_class *class = get_class_by_id(info->id, ifindex);
uint64_t bytes;
if (!class)
die("class not found");
bytes = rtnl_class_get_stat(class, RTNL_TC_BYTES);
rtnl_class_put(class);
return bytes;
}
void mirror_stats_refresh(void) {
nl_cache_refill(nl_handle, class_cache);
}
void mirror_stats_initialize(void) {
nl_handle = nl_handle_alloc();
if (!nl_handle)
die("unable to allocate handle");
if (nl_connect(nl_handle, NETLINK_ROUTE) < 0)
die("unable to connect to netlink");
link_cache = rtnl_link_alloc_cache(nl_handle);
if (!link_cache)
die("unable to allocate link cache");
eth = rtnl_link_get_by_name(link_cache, "eth0");
if (!eth)
die("unable to acquire eth0");
ifindex = rtnl_link_get_ifindex(eth);
class_cache = rtnl_class_alloc_cache(nl_handle, ifindex);
if (!class_cache)
die("unable to allocate class cache");
}
void mirror_stats_cleanup(void) {
rtnl_link_put(eth);
nl_cache_free(class_cache);
nl_cache_free(link_cache);
nl_close(nl_handle);
nl_handle_destroy(nl_handle);
}

25
rrdtool/mirror-nl-glue.h Normal file
View File

@ -0,0 +1,25 @@
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <libgen.h>
#include <netlink/route/class.h>
#include <netlink/route/link.h>
#include <netlink/cache-api.h>
#include <netlink/object.h>
struct class_info {
char *name;
char *id;
};
extern struct class_info cogent_class;
extern struct class_info orion_class;
extern struct class_info campus_class;
void mirror_stats_refresh(void);
void mirror_stats_initialize(void);
void mirror_stats_cleanup(void);
void die(const char *);
uint64_t get_class_byte_count(struct class_info *);

37
rrdtool/mirror-rrd.c Normal file
View File

@ -0,0 +1,37 @@
#include "mirror-nl-glue.h"
#include <rrd.h>
int main(void) {
char *argv[3];
unsigned long packet_count;
switch(fork()) {
case -1:
return -1;
case 0:
break;
default:
_exit(0);
}
mirror_stats_initialize();
argv[0] = malloc(1024);
for (;;) {
packet_count = get_class_byte_count(&cogent_class);
snprintf(argv[0], 1024, "N:%lu", packet_count);
rrd_update_r("/var/rrdtool/cogent.rrd", NULL, 1, argv);
packet_count = get_class_byte_count(&orion_class);
snprintf(argv[0], 1024, "N:%lu", packet_count);
rrd_update_r("/var/rrdtool/orion.rrd", NULL, 1, argv);
packet_count = get_class_byte_count(&campus_class);
snprintf(argv[0], 1024, "N:%lu", packet_count);
rrd_update_r("/var/rrdtool/campus.rrd", NULL, 1, argv);
if (rrd_test_error()) {
fprintf(stderr, "ERROR: %s\n", rrd_get_error());
rrd_clear_error();
}
sleep(5);
mirror_stats_refresh();
}
}

39
rrdtool/rrdgraph-monthly.sh Executable file
View File

@ -0,0 +1,39 @@
#!/bin/sh
/usr/bin/rrdtool graph /mirror/root/stats_monthly.png \
-s -1m \
--imgformat=PNG \
--title='Mirror Traffic' \
--base=1000 \
--height=120 \
--width=600 \
--alt-autoscale-max \
--lower-limit=0 \
--vertical-label='bits per second' \
--slope-mode \
--font TITLE:10: \
--font AXIS:8: \
--font LEGEND:8: \
--font UNIT:8: \
DEF:a="/var/rrdtool/cogent.rrd":snmp_oid:AVERAGE \
DEF:b="/var/rrdtool/orion.rrd":snmp_oid:AVERAGE \
DEF:c="/var/rrdtool/campus.rrd":snmp_oid:AVERAGE \
CDEF:cdefa=a,8,* \
CDEF:cdefe=b,8,* \
CDEF:cdefi=c,8,* \
CDEF:cdefbc=TIME,1318318854,GT,a,a,UN,0,a,IF,IF,TIME,1318318854,GT,b,b,UN,0,b,IF,IF,TIME,1318318854,GT,c,c,UN,0,c,IF,IF,+,+,8,* \
AREA:cdefa#157419FF:"Cogent" \
GPRINT:cdefa:LAST:"Current\:%8.2lf%s" \
GPRINT:cdefa:AVERAGE:"Average\:%8.2lf%s" \
GPRINT:cdefa:MAX:"Maximum\:%8.2lf%s\n" \
AREA:cdefe#00CF00FF:"Orion":STACK \
GPRINT:cdefe:LAST:" Current\:%8.2lf%s" \
GPRINT:cdefe:AVERAGE:"Average\:%8.2lf%s" \
GPRINT:cdefe:MAX:"Maximum\:%8.2lf%s\n" \
AREA:cdefi#EE5019FF:"Campus":STACK \
GPRINT:cdefi:LAST:"Current\:%8.2lf%s" \
GPRINT:cdefi:AVERAGE:"Average\:%8.2lf%s" \
GPRINT:cdefi:MAX:"Maximum\:%8.2lf%s\n" \
LINE1:cdefbc#000000FF:"Total" \
GPRINT:cdefbc:LAST:" Current\:%8.2lf%s" \
GPRINT:cdefbc:AVERAGE:"Average\:%8.2lf%s" \
GPRINT:cdefbc:MAX:"Maximum\:%8.2lf%s\n" >/dev/null 2>/dev/null

39
rrdtool/rrdgraph-yearly.sh Executable file
View File

@ -0,0 +1,39 @@
#!/bin/sh
/usr/bin/rrdtool graph /mirror/root/stats_yearly.png \
-s -1y \
--imgformat=PNG \
--title='Mirror Traffic' \
--base=1000 \
--height=120 \
--width=600 \
--alt-autoscale-max \
--lower-limit=0 \
--vertical-label='bits per second' \
--slope-mode \
--font TITLE:10: \
--font AXIS:8: \
--font LEGEND:8: \
--font UNIT:8: \
DEF:a="/var/rrdtool/cogent.rrd":snmp_oid:AVERAGE \
DEF:b="/var/rrdtool/orion.rrd":snmp_oid:AVERAGE \
DEF:c="/var/rrdtool/campus.rrd":snmp_oid:AVERAGE \
CDEF:cdefa=a,8,* \
CDEF:cdefe=b,8,* \
CDEF:cdefi=c,8,* \
CDEF:cdefbc=TIME,1318318854,GT,a,a,UN,0,a,IF,IF,TIME,1318318854,GT,b,b,UN,0,b,IF,IF,TIME,1318318854,GT,c,c,UN,0,c,IF,IF,+,+,8,* \
AREA:cdefa#157419FF:"Cogent" \
GPRINT:cdefa:LAST:"Current\:%8.2lf%s" \
GPRINT:cdefa:AVERAGE:"Average\:%8.2lf%s" \
GPRINT:cdefa:MAX:"Maximum\:%8.2lf%s\n" \
AREA:cdefe#00CF00FF:"Orion":STACK \
GPRINT:cdefe:LAST:" Current\:%8.2lf%s" \
GPRINT:cdefe:AVERAGE:"Average\:%8.2lf%s" \
GPRINT:cdefe:MAX:"Maximum\:%8.2lf%s\n" \
AREA:cdefi#EE5019FF:"Campus":STACK \
GPRINT:cdefi:LAST:"Current\:%8.2lf%s" \
GPRINT:cdefi:AVERAGE:"Average\:%8.2lf%s" \
GPRINT:cdefi:MAX:"Maximum\:%8.2lf%s\n" \
LINE1:cdefbc#000000FF:"Total" \
GPRINT:cdefbc:LAST:" Current\:%8.2lf%s" \
GPRINT:cdefbc:AVERAGE:"Average\:%8.2lf%s" \
GPRINT:cdefbc:MAX:"Maximum\:%8.2lf%s\n" >/dev/null 2>/dev/null

38
rrdtool/rrdgraph.sh Executable file
View File

@ -0,0 +1,38 @@
#!/bin/sh
/usr/bin/rrdtool graph /mirror/root/stats.png \
--imgformat=PNG \
--title='Mirror Traffic' \
--base=1000 \
--height=120 \
--width=600 \
--alt-autoscale-max \
--lower-limit=0 \
--vertical-label='bits per second' \
--slope-mode \
--font TITLE:10: \
--font AXIS:8: \
--font LEGEND:8: \
--font UNIT:8: \
DEF:a="/var/rrdtool/cogent.rrd":snmp_oid:AVERAGE \
DEF:b="/var/rrdtool/orion.rrd":snmp_oid:AVERAGE \
DEF:c="/var/rrdtool/campus.rrd":snmp_oid:AVERAGE \
CDEF:cdefa=a,8,* \
CDEF:cdefe=b,8,* \
CDEF:cdefi=c,8,* \
CDEF:cdefbc=TIME,1318318854,GT,a,a,UN,0,a,IF,IF,TIME,1318318854,GT,b,b,UN,0,b,IF,IF,TIME,1318318854,GT,c,c,UN,0,c,IF,IF,+,+,8,* \
AREA:cdefa#157419FF:"Cogent" \
GPRINT:cdefa:LAST:"Current\:%8.2lf%s" \
GPRINT:cdefa:AVERAGE:"Average\:%8.2lf%s" \
GPRINT:cdefa:MAX:"Maximum\:%8.2lf%s\n" \
AREA:cdefe#00CF00FF:"Orion":STACK \
GPRINT:cdefe:LAST:" Current\:%8.2lf%s" \
GPRINT:cdefe:AVERAGE:"Average\:%8.2lf%s" \
GPRINT:cdefe:MAX:"Maximum\:%8.2lf%s\n" \
AREA:cdefi#EE5019FF:"Campus":STACK \
GPRINT:cdefi:LAST:"Current\:%8.2lf%s" \
GPRINT:cdefi:AVERAGE:"Average\:%8.2lf%s" \
GPRINT:cdefi:MAX:"Maximum\:%8.2lf%s\n" \
LINE1:cdefbc#000000FF:"Total" \
GPRINT:cdefbc:LAST:" Current\:%8.2lf%s" \
GPRINT:cdefbc:AVERAGE:"Average\:%8.2lf%s" \
GPRINT:cdefbc:MAX:"Maximum\:%8.2lf%s\n" >/dev/null 2>/dev/null