X-Git-Url: https://arthur.barton.de/gitweb/?a=blobdiff_plain;f=src%2Frrdset.c;h=63aeacebd04fb42d0e3ac06fc110f398616295be;hb=73212e3a8731012fee476e373f4a5b647f5126e5;hp=89f873903a5e9b98a8c424bc4e6215d32d22dff9;hpb=c98acefa301f23d8c7d2857b8cde5fbb9c2326a9;p=netdata.git diff --git a/src/rrdset.c b/src/rrdset.c index 89f87390..63aeaceb 100644 --- a/src/rrdset.c +++ b/src/rrdset.c @@ -187,7 +187,7 @@ void rrdset_reset(RRDSET *st) { rrddim_foreach_read(rd, st) { rd->last_collected_time.tv_sec = 0; rd->last_collected_time.tv_usec = 0; - rd->counter = 0; + rd->collections_counter = 0; memset(rd->values, 0, rd->entries * sizeof(storage_number)); } } @@ -215,11 +215,16 @@ inline long align_entries_to_pagesize(RRD_MEMORY_MODE mode, long entries) { return entries; } -static inline void timeval_align(struct timeval *tv, int update_every) { +static inline void last_collected_time_align(struct timeval *tv, int update_every) { tv->tv_sec -= tv->tv_sec % update_every; tv->tv_usec = 500000; } +static inline void last_updated_time_align(struct timeval *tv, int update_every) { + tv->tv_sec -= tv->tv_sec % update_every; + tv->tv_usec = 0; +} + // ---------------------------------------------------------------------------- // RRDSET - free a chart @@ -229,14 +234,7 @@ void rrdset_free(RRDSET *st) { rrdhost_check_wrlock(st->rrdhost); // make sure we have a write lock on the host rrdset_wrlock(st); // lock this RRDSET - // ------------------------------------------------------------------------ - // free its children structures - - while(st->variables) rrdsetvar_free(st->variables); - while(st->alarms) rrdsetcalc_unlink(st->alarms); - while(st->dimensions) rrddim_free(st, st->dimensions); - - rrdfamily_free(st->rrdhost, st->rrdfamily); + // info("Removing chart '%s' ('%s')", st->id, st->name); // ------------------------------------------------------------------------ // remove it from the indexes @@ -246,6 +244,15 @@ void rrdset_free(RRDSET *st) { rrdset_index_del_name(st->rrdhost, st); + // ------------------------------------------------------------------------ + // free its children structures + + while(st->variables) rrdsetvar_free(st->variables); + while(st->alarms) rrdsetcalc_unlink(st->alarms); + while(st->dimensions) rrddim_free(st, st->dimensions); + + rrdfamily_free(st->rrdhost, st->rrdfamily); + // ------------------------------------------------------------------------ // unlink it from the host @@ -278,13 +285,42 @@ void rrdset_free(RRDSET *st) { freez(st); } +void rrdset_save(RRDSET *st) { + RRDDIM *rd; + + rrdset_check_rdlock(st); + + // info("Saving chart '%s' ('%s')", st->id, st->name); + + if(st->rrd_memory_mode == RRD_MEMORY_MODE_SAVE) { + debug(D_RRD_STATS, "Saving stats '%s' to '%s'.", st->name, st->cache_filename); + savememory(st->cache_filename, st, st->memsize); + } + + rrddim_foreach_read(rd, st) { + if(likely(rd->rrd_memory_mode == RRD_MEMORY_MODE_SAVE)) { + debug(D_RRD_STATS, "Saving dimension '%s' to '%s'.", rd->name, rd->cache_filename); + savememory(rd->cache_filename, rd, rd->memsize); + } + } +} + // ---------------------------------------------------------------------------- // RRDSET - create a chart -RRDSET *rrdset_create(RRDHOST *host, const char *type, const char *id, const char *name, const char *family - , const char *context, const char *title, const char *units, long priority - , int update_every, RRDSET_TYPE chart_type) { - +RRDSET *rrdset_create( + RRDHOST *host + , const char *type + , const char *id + , const char *name + , const char *family + , const char *context + , const char *title + , const char *units + , long priority + , int update_every + , RRDSET_TYPE chart_type +) { if(!type || !type[0]) { fatal("Cannot create rrd stats without a type."); return NULL; @@ -303,6 +339,7 @@ RRDSET *rrdset_create(RRDHOST *host, const char *type, const char *id, const cha RRDSET *st = rrdset_find(host, fullid); if(st) { + rrdset_flag_clear(st, RRDSET_FLAG_OBSOLETE); debug(D_RRD_CALLS, "RRDSET '%s', already exists.", fullid); return st; } @@ -398,7 +435,8 @@ RRDSET *rrdset_create(RRDHOST *host, const char *type, const char *id, const cha // make sure the database is aligned if(st->last_updated.tv_sec) - timeval_align(&st->last_updated, update_every); + last_updated_time_align(&st->last_updated, update_every); + // make sure we have the right memory mode // even if we cleared the memory @@ -443,6 +481,7 @@ RRDSET *rrdset_create(RRDHOST *host, const char *type, const char *id, const cha rrdset_flag_clear(st, RRDSET_FLAG_DETAIL); rrdset_flag_clear(st, RRDSET_FLAG_DEBUG); + rrdset_flag_clear(st, RRDSET_FLAG_OBSOLETE); // if(!strcmp(st->id, "disk_util.dm-0")) { // st->debug = 1; @@ -496,6 +535,8 @@ RRDSET *rrdset_create(RRDHOST *host, const char *type, const char *id, const cha rrdsetcalc_link_matching(st); rrdcalctemplate_link_matching(st); + rrdhost_cleanup(host); + rrdhost_unlock(host); return(st); @@ -543,15 +584,17 @@ inline void rrdset_next_usec(RRDSET *st, usec_t microseconds) { if(unlikely(since_last_usec < 0)) { // oops! the database is in the future - error("Database for chart '%s' on host '%s' is %lld microseconds in the future.", st->id, st->rrdhost->hostname, -since_last_usec); - memcpy(&st->last_collected_time, &now, sizeof(struct timeval)); - st->last_collected_time.tv_sec -= st->update_every; + error("Database for chart '%s' on host '%s' is %lld microseconds in the future. Adjusting it to current time.", st->id, st->rrdhost->hostname, -since_last_usec); + + st->last_collected_time.tv_sec = now.tv_sec - st->update_every; + st->last_collected_time.tv_usec = now.tv_usec; + last_collected_time_align(&st->last_collected_time, st->update_every); - memcpy(&st->last_updated, &now, sizeof(struct timeval)); - timeval_align(&st->last_updated, st->update_every); - st->last_updated.tv_sec -= st->update_every; + st->last_updated.tv_sec = now.tv_sec - st->update_every; + st->last_updated.tv_usec = now.tv_usec; + last_updated_time_align(&st->last_updated, st->update_every); - microseconds = st->update_every * USEC_PER_SEC; + microseconds = st->update_every * USEC_PER_SEC; since_last_usec = st->update_every * USEC_PER_SEC; } @@ -589,7 +632,7 @@ inline void rrdset_next_usec(RRDSET *st, usec_t microseconds) { static inline void rrdset_init_last_collected_time(RRDSET *st) { now_realtime_timeval(&st->last_collected_time); - timeval_align(&st->last_collected_time, st->update_every); + last_collected_time_align(&st->last_collected_time, st->update_every); } static inline usec_t rrdset_update_last_collected_time(RRDSET *st) { @@ -602,12 +645,12 @@ static inline usec_t rrdset_update_last_collected_time(RRDSET *st) { static inline void rrdset_init_last_updated_time(RRDSET *st) { // copy the last collected time to last updated time - memcpy(&st->last_updated, &st->last_collected_time, sizeof(struct timeval)); - timeval_align(&st->last_updated, st->update_every); - st->last_updated.tv_usec = 0; + st->last_updated.tv_sec = st->last_collected_time.tv_sec; + st->last_updated.tv_usec = st->last_collected_time.tv_usec; + last_updated_time_align(&st->last_updated, st->update_every); } -static inline void rrdset_done_push_int(RRDSET *st) { +static inline void rrdset_done_push_exclusive(RRDSET *st) { if(unlikely(!st->last_collected_time.tv_sec)) { // it is the first entry // set the last_collected_time to now @@ -619,17 +662,20 @@ static inline void rrdset_done_push_int(RRDSET *st) { rrdset_update_last_collected_time(st); } - st->counter++; st->counter_done++; + rrdset_rdlock(st); rrdset_done_push(st); + rrdset_unlock(st); } void rrdset_done(RRDSET *st) { if(unlikely(netdata_exit)) return; - if(unlikely(st->rrdhost->rrdpush_exclusive)) { - rrdset_done_push_int(st); + if(unlikely(st->rrd_memory_mode == RRD_MEMORY_MODE_NONE)) { + if(unlikely(st->rrdhost->rrdpush_enabled)) + rrdset_done_push_exclusive(st); + return; } @@ -666,6 +712,11 @@ void rrdset_done(RRDSET *st) { st->enabled = 1; */ + if(unlikely(rrdset_flag_check(st, RRDSET_FLAG_OBSOLETE))) { + error("Chart '%s' has the OBSOLETE flag set, but it is collected.", st->id); + rrdset_flag_clear(st, RRDSET_FLAG_OBSOLETE); + } + // check if the chart has a long time to be updated if(unlikely(st->usec_since_last_update > st->entries * update_every_ut)) { info("%s: took too long to be updated (%0.3Lf secs). Resetting it.", st->name, (long double)(st->usec_since_last_update / 1000000.0)); @@ -748,12 +799,15 @@ void rrdset_done(RRDSET *st) { } st->counter_done++; + if(unlikely(st->rrdhost->rrdpush_enabled)) + rrdset_done_push(st); + // calculate totals and count the dimensions int dimensions = 0; st->collected_total = 0; rrddim_foreach_read(rd, st) { dimensions++; - if(likely(rrddim_flag_check(rd, RRDDIM_FLAG_UPDATED))) + if(likely(rd->updated)) st->collected_total += rd->collected_value; } @@ -764,7 +818,7 @@ void rrdset_done(RRDSET *st) { // at this stage we do not interpolate anything rrddim_foreach_read(rd, st) { - if(unlikely(!rrddim_flag_check(rd, RRDDIM_FLAG_UPDATED))) { + if(unlikely(!rd->updated)) { rd->calculated_value = 0; continue; } @@ -826,7 +880,7 @@ void rrdset_done(RRDSET *st) { break; case RRD_ALGORITHM_INCREMENTAL: - if(unlikely(rd->counter <= 1)) { + if(unlikely(rd->collections_counter <= 1)) { rd->calculated_value = 0; continue; } @@ -866,7 +920,7 @@ void rrdset_done(RRDSET *st) { break; case RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL: - if(unlikely(rd->counter <= 1)) { + if(unlikely(rd->collections_counter <= 1)) { rd->calculated_value = 0; continue; } @@ -1050,7 +1104,7 @@ void rrdset_done(RRDSET *st) { continue; } - if(likely(rrddim_flag_check(rd, RRDDIM_FLAG_UPDATED) && rd->counter > 1 && iterations < st->gap_when_lost_iterations_above)) { + if(likely(rd->updated && rd->collections_counter > 1 && iterations < st->gap_when_lost_iterations_above)) { rd->values[st->current_entry] = pack_storage_number(new_value, storage_flags ); rd->last_stored_value = new_value; @@ -1113,7 +1167,7 @@ void rrdset_done(RRDSET *st) { st->last_collected_total = st->collected_total; rrddim_foreach_read(rd, st) { - if(unlikely(!rrddim_flag_check(rd, RRDDIM_FLAG_UPDATED))) + if(unlikely(!rd->updated)) continue; if(unlikely(rrdset_flag_check(st, RRDSET_FLAG_DEBUG))) @@ -1145,7 +1199,7 @@ void rrdset_done(RRDSET *st) { rd->calculated_value = 0; rd->collected_value = 0; - rrddim_flag_clear(rd, RRDDIM_FLAG_UPDATED); + rd->updated = 0; if(unlikely(rrdset_flag_check(st, RRDSET_FLAG_DEBUG))) debug(D_RRD_STATS, "%s/%s: END " @@ -1217,8 +1271,4 @@ void rrdset_done(RRDSET *st) { if(unlikely(pthread_setcancelstate(pthreadoldcancelstate, NULL) != 0)) error("Cannot set pthread cancel state to RESTORE (%d).", pthreadoldcancelstate); - - if(unlikely(st->rrdhost->rrdpush_enabled)) - rrdset_done_push_int(st); } -