]> git.itanic.dy.fi Git - rrdd/blob - rrdtool.c
Add support for creating rrd databases in case the file is missing
[rrdd] / rrdtool.c
1 #include <time.h>
2
3 #include <sys/types.h>
4 #include <sys/stat.h>
5 #include <unistd.h>
6 #include <string.h>
7
8 #include "rrdtool.h"
9 #include "process.h"
10
11 #define MAX_ARGS        512
12 #define ARGSTR_LEN      32768
13
14 #define RRDTOOL_CMD "/usr/bin/rrdtool"
15
16 /*
17  * Add new argument to a argument list
18  *
19  * args         pointer list to arguments
20  * argcnt       argument counter
21  * argstr       array where the actual arguments are stored
22  * idx          index in the argstr where the new argument will be appended
23  */
24 #define add_arg(args, argcnt, argstr, idx, fmt, arg...) \
25         args[argcnt] = argstr + idx;                    \
26         idx += sprintf(argstr + idx, fmt, ##arg);       \
27         argcnt++;                                       \
28         argstr[++idx] = 0
29
30 int rrdtool_draw_image(struct rrd_image *image)
31 {
32         char cmd[] = RRDTOOL_CMD;
33 //      char cmd[] = "echo";
34         char *args[512], argstr[ARGSTR_LEN];
35         int idx = 0, argcnt = 0, i,j;
36         char timestamp[256];
37         char tmp[256];
38         time_t t = time(0);
39
40         strftime(tmp, 256, "%d.%m.%Y %T (%Z) ", localtime(&t));
41         for (i = 0, j = 0; j < 256;) {
42                 if (tmp[i] == ':') {
43                         timestamp[j++] = '\\';
44                 }
45                 timestamp[j++] = tmp[i++];
46                 if (!tmp[i])
47                         break;
48         }
49         timestamp[j] = 0;
50
51
52         add_arg(args, argcnt, argstr, idx, " ");
53         add_arg(args, argcnt, argstr, idx, "graph");
54         add_arg(args, argcnt, argstr, idx, "%s", image->image_filename);
55
56         add_arg(args, argcnt, argstr, idx, "--start");
57         add_arg(args, argcnt, argstr, idx, "%s", image->timestart);
58         add_arg(args, argcnt, argstr, idx, "--end");
59         add_arg(args, argcnt, argstr, idx, "%s", image->timeend);
60         add_arg(args, argcnt, argstr, idx, "--width");
61         add_arg(args, argcnt, argstr, idx, "%d", image->width);
62         add_arg(args, argcnt, argstr, idx, "--height");
63         add_arg(args, argcnt, argstr, idx, "%d", image->height);
64         add_arg(args, argcnt, argstr, idx, "--imgformat");
65         add_arg(args, argcnt, argstr, idx, "%s", image->imageformat);
66
67         for (i = 0; image->options[i]; i++) {
68                 add_arg(args, argcnt, argstr, idx, "%s", image->options[i]);
69         }
70
71         for (i = 0; image->text[i]; i++) {
72                 args[argcnt++] = image->text[i];
73         }
74
75         add_arg(args, argcnt, argstr, idx, "COMMENT:Last update %s\\c", timestamp);
76
77         args[argcnt] = 0;
78
79         run(cmd, args);
80
81         return 0;
82 }
83
84 int rrdtool_draw_images(struct rrd_image **image)
85 {
86         int i;
87         for (i = 0; image[i]; i++)
88                 rrdtool_draw_image(image[i]);
89
90         return 0;
91 }
92
93 int rrdtool_update_data(struct rrd_database *rrd)
94 {
95         char data[1024];
96         char cmd[] = RRDTOOL_CMD;
97 //      char cmd[] = "echo";
98         char *cmdline[] = {
99                 "",
100                 "update",
101                 rrd->filename,
102                 data,
103                 0
104         };
105         int l;
106
107         rrd->last_update = time(0);
108         if (do_fork())
109                 return 0;
110
111         l = sprintf(data, "N:");
112
113         if (rrd->parse) {
114                 rrd->parse(data + l);
115                 run(cmd, cmdline);
116         }
117
118         if (rrd->images)
119                 rrdtool_draw_images(rrd->images);
120
121         while (harvest_zombies(0));
122         exit(0);
123 }
124
125 static int database_exists(struct rrd_database *db)
126 {
127         struct stat s;
128
129         /* If the filename exists, stat will return zero */
130         if (db->filename)
131                 return !stat(db->filename, &s);
132
133         return 1;
134 }
135
136 static int create_database(struct rrd_database *db)
137 {
138         char cmd[] = RRDTOOL_CMD;
139 //      char cmd[] = "echo";
140         char *args[512], argstr[ARGSTR_LEN];
141         int idx = 0, argcnt = 0;
142         int child, i;
143
144         if (!db->sources || !db->archives) {
145                 printf("Cannot create db \"%s\", insufficient source data\n",
146                         db->filename);
147                 return -1;
148         }
149
150         add_arg(args, argcnt, argstr, idx, " ");
151         add_arg(args, argcnt, argstr, idx, "create");
152         add_arg(args, argcnt, argstr, idx, "%s", db->filename);
153         add_arg(args, argcnt, argstr, idx, "--step");
154         add_arg(args, argcnt, argstr, idx, "%d", db->interval);
155
156         for (i = 0; db->sources[i].type; i++) {
157                 add_arg(args, argcnt, argstr, idx, "DS:%s:%s:%d:%f:%f",
158                         db->sources[i].name,
159                         db->sources[i].type,
160                         db->sources[i].heartbeat,
161                         db->sources[i].min,
162                         db->sources[i].max);
163         }
164
165         for (i = 0; db->archives[i].type; i++) {
166                 add_arg(args, argcnt, argstr, idx, "RRA:%s:%f:%d:%d",
167                         db->archives[i].type,
168                         db->archives[i].xff,
169                         db->archives[i].steps,
170                         db->archives[i].rows);
171         }
172
173         child = run(cmd, args);
174
175         harvest_zombies(child);
176
177         return 0;
178 }
179
180 int rrdtool_check_databases(struct rrd_database *dbs[])
181 {
182         struct rrd_database *db;
183         int i;
184
185         for (i = 0, db = dbs[i]; db; i++, db = dbs[i]) {
186                 if (database_exists(db)) {
187                         printf("database %s found\n", db->filename);
188                         continue;
189                 }
190                 printf("Database %s missing, creating\n", db->filename);
191                 create_database(db);
192         }
193         printf("All done\n");
194
195         return 0;
196 }