From: Costa Tsaousis (ktsaou) Date: Sun, 22 Jan 2017 15:23:19 +0000 (+0200) Subject: added ARL debugging info and errors on common pitfalls (only when -DNETDATA_INTERNAL_... X-Git-Tag: v1.5.0~5^2 X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=netdata.git;a=commitdiff_plain;h=0f3af2cbdf3876a4d83efd85b4ed1ec61867d7c4 added ARL debugging info and errors on common pitfalls (only when -DNETDATA_INTERNAL_CHECKS=1) --- diff --git a/src/adaptive_resortable_list.c b/src/adaptive_resortable_list.c index 032d553c..a37c396f 100644 --- a/src/adaptive_resortable_list.c +++ b/src/adaptive_resortable_list.c @@ -12,9 +12,11 @@ static inline void arl_callback_str2ull(const char *name, uint32_t hash, const c } // create a new ARL -ARL_BASE *arl_create(void (*processor)(const char *, uint32_t, const char *, void *), size_t rechecks) { +ARL_BASE *arl_create(const char *name, void (*processor)(const char *, uint32_t, const char *, void *), size_t rechecks) { ARL_BASE *base = callocz(1, sizeof(ARL_BASE)); + base->name = strdupz(name); + if(!processor) base->processor = arl_callback_str2ull; else @@ -40,6 +42,8 @@ void arl_free(ARL_BASE *arl_base) { freez(e); } + freez(arl_base->name); + #ifdef NETDATA_INTERNAL_CHECKS memset(arl_base, 0, sizeof(ARL_BASE)); #endif @@ -50,22 +54,37 @@ void arl_free(ARL_BASE *arl_base) { void arl_begin(ARL_BASE *base) { ARL_ENTRY *e; - /* - info("iteration %zu, expected %zu, wanted %zu, allocated %zu, fred %zu, relinkings %zu, found %zu, added %zu, fast %zu, slow %zu" - , base->iteration - , base->expected - , base->wanted - , base->allocated - , base->fred - , base->relinkings - , base->found - , base->added - , base->fast - , base->slow - ); - for(e = base->head; e ; e = e->next) fprintf(stderr, "%s ", e->name); - fprintf(stderr, "\n"); - */ +#ifdef NETDATA_INTERNAL_CHECKS + if(likely(base->iteration > 10)) { + // do these checks after the ARL has been sorted + + if(unlikely(base->relinkings > (base->expected + base->allocated))) + info("ARL '%s' has %zu relinkings with %zu expected and %zu allocated entries. Is the source changing so fast?" + , base->name, base->relinkings, base->expected, base->allocated); + + if(unlikely(base->slow > base->fast)) + info("ARL '%s' has %zu fast searches and %zu slow searches. Is the source really changing so fast?" + , base->name, base->fast, base->slow); + + if(unlikely(base->iteration % 60 == 0)) { + info("ARL '%s' statistics: iteration %zu, expected %zu, wanted %zu, allocated %zu, fred %zu, relinkings %zu, found %zu, added %zu, fast %zu, slow %zu" + , base->name + , base->iteration + , base->expected + , base->wanted + , base->allocated + , base->fred + , base->relinkings + , base->found + , base->added + , base->fast + , base->slow + ); + // for(e = base->head; e; e = e->next) fprintf(stderr, "%s ", e->name); + // fprintf(stderr, "\n"); + } + } +#endif if(unlikely(base->added || base->iteration % base->rechecks) == 1) { base->added = 0; @@ -140,6 +159,7 @@ int arl_find_or_create_and_relink(ARL_BASE *base, const char *s, const char *val if(e) { // found it in the keywords + base->relinkings++; // run the processor for it @@ -169,6 +189,11 @@ int arl_find_or_create_and_relink(ARL_BASE *base, const char *s, const char *val base->added++; } +#ifdef NETDATA_INTERNAL_CHECKS + if(unlikely(base->iteration % 60 == 0 && e->flags & ARL_ENTRY_FLAG_FOUND)) + info("ARL '%s': entry '%s' is already found. Did you forget to call arl_begin()?", base->name, s); +#endif + e->flags |= ARL_ENTRY_FLAG_FOUND; // link it here diff --git a/src/adaptive_resortable_list.h b/src/adaptive_resortable_list.h index b338afda..609cd0c4 100644 --- a/src/adaptive_resortable_list.h +++ b/src/adaptive_resortable_list.h @@ -56,6 +56,8 @@ typedef struct arl_entry { } ARL_ENTRY; typedef struct arl_base { + char *name; + size_t iteration; // incremented on each iteration (arl_begin()) size_t found; // the number of expected keywords found in this iteration size_t expected; // the number of expected keywords @@ -93,7 +95,7 @@ typedef struct arl_base { } ARL_BASE; // create a new ARL -extern ARL_BASE *arl_create(void (*processor)(const char *, uint32_t, const char *, void *), size_t rechecks); +extern ARL_BASE *arl_create(const char *name, void (*processor)(const char *, uint32_t, const char *, void *), size_t rechecks); // free an ARL extern void arl_free(ARL_BASE *arl_base); @@ -116,6 +118,11 @@ extern void arl_begin(ARL_BASE *base); static inline int arl_check(ARL_BASE *base, const char *keyword, const char *value) { ARL_ENTRY *e = base->next_keyword; +#ifdef NETDATA_INTERNAL_CHECKS + if(unlikely((base->fast + base->slow) % (base->expected + base->allocated) == 0 && (base->fast + base->slow) > (base->expected + base->allocated) * base->iteration)) + info("ARL '%s': Did you forget to call arl_begin()?", base->name); +#endif + // it should be the first entry (pointed by base->next_keyword) if(likely(!strcmp(keyword, e->name))) { // it is diff --git a/src/proc_meminfo.c b/src/proc_meminfo.c index 5c533195..19ba8da3 100644 --- a/src/proc_meminfo.c +++ b/src/proc_meminfo.c @@ -62,7 +62,7 @@ int do_proc_meminfo(int update_every, usec_t dt) { do_kernel = config_get_boolean("plugin:proc:/proc/meminfo", "kernel memory", 1); do_slab = config_get_boolean("plugin:proc:/proc/meminfo", "slab memory", 1); - arl_base = arl_create(NULL, 60); + arl_base = arl_create("meminfo", NULL, 60); arl_expect(arl_base, "MemTotal", &MemTotal); arl_expect(arl_base, "MemFree", &MemFree); arl_expect(arl_base, "Buffers", &Buffers); diff --git a/src/proc_net_netstat.c b/src/proc_net_netstat.c index c104160c..8741a71c 100644 --- a/src/proc_net_netstat.c +++ b/src/proc_net_netstat.c @@ -112,8 +112,8 @@ int do_proc_net_netstat(int update_every, usec_t dt) { do_tcpext_connaborts = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "TCP connection aborts", CONFIG_ONDEMAND_ONDEMAND); do_tcpext_memory = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "TCP memory pressures", CONFIG_ONDEMAND_ONDEMAND); - arl_ipext = arl_create(NULL, 60); - arl_tcpext = arl_create(NULL, 60); + arl_ipext = arl_create("netstat/ipext", NULL, 60); + arl_tcpext = arl_create("netstat/tcpext", NULL, 60); // -------------------------------------------------------------------- // IPv4 diff --git a/src/proc_net_snmp6.c b/src/proc_net_snmp6.c index 27a4f318..51d7121a 100644 --- a/src/proc_net_snmp6.c +++ b/src/proc_net_snmp6.c @@ -149,7 +149,7 @@ int do_proc_net_snmp6(int update_every, usec_t dt) { do_icmp_types = config_get_boolean_ondemand("plugin:proc:/proc/net/snmp6", "icmp types", CONFIG_ONDEMAND_ONDEMAND); do_ect = config_get_boolean_ondemand("plugin:proc:/proc/net/snmp6", "ect", CONFIG_ONDEMAND_ONDEMAND); - arl_base = arl_create(NULL, 60); + arl_base = arl_create("snmp6", NULL, 60); arl_expect(arl_base, "Ip6InReceives", &Ip6InReceives); arl_expect(arl_base, "Ip6InHdrErrors", &Ip6InHdrErrors); arl_expect(arl_base, "Ip6InTooBigErrors", &Ip6InTooBigErrors); diff --git a/src/proc_vmstat.c b/src/proc_vmstat.c index 12e6ddaa..ea917b98 100644 --- a/src/proc_vmstat.c +++ b/src/proc_vmstat.c @@ -31,7 +31,7 @@ int do_proc_vmstat(int update_every, usec_t dt) { do_numa = config_get_boolean_ondemand("plugin:proc:/proc/vmstat", "system-wide numa metric summary", CONFIG_ONDEMAND_ONDEMAND); - arl_base = arl_create(NULL, 60); + arl_base = arl_create("vmstat", NULL, 60); arl_expect(arl_base, "pgfault", &pgfault); arl_expect(arl_base, "pgmajfault", &pgmajfault); arl_expect(arl_base, "pgpgin", &pgpgin); diff --git a/src/rrd.c b/src/rrd.c index 27e8e6b2..bd0175ef 100644 --- a/src/rrd.c +++ b/src/rrd.c @@ -650,7 +650,7 @@ RRDDIM *rrddim_add(RRDSET *st, const char *id, const char *name, long multiplier { RRDDIM *rd = rrddim_find(st, id); if(rd) { - error("Cannot create rrd dimension '%s/%s', it already exists.", st->id, name); + debug(D_RRD_CALLS, "Cannot create rrd dimension '%s/%s', it already exists.", st->id, name?name:""); return rd; } diff --git a/src/sys_fs_cgroup.c b/src/sys_fs_cgroup.c index f4b3db2d..2b7254f4 100644 --- a/src/sys_fs_cgroup.c +++ b/src/sys_fs_cgroup.c @@ -594,7 +594,7 @@ static inline void cgroup_read_memory(struct memory *mem) { } if(unlikely(!mem->arl_base)) { - mem->arl_base = arl_create(NULL, 60); + mem->arl_base = arl_create("cgroup/memory", NULL, 60); arl_expect(mem->arl_base, "cache", &mem->cache); arl_expect(mem->arl_base, "rss", &mem->rss);