#include <u.h>
#include <libc.h>
#include <thread.h>
#include <bio.h>
#include <ndb.h>
#include "collectd.h"
char *hostname;
char *server;
uint interval = 10;
QLock snoozelock;
Rendez snoozerendez;
void
snooze(void)
{
qlock(&snoozelock);
rsleep(&snoozerendez);
qunlock(&snoozelock);
}
void
wakeupall(void)
{
qlock(&snoozelock);
rwakeupall(&snoozerendez);
qunlock(&snoozelock);
}
static void
usage(void)
{
fprint(2, "usage: %s [-h hostname] [-n interval] [net!]server[!service]\n", argv0);
exits("usage");
}
static void
submitproc(void *arg)
{
char *addr;
int fd;
Channel *c;
Packet *pp;
long n;
static uchar buf[PACKETMAX];
addr = netmkaddr(server, "udp", "collectd");
fd = dial(addr, nil, nil, nil);
if(fd < 0)
sysfatal("couldn't dial %s: %r", addr);
c = arg;
for(;;){
pp = recvp(c);
if(pp == nil)
sysfatal("bad packet");
n = convS2P(pp, buf, sizeof buf);
write(fd, buf, n);
pfree(pp);
}
}
static void (*proctab[])(void *) = {
cpuproc,
dfproc,
interfaceproc,
loadproc,
memoryproc,
swapproc,
uptimeproc,
usersproc,
submitproc,
};
void
threadmain(int argc, char *argv[])
{
Ndb *db;
Channel *c;
int i;
ARGBEGIN{
case 'h':
hostname = EARGF(usage());
break;
case 'n':
interval = atoi(EARGF(usage()));
break;
default:
usage();
}ARGEND
if(argc == 0)
usage();
server = argv[0];
/*
* By default, collectd prefers the FQDN for a given host.
* We attempt to honor this by first looking up the dom in the
* ndb(6) before falling back to sysname.
*/
if(hostname == nil){
db = ndbopen(nil);
if(db){
hostname = ndbgetvalue(db, nil, "sys", sysname(), "dom", nil);
ndbclose(db);
}
if(hostname == nil)
hostname = sysname();
}
/*
* We create individual procs for each supported plugin; a shared
* channel is employed to serialize submission to the server.
*/
snoozerendez.l = &snoozelock;
c = chancreate(sizeof(Packet *), 128);
for(i = 0; i < nelem(proctab); ++i)
proccreate(proctab[i], c, 8*1024);
for(;;){
sleep(interval*1000);
wakeupall();
}
}
|