summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCosta Tsaousis (ktsaou) <costa@tsaousis.gr>2016-10-01 03:14:05 +0300
committerCosta Tsaousis (ktsaou) <costa@tsaousis.gr>2016-10-01 03:14:05 +0300
commit714ed145493daf78847907328b44d78779347ff9 (patch)
tree7cda2dd46e13d4d3aa1a2c085ed55ebfa33acc1e
parent1394d17f16c68afb215b6f9619551f590290f4f9 (diff)
cgroups now also read usage_in_bytes, memsw_usage_in_bytes, failcnt and creates 2 new memory charts; fixes #1019
-rw-r--r--src/common.c17
-rw-r--r--src/common.h2
-rw-r--r--src/sys_fs_cgroup.c85
-rw-r--r--web/dashboard.css2
4 files changed, 104 insertions, 2 deletions
diff --git a/src/common.c b/src/common.c
index 64d50f636e..6f162672cf 100644
--- a/src/common.c
+++ b/src/common.c
@@ -1126,3 +1126,20 @@ void get_system_HZ(void) {
hz = (unsigned int) ticks;
}
+
+int read_single_number_file(const char *filename, unsigned long long *result) {
+ char buffer[1024 + 1];
+
+ int fd = open(filename, O_RDONLY, 0666);
+ if(unlikely(fd == -1)) return 1;
+
+ ssize_t r = read(fd, buffer, 1024);
+ if(unlikely(r == -1)) {
+ close(fd);
+ return 2;
+ }
+
+ close(fd);
+ *result = strtoull(buffer, NULL, 0);
+ return 0;
+}
diff --git a/src/common.h b/src/common.h
index 1a9289173f..4b9d75b4ec 100644
--- a/src/common.h
+++ b/src/common.h
@@ -184,4 +184,6 @@ extern void get_system_HZ(void);
#endif
#endif
+extern int read_single_number_file(const char *filename, unsigned long long *result);
+
#endif /* NETDATA_COMMON_H */
diff --git a/src/sys_fs_cgroup.c b/src/sys_fs_cgroup.c
index 010af824db..298f38a381 100644
--- a/src/sys_fs_cgroup.c
+++ b/src/sys_fs_cgroup.c
@@ -138,6 +138,18 @@ struct memory {
unsigned long long total_active_file;
unsigned long long total_unevictable;
*/
+
+ int usage_in_bytes_updated;
+ char *filename_usage_in_bytes;
+ unsigned long long usage_in_bytes;
+
+ int msw_usage_in_bytes_updated;
+ char *filename_msw_usage_in_bytes;
+ unsigned long long msw_usage_in_bytes;
+
+ int failcnt_updated;
+ char *filename_failcnt;
+ unsigned long long failcnt;
};
// https://www.kernel.org/doc/Documentation/cgroup-v1/cpuacct.txt
@@ -557,6 +569,24 @@ void cgroup_read_memory(struct memory *mem) {
mem->updated = 1;
}
+
+ mem->usage_in_bytes_updated = 0;
+ if(mem->filename_usage_in_bytes) {
+ if(likely(!read_single_number_file(mem->filename_usage_in_bytes, &mem->usage_in_bytes)))
+ mem->usage_in_bytes_updated = 1;
+ }
+
+ mem->msw_usage_in_bytes_updated = 0;
+ if(mem->filename_msw_usage_in_bytes) {
+ if(likely(!read_single_number_file(mem->filename_msw_usage_in_bytes, &mem->msw_usage_in_bytes)))
+ mem->msw_usage_in_bytes_updated = 1;
+ }
+
+ mem->failcnt_updated = 0;
+ if(mem->filename_failcnt) {
+ if(likely(!read_single_number_file(mem->filename_failcnt, &mem->failcnt)))
+ mem->failcnt_updated = 1;
+ }
}
void cgroup_read(struct cgroup *cg) {
@@ -990,6 +1020,27 @@ void find_all_cgroups() {
debug(D_CGROUP, "memory.stat filename for cgroup '%s': '%s'", cg->id, cg->memory.filename);
}
else debug(D_CGROUP, "memory.stat file for cgroup '%s': '%s' does not exist.", cg->id, filename);
+
+ snprintfz(filename, FILENAME_MAX, "%s%s/memory.usage_in_bytes", cgroup_memory_base, cg->id);
+ if(stat(filename, &buf) != -1) {
+ cg->memory.filename_usage_in_bytes = strdupz(filename);
+ debug(D_CGROUP, "memory.usage_in_bytes filename for cgroup '%s': '%s'", cg->id, cg->memory.filename_usage_in_bytes);
+ }
+ else debug(D_CGROUP, "memory.usage_in_bytes file for cgroup '%s': '%s' does not exist.", cg->id, filename);
+
+ snprintfz(filename, FILENAME_MAX, "%s%s/memory.msw_usage_in_bytes", cgroup_memory_base, cg->id);
+ if(stat(filename, &buf) != -1) {
+ cg->memory.filename_msw_usage_in_bytes = strdupz(filename);
+ debug(D_CGROUP, "memory.msw_usage_in_bytes filename for cgroup '%s': '%s'", cg->id, cg->memory.filename_msw_usage_in_bytes);
+ }
+ else debug(D_CGROUP, "memory.msw_usage_in_bytes file for cgroup '%s': '%s' does not exist.", cg->id, filename);
+
+ snprintfz(filename, FILENAME_MAX, "%s%s/memory.failcnt", cgroup_memory_base, cg->id);
+ if(stat(filename, &buf) != -1) {
+ cg->memory.filename_failcnt = strdupz(filename);
+ debug(D_CGROUP, "memory.failcnt filename for cgroup '%s': '%s'", cg->id, cg->memory.filename_failcnt);
+ }
+ else debug(D_CGROUP, "memory.failcnt file for cgroup '%s': '%s' does not exist.", cg->id, filename);
}
if(cgroup_enable_blkio) {
if(!cg->io_service_bytes.filename) {
@@ -1118,7 +1169,7 @@ void update_cgroup_charts(int update_every) {
st = rrdset_find_bytype(type, "mem");
if(!st) {
snprintfz(title, CHART_TITLE_MAX, "Memory Usage for cgroup %s", cg->chart_title);
- st = rrdset_create(type, "mem", NULL, "mem", "cgroup.mem", title, "MB", 40200, update_every,
+ st = rrdset_create(type, "mem", NULL, "mem", "cgroup.mem", title, "MB", 40210, update_every,
RRDSET_TYPE_STACKED);
rrddim_add(st, "cache", NULL, 1, 1024 * 1024, RRDDIM_ABSOLUTE);
@@ -1191,6 +1242,38 @@ void update_cgroup_charts(int update_every) {
}
}
+ if(cg->memory.usage_in_bytes_updated) {
+ st = rrdset_find_bytype(type, "mem_usage");
+ if(!st) {
+ snprintfz(title, CHART_TITLE_MAX, "Total Memory for cgroup %s", cg->chart_title);
+ st = rrdset_create(type, "mem_usage", NULL, "mem", "cgroup.mem_usage", title, "MB", 40200,
+ update_every, RRDSET_TYPE_STACKED);
+
+ rrddim_add(st, "ram", NULL, 1, 1024 * 1024, RRDDIM_ABSOLUTE);
+ rrddim_add(st, "swap", NULL, 1, 1024 * 1024, RRDDIM_ABSOLUTE);
+ }
+ else rrdset_next(st);
+
+ rrddim_set(st, "ram", cg->memory.usage_in_bytes);
+ 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);
+ rrdset_done(st);
+ }
+
+ if(cg->memory.failcnt_updated && cg->memory.failcnt > 0) {
+ st = rrdset_find_bytype(type, "mem_failcnt");
+ if(!st) {
+ snprintfz(title, CHART_TITLE_MAX, "Memory Limit Failures for cgroup %s", cg->chart_title);
+ st = rrdset_create(type, "mem_failcnt", NULL, "mem", "cgroup.mem_failcnt", title, "MB", 40250,
+ update_every, RRDSET_TYPE_LINE);
+
+ rrddim_add(st, "failures", NULL, 1, 1, RRDDIM_INCREMENTAL);
+ }
+ else rrdset_next(st);
+
+ rrddim_set(st, "failures", cg->memory.failcnt);
+ rrdset_done(st);
+ }
+
if(cg->io_service_bytes.updated && cg->io_service_bytes.Read + cg->io_service_bytes.Write > 0) {
st = rrdset_find_bytype(type, "io");
if(!st) {
diff --git a/web/dashboard.css b/web/dashboard.css
index e969158091..ee806ba471 100644
--- a/web/dashboard.css
+++ b/web/dashboard.css
@@ -209,7 +209,7 @@ body {
outline: thin dotted;
}
.netdata-legend-series > .netdata-legend-series-content::-webkit-scrollbar {
- display: block; /* was 'none', but chrome was hidding content with it */
+ display: block; /* was 'none', but chrome was hiding content with it */
}
.has-scrollbar > .netdata-legend-series-content::-webkit-scrollbar {
display: block;