#include #include #include #include #include #include "rrdtool.h" #include "process.h" #define MAX_ARGS 512 #define ARGSTR_LEN 32768 #define RRDTOOL_CMD "/usr/bin/rrdtool" /* * Add new argument to a argument list * * args pointer list to arguments * argcnt argument counter * argstr array where the actual arguments are stored * idx index in the argstr where the new argument will be appended */ #define add_arg(args, argcnt, argstr, idx, fmt, arg...) \ args[argcnt] = argstr + idx; \ idx += sprintf(argstr + idx, fmt, ##arg); \ argcnt++; \ argstr[++idx] = 0 int rrdtool_draw_image(struct rrd_image *image) { char cmd[] = RRDTOOL_CMD; // char cmd[] = "echo"; char *args[512], argstr[ARGSTR_LEN]; int idx = 0, argcnt = 0, i,j; char timestamp[256]; char tmp[256]; time_t t = time(0); strftime(tmp, 256, "%d.%m.%Y %T (%Z) ", localtime(&t)); for (i = 0, j = 0; j < 256;) { if (tmp[i] == ':') { timestamp[j++] = '\\'; } timestamp[j++] = tmp[i++]; if (!tmp[i]) break; } timestamp[j] = 0; add_arg(args, argcnt, argstr, idx, " "); add_arg(args, argcnt, argstr, idx, "graph"); add_arg(args, argcnt, argstr, idx, "%s", image->image_filename); add_arg(args, argcnt, argstr, idx, "--start"); add_arg(args, argcnt, argstr, idx, "%s", image->timestart); add_arg(args, argcnt, argstr, idx, "--end"); add_arg(args, argcnt, argstr, idx, "%s", image->timeend); add_arg(args, argcnt, argstr, idx, "--width"); add_arg(args, argcnt, argstr, idx, "%d", image->width); add_arg(args, argcnt, argstr, idx, "--height"); add_arg(args, argcnt, argstr, idx, "%d", image->height); add_arg(args, argcnt, argstr, idx, "--imgformat"); add_arg(args, argcnt, argstr, idx, "%s", image->imageformat); for (i = 0; image->options[i]; i++) { add_arg(args, argcnt, argstr, idx, "%s", image->options[i]); } for (i = 0; image->text[i]; i++) { args[argcnt++] = image->text[i]; } add_arg(args, argcnt, argstr, idx, "COMMENT:Last update %s\\c", timestamp); args[argcnt] = 0; run(cmd, args); return 0; } int rrdtool_draw_images(struct rrd_image **image) { int i; for (i = 0; image[i]; i++) rrdtool_draw_image(image[i]); return 0; } int rrdtool_update_data(struct rrd_database *rrd) { char data[1024]; char cmd[] = RRDTOOL_CMD; // char cmd[] = "echo"; char *cmdline[] = { "", "update", rrd->filename, data, 0 }; int l; rrd->last_update = time(0); if (do_fork()) return 0; l = sprintf(data, "N:"); if (rrd->parse) { rrd->parse(data + l, rrd->parser_data); run(cmd, cmdline); } if (rrd->images) rrdtool_draw_images(rrd->images); while (harvest_zombies(0)); exit(0); } static int database_exists(struct rrd_database *db) { struct stat s; /* If the filename exists, stat will return zero */ if (db->filename) return !stat(db->filename, &s); return 1; } static int create_database(struct rrd_database *db) { char cmd[] = RRDTOOL_CMD; // char cmd[] = "echo"; char *args[512], argstr[ARGSTR_LEN]; int idx = 0, argcnt = 0; int child, i; if (!db->sources || !db->archives) { printf("Cannot create db \"%s\", insufficient source data\n", db->filename); return -1; } add_arg(args, argcnt, argstr, idx, " "); add_arg(args, argcnt, argstr, idx, "create"); add_arg(args, argcnt, argstr, idx, "%s", db->filename); add_arg(args, argcnt, argstr, idx, "--step"); add_arg(args, argcnt, argstr, idx, "%d", db->interval); for (i = 0; db->sources[i].type; i++) { add_arg(args, argcnt, argstr, idx, "DS:%s:%s:%d:%f:%f", db->sources[i].name, db->sources[i].type, db->sources[i].heartbeat, db->sources[i].min, db->sources[i].max); } for (i = 0; db->archives[i].type; i++) { add_arg(args, argcnt, argstr, idx, "RRA:%s:%f:%d:%d", db->archives[i].type, db->archives[i].xff, db->archives[i].steps, db->archives[i].rows); } child = run(cmd, args); harvest_zombies(child); return 0; } int rrdtool_check_databases(struct rrd_database *dbs[]) { struct rrd_database *db; int i; for (i = 0, db = dbs[i]; db; i++, db = dbs[i]) { if (database_exists(db)) { printf("database %s found\n", db->filename); continue; } printf("Database %s missing, creating\n", db->filename); create_database(db); } printf("All done\n"); return 0; }