cgroups now also read usage_in_bytes, memsw_usage_in_bytes, failcnt and creates 2 new memory charts; fixes #1019
Costa Tsaousis (ktsaou) committed
Oct 1, 2016 at 03:14 UTC
714ed145493daf78847907328b44d78779347ff9
4 files changed
+104
-2
src/common.c
+17
@@ -1126,3 +1126,20 @@ void get_system_HZ(void) {
1126
1127
hz = (unsigned int) ticks;
1128
}
1129
+
1130
+int read_single_number_file(const char *filename, unsigned long long *result) {
1131
+ char buffer[1024 + 1];
1132
+
1133
+ int fd = open(filename, O_RDONLY, 0666);
1134
+ if(unlikely(fd == -1)) return 1;
1135
+
1136
+ ssize_t r = read(fd, buffer, 1024);
1137
+ if(unlikely(r == -1)) {
1138
+ close(fd);
1139
+ return 2;
1140
+ }
1141
+
1142
+ close(fd);
1143
+ *result = strtoull(buffer, NULL, 0);
1144
+ return 0;
1145
+}
src/common.h
+2
@@ -184,4 +184,6 @@ extern void get_system_HZ(void);
184
#endif
185
#endif
186
187
+extern int read_single_number_file(const char *filename, unsigned long long *result);
188
+
189
#endif /* NETDATA_COMMON_H */
src/sys_fs_cgroup.c
+84
-1
@@ -138,6 +138,18 @@ struct memory {
138
unsigned long long total_active_file;
139
unsigned long long total_unevictable;
140
*/
141
+
142
+ int usage_in_bytes_updated;
143
+ char *filename_usage_in_bytes;
144
+ unsigned long long usage_in_bytes;
145
+
146
+ int msw_usage_in_bytes_updated;
147
+ char *filename_msw_usage_in_bytes;
148
+ unsigned long long msw_usage_in_bytes;
149
+
150
+ int failcnt_updated;
151
+ char *filename_failcnt;
152
+ unsigned long long failcnt;
153
};
154
155
// https://www.kernel.org/doc/Documentation/cgroup-v1/cpuacct.txt
@@ -557,6 +569,24 @@ void cgroup_read_memory(struct memory *mem) {
569
570
mem->updated = 1;
571
}
572
+
573
+ mem->usage_in_bytes_updated = 0;
574
+ if(mem->filename_usage_in_bytes) {
575
+ if(likely(!read_single_number_file(mem->filename_usage_in_bytes, &mem->usage_in_bytes)))
576
+ mem->usage_in_bytes_updated = 1;
577
+ }
578
+
579
+ mem->msw_usage_in_bytes_updated = 0;
580
+ if(mem->filename_msw_usage_in_bytes) {
581
+ if(likely(!read_single_number_file(mem->filename_msw_usage_in_bytes, &mem->msw_usage_in_bytes)))
582
+ mem->msw_usage_in_bytes_updated = 1;
583
+ }
584
+
585
+ mem->failcnt_updated = 0;
586
+ if(mem->filename_failcnt) {
587
+ if(likely(!read_single_number_file(mem->filename_failcnt, &mem->failcnt)))
588
+ mem->failcnt_updated = 1;
589
+ }
590
}
591
592
void cgroup_read(struct cgroup *cg) {
@@ -990,6 +1020,27 @@ void find_all_cgroups() {
1020
debug(D_CGROUP, "memory.stat filename for cgroup '%s': '%s'", cg->id, cg->memory.filename);
1021
}
1022
else debug(D_CGROUP, "memory.stat file for cgroup '%s': '%s' does not exist.", cg->id, filename);
1023
+
1024
+ snprintfz(filename, FILENAME_MAX, "%s%s/memory.usage_in_bytes", cgroup_memory_base, cg->id);
1025
+ if(stat(filename, &buf) != -1) {
1026
+ cg->memory.filename_usage_in_bytes = strdupz(filename);
1027
+ debug(D_CGROUP, "memory.usage_in_bytes filename for cgroup '%s': '%s'", cg->id, cg->memory.filename_usage_in_bytes);
1028
+ }
1029
+ else debug(D_CGROUP, "memory.usage_in_bytes file for cgroup '%s': '%s' does not exist.", cg->id, filename);
1030
+
1031
+ snprintfz(filename, FILENAME_MAX, "%s%s/memory.msw_usage_in_bytes", cgroup_memory_base, cg->id);
1032
+ if(stat(filename, &buf) != -1) {
1033
+ cg->memory.filename_msw_usage_in_bytes = strdupz(filename);
1034
+ debug(D_CGROUP, "memory.msw_usage_in_bytes filename for cgroup '%s': '%s'", cg->id, cg->memory.filename_msw_usage_in_bytes);
1035
+ }
1036
+ else debug(D_CGROUP, "memory.msw_usage_in_bytes file for cgroup '%s': '%s' does not exist.", cg->id, filename);
1037
+
1038
+ snprintfz(filename, FILENAME_MAX, "%s%s/memory.failcnt", cgroup_memory_base, cg->id);
1039
+ if(stat(filename, &buf) != -1) {
1040
+ cg->memory.filename_failcnt = strdupz(filename);
1041
+ debug(D_CGROUP, "memory.failcnt filename for cgroup '%s': '%s'", cg->id, cg->memory.filename_failcnt);
1042
+ }
1043
+ else debug(D_CGROUP, "memory.failcnt file for cgroup '%s': '%s' does not exist.", cg->id, filename);
1044
}
1045
if(cgroup_enable_blkio) {
1046
if(!cg->io_service_bytes.filename) {
@@ -1118,7 +1169,7 @@ void update_cgroup_charts(int update_every) {
1169
st = rrdset_find_bytype(type, "mem");
1170
if(!st) {
1171
snprintfz(title, CHART_TITLE_MAX, "Memory Usage for cgroup %s", cg->chart_title);
1121
- st = rrdset_create(type, "mem", NULL, "mem", "cgroup.mem", title, "MB", 40200, update_every,
1172
+ st = rrdset_create(type, "mem", NULL, "mem", "cgroup.mem", title, "MB", 40210, update_every,
1173
RRDSET_TYPE_STACKED);
1174
1175
rrddim_add(st, "cache", NULL, 1, 1024 * 1024, RRDDIM_ABSOLUTE);
@@ -1191,6 +1242,38 @@ void update_cgroup_charts(int update_every) {
1242
}
1243
}
1244
1245
+ if(cg->memory.usage_in_bytes_updated) {
1246
+ st = rrdset_find_bytype(type, "mem_usage");
1247
+ if(!st) {
1248
+ snprintfz(title, CHART_TITLE_MAX, "Total Memory for cgroup %s", cg->chart_title);
1249
+ st = rrdset_create(type, "mem_usage", NULL, "mem", "cgroup.mem_usage", title, "MB", 40200,
1250
+ update_every, RRDSET_TYPE_STACKED);
1251
+
1252
+ rrddim_add(st, "ram", NULL, 1, 1024 * 1024, RRDDIM_ABSOLUTE);
1253
+ rrddim_add(st, "swap", NULL, 1, 1024 * 1024, RRDDIM_ABSOLUTE);
1254
+ }
1255
+ else rrdset_next(st);
1256
+
1257
+ rrddim_set(st, "ram", cg->memory.usage_in_bytes);
1258
+ rrddim_set(st, "swap", (cg->memory.msw_usage_in_bytes > cg->memory.usage_in_bytes)?cg->memory.msw_usage_in_bytes - cg->memory.usage_in_bytes:0);
1259
+ rrdset_done(st);
1260
+ }
1261
+
1262
+ if(cg->memory.failcnt_updated && cg->memory.failcnt > 0) {
1263
+ st = rrdset_find_bytype(type, "mem_failcnt");
1264
+ if(!st) {
1265
+ snprintfz(title, CHART_TITLE_MAX, "Memory Limit Failures for cgroup %s", cg->chart_title);
1266
+ st = rrdset_create(type, "mem_failcnt", NULL, "mem", "cgroup.mem_failcnt", title, "MB", 40250,
1267
+ update_every, RRDSET_TYPE_LINE);
1268
+
1269
+ rrddim_add(st, "failures", NULL, 1, 1, RRDDIM_INCREMENTAL);
1270
+ }
1271
+ else rrdset_next(st);
1272
+
1273
+ rrddim_set(st, "failures", cg->memory.failcnt);
1274
+ rrdset_done(st);
1275
+ }
1276
+
1277
if(cg->io_service_bytes.updated && cg->io_service_bytes.Read + cg->io_service_bytes.Write > 0) {
1278
st = rrdset_find_bytype(type, "io");
1279
if(!st) {
web/dashboard.css
+1
-1
@@ -209,7 +209,7 @@ body {
209
outline: thin dotted;
210
}
211
.netdata-legend-series > .netdata-legend-series-content::-webkit-scrollbar {
212
- display: block; /* was 'none', but chrome was hidding content with it */
212
+ display: block; /* was 'none', but chrome was hiding content with it */
213
}
214
.has-scrollbar > .netdata-legend-series-content::-webkit-scrollbar {
215
display: block;