summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlya Mashchenko <ilya@netdata.cloud>2022-05-12 10:16:48 +0300
committerGitHub <noreply@github.com>2022-05-12 10:16:48 +0300
commitb3c1cf515142d36740a8fb6b2717753176e8255d (patch)
treed5a674c1b401ac2fd0cec383a6f603f3350af693
parentd25f102dc1a96080ab307f8611982d5059163661 (diff)
feat(proc/cgroups.plugin): add PSI stall time charts (#12869)
-rw-r--r--collectors/cgroups.plugin/sys_fs_cgroup.c321
-rw-r--r--collectors/cgroups.plugin/tests/test_doubles.c4
-rw-r--r--collectors/proc.plugin/proc_pressure.c189
-rw-r--r--collectors/proc.plugin/proc_pressure.h34
-rw-r--r--web/gui/dashboard_info.js130
5 files changed, 474 insertions, 204 deletions
diff --git a/collectors/cgroups.plugin/sys_fs_cgroup.c b/collectors/cgroups.plugin/sys_fs_cgroup.c
index 53b7eeb89e..d830966f5a 100644
--- a/collectors/cgroups.plugin/sys_fs_cgroup.c
+++ b/collectors/cgroups.plugin/sys_fs_cgroup.c
@@ -1397,14 +1397,17 @@ static inline void cgroup2_read_pressure(struct pressure *res) {
return;
}
- res->some.value10 = strtod(procfile_lineword(ff, 0, 2), NULL);
- res->some.value60 = strtod(procfile_lineword(ff, 0, 4), NULL);
- res->some.value300 = strtod(procfile_lineword(ff, 0, 6), NULL);
+
+ res->some.share_time.value10 = strtod(procfile_lineword(ff, 0, 2), NULL);
+ res->some.share_time.value60 = strtod(procfile_lineword(ff, 0, 4), NULL);
+ res->some.share_time.value300 = strtod(procfile_lineword(ff, 0, 6), NULL);
+ res->some.total_time.value_total = str2ull(procfile_lineword(ff, 0, 8)) / 1000; // us->ms
if (lines > 2) {
- res->full.value10 = strtod(procfile_lineword(ff, 1, 2), NULL);
- res->full.value60 = strtod(procfile_lineword(ff, 1, 4), NULL);
- res->full.value300 = strtod(procfile_lineword(ff, 1, 6), NULL);
+ res->full.share_time.value10 = strtod(procfile_lineword(ff, 1, 2), NULL);
+ res->full.share_time.value60 = strtod(procfile_lineword(ff, 1, 4), NULL);
+ res->full.share_time.value300 = strtod(procfile_lineword(ff, 1, 6), NULL);
+ res->full.total_time.value_total = str2ull(procfile_lineword(ff, 0, 8)) / 1000; // us->ms
}
res->updated = 1;
@@ -1740,8 +1743,10 @@ char *k8s_parse_resolved_name(struct label **labels, char *data) {
}
static inline void free_pressure(struct pressure *res) {
- if (res->some.st) rrdset_is_obsolete(res->some.st);
- if (res->full.st) rrdset_is_obsolete(res->full.st);
+ if (res->some.share_time.st) rrdset_is_obsolete(res->some.share_time.st);
+ if (res->some.total_time.st) rrdset_is_obsolete(res->some.total_time.st);
+ if (res->full.share_time.st) rrdset_is_obsolete(res->full.share_time.st);
+ if (res->full.total_time.st) rrdset_is_obsolete(res->full.total_time.st);
freez(res->filename);
}
@@ -4505,17 +4510,20 @@ void update_cgroup_charts(int update_every) {
if (cg->options & CGROUP_OPTIONS_IS_UNIFIED) {
struct pressure *res = &cg->cpu_pressure;
+
if (likely(res->updated && res->some.enabled)) {
- if (unlikely(!res->some.st)) {
- RRDSET *chart;
- snprintfz(title, CHART_TITLE_MAX, "CPU pressure");
+ struct pressure_charts *pcs;
+ pcs = &res->some;
- chart = res->some.st = rrdset_create_localhost(
+ if (unlikely(!pcs->share_time.st)) {
+ RRDSET *chart;
+ snprintfz(title, CHART_TITLE_MAX, "CPU some pressure");
+ chart = pcs->share_time.st = rrdset_create_localhost(
cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
- , "cpu_pressure"
+ , "cpu_some_pressure"
, NULL
, "cpu"
- , "cgroup.cpu_pressure"
+ , "cgroup.cpu_some_pressure"
, title
, "percentage"
, PLUGIN_CGROUPS_NAME
@@ -4524,31 +4532,105 @@ void update_cgroup_charts(int update_every) {
, update_every
, RRDSET_TYPE_LINE
);
-
- rrdset_update_labels(chart = res->some.st, cg->chart_labels);
-
- res->some.rd10 = rrddim_add(chart, "some 10", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
- res->some.rd60 = rrddim_add(chart, "some 60", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
- res->some.rd300 = rrddim_add(chart, "some 300", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
+ rrdset_update_labels(chart = pcs->share_time.st, cg->chart_labels);
+ pcs->share_time.rd10 = rrddim_add(chart, "some 10", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
+ pcs->share_time.rd60 = rrddim_add(chart, "some 60", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
+ pcs->share_time.rd300 = rrddim_add(chart, "some 300", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
+ } else {
+ rrdset_next(pcs->share_time.st);
+ }
+ if (unlikely(!pcs->total_time.st)) {
+ RRDSET *chart;
+ snprintfz(title, CHART_TITLE_MAX, "CPU some pressure stall time");
+ chart = pcs->total_time.st = rrdset_create_localhost(
+ cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
+ , "cpu_some_pressure_stall_time"
+ , NULL
+ , "cpu"
+ , "cgroup.cpu_some_pressure_stall_time"
+ , title
+ , "ms"
+ , PLUGIN_CGROUPS_NAME
+ , PLUGIN_CGROUPS_MODULE_CGROUPS_NAME
+ , cgroup_containers_chart_priority + 2220
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+ rrdset_update_labels(chart = pcs->total_time.st, cg->chart_labels);
+ pcs->total_time.rdtotal = rrddim_add(chart, "time", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
} else {
- rrdset_next(res->some.st);
+ rrdset_next(pcs->total_time.st);
}
+ update_pressure_charts(pcs);
+ }
+ if (likely(res->updated && res->full.enabled)) {
+ struct pressure_charts *pcs;
+ pcs = &res->full;
- update_pressure_chart(&res->some);
+ if (unlikely(!pcs->share_time.st)) {
+ RRDSET *chart;
+ snprintfz(title, CHART_TITLE_MAX, "CPU full pressure");
+ chart = pcs->share_time.st = rrdset_create_localhost(
+ cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
+ , "cpu_full_pressure"
+ , NULL
+ , "cpu"
+ , "cgroup.cpu_full_pressure"
+ , title
+ , "percentage"
+ , PLUGIN_CGROUPS_NAME
+ , PLUGIN_CGROUPS_MODULE_CGROUPS_NAME
+ , cgroup_containers_chart_priority + 2240
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+ rrdset_update_labels(chart = pcs->share_time.st, cg->chart_labels);
+ pcs->share_time.rd10 = rrddim_add(chart, "full 10", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
+ pcs->share_time.rd60 = rrddim_add(chart, "full 60", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
+ pcs->share_time.rd300 = rrddim_add(chart, "full 300", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
+ } else {
+ rrdset_next(pcs->share_time.st);
+ }
+ if (unlikely(!pcs->total_time.st)) {
+ RRDSET *chart;
+ snprintfz(title, CHART_TITLE_MAX, "CPU full pressure stall time");
+ chart = pcs->total_time.st = rrdset_create_localhost(
+ cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
+ , "cpu_full_pressure_stall_time"
+ , NULL
+ , "cpu"
+ , "cgroup.cpu_full_pressure_stall_time"
+ , title
+ , "ms"
+ , PLUGIN_CGROUPS_NAME
+ , PLUGIN_CGROUPS_MODULE_CGROUPS_NAME
+ , cgroup_containers_chart_priority + 2260
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+ rrdset_update_labels(chart = pcs->total_time.st, cg->chart_labels);
+ pcs->total_time.rdtotal = rrddim_add(chart, "time", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ } else {
+ rrdset_next(pcs->total_time.st);
+ }
+ update_pressure_charts(pcs);
}
res = &cg->memory_pressure;
+
if (likely(res->updated && res->some.enabled)) {
- if (unlikely(!res->some.st)) {
- RRDSET *chart;
- snprintfz(title, CHART_TITLE_MAX, "Memory pressure");
+ struct pressure_charts *pcs;
+ pcs = &res->some;
- chart = res->some.st = rrdset_create_localhost(
+ if (unlikely(!pcs->share_time.st)) {
+ RRDSET *chart;
+ snprintfz(title, CHART_TITLE_MAX, "Memory some pressure");
+ chart = pcs->share_time.st = rrdset_create_localhost(
cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
- , "mem_pressure"
+ , "mem_some_pressure"
, NULL
, "mem"
- , "cgroup.memory_pressure"
+ , "cgroup.memory_some_pressure"
, title
, "percentage"
, PLUGIN_CGROUPS_NAME
@@ -4556,26 +4638,48 @@ void update_cgroup_charts(int update_every) {
, cgroup_containers_chart_priority + 2300
, update_every
, RRDSET_TYPE_LINE
- );
-
- rrdset_update_labels(chart = res->some.st, cg->chart_labels);
-
- res->some.rd10 = rrddim_add(chart, "some 10", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
- res->some.rd60 = rrddim_add(chart, "some 60", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
- res->some.rd300 = rrddim_add(chart, "some 300", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
+ );
+ rrdset_update_labels(chart = pcs->share_time.st, cg->chart_labels);
+ pcs->share_time.rd10 = rrddim_add(chart, "some 10", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
+ pcs->share_time.rd60 = rrddim_add(chart, "some 60", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
+ pcs->share_time.rd300 = rrddim_add(chart, "some 300", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
} else {
- rrdset_next(res->some.st);
+ rrdset_next(pcs->share_time.st);
}
-
- update_pressure_chart(&res->some);
+ if (unlikely(!pcs->total_time.st)) {
+ RRDSET *chart;
+ snprintfz(title, CHART_TITLE_MAX, "Memory some pressure stall time");
+ chart = pcs->total_time.st = rrdset_create_localhost(
+ cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
+ , "memory_some_pressure_stall_time"
+ , NULL
+ , "mem"
+ , "cgroup.memory_some_pressure_stall_time"
+ , title
+ , "ms"
+ , PLUGIN_CGROUPS_NAME
+ , PLUGIN_CGROUPS_MODULE_CGROUPS_NAME
+ , cgroup_containers_chart_priority + 2320
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+ rrdset_update_labels(chart = pcs->total_time.st, cg->chart_labels);
+ pcs->total_time.rdtotal = rrddim_add(chart, "time", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ } else {
+ rrdset_next(pcs->total_time.st);
+ }
+ update_pressure_charts(pcs);
}
if (likely(res->updated && res->full.enabled)) {
- if (unlikely(!res->full.st)) {
+ struct pressure_charts *pcs;
+ pcs = &res->full;
+
+ if (unlikely(!pcs->share_time.st)) {
RRDSET *chart;
snprintfz(title, CHART_TITLE_MAX, "Memory full pressure");
- chart = res->full.st = rrdset_create_localhost(
+ chart = pcs->share_time.st = rrdset_create_localhost(
cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
, "mem_full_pressure"
, NULL
@@ -4585,35 +4689,58 @@ void update_cgroup_charts(int update_every) {
, "percentage"
, PLUGIN_CGROUPS_NAME
, PLUGIN_CGROUPS_MODULE_CGROUPS_NAME
- , cgroup_containers_chart_priority + 2350
+ , cgroup_containers_chart_priority + 2340
, update_every
, RRDSET_TYPE_LINE
);
- rrdset_update_labels(chart = res->full.st, cg->chart_labels);
-
- res->full.rd10 = rrddim_add(chart, "full 10", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
- res->full.rd60 = rrddim_add(chart, "full 60", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
- res->full.rd300 = rrddim_add(chart, "full 300", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
+ rrdset_update_labels(chart = pcs->share_time.st, cg->chart_labels);
+ pcs->share_time.rd10 = rrddim_add(chart, "full 10", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
+ pcs->share_time.rd60 = rrddim_add(chart, "full 60", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
+ pcs->share_time.rd300 = rrddim_add(chart, "full 300", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
} else {
- rrdset_next(res->full.st);
+ rrdset_next(pcs->share_time.st);
}
-
- update_pressure_chart(&res->full);
+ if (unlikely(!pcs->total_time.st)) {
+ RRDSET *chart;
+ snprintfz(title, CHART_TITLE_MAX, "Memory full pressure stall time");
+ chart = pcs->total_time.st = rrdset_create_localhost(
+ cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
+ , "memory_full_pressure_stall_time"
+ , NULL
+ , "mem"
+ , "cgroup.memory_full_pressure_stall_time"
+ , title
+ , "ms"
+ , PLUGIN_CGROUPS_NAME
+ , PLUGIN_CGROUPS_MODULE_CGROUPS_NAME
+ , cgroup_containers_chart_priority + 2360
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+ rrdset_update_labels(chart = pcs->total_time.st, cg->chart_labels);
+ pcs->total_time.rdtotal = rrddim_add(chart, "time", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ } else {
+ rrdset_next(pcs->total_time.st);
+ }
+ update_pressure_charts(pcs);
}
res = &cg->io_pressure;
+
if (likely(res->updated && res->some.enabled)) {
- if (unlikely(!res->some.st)) {
- RRDSET *chart;
- snprintfz(title, CHART_TITLE_MAX, "I/O pressure");
+ struct pressure_charts *pcs;
+ pcs = &res->some;
- chart = res->some.st = rrdset_create_localhost(
+ if (unlikely(!pcs->share_time.st)) {
+ RRDSET *chart;
+ snprintfz(title, CHART_TITLE_MAX, "I/O some pressure");
+ chart = pcs->share_time.st = rrdset_create_localhost(
cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
- , "io_pressure"
+ , "io_some_pressure"
, NULL
, "disk"
- , "cgroup.io_pressure"
+ , "cgroup.io_some_pressure"
, title
, "percentage"
, PLUGIN_CGROUPS_NAME
@@ -4622,25 +4749,46 @@ void update_cgroup_charts(int update_every) {
, update_every
, RRDSET_TYPE_LINE
);
-
- rrdset_update_labels(chart = res->some.st, cg->chart_labels);
-
- res->some.rd10 = rrddim_add(chart, "some 10", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
- res->some.rd60 = rrddim_add(chart, "some 60", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
- res->some.rd300 = rrddim_add(chart, "some 300", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
+ rrdset_update_labels(chart = pcs->share_time.st, cg->chart_labels);
+ pcs->share_time.rd10 = rrddim_add(chart, "some 10", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
+ pcs->share_time.rd60 = rrddim_add(chart, "some 60", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
+ pcs->share_time.rd300 = rrddim_add(chart, "some 300", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
} else {
- rrdset_next(res->some.st);
+ rrdset_next(pcs->share_time.st);
}
-
- update_pressure_chart(&res->some);
+ if (unlikely(!pcs->total_time.st)) {
+ RRDSET *chart;
+ snprintfz(title, CHART_TITLE_MAX, "I/O some pressure stall time");
+ chart = pcs->total_time.st = rrdset_create_localhost(
+ cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
+ , "io_some_pressure_stall_time"
+ , NULL
+ , "disk"
+ , "cgroup.io_some_pressure_stall_time"
+ , title
+ , "ms"
+ , PLUGIN_CGROUPS_NAME
+ , PLUGIN_CGROUPS_MODULE_CGROUPS_NAME
+ , cgroup_containers_chart_priority + 2420
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+ rrdset_update_labels(chart = pcs->total_time.st, cg->chart_labels);
+ pcs->total_time.rdtotal = rrddim_add(chart, "time", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ } else {
+ rrdset_next(pcs->total_time.st);
+ }
+ update_pressure_charts(pcs);
}
if (likely(res->updated && res->full.enabled)) {
- if (unlikely(!res->full.st)) {
+ struct pressure_charts *pcs;
+ pcs = &res->full;
+
+ if (unlikely(!pcs->share_time.st)) {
RRDSET *chart;
snprintfz(title, CHART_TITLE_MAX, "I/O full pressure");
-
- chart = res->full.st = rrdset_create_localhost(
+ chart = pcs->share_time.st = rrdset_create_localhost(
cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
, "io_full_pressure"
, NULL
@@ -4650,21 +4798,40 @@ void update_cgroup_charts(int update_every) {
, "percentage"
, PLUGIN_CGROUPS_NAME
, PLUGIN_CGROUPS_MODULE_CGROUPS_NAME
- , cgroup_containers_chart_priority + 2450
+ , cgroup_containers_chart_priority + 2440
, update_every
, RRDSET_TYPE_LINE
);
-
- rrdset_update_labels(chart = res->full.st, cg->chart_labels);
-
- res->full.rd10 = rrddim_add(chart, "full 10", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
- res->full.rd60 = rrddim_add(chart, "full 60", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
- res->full.rd300 = rrddim_add(chart, "full 300", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
+ rrdset_update_labels(chart = pcs->share_time.st, cg->chart_labels);
+ pcs->share_time.rd10 = rrddim_add(chart, "full 10", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
+ pcs->share_time.rd60 = rrddim_add(chart, "full 60", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
+ pcs->share_time.rd300 = rrddim_add(chart, "full 300", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
} else {
- rrdset_next(res->full.st);
+ rrdset_next(pcs->share_time.st);
}
-
- update_pressure_chart(&res->full);
+ if (unlikely(!pcs->total_time.st)) {
+ RRDSET *chart;
+ snprintfz(title, CHART_TITLE_MAX, "I/O full pressure stall time");
+ chart = pcs->total_time.st = rrdset_create_localhost(
+ cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
+ , "io_full_pressure_stall_time"
+ , NULL
+ , "disk"
+ , "cgroup.io_full_pressure_stall_time"
+ , title
+ , "ms"
+ , PLUGIN_CGROUPS_NAME
+ , PLUGIN_CGROUPS_MODULE_CGROUPS_NAME
+ , cgroup_containers_chart_priority + 2460
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+ rrdset_update_labels(chart = pcs->total_time.st, cg->chart_labels);
+ pcs->total_time.rdtotal = rrddim_add(chart, "time", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ } else {
+ rrdset_next(pcs->total_time.st);
+ }
+ update_pressure_charts(pcs);
}
}
}
diff --git a/collectors/cgroups.plugin/tests/test_doubles.c b/collectors/cgroups.plugin/tests/test_doubles.c
index 5572fb2f50..9cefa6c98f 100644
--- a/collectors/cgroups.plugin/tests/test_doubles.c
+++ b/collectors/cgroups.plugin/tests/test_doubles.c
@@ -142,9 +142,9 @@ void rrdset_done(RRDSET *st)
UNUSED(st);
}
-void update_pressure_chart(struct pressure_chart *chart)
+void update_pressure_charts(struct pressure_charts *charts)
{
- UNUSED(chart);
+ UNUSED(charts);
}
void netdev_rename_device_add(
diff --git a/collectors/proc.plugin/proc_pressure.c b/collectors/proc.plugin/proc_pressure.c
index 4a40b4aafe..66884dbcba 100644
--- a/collectors/proc.plugin/proc_pressure.c
+++ b/collectors/proc.plugin/proc_pressure.c
@@ -8,22 +8,36 @@
// linux calculates this every 2 seconds, see kernel/sched/psi.c PSI_FREQ
#define MIN_PRESSURE_UPDATE_EVERY 2
+static int pressure_update_every = 0;
static struct pressure resources[PRESSURE_NUM_RESOURCES] = {
- {
- .some = { .id = "cpu_pressure", .title = "CPU Pressure" },
- },
- {
- .some = { .id = "memory_some_pressure", .title = "Memory Pressure" },
- .full = { .id = "memory_full_pressure", .title = "Memory Full Pressure" },
- },
- {
- .some = { .id = "io_some_pressure", .title = "I/O Pressure" },
- .full = { .id = "io_full_pressure", .title = "I/O Full Pressure" },
- },
+ {
+ .some =
+ {.share_time = {.id = "cpu_some_pressure", .title = "CPU some pressure"},
+ .total_time = {.id = "cpu_some_pressure_stall_time", .title = "CPU some pressure stall time"}},
+ .full =
+ {.share_time = {.id = "cpu_full_pressure", .title = "CPU full pressure"},
+ .total_time = {.id = "cpu_full_pressure_stall_time", .title = "CPU full pressure stall time"}},
+ },
+ {
+ .some =
+ {.share_time = {.id = "memory_some_pressure", .title = "Memory some pressure"},
+ .total_time = {.id = "memory_some_pressure_stall_time", .title = "Memory some pressure stall time"}},
+ .full =
+ {.share_time = {.id = "memory_full_pressure", .title = "Memory full pressure"},
+ .total_time = {.id = "memory_full_pressure_stall_time", .title = "Memory full pressure stall time"}},
+ },
+ {
+ .some =
+ {.share_time = {.id = "io_some_pressure", .title = "I/O some pressure"},
+ .total_time = {.id = "io_some_pressure_stall_time", .title = "I/O some pressure stall time"}},
+ .full =
+ {.share_time = {.id = "io_full_pressure", .title = "I/O full pressure"},
+ .total_time = {.id = "io_full_pressure_stall_time", .title = "I/O full pressure stall time"}},
+ },
};
-static struct {
+static struct resource_info {
procfile *pf;
const char *name; // metric file name
const char *family; // webui section name
@@ -34,12 +48,83 @@ static struct {
{ .name = "io", .family = "disk", .section_priority = NETDATA_CHART_PRIO_SYSTEM_IO },
};
-void update_pressure_chart(struct pressure_chart *chart) {
- rrddim_set_by_pointer(chart->st, chart->rd10, (collected_number)(chart->value10 * 100));
- rrddim_set_by_pointer(chart->st, chart->rd60, (collected_number) (chart->value60 * 100));
- rrddim_set_by_pointer(chart->st, chart->rd300, (collected_number) (chart->value300 * 100));
+void update_pressure_charts(struct pressure_charts *pcs) {
+ if (pcs->share_time.st) {
+ rrddim_set_by_pointer(
+ pcs->share_time.st, pcs->share_time.rd10, (collected_number)(pcs->share_time.value10 * 100));
+ rrddim_set_by_pointer(
+ pcs->share_time.st, pcs->share_time.rd60, (collected_number)(pcs->share_time.value60 * 100));
+ rrddim_set_by_pointer(
+ pcs->share_time.st, pcs->share_time.rd300, (collected_number)(pcs->share_time.value300 * 100));
+ rrdset_done(pcs->share_time.st);
+ }
+ if (pcs->total_time.st) {
+ rrddim_set_by_pointer(
+ pcs->total_time.st, pcs->total_time.rdtotal, (collected_number)(pcs->total_time.value_total));
+ rrdset_done(pcs->total_time.st);
+ }
+}
+
+static void proc_pressure_do_resource(procfile *ff, int res_idx, int some) {
+ struct pressure_charts *pcs;
+ struct resource_info ri;
+ pcs = some ? &resources[res_idx].some : &resources[res_idx].full;
+ ri = resource_info[res_idx];
+
+ if (unlikely(!pcs->share_time.st)) {
+ pcs->share_time.st = rrdset_create_localhost(
+ "system",
+ pcs->share_time.id,
+ NULL,
+ ri.family,
+ NULL,
+ pcs->share_time.title,
+ "percentage",
+ PLUGIN_PROC_NAME,
+ PLUGIN_PROC_MODULE_PRESSURE_NAME,
+ ri.section_priority + (some ? 40 : 50),
+ pressure_update_every,
+ RRDSET_TYPE_LINE);
+ pcs->share_time.rd10 =
+ rrddim_add(pcs->share_time.st, some ? "some 10" : "full 10", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
+ pcs->share_time.rd60 =
+ rrddim_add(pcs->share_time.st, some ? "some 60" : "full 60", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
+ pcs->share_time.rd300 =
+ rrddim_add(pcs->share_time.st, some ? "some 300" : "full 300", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
+ } else {
+ rrdset_next(pcs->share_time.st);
+ }
+ pcs->share_time.value10 = strtod(procfile_lineword(ff, some ? 0 : 1, 2), NULL);
+ pcs->share_time.value60 = strtod(procfile_lineword(ff, some ? 0 : 1, 4), NULL);
+ pcs->share_time.value300 = strtod(procfile_lineword(ff, some ? 0 : 1, 6), NULL);
+
+ if (unlikely(!pcs->total_time.st)) {
+ pcs->total_time.st = rrdset_create_localhost(
+ "system",
+ pcs->total_time.id,
+ NULL,
+ ri.family,
+ NULL,
+ pcs->total_time.title,
+ "ms",
+ PLUGIN_PROC_NAME,
+ PLUGIN_PROC_MODULE_PRESSURE_NAME,
+ ri.section_priority + (some ? 45 : 55),
+ pressure_update_every,
+ RRDSET_TYPE_LINE);
+ pcs->total_time.rdtotal = rrddim_add(pcs->total_time.st, "time", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ } else {
+ rrdset_next(pcs->total_time.st);
+ }
+ pcs->total_time.value_total = str2ull(procfile_lineword(ff, some ? 0 : 1, 8)) / 1000;
+}
- rrdset_done(chart->st);
+static void proc_pressure_do_resource_some(procfile *ff, int res_idx) {
+ proc_pressure_do_resource(ff, res_idx, 1);
+}
+
+static void proc_pressure_do_resource_full(procfile *ff, int res_idx) {
+ proc_pressure_do_resource(ff, res_idx, 0);
}
int do_proc_pressure(int update_every, usec_t dt) {
@@ -50,6 +135,7 @@ int do_proc_pressure(int update_every, usec_t dt) {
static char *base_path = NULL;
update_every = (update_every < MIN_PRESSURE_UPDATE_EVERY) ? MIN_PRESSURE_UPDATE_EVERY : update_every;
+ pressure_update_every = update_every;
if (next_pressure_dt <= dt) {
next_pressure_dt = update_every * USEC_PER_SEC;
@@ -80,11 +166,10 @@ int do_proc_pressure(int update_every, usec_t dt) {
snprintfz(config_key, CONFIG_MAX_NAME, "enable %s some pressure", resource_info[i].name);
do_some = config_get_boolean(CONFIG_SECTION_PLUGIN_PROC_PRESSURE, config_key, CONFIG_BOOLEAN_YES);
resources[i].some.enabled = do_some;
- if (resources[i].full.id) {
- snprintfz(config_key, CONFIG_MAX_NAME, "enable %s full pressure", resource_info[i].name);
- do_full = config_get_boolean(CONFIG_SECTION_PLUGIN_PROC_PRESSURE, config_key, CONFIG_BOOLEAN_YES);
- resources[i].full.enabled = do_full;
- }
+
+ snprintfz(config_key, CONFIG_MAX_NAME, "enable %s full pressure", resource_info[i].name);
+ do_full = config_get_boolean(CONFIG_SECTION_PLUGIN_PROC_PRESSURE, config_key, CONFIG_BOOLEAN_YES);
+ resources[i].full.enabled = do_full;
ff = procfile_open(filename, " =", PROCFILE_FLAG_DEFAULT);
if (unlikely(!ff)) {
@@ -108,65 +193,13 @@ int do_proc_pressure(int update_every, usec_t dt) {
continue;
}
- struct pressure_chart *chart;
if (do_some) {
- chart = &resources[i].some;
- if (unlikely(!chart->st)) {
- chart->st = rrdset_create_localhost(
- "system"
- , chart->id
- , NULL
- , resource_info[i].family
- , NULL
- , chart->title
- , "percentage"
- , PLUGIN_PROC_NAME
- , PLUGIN_PROC_MODULE_PRESSURE_NAME
- , resource_info[i].section_priority + 40
- , update_every
- , RRDSET_TYPE_LINE
- );
- chart->rd10 = rrddim_add(chart->st, "some 10", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
- chart->rd60 = rrddim_add(chart->st, "some 60", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
- chart->rd300 = rrddim_add(chart->st, "some 300", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
- } else {
- rrdset_next(chart->st);
- }
-
- chart->value10 = strtod(procfile_lineword(ff, 0, 2), NULL);
- chart->value60 = strtod(procfile_lineword(ff, 0, 4), NULL);
- chart->value300 = strtod(procfile_lineword(ff, 0, 6), NULL);
- update_pressure_chart(chart);
+ proc_pressure_do_resource_some(ff, i);
+ update_pressure_charts(&resources[i].some);
}
-
if (do_full && lines > 2) {
- chart = &resources[i].full;
- if (unlikely(!chart->st)) {
- chart->st = rrdset_create_localhost(
- "system"
- , chart->id
- , NULL
- , resource_info[i].family
- , NULL
- , chart->title
- , "percentage"
- , PLUGIN_PROC_NAME
- , PLUGIN_PROC_MODULE_PRESSURE_NAME
- , resource_info[i].section_priority + 45
- , update_every
- , RRDSET_TYPE_LINE
- );
- chart->rd10 = rrddim_add(chart->st, "full 10", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
- chart->rd60 = rrddim_add(chart->st, "full 60", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
- chart->rd300 = rrddim_add(chart->st, "full 300", NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
- } else {
- rrdset_next(chart->st);
- }
-
- chart->value10 = strtod(procfile_lineword(ff, 1, 2), NULL);
- chart->value60 = strtod(procfile_lineword(ff, 1, 4), NULL);
- chart->value300 = strtod(procfile_lineword(ff, 1, 6), NULL);
- update_pressure_chart(chart);
+ proc_pressure_do_resource_full(ff, i);
+ update_pressure_charts(&resources[i].full);
}
}
diff --git a/collectors/proc.plugin/proc_pressure.h b/collectors/proc.plugin/proc_pressure.h
index 3330218665..a421cf8a41 100644
--- a/collectors/proc.plugin/proc_pressure.h
+++ b/collectors/proc.plugin/proc_pressure.h
@@ -9,23 +9,35 @@ struct pressure {
int updated;
char *filename;
- struct pressure_chart {
+ struct pressure_charts {
int enabled;
- const char *id;
- const char *title;
+ struct pressure_share_time_chart {
+ const char *id;
+ const char *title;
- double value10;
- double value60;
- double value300;
+ double value10;
+ double value60;
+ double value300;
- RRDSET *st;
- RRDDIM *rd10;
- RRDDIM *rd60;
- RRDDIM *rd300;
+ RRDSET *st;
+ RRDDIM *rd10;
+ RRDDIM *rd60;
+ RRDDIM *rd300;
+ } share_time;
+
+ struct pressure_total_time_chart {
+ const char *id;
+ const char *title;
+
+ unsigned long long value_total;
+
+ RRDSET *st;
+ RRDDIM *rdtotal;
+ } total_time;
} some, full;
};
-extern void update_pressure_chart(struct pressure_chart *chart);
+extern void update_pressure_charts(struct pressure_charts *charts);
#endif //NETDATA_PROC_PRESSURE_H
diff --git a/web/gui/dashboard_info.js b/web/gui/dashboard_info.js
index 60cc02c933..35834aaf01 100644
--- a/web/gui/dashboard_info.js
+++ b/web/gui/dashboard_info.js
@@ -1309,29 +1309,61 @@ netdataDashboard.context = {
height: 0.7
},
- 'system.cpu_pressure': {
- info: '<a href="https://www.kernel.org/doc/html/latest/accounting/psi.html" target="_blank">Pressure Stall Information</a> ' +
- 'identifies and quantifies the disruptions caused by resource contentions. ' +
- 'The "some" line indicates the share of time in which at least <b>some</b> tasks are stalled on CPU. ' +
-