@cryptotaxi247 / netdata-1 / commits / 1c8a9f944

hosts except localhost save files in subdirectory in /var/cache/netdata and /var/lib/netdata

Costa Tsaousis (ktsaou) committed Feb 18, 2017 at 23:50 UTC 1c8a9f944e75831ca700852d7e8dad0e5c3fd0f7
5 files changed +175 -104
src/rrd.c
+3 -3
@@ -113,15 +113,15 @@ const char *rrdset_type_name(RRDSET_TYPE chart_type) {
113 // ----------------------------------------------------------------------------
114 // RRD - cache directory
115
116 -char *rrdset_cache_dir(RRDHOST *host, const char *id) {
116 +char *rrdset_cache_dir(RRDHOST *host, const char *id, const char *config_section) {
117 char *ret = NULL;
118
119 char b[FILENAME_MAX + 1];
120 char n[FILENAME_MAX + 1];
121 rrdset_strncpyz_name(b, id, FILENAME_MAX);
122
123 - snprintfz(n, FILENAME_MAX, "%s/%s", netdata_configured_cache_dir, b);
124 - ret = config_get(id, "cache directory", n);
123 + snprintfz(n, FILENAME_MAX, "%s/%s", host->cache_dir, b);
124 + ret = config_get(config_section, "cache directory", n);
125
126 if(host->rrd_memory_mode == RRD_MEMORY_MODE_MAP || host->rrd_memory_mode == RRD_MEMORY_MODE_SAVE) {
127 int r = mkdir(ret, 0775);
src/rrd.h
+8 -2
@@ -216,6 +216,8 @@ struct rrdset {
216 // since the config always has a higher priority
217 // (the user overwrites the name of the charts)
218
219 + char *config_section; // the config section for the chart
220 +
221 char *type; // the type of graph RRD_TYPE_* (a category, for determining graphing options)
222 char *family; // grouping sets under the same family
223 char *title; // title shown to user
@@ -325,6 +327,9 @@ struct rrdhost {
327 avl_tree_lock rrdfamily_root_index; // the host's chart families index
328 avl_tree_lock variables_root_index; // the host's chart variables index
329
330 + char *cache_dir; // the directory to save RRD cache files
331 + char *varlib_dir; // the directory to save health log
332 +
333 // all RRDCALCs are primarily allocated and linked here
334 // RRDCALCs may be linked to charts at any point
335 // (charts may or may not exist when these are loaded)
@@ -385,7 +390,7 @@ extern RRDSET *rrdset_create(RRDHOST *host
390 , const char *units
391 , long priority
392 , int update_every
388 - , int chart_type);
393 + , RRDSET_TYPE chart_type);
394
395 #define rrdset_create_localhost(type, id, name, family, context, title, units, priority, update_every, chart_type) rrdset_create(localhost, type, id, name, family, context, title, units, priority, update_every, chart_type)
396
@@ -463,10 +468,11 @@ extern collected_number rrddim_set(RRDSET *st, const char *id, collected_number
468
469 #ifdef NETDATA_RRD_INTERNALS
470
471 +extern void rrdset_free(RRDSET *st);
472 extern avl_tree_lock rrdhost_root_index;
473
474 extern char *rrdset_strncpyz_name(char *to, const char *from, size_t length);
469 -extern char *rrdset_cache_dir(RRDHOST *host, const char *id);
475 +extern char *rrdset_cache_dir(RRDHOST *host, const char *id, const char *config_section);
476
477 extern void rrdset_reset(RRDSET *st);
478
src/rrddim.c
+9 -6
@@ -43,7 +43,7 @@ inline void rrddim_set_name(RRDSET *st, RRDDIM *rd, const char *name) {
43
44 char varname[CONFIG_MAX_NAME + 1];
45 snprintfz(varname, CONFIG_MAX_NAME, "dim %s name", rd->id);
46 - rd->name = config_set_default(st->id, varname, name);
46 + rd->name = config_set_default(st->config_section, varname, name);
47 rd->hash_name = simple_hash(rd->name);
48
49 rrddimvar_rename_all(rd);
@@ -84,7 +84,6 @@ RRDDIM *rrddim_add(RRDSET *st, const char *id, const char *name, collected_numbe
84 rd->variables = NULL;
85 rd->next = NULL;
86 rd->rrdset = NULL;
87 - rd->rrd_memory_mode = st->rrd_memory_mode;
87
88 struct timeval now;
89 now_realtime_timeval(&now);
@@ -124,6 +123,10 @@ RRDDIM *rrddim_add(RRDSET *st, const char *id, const char *name, collected_numbe
123 error("File %s does not have the expected algorithm (expected %u '%s', found %u '%s'). Previous values may be wrong."
124 , fullfilename, algorithm, rrd_algorithm_name(algorithm), rd->algorithm,
125 rrd_algorithm_name(rd->algorithm));
126 +
127 + // make sure we have the right memory mode
128 + // even if we cleared the memory
129 + rd->rrd_memory_mode = st->rrd_memory_mode;
130 }
131 }
132
@@ -143,17 +146,17 @@ RRDDIM *rrddim_add(RRDSET *st, const char *id, const char *name, collected_numbe
146 rd->cache_filename = strdupz(fullfilename);
147
148 snprintfz(varname, CONFIG_MAX_NAME, "dim %s name", rd->id);
146 - rd->name = config_get(st->id, varname, (name && *name)?name:rd->id);
149 + rd->name = config_get(st->config_section, varname, (name && *name)?name:rd->id);
150 rd->hash_name = simple_hash(rd->name);
151
152 snprintfz(varname, CONFIG_MAX_NAME, "dim %s algorithm", rd->id);
150 - rd->algorithm = rrd_algorithm_id(config_get(st->id, varname, rrd_algorithm_name(algorithm)));
153 + rd->algorithm = rrd_algorithm_id(config_get(st->config_section, varname, rrd_algorithm_name(algorithm)));
154
155 snprintfz(varname, CONFIG_MAX_NAME, "dim %s multiplier", rd->id);
153 - rd->multiplier = config_get_number(st->id, varname, multiplier);
156 + rd->multiplier = config_get_number(st->config_section, varname, multiplier);
157
158 snprintfz(varname, CONFIG_MAX_NAME, "dim %s divisor", rd->id);
156 - rd->divisor = config_get_number(st->id, varname, divisor);
159 + rd->divisor = config_get_number(st->config_section, varname, divisor);
160 if(!rd->divisor) rd->divisor = 1;
161
162 rd->entries = st->entries;
src/rrdhost.c
+30 -25
@@ -93,13 +93,38 @@ RRDHOST *rrdhost_create(const char *hostname, const char *guid) {
93
94 if(!localhost) {
95 // this is localhost
96 - snprintfz(filename, FILENAME_MAX, "%s/health/health-log.db", netdata_configured_varlib_dir);
96 +
97 + host->cache_dir = strdupz(netdata_configured_cache_dir);
98 + host->varlib_dir = strdupz(netdata_configured_varlib_dir);
99 +
100 + snprintfz(filename, FILENAME_MAX, "%s/health/health-log.db", host->varlib_dir);
101 host->health_log_filename = strdupz(config_get("health", "health db file", filename));
102 +
103 }
104 else {
105 // this is not localhost - append our GUID to localhost path
101 - snprintfz(filename, FILENAME_MAX, "%s.%s", localhost->health_log_filename, host->machine_guid);
106 +
107 + snprintfz(filename, FILENAME_MAX, "%s/%s", netdata_configured_cache_dir, host->machine_guid);
108 + host->cache_dir = strdupz(filename);
109 +
110 + if(host->rrd_memory_mode == RRD_MEMORY_MODE_MAP || host->rrd_memory_mode == RRD_MEMORY_MODE_SAVE) {
111 + int r = mkdir(host->cache_dir, 0775);
112 + if(r != 0 && errno != EEXIST)
113 + error("Cannot create directory '%s'", host->cache_dir);
114 + }
115 +
116 + snprintfz(filename, FILENAME_MAX, "%s/%s", netdata_configured_varlib_dir, host->machine_guid);
117 + host->varlib_dir = strdupz(filename);
118 +
119 + if(host->health_enabled) {
120 + int r = mkdir(host->varlib_dir, 0775);
121 + if(r != 0 && errno != EEXIST)
122 + error("Cannot create directory '%s'", host->varlib_dir);
123 + }
124 +
125 + snprintfz(filename, FILENAME_MAX, "%s/health/health-log.db", host->varlib_dir);
126 host->health_log_filename = strdupz(filename);
127 +
128 }
129
130 snprintfz(filename, FILENAME_MAX, "%s/alarm-notify.sh", netdata_configured_plugins_dir);
@@ -191,34 +216,14 @@ void rrdhost_free(RRDHOST *host) {
216 for(st = host->rrdset_root; st ;) {
217 RRDSET *next = st->next;
218
194 - pthread_rwlock_wrlock(&st->rwlock);
195 -
196 - while(st->variables) rrdsetvar_free(st->variables);
197 - while(st->alarms) rrdsetcalc_unlink(st->alarms);
198 - while(st->dimensions) rrddim_free(st, st->dimensions);
199 -
200 - if(unlikely(rrdset_index_del(host, st) != st))
201 - error("RRDSET: INTERNAL ERROR: attempt to remove from index chart '%s', removed a different chart.", st->id);
202 -
203 - rrdset_index_del_name(host, st);
204 -
205 - st->rrdfamily->use_count--;
206 - if(!st->rrdfamily->use_count)
207 - rrdfamily_free(host, st->rrdfamily);
208 -
209 - pthread_rwlock_unlock(&st->rwlock);
210 -
211 - if(st->rrd_memory_mode == RRD_MEMORY_MODE_SAVE || st->rrd_memory_mode == RRD_MEMORY_MODE_MAP) {
212 - debug(D_RRD_CALLS, "Unmapping stats '%s'.", st->name);
213 - munmap(st, st->memsize);
214 - }
215 - else
216 - freez(st);
219 + rrdset_free(st);
220
221 st = next;
222 }
223 host->rrdset_root = NULL;
224
225 + freez(host->cache_dir);
226 + freez(host->varlib_dir);
227 freez(host->health_default_exec);
228 freez(host->health_default_recipient);
229 freez(host->health_log_filename);
src/rrdset.c
+125 -68
@@ -133,12 +133,12 @@ void rrdset_set_name(RRDSET *st, const char *name) {
133
134 if(st->name) {
135 rrdset_index_del_name(st->rrdhost, st);
136 - st->name = config_set_default(st->id, "name", b);
136 + st->name = config_set_default(st->config_section, "name", b);
137 st->hash_name = simple_hash(st->name);
138 rrdsetvar_rename_all(st);
139 }
140 else {
141 - st->name = config_get(st->id, "name", b);
141 + st->name = config_get(st->config_section, "name", b);
142 st->hash_name = simple_hash(st->name);
143 }
144
@@ -206,12 +206,44 @@ static inline void timeval_align(struct timeval *tv, int update_every) {
206 tv->tv_usec = 500000;
207 }
208
209 +// ----------------------------------------------------------------------------
210 +// RRDSET - free a chart
211 +
212 +void rrdset_free(RRDSET *st) {
213 + pthread_rwlock_wrlock(&st->rwlock);
214 +
215 + while(st->variables) rrdsetvar_free(st->variables);
216 + while(st->alarms) rrdsetcalc_unlink(st->alarms);
217 + while(st->dimensions) rrddim_free(st, st->dimensions);
218 +
219 + if(unlikely(rrdset_index_del(st->rrdhost, st) != st))
220 + error("RRDSET: INTERNAL ERROR: attempt to remove from index chart '%s', removed a different chart.", st->id);
221 +
222 + rrdset_index_del_name(st->rrdhost, st);
223 +
224 + st->rrdfamily->use_count--;
225 + if(!st->rrdfamily->use_count)
226 + rrdfamily_free(st->rrdhost, st->rrdfamily);
227 +
228 + pthread_rwlock_unlock(&st->rwlock);
229 +
230 + // free directly allocated memory
231 + freez(st->config_section);
232 +
233 + if(st->rrd_memory_mode == RRD_MEMORY_MODE_SAVE || st->rrd_memory_mode == RRD_MEMORY_MODE_MAP) {
234 + debug(D_RRD_CALLS, "Unmapping stats '%s'.", st->name);
235 + munmap(st, st->memsize);
236 + }
237 + else
238 + freez(st);
239 +}
240 +
241 // ----------------------------------------------------------------------------
242 // RRDSET - create a chart
243
244 RRDSET *rrdset_create(RRDHOST *host, const char *type, const char *id, const char *name, const char *family
245 , const char *context, const char *title, const char *units, long priority
214 - , int update_every, int chart_type) {
246 + , int update_every, RRDSET_TYPE chart_type) {
247
248 if(!type || !type[0]) {
249 fatal("Cannot create rrd stats without a type.");
@@ -223,9 +255,10 @@ RRDSET *rrdset_create(RRDHOST *host, const char *type, const char *id, const cha
255 return NULL;
256 }
257
226 - char fullid[RRD_ID_LENGTH_MAX + 1];
227 - char fullfilename[FILENAME_MAX + 1];
258 + // ------------------------------------------------------------------------
259 + // check if it already exists
260
261 + char fullid[RRD_ID_LENGTH_MAX + 1];
262 snprintfz(fullid, RRD_ID_LENGTH_MAX, "%s.%s", type, id);
263
264 RRDSET *st = rrdset_find(host, fullid);
@@ -234,77 +267,101 @@ RRDSET *rrdset_create(RRDHOST *host, const char *type, const char *id, const cha
267 return st;
268 }
269
237 - long rentries = config_get_number(fullid, "history", host->rrd_history_entries);
270 + char fullfilename[FILENAME_MAX + 1];
271 +
272 + // ------------------------------------------------------------------------
273 + // compose the config_section for this chart
274 +
275 + char config_section[RRD_ID_LENGTH_MAX + 1];
276 + if(host == localhost)
277 + strcpy(config_section, fullid);
278 + else
279 + snprintfz(config_section, RRD_ID_LENGTH_MAX, "%s/%s", host->machine_guid, fullid);
280 +
281 + // ------------------------------------------------------------------------
282 + // get the options from the config, we need to create it
283 +
284 + long rentries = config_get_number(config_section, "history", host->rrd_history_entries);
285 long entries = align_entries_to_pagesize(rentries);
239 - if(entries != rentries) entries = config_set_number(fullid, "history", entries);
286 + if(entries != rentries) entries = config_set_number(config_section, "history", entries);
287
241 - int enabled = config_get_boolean(fullid, "enabled", 1);
288 + int enabled = config_get_boolean(config_section, "enabled", 1);
289 if(!enabled) entries = 5;
290
291 unsigned long size = sizeof(RRDSET);
245 - char *cache_dir = rrdset_cache_dir(host, fullid);
292 + char *cache_dir = rrdset_cache_dir(host, fullid, config_section);
293 +
294 + // ------------------------------------------------------------------------
295 + // load it or allocate it
296
297 debug(D_RRD_CALLS, "Creating RRD_STATS for '%s.%s'.", type, id);
298
299 snprintfz(fullfilename, FILENAME_MAX, "%s/main.db", cache_dir);
250 - if(host->rrd_memory_mode != RRD_MEMORY_MODE_RAM) st = (RRDSET *)mymmap(fullfilename, size, ((host->rrd_memory_mode == RRD_MEMORY_MODE_MAP)?MAP_SHARED:MAP_PRIVATE), 0);
251 - if(st) {
252 - if(strcmp(st->magic, RRDSET_MAGIC) != 0) {
253 - errno = 0;
254 - info("Initializing file %s.", fullfilename);
255 - memset(st, 0, size);
256 - }
257 - else if(strcmp(st->id, fullid) != 0) {
258 - errno = 0;
259 - error("File %s contents are not for chart %s. Clearing it.", fullfilename, fullid);
260 - // munmap(st, size);
261 - // st = NULL;
262 - memset(st, 0, size);
263 - }
264 - else if(st->memsize != size || st->entries != entries) {
265 - errno = 0;
266 - error("File %s does not have the desired size. Clearing it.", fullfilename);
267 - memset(st, 0, size);
268 - }
269 - else if(st->update_every != update_every) {
270 - errno = 0;
271 - error("File %s does not have the desired update frequency. Clearing it.", fullfilename);
272 - memset(st, 0, size);
273 - }
274 - else if((now_realtime_sec() - st->last_updated.tv_sec) > update_every * entries) {
275 - errno = 0;
276 - error("File %s is too old. Clearing it.", fullfilename);
277 - memset(st, 0, size);
278 - }
300 + if(host->rrd_memory_mode != RRD_MEMORY_MODE_RAM) {
301 + st = (RRDSET *) mymmap(fullfilename, size, ((host->rrd_memory_mode == RRD_MEMORY_MODE_MAP) ? MAP_SHARED : MAP_PRIVATE), 0);
302 + if(st) {
303 + memset(&st->avl, 0, sizeof(avl));
304 + memset(&st->avlname, 0, sizeof(avl));
305 + memset(&st->variables_root_index, 0, sizeof(avl_tree_lock));
306 + memset(&st->dimensions_index, 0, sizeof(avl_tree_lock));
307 + memset(&st->rwlock, 0, sizeof(pthread_rwlock_t));
308 +
309 + st->name = NULL;
310 + st->type = NULL;
311 + st->family = NULL;
312 + st->context = NULL;
313 + st->title = NULL;
314 + st->units = NULL;
315 + st->dimensions = NULL;
316 + st->next = NULL;
317 + st->variables = NULL;
318 + st->alarms = NULL;
319 + st->flags = 0x00000000;
320 +
321 + if(strcmp(st->magic, RRDSET_MAGIC) != 0) {
322 + errno = 0;
323 + info("Initializing file %s.", fullfilename);
324 + memset(st, 0, size);
325 + }
326 + else if(strcmp(st->id, fullid) != 0) {
327 + errno = 0;
328 + error("File %s contents are not for chart %s. Clearing it.", fullfilename, fullid);
329 + // munmap(st, size);
330 + // st = NULL;
331 + memset(st, 0, size);
332 + }
333 + else if(st->memsize != size || st->entries != entries) {
334 + errno = 0;
335 + error("File %s does not have the desired size. Clearing it.", fullfilename);
336 + memset(st, 0, size);
337 + }
338 + else if(st->update_every != update_every) {
339 + errno = 0;
340 + error("File %s does not have the desired update frequency. Clearing it.", fullfilename);
341 + memset(st, 0, size);
342 + }
343 + else if((now_realtime_sec() - st->last_updated.tv_sec) > update_every * entries) {
344 + errno = 0;
345 + error("File %s is too old. Clearing it.", fullfilename);
346 + memset(st, 0, size);
347 + }
348
280 - // make sure the database is aligned
281 - if(st->last_updated.tv_sec)
282 - timeval_align(&st->last_updated, update_every);
283 - }
349 + // make sure the database is aligned
350 + if(st->last_updated.tv_sec)
351 + timeval_align(&st->last_updated, update_every);
352
285 - if(st) {
286 - st->name = NULL;
287 - st->type = NULL;
288 - st->family = NULL;
289 - st->context = NULL;
290 - st->title = NULL;
291 - st->units = NULL;
292 - st->dimensions = NULL;
293 - st->next = NULL;
294 - st->rrd_memory_mode = host->rrd_memory_mode;
295 - st->variables = NULL;
296 - st->alarms = NULL;
297 - memset(&st->rwlock, 0, sizeof(pthread_rwlock_t));
298 - memset(&st->avl, 0, sizeof(avl));
299 - memset(&st->avlname, 0, sizeof(avl));
300 - memset(&st->variables_root_index, 0, sizeof(avl_tree_lock));
301 - memset(&st->dimensions_index, 0, sizeof(avl_tree_lock));
353 + // make sure we have the right memory mode
354 + // even if we cleared the memory
355 + st->rrd_memory_mode = host->rrd_memory_mode;
356 + }
357 }
303 - else {
358 +
359 + if(unlikely(!st)) {
360 st = callocz(1, size);
361 st->rrd_memory_mode = RRD_MEMORY_MODE_RAM;
362 }
363
364 + st->config_section = strdup(config_section);
365 st->rrdhost = host;
366 st->memsize = size;
367 st->entries = entries;
@@ -320,15 +377,15 @@ RRDSET *rrdset_create(RRDHOST *host, const char *type, const char *id, const cha
377
378 st->cache_dir = cache_dir;
379
323 - st->chart_type = rrdset_type_id(config_get(st->id, "chart type", rrdset_type_name(chart_type)));
324 - st->type = config_get(st->id, "type", type);
325 - st->family = config_get(st->id, "family", family?family:st->type);
326 - st->units = config_get(st->id, "units", units?units:"");
380 + st->chart_type = rrdset_type_id(config_get(st->config_section, "chart type", rrdset_type_name(chart_type)));
381 + st->type = config_get(st->config_section, "type", type);
382 + st->family = config_get(st->config_section, "family", family?family:st->type);
383 + st->units = config_get(st->config_section, "units", units?units:"");
384
328 - st->context = config_get(st->id, "context", context?context:st->id);
385 + st->context = config_get(st->config_section, "context", context?context:st->id);
386 st->hash_context = simple_hash(st->context);
387
331 - st->priority = config_get_number(st->id, "priority", priority);
388 + st->priority = config_get_number(st->config_section, "priority", priority);
389 if(enabled)
390 rrdset_flag_set(st, RRDSET_FLAG_ENABLED);
391 else
@@ -351,7 +408,7 @@ RRDSET *rrdset_create(RRDHOST *host, const char *type, const char *id, const cha
408 st->counter_done = 0;
409
410 st->gap_when_lost_iterations_above = (int) (
354 - config_get_number(st->id, "gap when lost iterations above", RRD_DEFAULT_GAP_INTERPOLATIONS) + 2);
411 + config_get_number(st->config_section, "gap when lost iterations above", RRD_DEFAULT_GAP_INTERPOLATIONS) + 2);
412
413 avl_init_lock(&st->dimensions_index, rrddim_compare);
414 avl_init_lock(&st->variables_root_index, rrdvar_compare);
@@ -367,7 +424,7 @@ RRDSET *rrdset_create(RRDHOST *host, const char *type, const char *id, const cha
424 char varvalue2[CONFIG_MAX_VALUE + 1];
425 snprintfz(varvalue, CONFIG_MAX_VALUE, "%s (%s)", title?title:"", st->name);
426 json_escape_string(varvalue2, varvalue, sizeof(varvalue2));
370 - st->title = config_get(st->id, "title", varvalue2);
427 + st->title = config_get(st->config_section, "title", varvalue2);
428 }
429
430 st->rrdfamily = rrdfamily_create(host, st->family);