0
0
Fork 0
mirror of https://github.com/netdata/netdata.git synced 2025-04-10 16:17:36 +00:00

Debugfs collector ()

Co-authored-by: Fotis Voutsas <fotis@netdata.cloud>
Co-authored-by: Austin S. Hemmelgarn <ahferroin7@gmail.com>
Co-authored-by: ilyam8 <ilya@netdata.cloud>
This commit is contained in:
thiagoftsm 2023-05-15 16:06:26 +00:00 committed by GitHub
parent bdc40c318a
commit 588096c6b6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 1039 additions and 4 deletions

4
.github/labeler.yml vendored
View file

@ -78,6 +78,10 @@ collectors/cups:
- collectors/cups.plugin/*
- collectors/cups.plugin/**/*
collectors/debugfs:
- collectors/debugfs.plugin/*
- collectors/debugfs.plugin/**/*
collectors/diskspace:
- collectors/diskspace.plugin/*
- collectors/diskspace.plugin/**/*

3
.gitignore vendored
View file

@ -74,6 +74,9 @@ collectors/ebpf.plugin/reset_netdata_trace.sh
!ebpf.plugin/
collectors/ebpf.plugin/includes/
debugfs.plugin
!debugfs.plugin/
# protoc generated files
*.pb.cc
*.pb.h

View file

