0
0
Fork 0
mirror of https://github.com/netdata/netdata.git synced 2025-04-14 09:38:34 +00:00
netdata_netdata/collectors/debugfs.plugin/debugfs_plugin.c
Costa Tsaousis 3e508c8f95
New logging layer ()
* cleanup of logging - wip

* first working iteration

* add errno annotator

* replace old logging functions with netdata_logger()

* cleanup

* update error_limit

* fix remanining error_limit references

* work on fatal()

* started working on structured logs

* full cleanup

* default logging to files; fix all plugins initialization

* fix formatting of numbers

* cleanup and reorg

* fix coverity issues

* cleanup obsolete code

* fix formatting of numbers

* fix log rotation

* fix for older systems

* add detection of systemd journal via stderr

* finished on access.log

* remove left-over transport

* do not add empty fields to the logs

* journal get compact uuids; X-Transaction-ID header is added in web responses

* allow compiling on systems without memfd sealing

* added libnetdata/uuid directory

* move datetime formatters to libnetdata

* add missing files

* link the makefiles in libnetdata

* added uuid_parse_flexi() to parse UUIDs with and without hyphens; the web server now read X-Transaction-ID and uses it for functions and web responses

* added stream receiver, sender, proc plugin and pluginsd log stack

* iso8601 advanced usage; line_splitter module in libnetdata; code cleanup

* add message ids to streaming inbound and outbound connections

* cleanup line_splitter between lines to avoid logging garbage; when killing children, kill them with SIGABRT if internal checks is enabled

* send SIGABRT to external plugins only if we are not shutting down

* fix cross cleanup in pluginsd parser

* fatal when there is a stack error in logs

* compile netdata with -fexceptions

* do not kill external plugins with SIGABRT

* metasync info logs to debug level

* added severity to logs

* added json output; added options per log output; added documentation; fixed issues mentioned

* allow memfd only on linux

* moved journal low level functions to journal.c/h

* move health logs to daemon.log with proper priorities

* fixed a couple of bugs; health log in journal

* updated docs

* systemd-cat-native command to push structured logs to journal from the command line

* fix makefiles

* restored NETDATA_LOG_SEVERITY_LEVEL

* fix makefiles

* systemd-cat-native can also work as the logger of Netdata scripts

* do not require a socket to systemd-journal to log-as-netdata

* alarm notify logs in native format

* properly compare log ids

* fatals log alerts; alarm-notify.sh working

* fix overflow warning

* alarm-notify.sh now logs the request (command line)

* anotate external plugins logs with the function cmd they run

* added context, component and type to alarm-notify.sh; shell sanitization removes control character and characters that may be expanded by bash

* reformatted alarm-notify logs

* unify cgroup-network-helper.sh

* added quotes around params

* charts.d.plugin switched logging to journal native

* quotes for logfmt

* unify the status codes of streaming receivers and senders

* alarm-notify: dont log anything, if there is nothing to do

* all external plugins log to stderr when running outside netdata; alarm-notify now shows an error when notifications menthod are needed but are not available

* migrate cgroup-name.sh to new logging

* systemd-cat-native now supports messages with newlines

* socket.c logs use priority

* cleanup log field types

* inherit the systemd set INVOCATION_ID if found

* allow systemd-cat-native to send messages to a systemd-journal-remote URL

* log2journal command that can convert structured logs to journal export format

* various fixes and documentation of log2journal

* updated log2journal docs

* updated log2journal docs

* updated documentation of fields

* allow compiling without libcurl

* do not use socket as format string

* added version information to newly added tools

* updated documentation and help messages

* fix the namespace socket path

* print errno with error

* do not timeout

* updated docs

* updated docs

* updated docs

* log2journal updated docs and params

* when talking to a remote journal, systemd-cat-native batches the messages

* enable lz4 compression for systemd-cat-native when sending messages to a systemd-journal-remote

* Revert "enable lz4 compression for systemd-cat-native when sending messages to a systemd-journal-remote"

This reverts commit b079d53c11.

* note about uncompressed traffic

* log2journal: code reorg and cleanup to make modular

* finished rewriting log2journal

* more comments

* rewriting rules support

* increased limits

* updated docs

* updated docs

* fix old log call

* use journal only when stderr is connected to journal

* update netdata.spec for libcurl, libpcre2 and log2journal

* pcre2-devel

* do not require pcre2 in centos < 8, amazonlinux < 2023, open suse

* log2journal only on systems pcre2 is available

* ignore log2journal in .gitignore

* avoid log2journal on centos 7, amazonlinux 2 and opensuse

* add pcre2-8 to static build

* undo last commit

* Bundle to static

Signed-off-by: Tasos Katsoulas <tasos@netdata.cloud>

* Add build deps for deb packages

Signed-off-by: Tasos Katsoulas <tasos@netdata.cloud>

* Add dependencies; build from source

Signed-off-by: Tasos Katsoulas <tasos@netdata.cloud>

* Test build for amazon linux and centos expect to fail for suse

Signed-off-by: Tasos Katsoulas <tasos@netdata.cloud>

* fix minor oversight

Signed-off-by: Tasos Katsoulas <tasos@netdata.cloud>

* Reorg code

* Add the install from source (deps) as a TODO
* Not enable the build on suse ecosystem

Signed-off-by: Tasos Katsoulas <tasos@netdata.cloud>

---------

Signed-off-by: Tasos Katsoulas <tasos@netdata.cloud>
Co-authored-by: Tasos Katsoulas <tasos@netdata.cloud>
2023-11-22 10:27:25 +02:00

243 lines
6.8 KiB
C

// 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},
// Linux powercap metrics is here because it needs privilege to read each RAPL zone
{ .name = "/sys/devices/virtual/powercap", .enabled = CONFIG_BOOLEAN_YES,
.func = do_sys_devices_virtual_powercap},
// 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) {
netdata_log_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) {
netdata_log_error("Cannot find if CAP_DAC_READ_SEARCH is effective.");
ret = 0;
} else {
if (cfv != CAP_SET) {
netdata_log_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)
{
clocks_init();
nd_log_initialize_for_external_plugins("debugfs.plugin");
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) {
// netdata_log_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
netdata_log_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
netdata_log_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) {
netdata_log_info("all modules are disabled, exiting...");
return 1;
}
}
fprintf(stdout, "EXIT\n");
fflush(stdout);
return 0;
}