}
// 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
freez(e);
}
+ freez(arl_base->name);
+
#ifdef NETDATA_INTERNAL_CHECKS
memset(arl_base, 0, sizeof(ARL_BASE));
#endif
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;
if(e) {
// found it in the keywords
+
base->relinkings++;
// run the processor for it
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
} 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
} 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);
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
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);
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
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);
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);
{
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:"<NONAME>");
return rd;
}
}
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);