@ -507,6 +507,13 @@ target_include_directories(libnetdata BEFORE PUBLIC ${GENERATED_CONFIG_H_DIR})
set(APPS_PLUGIN_FILES
collectors/apps.plugin/apps_plugin.c)
set(DEBUGFS_PLUGIN_FILES
collectors/debugfs.plugin/debugfs_plugin.c
collectors/debugfs.plugin/debugfs_plugin.h
collectors/debugfs.plugin/debugfs_extfrag.c
collectors/debugfs.plugin/debugfs_zswap.c
)
set(FREEBSD_PLUGIN_FILES
collectors/freebsd.plugin/plugin_freebsd.c
collectors/freebsd.plugin/plugin_freebsd.h
@ -1363,6 +1370,21 @@ target_include_directories(netdatacli BEFORE PUBLIC ${GENERATED_CONFIG_H_DIR})
target_compile_options(netdatacli PUBLIC ${NETDATA_COMMON_CFLAGS})
# -----------------------------------------------------------------------------
# debugfs.plugin
IF(ENABLE_PLUGIN_DEBUGFS)
message(STATUS "debugfs.plugin: enabled")
add_executable(debugfs.plugin ${GENERATED_CONFIG_H} ${DEBUGFS_PLUGIN_FILES})
target_link_libraries (debugfs.plugin libnetdata ${NETDATA_COMMON_LIBRARIES} ${CAP_LIBRARIES})
target_include_directories(debugfs.plugin PUBLIC ${NETDATA_COMMON_INCLUDE_DIRS} ${CAP_INCLUDE_DIRS})
target_include_directories(debugfs.plugin BEFORE PUBLIC ${GENERATED_CONFIG_H_DIR})
target_compile_options(debugfs.plugin PUBLIC ${NETDATA_COMMON_CFLAGS} ${CAP_CFLAGS_OTHER})
ELSE()
message(STATUS "debugfs.plugin: disabled")
ENDIF()
# -----------------------------------------------------------------------------
# apps.plugin

View file

@ -212,6 +212,14 @@ APPS_PLUGIN_FILES = \
$(LIBNETDATA_FILES) \
$(NULL)
DEBUGFS_PLUGIN_FILES = \
collectors/debugfs.plugin/debugfs_plugin.c \
collectors/debugfs.plugin/debugfs_plugin.h \
collectors/debugfs.plugin/debugfs_extfrag.c \
collectors/debugfs.plugin/debugfs_zswap.c \
$(LIBNETDATA_FILES) \
$(NULL)
FREEBSD_PLUGIN_FILES = \
collectors/freebsd.plugin/plugin_freebsd.c \
collectors/freebsd.plugin/plugin_freebsd.h \
@ -1168,6 +1176,15 @@ if ENABLE_PLUGIN_APPS
$(NULL)
endif
if ENABLE_PLUGIN_DEBUGFS
plugins_PROGRAMS += debugfs.plugin
debugfs_plugin_SOURCES = $(DEBUGFS_PLUGIN_FILES)
debugfs_plugin_LDADD = \
$(NETDATA_COMMON_LIBS) \
$(OPTIONAL_LIBCAP_LIBS) \
$(NULL)
endif
if ENABLE_PLUGIN_CGROUP_NETWORK
plugins_PROGRAMS += cgroup-network
cgroup_network_SOURCES = $(CGROUP_NETWORK_FILES)

View file

@ -8,6 +8,7 @@ SUBDIRS = \
cgroups.plugin \
charts.d.plugin \
cups.plugin \
debugfs.plugin \
diskspace.plugin \
timex.plugin \
ioping.plugin \

View file

@ -24,8 +24,17 @@
#define NETDATA_CHART_PRIO_SYSTEM_PGPGIO 151
#define NETDATA_CHART_PRIO_SYSTEM_RAM 200
#define NETDATA_CHART_PRIO_SYSTEM_SWAP 201
#define NETDATA_CHART_PRIO_SYSTEM_SWAP_CALLS 202
#define NETDATA_CHART_PRIO_SYSTEM_SWAPIO 250
#define NETDATA_CHART_PRIO_SYSTEM_ZSWAPIO 300
#define NETDATA_CHART_PRIO_SYSTEM_ZSWAP_COMPRESS_RATIO 301
#define NETDATA_CHART_PRIO_SYSTEM_ZSWAP_POOL_TOT_SIZE 302
#define NETDATA_CHART_PRIO_SYSTEM_ZSWAP_STORED_PAGE 303
#define NETDATA_CHART_PRIO_SYSTEM_ZSWAP_REJECTS 304
#define NETDATA_CHART_PRIO_SYSTEM_ZSWAP_POOL_LIM_HIT 305
#define NETDATA_CHART_PRIO_SYSTEM_ZSWAP_WRT_BACK_PAGES 306
#define NETDATA_CHART_PRIO_SYSTEM_ZSWAP_SAME_FILL_PAGE 307
#define NETDATA_CHART_PRIO_SYSTEM_ZSWAP_DUPP_ENTRY 308
#define NETDATA_CHART_PRIO_SYSTEM_NET 500
#define NETDATA_CHART_PRIO_SYSTEM_IPV4 500 // freebsd only
#define NETDATA_CHART_PRIO_SYSTEM_IP 501
@ -103,6 +112,7 @@
#define NETDATA_CHART_PRIO_MEM_ZRAM_SAVINGS 1601
#define NETDATA_CHART_PRIO_MEM_ZRAM_RATIO 1602
#define NETDATA_CHART_PRIO_MEM_ZRAM_EFFICIENCY 1603
#define NETDATA_CHART_PRIO_MEM_FRAGMENTATION 1700
// Disks

View file

@ -89,6 +89,7 @@ ioping: ioping
go.d.plugin: *go.d.plugin*
slabinfo.plugin: slabinfo.plugin
ebpf.plugin: *ebpf.plugin*
debugfs.plugin: *debugfs.plugin*
# agent-service-discovery
agent_sd: agent_sd

View file

@ -0,0 +1,9 @@
# SPDX-License-Identifier: GPL-3.0-or-later
AUTOMAKE_OPTIONS = subdir-objects
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
dist_noinst_DATA = \
README.md \
$(NULL)

View file

@ -0,0 +1,65 @@
# OS provided metrics (debugfs.plugin)
`debugfs.plugin` gathers metrics from the `/sys/kernel/debug` folder on Linux
systems. [Debugfs](https://docs.kernel.org/filesystems/debugfs.html) exists as an easy way for kernel developers to
make information available to user space.
This plugin
is [external](https://github.com/netdata/netdata/tree/master/collectors#collector-architecture-and-terminology),
the netdata daemon spawns it as a long-running independent process.
In detail, it collects metrics from:
- `/sys/kernel/debug/extfrag` (Memory fragmentation index for each order and zone).
- `/sys/kernel/debug/zswap` ([Zswap](https://www.kernel.org/doc/Documentation/vm/zswap.txt) performance statistics).
## Prerequisites
### Permissions
> No user action required.
The debugfs root directory is accessible only to the root user by default. Netdata
uses [Linux Capabilities](https://man7.org/linux/man-pages/man7/capabilities.7.html) to give the plugin access
to debugfs. `CAP_DAC_READ_SEARCH` is added automatically during installation. This capability allows bypassing file read
permission checks and directory read and execute permission checks. If file capabilities are not usable, then the plugin is instead installed with the SUID bit set in permissions so that it runs as root.
## Metrics
| Metric | Scope | Dimensions | Units | Labels |
|-------------------------------------|:---------:|:---------------------------------------------------------------------------------------:|:------------:|:---------:|
| mem.fragmentation_index_dma | numa node | order0, order1, order2, order3, order4, order5, order6, order7, order8, order9, order10 | index | numa_node |
| mem.fragmentation_index_dma32 | numa node | order0, order1, order2, order3, order4, order5, order6, order7, order8, order9, order10 | index | numa_node |
| mem.fragmentation_index_normal | numa node | order0, order1, order2, order3, order4, order5, order6, order7, order8, order9, order10 | index | numa_node |
| system.zswap_pool_compression_ratio | | compression_ratio | ratio | |
| system.zswap_pool_compressed_size | | compressed_size | bytes | |
| system.zswap_pool_raw_size | | uncompressed_size | bytes | |
| system.zswap_rejections | | compress_poor, kmemcache_fail, alloc_fail, reclaim_fail | rejections/s | |
| system.zswap_pool_limit_hit | | limit | events/s | |
| system.zswap_written_back_raw_bytes | | written_back | bytes/s | |
| system.zswap_same_filled_raw_size | | same_filled | bytes | |
| system.zswap_duplicate_entry | | entries | entries/s | |
## Troubleshooting
To troubleshoot issues with the collector, run the `debugfs.plugin` in the terminal. The output
should give you clues as to why the collector isn't working.
- Navigate to the `plugins.d` directory, usually at `/usr/libexec/netdata/plugins.d/`. If that's not the case on
your system, open `netdata.conf` and look for the `plugins` setting under `[directories]`.
```bash
cd /usr/libexec/netdata/plugins.d/
```
- Switch to the `netdata` user.
```bash
sudo -u netdata -s
```
- Run the `debugfs.plugin` to debug the collector:
```bash
./debugfs.plugin
```

View file

@ -0,0 +1,123 @@
// SPDX-License-Identifier: GPL-3.0-or-later
#include "debugfs_plugin.h"
#define NETDATA_ORDER_FRAGMENTATION 11
static char *orders[NETDATA_ORDER_FRAGMENTATION] = { "order0", "order1", "order2", "order3", "order4",
"order5", "order6", "order7", "order8", "order9",
"order10"
};
static struct netdata_extrafrag {
char *node_zone;
uint32_t hash;
char *id;
collected_number orders[NETDATA_ORDER_FRAGMENTATION];
struct netdata_extrafrag *next;
} *netdata_extrafrags_root = NULL;
static struct netdata_extrafrag *find_or_create_extrafrag(const char *name)
{
struct netdata_extrafrag *extrafrag;
uint32_t hash = simple_hash(name);
// search it, from beginning to the end
for (extrafrag = netdata_extrafrags_root ; extrafrag ; extrafrag = extrafrag->next) {
if (unlikely(hash == extrafrag->hash && !strcmp(name, extrafrag->node_zone))) {
return extrafrag;
}
}
extrafrag = callocz(1, sizeof(struct netdata_extrafrag));
extrafrag->node_zone = strdupz(name);
extrafrag->hash = hash;
if (netdata_extrafrags_root) {
struct netdata_extrafrag *last_node;
for (last_node = netdata_extrafrags_root; last_node->next ; last_node = last_node->next);
last_node->next = extrafrag;
} else
netdata_extrafrags_root = extrafrag;
return extrafrag;
}
static void extfrag_send_chart(char *chart_id, collected_number *values)
{
int i;
fprintf(stdout, "BEGIN mem.fragmentation_index_%s\n", chart_id);
for (i = 0; i < NETDATA_ORDER_FRAGMENTATION; i++) {
fprintf(stdout, "SET %s = %lld\n", orders[i], values[i]);
}
fprintf(stdout, "END\n");
fflush(stdout);
}
int do_debugfs_extfrag(int update_every, const char *name) {
static procfile *ff = NULL;
static int chart_order = NETDATA_CHART_PRIO_MEM_FRAGMENTATION;
if (unlikely(!ff)) {
char filename[FILENAME_MAX + 1];
snprintfz(filename,
FILENAME_MAX,
"%s%s",
netdata_configured_host_prefix,
"/sys/kernel/debug/extfrag/extfrag_index");
ff = procfile_open(filename, " \t,", PROCFILE_FLAG_DEFAULT);
if (unlikely(!ff)) return 1;
}
ff = procfile_readall(ff);
if (unlikely(!ff)) return 1;
size_t l, i, j, lines = procfile_lines(ff);
for (l = 0; l < lines; l++) {
char chart_id[64];
char zone_lowercase[32];
if (unlikely(procfile_linewords(ff, l) < 15)) continue;
char *zone = procfile_lineword(ff, l, 3);
strncpyz(zone_lowercase, zone, 31);
debugfs2lower(zone_lowercase);
char *id = procfile_lineword(ff, l, 1);
snprintfz(chart_id, 63, "node_%s_%s", id, zone_lowercase);
debugfs2lower(chart_id);
struct netdata_extrafrag *extrafrag = find_or_create_extrafrag(chart_id);
collected_number *line_orders = extrafrag->orders;
for (i = 4, j = 0 ; i < 15; i++, j++) {
NETDATA_DOUBLE value = str2ndd(procfile_lineword(ff, l, i), NULL);
line_orders[j] = (collected_number) (value * 1000.0);
}
if (unlikely(!extrafrag->id)) {
extrafrag->id = extrafrag->node_zone;
fprintf(
stdout,
"CHART mem.fragmentation_index_%s '' 'Memory fragmentation index for each order' 'index' 'fragmentation' 'mem.fragmentation_index_%s' 'line' %d %d '' 'debugfs.plugin' '%s'\n",
extrafrag->node_zone,
zone_lowercase,
chart_order++, // FIXME: the same zones must have the same order
update_every,
name);
for (i = 0; i < NETDATA_ORDER_FRAGMENTATION; i++) {
fprintf(stdout, "DIMENSION '%s' '%s' absolute 1 1000 ''\n", orders[i], orders[i]);
}
fprintf(stdout,
"CLABEL 'numa_node' 'node%s' 1\n"
"CLABEL_COMMIT\n",
id);
}
extfrag_send_chart(chart_id, line_orders);
}
return 0;
}

View file

@ -0,0 +1,244 @@
// SPDX-License-Identifier: GPL-3.0-or-later
#include "debugfs_plugin.h"
#include "libnetdata/required_dummies.h"
static char *user_config_dir = CONFIG_DIR;
static char *stock_config_dir = LIBCONFIG_DIR;
static int update_every = 1;
static struct debugfs_module {
const char *name;
int enabled;
int (*func)(int update_every, const char *name);
} debugfs_modules[] = {
// Memory Fragmentation
{ .name = "/sys/kernel/debug/extfrag", .enabled = CONFIG_BOOLEAN_YES,
.func = do_debugfs_extfrag},
{ .name = "/sys/kernel/debug/zswap", .enabled = CONFIG_BOOLEAN_YES,
.func = do_debugfs_zswap},
// The terminator
{ .name = NULL, .enabled = CONFIG_BOOLEAN_NO, .func = NULL}
};
#ifdef HAVE_CAPABILITY
static int debugfs_check_capabilities()
{
cap_t caps = cap_get_proc();
if (!caps) {
error("Cannot get current capabilities.");
return 0;
}
int ret = 1;
cap_flag_value_t cfv = CAP_CLEAR;
if (cap_get_flag(caps, CAP_DAC_READ_SEARCH, CAP_EFFECTIVE, &cfv) == -1) {
error("Cannot find if CAP_DAC_READ_SEARCH is effective.");
ret = 0;
} else {
if (cfv != CAP_SET) {
error("debugfs.plugin should run with CAP_DAC_READ_SEARCH.");
ret = 0;
}
}
cap_free(caps);
return ret;
}
#else
static int debugfs_check_capabilities()
{
return 0;
}
#endif
// TODO: This is a function used by 3 different collector, we should do it global (next PR)
static int debugfs_am_i_running_as_root()
{
uid_t uid = getuid(), euid = geteuid();
if (uid == 0 || euid == 0) {
return 1;
}
return 0;
}
void debugfs2lower(char *name)
{
while (*name) {
*name = tolower(*name);
name++;
}
}
// Consiidering our goal to redce binaries, I preferred to copy function, instead to force link with unecessary libs
const char *debugfs_rrdset_type_name(RRDSET_TYPE chart_type) {
switch(chart_type) {
case RRDSET_TYPE_LINE:
default:
return RRDSET_TYPE_LINE_NAME;
case RRDSET_TYPE_AREA:
return RRDSET_TYPE_AREA_NAME;
case RRDSET_TYPE_STACKED:
return RRDSET_TYPE_STACKED_NAME;
}
}
const char *debugfs_rrd_algorithm_name(RRD_ALGORITHM algorithm) {
switch(algorithm) {
case RRD_ALGORITHM_ABSOLUTE:
default:
return RRD_ALGORITHM_ABSOLUTE_NAME;
case RRD_ALGORITHM_INCREMENTAL:
return RRD_ALGORITHM_INCREMENTAL_NAME;
case RRD_ALGORITHM_PCENT_OVER_ROW_TOTAL:
return RRD_ALGORITHM_PCENT_OVER_ROW_TOTAL_NAME;
case RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL:
return RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL_NAME;
}
}
int debugfs_check_sys_permission() {
int ret = 0;
char filename[FILENAME_MAX + 1];
snprintfz(filename, FILENAME_MAX, "%s/sys/kernel/debug/extfrag/extfrag_index", netdata_configured_host_prefix);
procfile *ff = procfile_open(filename, NULL, PROCFILE_FLAG_NO_ERROR_ON_FILE_IO);
if(!ff) goto dcsp_cleanup;
ff = procfile_readall(ff);
if(!ff) goto dcsp_cleanup;
ret = 1;
dcsp_cleanup:
if (!ret)
perror("Cannot open /sys/kernel/debug/extfrag/extfrag_index file");
procfile_close(ff);
return ret;
}
static void debugfs_parse_args(int argc, char **argv)
{
int i, freq = 0;
for(i = 1; i < argc; i++) {
if(!freq) {
int n = (int)str2l(argv[i]);
if(n > 0) {
freq = n;
continue;
}
}
if(strcmp("test-permissions", argv[i]) == 0 || strcmp("-t", argv[i]) == 0) {
if(!debugfs_check_sys_permission()) {
exit(2);
}
printf("OK\n");
exit(0);
}
}
if(freq > 0) update_every = freq;
}
int main(int argc, char **argv)
{
// debug_flags = D_PROCFILE;
stderror = stderr;
// set the name for logging
program_name = "debugfs.plugin";
// disable syslog for debugfs.plugin
error_log_syslog = 0;
netdata_configured_host_prefix = getenv("NETDATA_HOST_PREFIX");
if (verify_netdata_host_prefix() == -1)
exit(1);
user_config_dir = getenv("NETDATA_USER_CONFIG_DIR");
if (user_config_dir == NULL) {
user_config_dir = CONFIG_DIR;
}
stock_config_dir = getenv("NETDATA_STOCK_CONFIG_DIR");
if (stock_config_dir == NULL) {
// info("NETDATA_CONFIG_DIR is not passed from netdata");
stock_config_dir = LIBCONFIG_DIR;
}
// FIXME: should first check if /sys/kernel/debug is mounted
// FIXME: remove debugfs_check_sys_permission() after https://github.com/netdata/netdata/issues/15048 is fixed
if (!debugfs_check_capabilities() && !debugfs_am_i_running_as_root() && !debugfs_check_sys_permission()) {
uid_t uid = getuid(), euid = geteuid();
#ifdef HAVE_CAPABILITY
error(
"debugfs.plugin should either run as root (now running with uid %u, euid %u) or have special capabilities. "
"Without these, debugfs.plugin cannot access /sys/kernel/debug. "
"To enable capabilities run: sudo setcap cap_dac_read_search,cap_sys_ptrace+ep %s; "
"To enable setuid to root run: sudo chown root:netdata %s; sudo chmod 4750 %s; ",
uid,
euid,
argv[0],
argv[0],
argv[0]);
#else
error(
"debugfs.plugin should either run as root (now running with uid %u, euid %u) or have special capabilities. "
"Without these, debugfs.plugin cannot access /sys/kernel/debug."
"Your system does not support capabilities. "
"To enable setuid to root run: sudo chown root:netdata %s; sudo chmod 4750 %s; ",
uid,
euid,
argv[0],
argv[0]);
#endif
exit(1);
}
// if (!debugfs_check_sys_permission()) {
// exit(2);
// }
debugfs_parse_args(argc, argv);
size_t iteration;
usec_t step = update_every * USEC_PER_SEC;
heartbeat_t hb;
heartbeat_init(&hb);
for (iteration = 0; iteration < 86400; iteration++) {
heartbeat_next(&hb, step);
int enabled = 0;
for (int i = 0; debugfs_modules[i].name; i++) {
struct debugfs_module *pm = &debugfs_modules[i];
if (unlikely(!pm->enabled))
continue;
pm->enabled = !pm->func(update_every, pm->name);
if (likely(pm->enabled))
enabled++;
}
if (!enabled) {
info("all modules are disabled, exiting...");
return 1;
}
}
return 0;
}

View file

@ -0,0 +1,16 @@
// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef NETDATA_DEBUGFS_PLUGIN_H
#define NETDATA_DEBUGFS_PLUGIN_H 1
#include "libnetdata/libnetdata.h"
#include "collectors/all.h"
#include "database/rrd.h"
int do_debugfs_extfrag(int update_every, const char *name);
int do_debugfs_zswap(int update_every, const char *name);
void debugfs2lower(char *name);
const char *debugfs_rrdset_type_name(RRDSET_TYPE chart_type);
const char *debugfs_rrd_algorithm_name(RRD_ALGORITHM algorithm);
#endif // NETDATA_DEBUGFS_PLUGIN_H

View file

@ -0,0 +1,432 @@
// SPDX-License-Identifier: GPL-3.0-or-later
#include "debugfs_plugin.h"
static long system_page_size = 4096;
static collected_number pages_to_bytes(collected_number value)
{
return value * system_page_size;
}
struct netdata_zswap_metric {
const char *filename;
const char *chart_id;
const char *title;
const char *units;
RRDSET_TYPE charttype;
int prio;
const char *dimension;
RRD_ALGORITHM algorithm;
int divisor;
int enabled;
int chart_created;
collected_number value;
collected_number (*convertv)(collected_number v);
};
static struct netdata_zswap_metric zswap_calculated_metrics[] = {
{.filename = "",
.chart_id = "pool_compression_ratio",
.dimension = "compression_ratio",
.units = "ratio",
.title = "Zswap compression ratio",
.algorithm = RRD_ALGORITHM_ABSOLUTE,
.charttype = RRDSET_TYPE_LINE,
.enabled = CONFIG_BOOLEAN_YES,
.chart_created = CONFIG_BOOLEAN_NO,
.prio = NETDATA_CHART_PRIO_SYSTEM_ZSWAP_COMPRESS_RATIO,
.divisor = 100,
.convertv = NULL,
.value = -1},
};
enum netdata_zswap_calculated {
NETDATA_ZSWAP_COMPRESSION_RATIO_CHART,
};
enum netdata_zwap_independent {
NETDATA_ZSWAP_POOL_TOTAL_SIZE,
NETDATA_ZSWAP_STORED_PAGES,
NETDATA_ZSWAP_POOL_LIMIT_HIT,
NETDATA_ZSWAP_WRITTEN_BACK_PAGES,
NETDATA_ZSWAP_SAME_FILLED_PAGES,
NETDATA_ZSWAP_DUPLICATE_ENTRY,
// Terminator
NETDATA_ZSWAP_SITE_END
};
static struct netdata_zswap_metric zswap_independent_metrics[] = {
// https://elixir.bootlin.com/linux/latest/source/mm/zswap.c
{.filename = "/sys/kernel/debug/zswap/pool_total_size",
.chart_id = "pool_compressed_size",
.dimension = "compressed_size",
.units = "bytes",
.title = "Zswap compressed bytes currently stored",
.algorithm = RRD_ALGORITHM_ABSOLUTE,
.charttype = RRDSET_TYPE_AREA,
.enabled = CONFIG_BOOLEAN_YES,
.chart_created = CONFIG_BOOLEAN_NO,
.prio = NETDATA_CHART_PRIO_SYSTEM_ZSWAP_POOL_TOT_SIZE,
.divisor = 1,
.convertv = NULL,
.value = -1},
{.filename = "/sys/kernel/debug/zswap/stored_pages",
.chart_id = "pool_raw_size",
.dimension = "uncompressed_size",
.units = "bytes",
.title = "Zswap uncompressed bytes currently stored",
.algorithm = RRD_ALGORITHM_ABSOLUTE,
.charttype = RRDSET_TYPE_AREA,
.enabled = CONFIG_BOOLEAN_YES,
.chart_created = CONFIG_BOOLEAN_NO,
.prio = NETDATA_CHART_PRIO_SYSTEM_ZSWAP_STORED_PAGE,
.divisor = 1,
.convertv = pages_to_bytes,
.value = -1},
{.filename = "/sys/kernel/debug/zswap/pool_limit_hit",
.chart_id = "pool_limit_hit",
.dimension = "limit",
.units = "events/s",
.title = "Zswap pool limit was reached",
.algorithm = RRD_ALGORITHM_INCREMENTAL,
.charttype = RRDSET_TYPE_LINE,
.enabled = CONFIG_BOOLEAN_YES,
.chart_created = CONFIG_BOOLEAN_NO,
.prio = NETDATA_CHART_PRIO_SYSTEM_ZSWAP_POOL_LIM_HIT,
.divisor = 1,
.convertv = NULL,
.value = -1},
{.filename = "/sys/kernel/debug/zswap/written_back_pages",
.chart_id = "written_back_raw_bytes",
.dimension = "written_back",
.units = "bytes/s",
.title = "Zswap uncomressed bytes written back when pool limit was reached",
.algorithm = RRD_ALGORITHM_INCREMENTAL,
.charttype = RRDSET_TYPE_AREA,
.enabled = CONFIG_BOOLEAN_YES,
.chart_created = CONFIG_BOOLEAN_NO,
.prio = NETDATA_CHART_PRIO_SYSTEM_ZSWAP_WRT_BACK_PAGES,
.divisor = 1,
.convertv = pages_to_bytes,
.value = -1},
{.filename = "/sys/kernel/debug/zswap/same_filled_pages",
.chart_id = "same_filled_raw_size",
.dimension = "same_filled",
.units = "bytes",
.title = "Zswap same-value filled uncompressed bytes currently stored",
.algorithm = RRD_ALGORITHM_ABSOLUTE,
.charttype = RRDSET_TYPE_AREA,
.enabled = CONFIG_BOOLEAN_YES,
.chart_created = CONFIG_BOOLEAN_NO,
.prio = NETDATA_CHART_PRIO_SYSTEM_ZSWAP_SAME_FILL_PAGE,
.divisor = 1,
.convertv = pages_to_bytes,
.value = -1},
{.filename = "/sys/kernel/debug/zswap/duplicate_entry",
.chart_id = "duplicate_entry",
.dimension = "duplicate",
.units = "entries/s",
.title = "Zswap duplicate store was encountered",
.algorithm = RRD_ALGORITHM_INCREMENTAL,
.charttype = RRDSET_TYPE_LINE,
.enabled = CONFIG_BOOLEAN_YES,
.chart_created = CONFIG_BOOLEAN_NO,
.prio = NETDATA_CHART_PRIO_SYSTEM_ZSWAP_DUPP_ENTRY,
.divisor = 1,
.convertv = NULL,
.value = -1},
// The terminator
{.filename = NULL,
.chart_id = NULL,
.dimension = NULL,
.units = NULL,
.title = NULL,
.algorithm = RRD_ALGORITHM_ABSOLUTE,
.charttype = RRDSET_TYPE_LINE,
.enabled = CONFIG_BOOLEAN_NO,
.chart_created = CONFIG_BOOLEAN_NO,
.prio = -1,
.value = -1}};
enum netdata_zswap_rejected {
NETDATA_ZSWAP_REJECTED_CHART,
NETDATA_ZSWAP_REJECTED_COMPRESS_POOR,
NETDATA_ZSWAP_REJECTED_KMEM_FAIL,
NETDATA_ZSWAP_REJECTED_RALLOC_FAIL,
NETDATA_ZSWAP_REJECTED_RRECLAIM_FAIL,
// Terminator
NETDATA_ZSWAP_REJECTED_END
};
static struct netdata_zswap_metric zswap_rejected_metrics[] = {
{.filename = "/sys/kernel/debug/zswap/",
.chart_id = "rejections",
.dimension = NULL,
.units = "rejections/s",
.title = "Zswap rejections",
.algorithm = RRD_ALGORITHM_INCREMENTAL,
.charttype = RRDSET_TYPE_STACKED,
.enabled = CONFIG_BOOLEAN_YES,
.chart_created = CONFIG_BOOLEAN_NO,
.prio = NETDATA_CHART_PRIO_SYSTEM_ZSWAP_REJECTS,
.divisor = 1,
.convertv = NULL,
.value = -1},
{.filename = "/sys/kernel/debug/zswap/reject_compress_poor",
.chart_id = "reject_compress_poor",
.dimension = "compress_poor",
.units = NULL,
.title = NULL,
.algorithm = RRD_ALGORITHM_INCREMENTAL,
.charttype = RRDSET_TYPE_STACKED,
.enabled = CONFIG_BOOLEAN_YES,
.chart_created = CONFIG_BOOLEAN_NO,
.prio = NETDATA_CHART_PRIO_SYSTEM_ZSWAP_REJECTS,
.divisor = 1,
.convertv = NULL,
.value = -1},
{.filename = "/sys/kernel/debug/zswap/reject_kmemcache_fail",
.chart_id = "reject_kmemcache_fail",
.dimension = "kmemcache_fail",
.units = NULL,
.title = NULL,
.algorithm = RRD_ALGORITHM_INCREMENTAL,
.charttype = RRDSET_TYPE_STACKED,
.enabled = CONFIG_BOOLEAN_YES,
.chart_created = CONFIG_BOOLEAN_NO,
.prio = NETDATA_CHART_PRIO_SYSTEM_ZSWAP_REJECTS,
.divisor = 1,
.convertv = NULL,
.value = -1},
{.filename = "/sys/kernel/debug/zswap/reject_alloc_fail",
.chart_id = "reject_alloc_fail",
.dimension = "alloc_fail",
.units = NULL,
.title = NULL,
.algorithm = RRD_ALGORITHM_INCREMENTAL,
.charttype = RRDSET_TYPE_STACKED,
.enabled = CONFIG_BOOLEAN_YES,
.chart_created = CONFIG_BOOLEAN_NO,
.prio = NETDATA_CHART_PRIO_SYSTEM_ZSWAP_REJECTS,
.divisor = 1,
.convertv = NULL,
.value = -1},
{.filename = "/sys/kernel/debug/zswap/reject_reclaim_fail",
.chart_id = "reject_reclaim_fail",
.dimension = "reclaim_fail",
.units = NULL,
.title = NULL,
.algorithm = RRD_ALGORITHM_INCREMENTAL,
.charttype = RRDSET_TYPE_STACKED,
.enabled = CONFIG_BOOLEAN_YES,
.chart_created = CONFIG_BOOLEAN_NO,
.prio = NETDATA_CHART_PRIO_SYSTEM_ZSWAP_REJECTS,
.divisor = 1,
.convertv = NULL,
.value = -1},
// The terminator
{.filename = NULL,
.chart_id = NULL,
.dimension = NULL,
.units = NULL,
.title = NULL,
.algorithm = RRD_ALGORITHM_ABSOLUTE,
.charttype = RRDSET_TYPE_STACKED,
.enabled = CONFIG_BOOLEAN_NO,
.chart_created = CONFIG_BOOLEAN_NO,
.prio = -1,
.value = -1}};
int zswap_collect_data(struct netdata_zswap_metric *metric)
{
int fd;
int ret = 0;
char buffer[512];
char filename[FILENAME_MAX + 1];
snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, metric->filename);
// we are not using profile_open/procfile_read, because they will generate error during runtime.
fd = open(filename, O_RDONLY, 0444);
if (fd < 0) {
error("Cannot open file %s", filename);
return -1;
}
ssize_t r = read(fd, buffer, 511);
// We expect at list 1 character
if (r < 2) {
error("Cannot parse file %s", filename);
ret = -1;
goto zswap_collect_end;
}
// We discard breakline
buffer[r - 1] = '\0';
metric->value = str2ll(buffer, NULL);
if (metric->convertv)
metric->value = metric->convertv(metric->value);
zswap_collect_end:
close(fd);
return ret;
}
static void
zswap_send_chart(struct netdata_zswap_metric *metric, int update_every, const char *name, const char *option)
{
fprintf(
stdout,
"CHART system.zswap_%s '' '%s' '%s' 'zswap' '' '%s' %d %d '%s' 'debugfs.plugin' '%s'\n",
metric->chart_id,
metric->title,
metric->units,
debugfs_rrdset_type_name(metric->charttype),
metric->prio,
update_every,
(!option) ? "" : option,
name);
}
static void zswap_send_dimension(struct netdata_zswap_metric *metric)
{
int div = metric->divisor > 0 ? metric->divisor : 1;
fprintf(
stdout,
"DIMENSION '%s' '%s' %s 1 %d ''\n",
metric->dimension,
metric->dimension,
debugfs_rrd_algorithm_name(metric->algorithm),
div);
}
static void zswap_send_begin(struct netdata_zswap_metric *metric)
{
fprintf(stdout, "BEGIN system.zswap_%s\n", metric->chart_id);
}
static void zswap_send_set(struct netdata_zswap_metric *metric)
{
fprintf(stdout, "SET %s = %lld\n", metric->dimension, metric->value);
}
static void zswap_send_end_and_flush()
{
fprintf(stdout, "END\n");
fflush(stdout);
}
static void zswap_independent_chart(struct netdata_zswap_metric *metric, int update_every, const char *name)
{
if (unlikely(!metric->chart_created)) {
metric->chart_created = CONFIG_BOOLEAN_YES;
zswap_send_chart(metric, update_every, name, NULL);
zswap_send_dimension(metric);
}
zswap_send_begin(metric);
zswap_send_set(metric);
zswap_send_end_and_flush();
}
void zswap_reject_chart(int update_every, const char *name)
{
struct netdata_zswap_metric *metric = &zswap_rejected_metrics[NETDATA_ZSWAP_REJECTED_CHART];
if (unlikely(!metric->chart_created)) {
metric->chart_created = CONFIG_BOOLEAN_YES;
zswap_send_chart(metric, update_every, name, NULL);
for (int i = NETDATA_ZSWAP_REJECTED_COMPRESS_POOR; zswap_rejected_metrics[i].filename; i++) {
metric = &zswap_rejected_metrics[i];
if (likely(metric->enabled))
zswap_send_dimension(metric);
}
}
metric = &zswap_rejected_metrics[NETDATA_ZSWAP_REJECTED_CHART];
zswap_send_begin(metric);
for (int i = NETDATA_ZSWAP_REJECTED_COMPRESS_POOR; zswap_rejected_metrics[i].filename; i++) {
metric = &zswap_rejected_metrics[i];
if (likely(metric->enabled))
zswap_send_set(metric);
}
zswap_send_end_and_flush();
}
static void zswap_obsolete_charts(int update_every, const char *name)
{
struct netdata_zswap_metric *metric = NULL;
for (int i = 0; zswap_independent_metrics[i].filename; i++) {
metric = &zswap_independent_metrics[i];
if (likely(metric->chart_created))
zswap_send_chart(metric, update_every, name, "obsolete");
}
metric = &zswap_rejected_metrics[NETDATA_ZSWAP_REJECTED_CHART];
if (likely(metric->chart_created))
zswap_send_chart(metric, update_every, name, "obsolete");
metric = &zswap_calculated_metrics[NETDATA_ZSWAP_COMPRESSION_RATIO_CHART];
if (likely(metric->chart_created))
zswap_send_chart(metric, update_every, name, "obsolete");
}
int do_debugfs_zswap(int update_every, const char *name)
{
system_page_size = sysconf(_SC_PAGESIZE);
struct netdata_zswap_metric *metric = NULL;
int enabled = 0;
for (int i = 0; zswap_independent_metrics[i].filename; i++) {
metric = &zswap_independent_metrics[i];
if (unlikely(!metric->enabled))
continue;
if (unlikely(!(metric->enabled = !zswap_collect_data(metric))))
continue;
zswap_independent_chart(metric, update_every, name);
enabled++;
}
struct netdata_zswap_metric *metric_size = &zswap_independent_metrics[NETDATA_ZSWAP_POOL_TOTAL_SIZE];
struct netdata_zswap_metric *metric_raw_size = &zswap_independent_metrics[NETDATA_ZSWAP_STORED_PAGES];
if (metric_size->enabled && metric_raw_size->enabled) {
metric = &zswap_calculated_metrics[NETDATA_ZSWAP_COMPRESSION_RATIO_CHART];
metric->value = 0;
if (metric_size->value > 0)
metric->value =
(collected_number)((NETDATA_DOUBLE)metric_raw_size->value / (NETDATA_DOUBLE)metric_size->value * 100);
zswap_independent_chart(metric, update_every, name);
}
int enabled_rejected = 0;
for (int i = NETDATA_ZSWAP_REJECTED_COMPRESS_POOR; zswap_rejected_metrics[i].filename; i++) {
metric = &zswap_rejected_metrics[i];
if (unlikely(!metric->enabled))
continue;
if (unlikely(!(metric->enabled = !zswap_collect_data(metric))))
continue;
enabled++;
enabled_rejected++;
}
if (likely(enabled_rejected > 0))
zswap_reject_chart(update_every, name);
if (!enabled) {
zswap_obsolete_charts(update_every, name);
return -1;
}
return 0;
}

View file

@ -0,0 +1,12 @@
metric,scode,dimensions,unit,description,chart_type,labels,plugin,module
mem.fragmentation_index_dma,node,"order0, order1, order2, order3, order4, order5, order6, order7, order8, order9, order10",index,Memory fragmentation index for each order,line,numa_node,debugfs.plugin,/sys/kernel/debug/extfrag
mem.fragmentation_index_dma32,node,"order0, order1, order2, order3, order4, order5, order6, order7, order8, order9, order10",index,Memory fragmentation index for each order,line,numa_node,debugfs.plugin,/sys/kernel/debug/extfrag
mem.fragmentation_index_normal,node,"order0, order1, order2, order3, order4, order5, order6, order7, order8, order9, order10",index,Memory fragmentation index for each order,line,numa_node,debugfs.plugin,/sys/kernel/debug/extfrag
system.zswap_pool_compression_ratio,,compression_ratio,ratio,Zswap compression ratio,line,,debugfs.plugin,/sys/kernel/debug/zswap
system.zswap_pool_compressed_size,,compressed_size,bytes,Zswap compressed bytes currently stored,area,,debugfs.plugin,/sys/kernel/debug/zswap
system.zswap_pool_raw_size,,uncompressed_size,bytes,Zswap uncompressed bytes currently stored,area,,debugfs.plugin,/sys/kernel/debug/zswap
system.zswap_rejections,,"compress_poor, kmemcache_fail, alloc_fail, reclaim_fail",rejections/s,Zswap rejections,stacked,,debugfs.plugin,/sys/kernel/debug/zswap
system.zswap_pool_limit_hit,,limit,events/s,Zswap pool limit was reached,line,,debugfs.plugin,/sys/kernel/debug/zswap
system.zswap_written_back_raw_bytes,,written_back,bytes/s,Zswap uncomressed bytes written back when pool limit was reached,area,,debugfs.plugin,/sys/kernel/debug/zswap
system.zswap_same_filled_raw_size,,same_filled,bytes,Zswap same-value filled uncompressed bytes currently stored,area,,debugfs.plugin,/sys/kernel/debug/zswap
system.zswap_duplicate_entry,,duplicate,entries/s,Zswap duplicate store was encountered,line,,debugfs.plugin,/sys/kernel/debug/zswap
1 metric scode dimensions unit description chart_type labels plugin module
2 mem.fragmentation_index_dma node order0, order1, order2, order3, order4, order5, order6, order7, order8, order9, order10 index Memory fragmentation index for each order line numa_node debugfs.plugin /sys/kernel/debug/extfrag
3 mem.fragmentation_index_dma32 node order0, order1, order2, order3, order4, order5, order6, order7, order8, order9, order10 index Memory fragmentation index for each order line numa_node debugfs.plugin /sys/kernel/debug/extfrag
4 mem.fragmentation_index_normal node order0, order1, order2, order3, order4, order5, order6, order7, order8, order9, order10 index Memory fragmentation index for each order line numa_node debugfs.plugin /sys/kernel/debug/extfrag
5 system.zswap_pool_compression_ratio compression_ratio ratio Zswap compression ratio line debugfs.plugin /sys/kernel/debug/zswap
6 system.zswap_pool_compressed_size compressed_size bytes Zswap compressed bytes currently stored area debugfs.plugin /sys/kernel/debug/zswap
7 system.zswap_pool_raw_size uncompressed_size bytes Zswap uncompressed bytes currently stored area debugfs.plugin /sys/kernel/debug/zswap
8 system.zswap_rejections compress_poor, kmemcache_fail, alloc_fail, reclaim_fail rejections/s Zswap rejections stacked debugfs.plugin /sys/kernel/debug/zswap
9 system.zswap_pool_limit_hit limit events/s Zswap pool limit was reached line debugfs.plugin /sys/kernel/debug/zswap
10 system.zswap_written_back_raw_bytes written_back bytes/s Zswap uncomressed bytes written back when pool limit was reached area debugfs.plugin /sys/kernel/debug/zswap
11 system.zswap_same_filled_raw_size same_filled bytes Zswap same-value filled uncompressed bytes currently stored area debugfs.plugin /sys/kernel/debug/zswap
12 system.zswap_duplicate_entry duplicate entries/s Zswap duplicate store was encountered line debugfs.plugin /sys/kernel/debug/zswap

View file

@ -752,7 +752,7 @@ static void ebpf_create_swap_charts(int update_every)
EBPF_COMMON_DIMENSION_CALL, NETDATA_SYSTEM_SWAP_SUBMENU,
NULL,
NETDATA_EBPF_CHART_TYPE_LINE,
202,
NETDATA_CHART_PRIO_SYSTEM_SWAP_CALLS,
ebpf_create_global_dimension,
swap_publish_aggregated, NETDATA_SWAP_END,
update_every, NETDATA_EBPF_MODULE_NAME_SWAP);

View file

@ -1293,6 +1293,21 @@ if test "${build_ml}" = "yes"; then
fi
# -----------------------------------------------------------------------------
# debugfs.plugin
if test "${build_target}" = "linux"; then
AC_DEFINE([ENABLE_DEBUGFS_PLUGIN], [1], [debugfs.plugin])
enable_plugin_debugfs="yes"
else
enable_plugin_debugfs="no"
fi
AC_MSG_CHECKING([if debugfs.plugin should be enabled])
AC_MSG_RESULT([${enable_plugin_debugfs}])
AM_CONDITIONAL([ENABLE_PLUGIN_DEBUGFS], [test "${enable_plugin_debugfs}" = "yes"])
# -----------------------------------------------------------------------------
# ebpf.plugin
@ -1808,6 +1823,7 @@ AC_CONFIG_FILES([
collectors/apps.plugin/Makefile
collectors/cgroups.plugin/Makefile
collectors/charts.d.plugin/Makefile
collectors/debugfs.plugin/Makefile
collectors/diskspace.plugin/Makefile
collectors/timex.plugin/Makefile
collectors/ioping.plugin/Makefile

View file

@ -61,6 +61,7 @@ case "$1" in
chown -R root:netdata /usr/libexec/netdata/plugins.d
setcap cap_dac_read_search,cap_sys_ptrace+ep /usr/libexec/netdata/plugins.d/apps.plugin
setcap cap_dac_read_search+ep /usr/libexec/netdata/plugins.d/slabinfo.plugin
setcap cap_dac_read_search+ep /usr/libexec/netdata/plugins.d/debugfs.plugin
if capsh --supports=cap_perfmon 2>/dev/null; then
setcap cap_perfmon+ep /usr/libexec/netdata/plugins.d/perf.plugin

View file

@ -113,6 +113,7 @@ override_dh_fixperms:
# given extra capabilities in the postinst script.
#
chmod 0750 $(TOP)/usr/libexec/netdata/plugins.d/apps.plugin
chmod 0750 $(TOP)/usr/libexec/netdata/plugins.d/debugfs.plugin
chmod 0750 $(TOP)/usr/libexec/netdata/plugins.d/perf.plugin
chmod 0750 $(TOP)/usr/libexec/netdata/plugins.d/slabinfo.plugin
chmod 0750 $(TOP)/usr/libexec/netdata/plugins.d/go.d.plugin

View file

@ -115,6 +115,12 @@
#define FEAT_APPS_PLUGIN 0
#endif
#ifdef ENABLE_DEBUGFS_PLUGIN
#define FEAT_DEBUGFS_PLUGIN 1
#else
#define FEAT_DEBUGFS_PLUGIN 0
#endif
#ifdef HAVE_FREEIPMI
#define FEAT_IPMI 1
#else
@ -291,6 +297,7 @@ void print_build_info(void) {
printf(" apps: %s\n", FEAT_YES_NO(FEAT_APPS_PLUGIN));
printf(" cgroup Network Tracking: %s\n", FEAT_YES_NO(FEAT_CGROUP_NET));
printf(" CUPS: %s\n", FEAT_YES_NO(FEAT_CUPS));
printf(" debugfs: %s\n", FEAT_YES_NO(FEAT_DEBUGFS_PLUGIN));
printf(" EBPF: %s\n", FEAT_YES_NO(FEAT_EBPF));
printf(" IPMI: %s\n", FEAT_YES_NO(FEAT_IPMI));
printf(" NFACCT: %s\n", FEAT_YES_NO(FEAT_NFACCT));
@ -349,6 +356,7 @@ void print_build_info_json(void) {
printf(" \"apps\": %s,\n", FEAT_JSON_BOOL(FEAT_APPS_PLUGIN));
printf(" \"cgroup-net\": %s,\n", FEAT_JSON_BOOL(FEAT_CGROUP_NET));
printf(" \"cups\": %s,\n", FEAT_JSON_BOOL(FEAT_CUPS));
printf(" \"debugfs\": %s,\n", FEAT_JSON_BOOL(FEAT_DEBUGFS_PLUGIN));
printf(" \"ebpf\": %s,\n", FEAT_JSON_BOOL(FEAT_EBPF));
printf(" \"ipmi\": %s,\n", FEAT_JSON_BOOL(FEAT_IPMI));
printf(" \"nfacct\": %s,\n", FEAT_JSON_BOOL(FEAT_NFACCT));
@ -424,6 +432,9 @@ void analytics_build_info(BUFFER *b) {
#ifdef ENABLE_APPS_PLUGIN
add_to_bi(b, "apps");
#endif
#ifdef ENABLE_DEBUGFS_PLUGIN
add_to_bi(b, "debugfs");
#endif
#ifdef HAVE_SETNS
add_to_bi(b, "cgroup Network Tracking");
#endif

View file

@ -1229,6 +1229,23 @@ if [ "$(id -u)" -eq 0 ]; then
fi
fi
if [ -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/debugfs.plugin" ]; then
run chown "root:${NETDATA_GROUP}" "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/debugfs.plugin"
capabilities=0
if ! iscontainer && command -v setcap 1> /dev/null 2>&1; then
run chmod 0750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/debugfs.plugin"
if run setcap cap_dac_read_search+ep "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/debugfs.plugin"; then
# if we managed to setcap, but we fail to execute debugfs.plugin setuid to root
"${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/debugfs.plugin" -t > /dev/null 2>&1 && capabilities=1 || capabilities=0
fi
fi
if [ $capabilities -eq 0 ]; then
# fix debugfs.plugin to be setuid to root
run chmod 4750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/debugfs.plugin"
fi
fi
if [ -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/freeipmi.plugin" ]; then
run chown "root:${NETDATA_GROUP}" "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/freeipmi.plugin"
run chmod 4750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/freeipmi.plugin"

View file

@ -280,6 +280,10 @@ install -m 4750 -p freeipmi.plugin "${RPM_BUILD_ROOT}%{_libexecdir}/%{name}/plug
# Install apps.plugin
install -m 4750 -p apps.plugin "${RPM_BUILD_ROOT}%{_libexecdir}/%{name}/plugins.d/apps.plugin"
# ###########################################################
# Install debugfs.plugin
install -m 0750 -p debugfs.plugin "${RPM_BUILD_ROOT}%{_libexecdir}/%{name}/plugins.d/debugfs.plugin"
# ###########################################################
# Install perf.plugin
install -m 4750 -p perf.plugin "${RPM_BUILD_ROOT}%{_libexecdir}/%{name}/plugins.d/perf.plugin"
@ -501,7 +505,10 @@ rm -rf "${RPM_BUILD_ROOT}"
# %caps(cap_perfmon=ep) %attr(0750,root,netdata) %{_libexecdir}/%{name}/plugins.d/perf.plugin
%caps(cap_sys_admin=ep) %attr(0750,root,netdata) %{_libexecdir}/%{name}/plugins.d/perf.plugin
# perf plugin
# debugfs plugin
%caps(cap_dac_read_search=ep) %attr(0750,root,netdata) %{_libexecdir}/%{name}/plugins.d/debugfs.plugin
# slabinfo plugin
%caps(cap_dac_read_search=ep) %attr(0750,root,netdata) %{_libexecdir}/%{name}/plugins.d/slabinfo.plugin
# go.d.plugin (the capability required for wireguard module)

View file

@ -104,7 +104,8 @@ RUN chown -R root:root \
chmod 0755 /usr/libexec/netdata/plugins.d/*.plugin && \
chmod 4755 \
/usr/libexec/netdata/plugins.d/cgroup-network \
/usr/libexec/netdata/plugins.d/apps.plugin && \
/usr/libexec/netdata/plugins.d/apps.plugin \
/usr/libexec/netdata/plugins.d/debugfs.plugin && \
if [ -f /usr/libexec/netdata/plugins.d/freeipmi.plugin ]; then \
chmod 4755 /usr/libexec/netdata/plugins.d/freeipmi.plugin; \
fi && \

View file

@ -171,6 +171,7 @@ progress "changing plugins ownership and permissions"
if command -v setcap >/dev/null 2>&1; then
run setcap "cap_dac_read_search,cap_sys_ptrace=ep" "usr/libexec/netdata/plugins.d/apps.plugin"
run setcap "cap_dac_read_search=ep" "usr/libexec/netdata/plugins.d/slabinfo.plugin"
run setcap "cap_dac_read_search=ep" "usr/libexec/netdata/plugins.d/debugfs.plugin"
if command -v capsh >/dev/null 2>&1 && capsh --supports=cap_perfmon 2>/dev/null ; then
run setcap "cap_perfmon=ep" "usr/libexec/netdata/plugins.d/perf.plugin"
@ -180,7 +181,7 @@ if command -v setcap >/dev/null 2>&1; then
run setcap "cap_net_admin,cap_net_raw=eip" "usr/libexec/netdata/plugins.d/go.d.plugin"
else
for x in apps.plugin perf.plugin slabinfo.plugin; do
for x in apps.plugin perf.plugin slabinfo.plugin debugfs.plugin; do
f="usr/libexec/netdata/plugins.d/${x}"
run chown root:${NETDATA_GROUP} "${f}"
run chmod 4750 "${f}"

View file

@ -883,6 +883,19 @@ netdataDashboard.submenu = {
'When the kernel or an application requests some memory, the buddy allocator provides a page that matches closest the request.'
},
'mem.fragmentation': {
info: 'These charts show whether the kernel will compact memory or direct reclaim to satisfy a high-order allocation. '+
'The extfrag/extfrag_index file in debugfs shows what the fragmentation index for each order is in each zone in the system.' +
'Values tending towards 0 imply allocations would fail due to lack of memory, values towards 1000 imply failures are due to ' +
'fragmentation and -1 implies that the allocation will succeed as long as watermarks are met.'
},
'system.zswap': {
info : 'Zswap is a backend for frontswap that takes pages that are in the process of being swapped out and attempts to compress and store them in a ' +
'RAM-based memory pool. This can result in a significant I/O reduction on the swap device and, in the case where decompressing from RAM is faster ' +
'than reading from the swap device, can also improve workload performance.'
},
'ip.ecn': {
info: '<a href="https://en.wikipedia.org/wiki/Explicit_Congestion_Notification" target="_blank">Explicit Congestion Notification (ECN)</a> '+
'is an extension to the IP and to the TCP that allows end-to-end notification of network congestion without dropping packets. '+
@ -1522,6 +1535,14 @@ netdataDashboard.context = {
info: '<a href="https://en.wikipedia.org/wiki/Entropy_(computing)" target="_blank">Entropy</a>, is a pool of random numbers (<a href="https://en.wikipedia.org/wiki//dev/random" target="_blank">/dev/random</a>) that is mainly used in cryptography. If the pool of entropy gets empty, processes requiring random numbers may run a lot slower (it depends on the interface each program uses), waiting for the pool to be replenished. Ideally a system with high entropy demands should have a hardware device for that purpose (TPM is one such device). There are also several software-only options you may install, like <code>haveged</code>, although these are generally useful only in servers.'
},
'system.zswap_rejections': {
info: '<p>Zswap rejected pages per access.</p>' +
'<p><b>CompressPoor</b> - compressed page was too big for the allocator to store. ' +
'<b>KmemcacheFail</b> - number of entry metadata that could not be allocated. ' +
'<b>AllocFail</b> - allocator could not get memory. ' +
'<b>ReclaimFail</b> - memory cannot be reclaimed (pool limit was reached).</p>'
},
'system.clock_sync_state': {
info:'<p>The system clock synchronization state as provided by the <a href="https://man7.org/linux/man-pages/man2/adjtimex.2.html" target="_blank">ntp_adjtime()</a> system call. '+
'An unsynchronized clock may be the result of synchronization issues by the NTP daemon or a hardware clock fault. '+