diff options
author | Costa Tsaousis <costa@netdata.cloud> | 2022-10-05 14:13:46 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-05 14:13:46 +0300 |
commit | 8fc3b351a2e7fc96eced8f924de2e9cec9842128 (patch) | |
tree | bde41c66573ccaf8876c280e00742cc6096b587c /collectors/cgroups.plugin/sys_fs_cgroup.c | |
parent | 6850878e697d66dc90b9af1e750b22238c63c292 (diff) |
Allow netdata plugins to expose functions for querying more information about specific charts (#13720)
* function renames and code cleanup in popen.c; no actual code changes
* netdata popen() now opens both child process stdin and stdout and returns FILE * for both
* pass both input and output to parser structures
* updated rrdset to call custom functions
* RRDSET FUNCTION leading calls for both sync and async operation
* put RRDSET functions to a separate file
* added format and timeout at function definition
* support for synchronous (internal plugins) and asynchronous (external plugins and children) functions
* /api/v1/function endpoint
* functions are now attached to the host and there is a dictionary view per chart
* functions implemented at plugins.d
* remove the defer until keyword hook from plugins.d when it is done
* stream sender implementation of functions
* sanitization of all functions so that certain characters are only allowed
* strictier sanitization
* common max size
* 1st working plugins.d example
* always init inflight dictionary
* properly destroy dictionaries to avoid parallel insertion of items
* add more debugging on disconnection reasons
* add more debugging on disconnection reasons again
* streaming receiver respects newlines
* dont use the same fp for both streaming receive and send
* dont free dbengine memory with internal checks
* make sender proceed in the buffer
* added timing info and garbage collection at plugins.d
* added info about routing nodes
* added info about routing nodes with delay
* added more info about delays
* added more info about delays again
* signal sending thread to wake up
* streaming version labeling and commented code to support capabilities
* added functions to /api/v1/data, /api/v1/charts, /api/v1/chart, /api/v1/info
* redirect top output to stdout
* address coverity findings
* fix resource leaks of popen
* log attempts to connect to individual destinations
* better messages
* properly parse destinations
* try to find a function from the most matching to the least matching
* log added streaming destinations
* rotate destinations bypassing a node in the middle that does not accept our connection
* break the loops properly
* use typedef to define callbacks
* capabilities negotiation during streaming
* functions exposed upstream based on capabilities; compression disabled per node persisting reconnects; always try to connect with all capabilities
* restore functionality to lookup functions
* better logging of capabilities
* remove old versions from capabilities when a newer version is there
* fix formatting
* optimization for plugins.d rrdlabels to avoid creating and destructing dictionaries all the time
* delayed health initialization for rrddim and rrdset
* cleanup health initialization
* fix for popen() not returning the right value
* add health worker jobs for initializing rrdset and rrddim
* added content type support for functions; apps.plugin permanent function to display all the processes
* fixes for functions parameters parsing in apps.plugin
* fix for process matching in apps.plugiin
* first working function for apps.plugin
* Dashboard ACL is disabled for functions; Function errors are all in JSON format
* apps.plugin function processes returns json table
* use json_escape_string() to escape message
* fix formatting
* apps.plugin exposes all its metrics to function processes
* fix json formatting when filtering out some rows
* reopen the internal pipe of rrdpush in case of errors
* misplaced statement
* do not use buffer->len
* support for GLOBAL functions (functions that are not linked to a chart
* added /api/v1/functions endpoint; removed format from the FUNCTIONS api;
* swagger documentation about the new api end points
* added plugins.d documentation about functions
* never re-close a file
* remove uncessesary ifdef
* fixed issues identified by codacy
* fix for null label value
* make edit-config copy-and-paste friendly
* Revert "make edit-config copy-and-paste friendly"
This reverts commit 54500c0e0a97f65a0c66c4d34e966f6a9056698e.
* reworked sender handshake to fix coverity findings
* timeout is zero, for both send_timeout() and recv_timeout()
* properly detect that parent closed the socket
* support caching of function responses; limit function response to 10MB; added protection from malformed function responses
* disabled excessive logging
* added units to apps.plugin function processes and normalized all values to be human readable
* shorter field names
* fixed issues reported
* fixed apps.plugin error response; tested that pluginsd can properly handle faulty responses
* use double linked list macros for double linked list management
* faster apps.plugin function printing by minimizing file operations
* added memory percentage
* fix compatibility issues with older compilers and FreeBSD
* rrdpush sender code cleanup; rrhost structure cleanup from sender flags and variables;
* fix letftover variable in ifdef
* apps.plugin: do not call detach from the thread; exit immediately when input is broken
* exclude AR charts from health
* flush cleaner; prefer sender output
* clarity
* do not fill the cbuffer if not connected
* fix
* dont enabled host->sender if streaming is not enabled; send host label updates to parent;
* functions are only available through ACLK
* Prepared statement reports only in dev mode
* fix AR chart detection
* fix for streaming not being enabling itself
* more cleanup of sender and receiver structures
* moved read-only flags and configuration options to rrdhost->options
* fixed merge with master
* fix for incomplete rename
* prevent service thread from working on charts that are being collected
Co-authored-by: Stelios Fragkakis <52996999+stelfrag@users.noreply.github.com>
Diffstat (limited to 'collectors/cgroups.plugin/sys_fs_cgroup.c')
-rw-r--r-- | collectors/cgroups.plugin/sys_fs_cgroup.c | 50 |
1 files changed, 26 insertions, 24 deletions
diff --git a/collectors/cgroups.plugin/sys_fs_cgroup.c b/collectors/cgroups.plugin/sys_fs_cgroup.c index 74aedf2b52..3bee46dcf4 100644 --- a/collectors/cgroups.plugin/sys_fs_cgroup.c +++ b/collectors/cgroups.plugin/sys_fs_cgroup.c @@ -153,14 +153,15 @@ static enum cgroups_systemd_setting cgroups_detect_systemd(const char *exec) char buf[MAXSIZE_PROC_CMDLINE]; char *begin, *end; - FILE *f = mypopen(exec, &command_pid); + FILE *fp_child_input; + FILE *fp_child_output = netdata_popen(exec, &command_pid, &fp_child_input); - if (!f) + if (!fp_child_output) return retval; fd_set rfds; struct timeval timeout; - int fd = fileno(f); + int fd = fileno(fp_child_output); int ret = -1; FD_ZERO(&rfds); @@ -177,7 +178,7 @@ static enum cgroups_systemd_setting cgroups_detect_systemd(const char *exec) } else if (ret == 0) { info("Cannot get the output of \"%s\" within %"PRId64" seconds", exec, (int64_t)timeout.tv_sec); } else { - while (fgets(buf, MAXSIZE_PROC_CMDLINE, f) != NULL) { + while (fgets(buf, MAXSIZE_PROC_CMDLINE, fp_child_output) != NULL) { if ((begin = strstr(buf, SYSTEMD_HIERARCHY_STRING))) { end = begin = begin + strlen(SYSTEMD_HIERARCHY_STRING); if (!*begin) @@ -196,7 +197,7 @@ static enum cgroups_systemd_setting cgroups_detect_systemd(const char *exec) } } - if (mypclose(f, command_pid)) + if (netdata_pclose(fp_child_input, fp_child_output, command_pid)) return SYSTEMD_CGROUP_ERR; return retval; @@ -210,18 +211,19 @@ static enum cgroups_type cgroups_try_detect_version() int cgroups2_available = 0; // 1. check if cgroups2 available on system at all - FILE *f = mypopen("grep cgroup /proc/filesystems", &command_pid); - if (!f) { + FILE *fp_child_input; + FILE *fp_child_output = netdata_popen("grep cgroup /proc/filesystems", &command_pid, &fp_child_input); + if (!fp_child_output) { error("popen failed"); return CGROUPS_AUTODETECT_FAIL; } - while (fgets(buf, MAXSIZE_PROC_CMDLINE, f) != NULL) { + while (fgets(buf, MAXSIZE_PROC_CMDLINE, fp_child_output) != NULL) { if (strstr(buf, "cgroup2")) { cgroups2_available = 1; break; } } - if(mypclose(f, command_pid)) + if(netdata_pclose(fp_child_input, fp_child_output, command_pid)) return CGROUPS_AUTODETECT_FAIL; if(!cgroups2_available) @@ -254,19 +256,19 @@ static enum cgroups_type cgroups_try_detect_version() // 4. if we are unified as on Fedora (default cgroups2 only mode) // check kernel command line flag that can override that setting - f = fopen("/proc/cmdline", "r"); - if (!f) { + FILE *fp = fopen("/proc/cmdline", "r"); + if (!fp) { error("Error reading kernel boot commandline parameters"); return CGROUPS_AUTODETECT_FAIL; } - if (!fgets(buf, MAXSIZE_PROC_CMDLINE, f)) { + if (!fgets(buf, MAXSIZE_PROC_CMDLINE, fp)) { error("couldn't read all cmdline params into buffer"); - fclose(f); + fclose(fp); return CGROUPS_AUTODETECT_FAIL; } - fclose(f); + fclose(fp); if (strstr(buf, "systemd.unified_cgroup_hierarchy=0")) { info("cgroups v2 (unified cgroups) is available but are disabled on this system."); @@ -1665,16 +1667,16 @@ static inline void read_cgroup_network_interfaces(struct cgroup *cg) { } debug(D_CGROUP, "executing cgroup_identifier %s --cgroup '%s' for cgroup '%s'", cgroups_network_interface_script, cgroup_identifier, cg->id); - FILE *fp; - (void)mypopen_raw_default_flags_and_environment(&cgroup_pid, &fp, cgroups_network_interface_script, "--cgroup", cgroup_identifier); - if(!fp) { + FILE *fp_child_input, *fp_child_output; + (void)netdata_popen_raw_default_flags_and_environment(&cgroup_pid, &fp_child_input, &fp_child_output, cgroups_network_interface_script, "--cgroup", cgroup_identifier); + if(!fp_child_output) { error("CGROUP: cannot popen(%s --cgroup \"%s\", \"r\").", cgroups_network_interface_script, cgroup_identifier); return; } char *s; char buffer[CGROUP_NETWORK_INTERFACE_MAX_LINE + 1]; - while((s = fgets(buffer, CGROUP_NETWORK_INTERFACE_MAX_LINE, fp))) { + while((s = fgets(buffer, CGROUP_NETWORK_INTERFACE_MAX_LINE, fp_child_output))) { trim(s); if(*s && *s != '\n') { @@ -1709,7 +1711,7 @@ static inline void read_cgroup_network_interfaces(struct cgroup *cg) { } } - mypclose(fp, cgroup_pid); + netdata_pclose(fp_child_input, fp_child_output, cgroup_pid); // debug(D_CGROUP, "closed cgroup_identifier for cgroup '%s'", cg->id); } @@ -1871,9 +1873,9 @@ static inline void discovery_rename_cgroup(struct cgroup *cg) { debug(D_CGROUP, "executing command %s \"%s\" for cgroup '%s'", cgroups_rename_script, cg->intermediate_id, cg->chart_id); pid_t cgroup_pid; - FILE *fp; - (void)mypopen_raw_default_flags_and_environment(&cgroup_pid, &fp, cgroups_rename_script, cg->id, cg->intermediate_id); - if (!fp) { + FILE *fp_child_input, *fp_child_output; + (void)netdata_popen_raw_default_flags_and_environment(&cgroup_pid, &fp_child_input, &fp_child_output, cgroups_rename_script, cg->id, cg->intermediate_id); + if (!fp_child_output) { error("CGROUP: cannot popen(%s \"%s\", \"r\").", cgroups_rename_script, cg->intermediate_id); cg->pending_renames = 0; cg->processed = 1; @@ -1881,8 +1883,8 @@ static inline void discovery_rename_cgroup(struct cgroup *cg) { } char buffer[CGROUP_CHARTID_LINE_MAX + 1]; - char *new_name = fgets(buffer, CGROUP_CHARTID_LINE_MAX, fp); - int exit_code = mypclose(fp, cgroup_pid); + char *new_name = fgets(buffer, CGROUP_CHARTID_LINE_MAX, fp_child_output); + int exit_code = netdata_pclose(fp_child_input, fp_child_output, cgroup_pid); switch (exit_code) { case 0: |