added ARL debugging info and errors on common pitfalls (only when -DNETDATA_INTERNAL_CHECKS=1)
Costa Tsaousis (ktsaou) committed
Jan 22, 2017 at 17:23 UTC
0f3af2cbdf3876a4d83efd85b4ed1ec61867d7c4
8 files changed
+57
-25
src/adaptive_resortable_list.c
+42
-17
@@ -12,9 +12,11 @@ static inline void arl_callback_str2ull(const char *name, uint32_t hash, const c
12
}
13
14
// create a new ARL
15
-ARL_BASE *arl_create(void (*processor)(const char *, uint32_t, const char *, void *), size_t rechecks) {
15
+ARL_BASE *arl_create(const char *name, void (*processor)(const char *, uint32_t, const char *, void *), size_t rechecks) {
16
ARL_BASE *base = callocz(1, sizeof(ARL_BASE));
17
18
+ base->name = strdupz(name);
19
+
20
if(!processor)
21
base->processor = arl_callback_str2ull;
22
else
@@ -40,6 +42,8 @@ void arl_free(ARL_BASE *arl_base) {
42
freez(e);
43
}
44
45
+ freez(arl_base->name);
46
+
47
#ifdef NETDATA_INTERNAL_CHECKS
48
memset(arl_base, 0, sizeof(ARL_BASE));
49
#endif
@@ -50,22 +54,37 @@ void arl_free(ARL_BASE *arl_base) {
54
void arl_begin(ARL_BASE *base) {
55
ARL_ENTRY *e;
56
53
- /*
54
- info("iteration %zu, expected %zu, wanted %zu, allocated %zu, fred %zu, relinkings %zu, found %zu, added %zu, fast %zu, slow %zu"
55
- , base->iteration
56
- , base->expected
57
- , base->wanted
58
- , base->allocated
59
- , base->fred
60
- , base->relinkings
61
- , base->found
62
- , base->added
63
- , base->fast
64
- , base->slow
65
- );
66
- for(e = base->head; e ; e = e->next) fprintf(stderr, "%s ", e->name);
67
- fprintf(stderr, "\n");
68
- */
57
+#ifdef NETDATA_INTERNAL_CHECKS
58
+ if(likely(base->iteration > 10)) {
59
+ // do these checks after the ARL has been sorted
60
+
61
+ if(unlikely(base->relinkings > (base->expected + base->allocated)))
62
+ info("ARL '%s' has %zu relinkings with %zu expected and %zu allocated entries. Is the source changing so fast?"
63
+ , base->name, base->relinkings, base->expected, base->allocated);
64
+
65
+ if(unlikely(base->slow > base->fast))
66
+ info("ARL '%s' has %zu fast searches and %zu slow searches. Is the source really changing so fast?"
67
+ , base->name, base->fast, base->slow);
68
+
69
+ if(unlikely(base->iteration % 60 == 0)) {
70
+ info("ARL '%s' statistics: iteration %zu, expected %zu, wanted %zu, allocated %zu, fred %zu, relinkings %zu, found %zu, added %zu, fast %zu, slow %zu"
71
+ , base->name
72
+ , base->iteration
73
+ , base->expected
74
+ , base->wanted
75
+ , base->allocated
76
+ , base->fred
77
+ , base->relinkings
78
+ , base->found
79
+ , base->added
80
+ , base->fast
81
+ , base->slow
82
+ );
83
+ // for(e = base->head; e; e = e->next) fprintf(stderr, "%s ", e->name);
84
+ // fprintf(stderr, "\n");
85
+ }
86
+ }
87
+#endif
88
89
if(unlikely(base->added || base->iteration % base->rechecks) == 1) {
90
base->added = 0;
@@ -140,6 +159,7 @@ int arl_find_or_create_and_relink(ARL_BASE *base, const char *s, const char *val
159
160
if(e) {
161
// found it in the keywords
162
+
163
base->relinkings++;
164
165
// 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
189
base->added++;
190
}
191
192
+#ifdef NETDATA_INTERNAL_CHECKS
193
+ if(unlikely(base->iteration % 60 == 0 && e->flags & ARL_ENTRY_FLAG_FOUND))
194
+ info("ARL '%s': entry '%s' is already found. Did you forget to call arl_begin()?", base->name, s);
195
+#endif
196
+
197
e->flags |= ARL_ENTRY_FLAG_FOUND;
198
199
// link it here
src/adaptive_resortable_list.h
+8
-1
@@ -56,6 +56,8 @@ typedef struct arl_entry {
56
} ARL_ENTRY;
57
58
typedef struct arl_base {
59
+ char *name;
60
+
61
size_t iteration; // incremented on each iteration (arl_begin())
62
size_t found; // the number of expected keywords found in this iteration
63
size_t expected; // the number of expected keywords
@@ -93,7 +95,7 @@ typedef struct arl_base {
95
} ARL_BASE;
96
97
// create a new ARL
96
-extern ARL_BASE *arl_create(void (*processor)(const char *, uint32_t, const char *, void *), size_t rechecks);
98
+extern ARL_BASE *arl_create(const char *name, void (*processor)(const char *, uint32_t, const char *, void *), size_t rechecks);
99
100
// free an ARL
101
extern void arl_free(ARL_BASE *arl_base);
@@ -116,6 +118,11 @@ extern void arl_begin(ARL_BASE *base);
118
static inline int arl_check(ARL_BASE *base, const char *keyword, const char *value) {
119
ARL_ENTRY *e = base->next_keyword;
120
121
+#ifdef NETDATA_INTERNAL_CHECKS
122
+ if(unlikely((base->fast + base->slow) % (base->expected + base->allocated) == 0 && (base->fast + base->slow) > (base->expected + base->allocated) * base->iteration))
123
+ info("ARL '%s': Did you forget to call arl_begin()?", base->name);
124
+#endif
125
+
126
// it should be the first entry (pointed by base->next_keyword)
127
if(likely(!strcmp(keyword, e->name))) {
128
// it is
src/proc_meminfo.c
+1
-1
@@ -62,7 +62,7 @@ int do_proc_meminfo(int update_every, usec_t dt) {
62
do_kernel = config_get_boolean("plugin:proc:/proc/meminfo", "kernel memory", 1);
63
do_slab = config_get_boolean("plugin:proc:/proc/meminfo", "slab memory", 1);
64
65
- arl_base = arl_create(NULL, 60);
65
+ arl_base = arl_create("meminfo", NULL, 60);
66
arl_expect(arl_base, "MemTotal", &MemTotal);
67
arl_expect(arl_base, "MemFree", &MemFree);
68
arl_expect(arl_base, "Buffers", &Buffers);
src/proc_net_netstat.c
+2
-2
@@ -112,8 +112,8 @@ int do_proc_net_netstat(int update_every, usec_t dt) {
112
do_tcpext_connaborts = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "TCP connection aborts", CONFIG_ONDEMAND_ONDEMAND);
113
do_tcpext_memory = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "TCP memory pressures", CONFIG_ONDEMAND_ONDEMAND);
114
115
- arl_ipext = arl_create(NULL, 60);
116
- arl_tcpext = arl_create(NULL, 60);
115
+ arl_ipext = arl_create("netstat/ipext", NULL, 60);
116
+ arl_tcpext = arl_create("netstat/tcpext", NULL, 60);
117
118
// --------------------------------------------------------------------
119
// IPv4
src/proc_net_snmp6.c
+1
-1
@@ -149,7 +149,7 @@ int do_proc_net_snmp6(int update_every, usec_t dt) {
149
do_icmp_types = config_get_boolean_ondemand("plugin:proc:/proc/net/snmp6", "icmp types", CONFIG_ONDEMAND_ONDEMAND);
150
do_ect = config_get_boolean_ondemand("plugin:proc:/proc/net/snmp6", "ect", CONFIG_ONDEMAND_ONDEMAND);
151
152
- arl_base = arl_create(NULL, 60);
152
+ arl_base = arl_create("snmp6", NULL, 60);
153
arl_expect(arl_base, "Ip6InReceives", &Ip6InReceives);
154
arl_expect(arl_base, "Ip6InHdrErrors", &Ip6InHdrErrors);
155
arl_expect(arl_base, "Ip6InTooBigErrors", &Ip6InTooBigErrors);
src/proc_vmstat.c
+1
-1
@@ -31,7 +31,7 @@ int do_proc_vmstat(int update_every, usec_t dt) {
31
do_numa = config_get_boolean_ondemand("plugin:proc:/proc/vmstat", "system-wide numa metric summary", CONFIG_ONDEMAND_ONDEMAND);
32
33
34
- arl_base = arl_create(NULL, 60);
34
+ arl_base = arl_create("vmstat", NULL, 60);
35
arl_expect(arl_base, "pgfault", &pgfault);
36
arl_expect(arl_base, "pgmajfault", &pgmajfault);
37
arl_expect(arl_base, "pgpgin", &pgpgin);
src/rrd.c
+1
-1
@@ -650,7 +650,7 @@ RRDDIM *rrddim_add(RRDSET *st, const char *id, const char *name, long multiplier
650
{
651
RRDDIM *rd = rrddim_find(st, id);
652
if(rd) {
653
- error("Cannot create rrd dimension '%s/%s', it already exists.", st->id, name);
653
+ debug(D_RRD_CALLS, "Cannot create rrd dimension '%s/%s', it already exists.", st->id, name?name:"<NONAME>");
654
return rd;
655
}
656
src/sys_fs_cgroup.c
+1
-1
@@ -594,7 +594,7 @@ static inline void cgroup_read_memory(struct memory *mem) {
594
}
595
596
if(unlikely(!mem->arl_base)) {
597
- mem->arl_base = arl_create(NULL, 60);
597
+ mem->arl_base = arl_create("cgroup/memory", NULL, 60);
598
599
arl_expect(mem->arl_base, "cache", &mem->cache);
600
arl_expect(mem->arl_base, "rss", &mem->rss);