diff options
Diffstat (limited to 'collectors/apps.plugin')
-rw-r--r-- | collectors/apps.plugin/apps_plugin.c | 851 | ||||
-rw-r--r-- | collectors/apps.plugin/metrics.csv | 160 | ||||
-rw-r--r-- | collectors/apps.plugin/multi_metadata.yaml | 662 |
3 files changed, 1383 insertions, 290 deletions
diff --git a/collectors/apps.plugin/apps_plugin.c b/collectors/apps.plugin/apps_plugin.c index 3132b2243..105c54262 100644 --- a/collectors/apps.plugin/apps_plugin.c +++ b/collectors/apps.plugin/apps_plugin.c @@ -2,7 +2,7 @@ /* * netdata apps.plugin - * (C) Copyright 2016-2017 Costa Tsaousis <costa@tsaousis.gr> + * (C) Copyright 2023 Netdata Inc. * Released under GPL v3+ */ @@ -106,6 +106,7 @@ static int enable_file_charts = 1, max_fds_cache_seconds = 60, #endif + enable_function_cmdline = 0, enable_detailed_uptime_charts = 0, enable_users_charts = 1, enable_groups_charts = 1, @@ -140,6 +141,17 @@ static const char *proc_states[] = { // internal flags // handled in code (automatically set) +// log each problem once per process +// log flood protection flags (log_thrown) +typedef enum __attribute__((packed)) { + PID_LOG_IO = (1 << 0), + PID_LOG_STATUS = (1 << 1), + PID_LOG_CMDLINE = (1 << 2), + PID_LOG_FDS = (1 << 3), + PID_LOG_STAT = (1 << 4), + PID_LOG_LIMITS = (1 << 5), +} PID_LOG; + static int show_guest_time = 0, // 1 when guest values are collected show_guest_time_old = 0, @@ -168,7 +180,7 @@ static size_t // the metrics. This results in utilization that exceeds the total utilization // of the system. // -// With normalization we align the per-process utilization, to the total of +// During normalization, we align the per-process utilization, to the total of // the system. We first consume the exited children utilization and it the // collected values is above the total, we proportionally scale each reported // metric. @@ -210,6 +222,27 @@ struct openfds { kernel_uint_t other; }; +#define pid_openfds_sum(p) ((p)->openfds.files + (p)->openfds.pipes + (p)->openfds.sockets + (p)->openfds.inotifies + (p)->openfds.eventfds + (p)->openfds.timerfds + (p)->openfds.signalfds + (p)->openfds.eventpolls + (p)->openfds.other) + +struct pid_limits { +// kernel_uint_t max_cpu_time; +// kernel_uint_t max_file_size; +// kernel_uint_t max_data_size; +// kernel_uint_t max_stack_size; +// kernel_uint_t max_core_file_size; +// kernel_uint_t max_resident_set; +// kernel_uint_t max_processes; + kernel_uint_t max_open_files; +// kernel_uint_t max_locked_memory; +// kernel_uint_t max_address_space; +// kernel_uint_t max_file_locks; +// kernel_uint_t max_pending_signals; +// kernel_uint_t max_msgqueue_size; +// kernel_uint_t max_nice_priority; +// kernel_uint_t max_realtime_priority; +// kernel_uint_t max_realtime_timeout; +}; + // ---------------------------------------------------------------------------- // target // @@ -267,6 +300,8 @@ struct target { struct openfds openfds; + NETDATA_DOUBLE max_open_files_percent; + kernel_uint_t starttime; kernel_uint_t collected_starttime; kernel_uint_t uptime_min; @@ -317,12 +352,6 @@ struct pid_fd { struct pid_stat { int32_t pid; - char comm[MAX_COMPARE_NAME + 1]; - char *cmdline; - - uint32_t log_thrown; - - char state; int32_t ppid; // int32_t pgrp; // int32_t session; @@ -330,6 +359,11 @@ struct pid_stat { // int32_t tpgid; // uint64_t flags; + char state; + + char comm[MAX_COMPARE_NAME + 1]; + char *cmdline; + // these are raw values collected kernel_uint_t minflt_raw; kernel_uint_t cminflt_raw; @@ -414,22 +448,30 @@ struct pid_stat { kernel_uint_t io_storage_bytes_written; kernel_uint_t io_cancelled_write_bytes; + kernel_uint_t uptime; + struct pid_fd *fds; // array of fds it uses size_t fds_size; // the size of the fds array struct openfds openfds; + struct pid_limits limits; - int children_count; // number of processes directly referencing this - unsigned char keep:1; // 1 when we need to keep this process in memory even after it exited - int keeploops; // increases by 1 every time keep is 1 and updated 0 - unsigned char updated:1; // 1 when the process is currently running - unsigned char merged:1; // 1 when it has been merged to its parent - unsigned char read:1; // 1 when we have already read this process for this iteration + NETDATA_DOUBLE openfds_limits_percent; int sortlist; // higher numbers = top on the process tree // each process gets a unique number + int children_count; // number of processes directly referencing this + int keeploops; // increases by 1 every time keep is 1 and updated 0 + + PID_LOG log_thrown; + + bool keep; // true when we need to keep this process in memory even after it exited + bool updated; // true when the process is currently running + bool merged; // true when it has been merged to its parent + bool read; // true when we have already read this process for this iteration bool matched_by_config; + struct target *target; // app_groups.conf targets struct target *user_target; // uid based targets struct target *group_target; // gid based targets @@ -439,8 +481,7 @@ struct pid_stat { usec_t io_collected_usec; usec_t last_io_collected_usec; - - kernel_uint_t uptime; + usec_t last_limits_collected_usec; char *fds_dirname; // the full directory name in /proc/PID/fd @@ -448,6 +489,7 @@ struct pid_stat { char *status_filename; char *io_filename; char *cmdline_filename; + char *limits_filename; struct pid_stat *parent; struct pid_stat *prev; @@ -458,14 +500,6 @@ size_t pagesize; kernel_uint_t global_uptime; -// log each problem once per process -// log flood protection flags (log_thrown) -#define PID_LOG_IO 0x00000001 -#define PID_LOG_STATUS 0x00000002 -#define PID_LOG_CMDLINE 0x00000004 -#define PID_LOG_FDS 0x00000008 -#define PID_LOG_STAT 0x00000010 - static struct pid_stat *root_of_pids = NULL, // global list of all processes running **all_pids = NULL; // to avoid allocations, we pre-allocate @@ -524,8 +558,6 @@ static int all_files_len = 0, all_files_size = 0; -long currentmaxfds = 0; - // ---------------------------------------------------------------------------- // read users and groups from files @@ -665,7 +697,7 @@ int read_user_or_group_ids(struct user_or_group_ids *ids, struct timespec *last_ } else { if(unlikely(avl_insert(&ids->index, (avl_t *) user_or_group_id) != (void *) user_or_group_id)) { - error("INTERNAL ERROR: duplicate indexing of id during realloc"); + netdata_log_error("INTERNAL ERROR: duplicate indexing of id during realloc"); }; user_or_group_id->next = ids->root; @@ -681,7 +713,7 @@ int read_user_or_group_ids(struct user_or_group_ids *ids, struct timespec *last_ while(user_or_group_id) { if(unlikely(!user_or_group_id->updated)) { if(unlikely((struct user_or_group_id *)avl_remove(&ids->index, (avl_t *) user_or_group_id) != user_or_group_id)) - error("INTERNAL ERROR: removal of unused id from index, removed a different id"); + netdata_log_error("INTERNAL ERROR: removal of unused id from index, removed a different id"); if(prev_user_id) prev_user_id->next = user_or_group_id->next; @@ -946,7 +978,7 @@ static int read_apps_groups_conf(const char *path, const char *file) // add this target struct target *n = get_apps_groups_target(s, w, name); if(!n) { - error("Cannot create target '%s' (line %zu, word %zu)", s, line, word); + netdata_log_error("Cannot create target '%s' (line %zu, word %zu)", s, line, word); continue; } @@ -996,7 +1028,7 @@ static inline void del_pid_entry(pid_t pid) { struct pid_stat *p = all_pids[pid]; if(unlikely(!p)) { - error("attempted to free pid %d that is not allocated.", pid); + netdata_log_error("attempted to free pid %d that is not allocated.", pid); return; } @@ -1018,6 +1050,7 @@ static inline void del_pid_entry(pid_t pid) { freez(p->fds_dirname); freez(p->stat_filename); freez(p->status_filename); + freez(p->limits_filename); #ifndef __FreeBSD__ arl_free(p->status_arl); #endif @@ -1032,9 +1065,9 @@ static inline void del_pid_entry(pid_t pid) { // ---------------------------------------------------------------------------- -static inline int managed_log(struct pid_stat *p, uint32_t log, int status) { +static inline int managed_log(struct pid_stat *p, PID_LOG log, int status) { if(unlikely(!status)) { - // error("command failed log %u, errno %d", log, errno); + // netdata_log_error("command failed log %u, errno %d", log, errno); if(unlikely(debug_enabled || errno != ENOENT)) { if(unlikely(debug_enabled || !(p->log_thrown & log))) { @@ -1042,41 +1075,48 @@ static inline int managed_log(struct pid_stat *p, uint32_t log, int status) { switch(log) { case PID_LOG_IO: #ifdef __FreeBSD__ - error("Cannot fetch process %d I/O info (command '%s')", p->pid, p->comm); + netdata_log_error("Cannot fetch process %d I/O info (command '%s')", p->pid, p->comm); #else - error("Cannot process %s/proc/%d/io (command '%s')", netdata_configured_host_prefix, p->pid, p->comm); + netdata_log_error("Cannot process %s/proc/%d/io (command '%s')", netdata_configured_host_prefix, p->pid, p->comm); #endif break; case PID_LOG_STATUS: #ifdef __FreeBSD__ - error("Cannot fetch process %d status info (command '%s')", p->pid, p->comm); + netdata_log_error("Cannot fetch process %d status info (command '%s')", p->pid, p->comm); #else - error("Cannot process %s/proc/%d/status (command '%s')", netdata_configured_host_prefix, p->pid, p->comm); + netdata_log_error("Cannot process %s/proc/%d/status (command '%s')", netdata_configured_host_prefix, p->pid, p->comm); #endif break; case PID_LOG_CMDLINE: #ifdef __FreeBSD__ - error("Cannot fetch process %d command line (command '%s')", p->pid, p->comm); + netdata_log_error("Cannot fetch process %d command line (command '%s')", p->pid, p->comm); #else - error("Cannot process %s/proc/%d/cmdline (command '%s')", netdata_configured_host_prefix, p->pid, p->comm); + netdata_log_error("Cannot process %s/proc/%d/cmdline (command '%s')", netdata_configured_host_prefix, p->pid, p->comm); #endif break; case PID_LOG_FDS: #ifdef __FreeBSD__ - error("Cannot fetch process %d files (command '%s')", p->pid, p->comm); + netdata_log_error("Cannot fetch process %d files (command '%s')", p->pid, p->comm); #else - error("Cannot process entries in %s/proc/%d/fd (command '%s')", netdata_configured_host_prefix, p->pid, p->comm); + netdata_log_error("Cannot process entries in %s/proc/%d/fd (command '%s')", netdata_configured_host_prefix, p->pid, p->comm); #endif break; + case PID_LOG_LIMITS: + #ifdef __FreeBSD__ + ; + #else + netdata_log_error("Cannot process %s/proc/%d/limits (command '%s')", netdata_configured_host_prefix, p->pid, p->comm); + #endif + case PID_LOG_STAT: break; default: - error("unhandled error for pid %d, command '%s'", p->pid, p->comm); + netdata_log_error("unhandled error for pid %d, command '%s'", p->pid, p->comm); break; } } @@ -1084,7 +1124,7 @@ static inline int managed_log(struct pid_stat *p, uint32_t log, int status) { errno = 0; } else if(unlikely(p->log_thrown & log)) { - // error("unsetting log %u on pid %d", log, p->pid); + // netdata_log_error("unsetting log %u on pid %d", log, p->pid); p->log_thrown &= ~log; } @@ -1276,8 +1316,7 @@ void arl_callback_status_voluntary_ctxt_switches(const char *name, uint32_t hash if(unlikely(procfile_linewords(aptr->ff, aptr->line) < 2)) return; struct pid_stat *p = aptr->p; - pid_incremental_rate( - stat, p->status_voluntary_ctxt_switches, str2kernel_uint_t(procfile_lineword(aptr->ff, aptr->line, 1))); + pid_incremental_rate(stat, p->status_voluntary_ctxt_switches, str2kernel_uint_t(procfile_lineword(aptr->ff, aptr->line, 1))); } void arl_callback_status_nonvoluntary_ctxt_switches(const char *name, uint32_t hash, const char *value, void *dst) { @@ -1286,8 +1325,7 @@ void arl_callback_status_nonvoluntary_ctxt_switches(const char *name, uint32_t h if(unlikely(procfile_linewords(aptr->ff, aptr->line) < 2)) return; struct pid_stat *p = aptr->p; - pid_incremental_rate( - stat, p->status_nonvoluntary_ctxt_switches, str2kernel_uint_t(procfile_lineword(aptr->ff, aptr->line, 1))); + pid_incremental_rate(stat, p->status_nonvoluntary_ctxt_switches, str2kernel_uint_t(procfile_lineword(aptr->ff, aptr->line, 1))); } static void update_proc_state_count(char proc_state) { @@ -1313,6 +1351,64 @@ static void update_proc_state_count(char proc_state) { } #endif // !__FreeBSD__ +#define MAX_PROC_PID_LIMITS 8192 +#define PROC_PID_LIMITS_MAX_OPEN_FILES_KEY "\nMax open files " + +static inline kernel_uint_t get_proc_pid_limits_limit(char *buf, const char *key, size_t key_len, kernel_uint_t def) { + char *line = strstr(buf, key); + if(!line) + return def; + + char *v = &line[key_len]; + while(isspace(*v)) v++; + + return str2ull(v, NULL); +} + +static inline int read_proc_pid_limits(struct pid_stat *p, void *ptr) { + (void)ptr; + +#ifdef __FreeBSD__ + return 0; +#else + static char proc_pid_limits_buffer[MAX_PROC_PID_LIMITS + 1]; + int ret = 0; + + kernel_uint_t all_fds = pid_openfds_sum(p); + if(all_fds < p->limits.max_open_files / 2 && p->io_collected_usec > p->last_limits_collected_usec && p->io_collected_usec - p->last_limits_collected_usec <= 60 * USEC_PER_SEC) + // too frequent, we want to collect limits once per minute + goto cleanup; + + if(unlikely(!p->limits_filename)) { + char filename[FILENAME_MAX + 1]; + snprintfz(filename, FILENAME_MAX, "%s/proc/%d/limits", netdata_configured_host_prefix, p->pid); + p->limits_filename = strdupz(filename); + } + + int fd = open(p->limits_filename, procfile_open_flags, 0666); + if(unlikely(fd == -1)) goto cleanup; + + ssize_t bytes = read(fd, proc_pid_limits_buffer, MAX_PROC_PID_LIMITS); + close(fd); + + if(bytes <= 0) + goto cleanup; + + p->limits.max_open_files = get_proc_pid_limits_limit(proc_pid_limits_buffer, PROC_PID_LIMITS_MAX_OPEN_FILES_KEY, sizeof(PROC_PID_LIMITS_MAX_OPEN_FILES_KEY) - 1, 0); + p->last_limits_collected_usec = p->io_collected_usec; + + ret = 1; + +cleanup: + if(p->limits.max_open_files) + p->openfds_limits_percent = (NETDATA_DOUBLE)all_fds * 100.0 / (NETDATA_DOUBLE)p->limits.max_open_files; + else + p->openfds_limits_percent = 0.0; + + return ret; +#endif +} + static inline int read_proc_pid_status(struct pid_stat *p, void *ptr) { p->status_vmsize = 0; p->status_vmrss = 0; @@ -1470,7 +1566,7 @@ static inline int read_proc_pid_stat(struct pid_stat *p, void *ptr) { if(enable_guest_charts) { enable_guest_charts = 0; - info("Guest charts aren't supported by FreeBSD"); + netdata_log_info("Guest charts aren't supported by FreeBSD"); } #else pid_incremental_rate(stat, p->minflt, str2kernel_uint_t(procfile_lineword(ff, 0, 9))); @@ -1732,7 +1828,7 @@ cleanup: int file_descriptor_compare(void* a, void* b) { #ifdef NETDATA_INTERNAL_CHECKS if(((struct file_descriptor *)a)->magic != 0x0BADCAFE || ((struct file_descriptor *)b)->magic != 0x0BADCAFE) - error("Corrupted index data detected. Please report this."); + netdata_log_error("Corrupted index data detected. Please report this."); #endif /* NETDATA_INTERNAL_CHECKS */ if(((struct file_descriptor *)a)->hash < ((struct file_descriptor *)b)->hash) @@ -1776,7 +1872,7 @@ static inline void file_descriptor_not_used(int id) #ifdef NETDATA_INTERNAL_CHECKS if(all_files[id].magic != 0x0BADCAFE) { - error("Ignoring request to remove empty file id %d.", id); + netdata_log_error("Ignoring request to remove empty file id %d.", id); return; } #endif /* NETDATA_INTERNAL_CHECKS */ @@ -1790,7 +1886,7 @@ static inline void file_descriptor_not_used(int id) debug_log(" >> slot %d is empty.", id); if(unlikely(file_descriptor_remove(&all_files[id]) != (void *)&all_files[id])) - error("INTERNAL ERROR: removal of unused fd from index, removed a different fd"); + netdata_log_error("INTERNAL ERROR: removal of unused fd from index, removed a different fd"); #ifdef NETDATA_INTERNAL_CHECKS all_files[id].magic = 0x00000000; @@ -1799,9 +1895,14 @@ static inline void file_descriptor_not_used(int id) } } else - error("Request to decrease counter of fd %d (%s), while the use counter is 0", id, all_files[id].name); + netdata_log_error("Request to decrease counter of fd %d (%s), while the use counter is 0", + id, + all_files[id].name); } - else error("Request to decrease counter of fd %d, which is outside the array size (1 to %d)", id, all_files_size); + else + netdata_log_error("Request to decrease counter of fd %d, which is outside the array size (1 to %d)", + id, + all_files_size); } static inline void all_files_grow() { @@ -1823,7 +1924,7 @@ static inline void all_files_grow() { for(i = 0; i < all_files_size; i++) { if(!all_files[i].count) continue; if(unlikely(file_descriptor_add(&all_files[i]) != (void *)&all_files[i])) - error("INTERNAL ERROR: duplicate indexing of fd during realloc."); + netdata_log_error("INTERNAL ERROR: duplicate indexing of fd during realloc."); } debug_log(" >> re-indexing done."); @@ -1864,7 +1965,7 @@ static inline int file_descriptor_set_on_empty_slot(const char *name, uint32_t h #ifdef NETDATA_INTERNAL_CHECKS if(all_files[c].magic == 0x0BADCAFE && all_files[c].name && file_descriptor_find(all_files[c].name, all_files[c].hash)) - error("fd on position %d is not cleared properly. It still has %s in it.", c, all_files[c].name); + netdata_log_error("fd on position %d is not cleared properly. It still has %s in it.", c, all_files[c].name); #endif /* NETDATA_INTERNAL_CHECKS */ debug_log(" >> %s fd position %d for %s (last name: %s)", all_files[c].name?"re-using":"using", c, name, all_files[c].name); @@ -1895,7 +1996,7 @@ static inline int file_descriptor_set_on_empty_slot(const char *name, uint32_t h all_files[c].magic = 0x0BADCAFE; #endif /* NETDATA_INTERNAL_CHECKS */ if(unlikely(file_descriptor_add(&all_files[c]) != (void *)&all_files[c])) - error("INTERNAL ERROR: duplicate indexing of fd."); + netdata_log_error("INTERNAL ERROR: duplicate indexing of fd."); debug_log("using fd position %d (name: %s)", c, all_files[c].name); @@ -2013,13 +2114,13 @@ static inline int read_pid_file_descriptors(struct pid_stat *p, void *ptr) { mib[3] = p->pid; if (unlikely(sysctl(mib, 4, NULL, &size, NULL, 0))) { - error("sysctl error: Can't get file descriptors data size for pid %d", p->pid); + netdata_log_error("sysctl error: Can't get file descriptors data size for pid %d", p->pid); return 0; } if (likely(size > 0)) fdsbuf = reallocz(fdsbuf, size); if (unlikely(sysctl(mib, 4, fdsbuf, &size, NULL, 0))) { - error("sysctl error: Can't get file descriptors data for pid %d", p->pid); + netdata_log_error("sysctl error: Can't get file descriptors data for pid %d", p->pid); return 0; } @@ -2192,7 +2293,7 @@ static inline int read_pid_file_descriptors(struct pid_stat *p, void *ptr) { // cannot read the link if(debug_enabled || (p->target && p->target->debug_enabled)) - error("Cannot read link %s", p->fds[fdid].filename); + netdata_log_error("Cannot read link %s", p->fds[fdid].filename); if(unlikely(p->fds[fdid].fd < 0)) { file_descriptor_not_used(-p->fds[fdid].fd); @@ -2454,7 +2555,7 @@ static inline void process_exited_processes() { if(majflt) debug_find_lost_child(p, majflt, 2); } - p->keep = 1; + p->keep = true; debug_log(" > remaining resources - KEEP - for another loop: %s (%d %s total resources: utime=" KERNEL_UINT_FORMAT " stime=" KERNEL_UINT_FORMAT " gtime=" KERNEL_UINT_FORMAT " minflt=" KERNEL_UINT_FORMAT " majflt=" KERNEL_UINT_FORMAT ")" , p->comm @@ -2469,7 +2570,7 @@ static inline void process_exited_processes() { for(pp = p->parent; pp ; pp = pp->parent) { if(pp->updated) break; - pp->keep = 1; + pp->keep = true; debug_log(" > - KEEP - parent for another loop: %s (%d %s)" , pp->comm @@ -2523,7 +2624,7 @@ static inline void link_all_processes_to_their_parents(void) { } else { p->parent = NULL; - error("pid %d %s states parent %d, but the later does not exist.", p->pid, p->comm, p->ppid); + netdata_log_error("pid %d %s states parent %d, but the later does not exist.", p->pid, p->comm, p->ppid); } } } @@ -2561,13 +2662,13 @@ static int compar_pid(const void *pid1, const void *pid2) { static inline int collect_data_for_pid(pid_t pid, void *ptr) { if(unlikely(pid < 0 || pid > pid_max)) { - error("Invalid pid %d read (expected %d to %d). Ignoring process.", pid, 0, pid_max); + netdata_log_error("Invalid pid %d read (expected %d to %d). Ignoring process.", pid, 0, pid_max); return 0; } struct pid_stat *p = get_pid_entry(pid); if(unlikely(!p || p->read)) return 0; - p->read = 1; + p->read = true; // debug_log("Reading process %d (%s), sortlist %d", p->pid, p->comm, p->sortlist); @@ -2580,7 +2681,7 @@ static inline int collect_data_for_pid(pid_t pid, void *ptr) { // check its parent pid if(unlikely(p->ppid < 0 || p->ppid > pid_max)) { - error("Pid %d (command '%s') states invalid parent pid %d. Using 0.", pid, p->comm, p->ppid); + netdata_log_error("Pid %d (command '%s') states invalid parent pid %d. Using 0.", pid, p->comm, p->ppid); p->ppid = 0; } @@ -2599,8 +2700,10 @@ static inline int collect_data_for_pid(pid_t pid, void *ptr) { // -------------------------------------------------------------------- // /proc/<pid>/fd - if(enable_file_charts) - managed_log(p, PID_LOG_FDS, read_pid_file_descriptors(p, ptr)); + if(enable_file_charts) { + managed_log(p, PID_LOG_FDS, read_pid_file_descriptors(p, ptr)); + managed_log(p, PID_LOG_LIMITS, read_proc_pid_limits(p, ptr)); + } // -------------------------------------------------------------------- // done! @@ -2609,8 +2712,8 @@ static inline int collect_data_for_pid(pid_t pid, void *ptr) { debug_log("Read process %d (%s) sortlisted %d, but its parent %d (%s) sortlisted %d, is not read", p->pid, p->comm, p->sortlist, all_pids[p->ppid]->pid, all_pids[p->ppid]->comm, all_pids[p->ppid]->sortlist); // mark it as updated - p->updated = 1; - p->keep = 0; + p->updated = true; + p->keep = false; p->keeploops = 0; return 1; @@ -2632,7 +2735,7 @@ static int collect_data_for_all_processes(void) { int mib[3] = { CTL_KERN, KERN_PROC, KERN_PROC_PROC }; if (unlikely(sysctl(mib, 3, NULL, &new_procbase_size, NULL, 0))) { - error("sysctl error: Can't get processes data size"); + netdata_log_error("sysctl error: Can't get processes data size"); return 0; } @@ -2652,7 +2755,7 @@ static int collect_data_for_all_processes(void) { // get the processes from the system if (unlikely(sysctl(mib, 3, procbase, &new_procbase_size, NULL, 0))) { - error("sysctl error: Can't get processes data"); + netdata_log_error("sysctl error: Can't get processes data"); return 0; } @@ -2667,9 +2770,9 @@ static int collect_data_for_all_processes(void) { size_t slc = 0; #endif for(p = root_of_pids; p ; p = p->next) { - p->read = 0; // mark it as not read, so that collect_data_for_pid() will read it - p->updated = 0; - p->merged = 0; + p->read = false; // mark it as not read, so that collect_data_for_pid() will read it + p->updated = false; + p->merged = false; p->children_count = 0; p->parent = NULL; @@ -2680,7 +2783,7 @@ static int collect_data_for_all_processes(void) { #if (ALL_PIDS_ARE_READ_INSTANTLY == 0) if(unlikely(slc != all_pids_count)) { - error("Internal error: I was thinking I had %zu processes in my arrays, but it seems there are %zu.", all_pids_count, slc); + netdata_log_error("Internal error: I was thinking I had %zu processes in my arrays, but it seems there are %zu.", all_pids_count, slc); all_pids_count = slc; } @@ -2795,7 +2898,7 @@ static void cleanup_exited_pids(void) { } else { if(unlikely(p->keep)) p->keeploops++; - p->keep = 0; + p->keep = false; p = p->next; } } @@ -2811,7 +2914,7 @@ static void apply_apps_groups_targets_inheritance(void) { if(unlikely(debug_enabled)) loops++; found = 0; for(p = root_of_pids; p ; p = p->next) { - // if this process does not have a target + // if this process does not have a target, // and it has a parent // and its parent has a target // then, set the parent's target to this process @@ -2849,7 +2952,7 @@ static void apply_apps_groups_targets_inheritance(void) { )) { // mark it as merged p->parent->children_count--; - p->merged = 1; + p->merged = true; // the parent inherits the child's target, if it does not have a target itself if(unlikely(p->target && !p->parent->target)) { @@ -2878,7 +2981,7 @@ static void apply_apps_groups_targets_inheritance(void) { if(unlikely(debug_enabled)) loops++; for(p = root_of_pids; p ; p = p->next) { // if the process is not merged itself - // then is is a top level process + // then it is a top level process if(unlikely(!p->merged && !p->target)) p->target = apps_groups_default_target; @@ -2959,6 +3062,8 @@ static size_t zero_all_targets(struct target *root) { w->openfds.signalfds = 0; w->openfds.eventpolls = 0; w->openfds.other = 0; + + w->max_open_files_percent = 0.0; } w->collected_starttime = 0; @@ -3090,9 +3195,6 @@ static inline void aggregate_pid_fds_on_targets(struct pid_stat *p) { aggregate_fd_on_target(fd, u); aggregate_fd_on_target(fd, g); } - - if (currentfds >= currentmaxfds) - currentmaxfds = currentfds; } static inline void aggregate_pid_on_target(struct target *w, struct pid_stat *p, struct target *o) { @@ -3104,10 +3206,13 @@ static inline void aggregate_pid_on_target(struct target *w, struct pid_stat *p, } if(unlikely(!w)) { - error("pid %d %s was left without a target!", p->pid, p->comm); + netdata_log_error("pid %d %s was left without a target!", p->pid, p->comm); return; } + if(p->openfds_limits_percent > w->max_open_files_percent) + w->max_open_files_percent = p->openfds_limits_percent; + w->cutime += p->cutime; w->cstime += p->cstime; w->cgtime += p->cgtime; @@ -3712,30 +3817,82 @@ static void send_collected_data_to_netdata(struct target *root, const char *type send_END(); if(enable_file_charts) { - send_BEGIN(type, "files", dt); + send_BEGIN(type, "fds_open_limit", dt); for (w = root; w; w = w->next) { if (unlikely(w->exposed && w->processes)) - send_SET(w->name, w->openfds.files); + send_SET(w->name, w->max_open_files_percent * 100.0); } - if (!strcmp("apps", type)){ - kernel_uint_t usedfdpercentage = (kernel_uint_t) ((currentmaxfds * 100) / sysconf(_SC_OPEN_MAX)); - fprintf(stdout, "VARIABLE fdperc = " KERNEL_UINT_FORMAT "\n", usedfdpercentage); + send_END(); + + send_BEGIN(type, "fds_open", dt); + for (w = root; w; w = w->next) { + if (unlikely(w->exposed && w->processes)) + send_SET(w->name, pid_openfds_sum(w)); } send_END(); - send_BEGIN(type, "sockets", dt); + send_BEGIN(type, "fds_files", dt); + for (w = root; w; w = w->next) { + if (unlikely(w->exposed && w->processes)) + send_SET(w->name, w->openfds.files); + } + send_END(); + + send_BEGIN(type, "fds_sockets", dt); for (w = root; w; w = w->next) { if (unlikely(w->exposed && w->processes)) send_SET(w->name, w->openfds.sockets); } send_END(); - send_BEGIN(type, "pipes", dt); + send_BEGIN(type, "fds_pipes", dt); for (w = root; w; w = w->next) { if (unlikely(w->exposed && w->processes)) send_SET(w->name, w->openfds.pipes); } send_END(); + + send_BEGIN(type, "fds_inotifies", dt); + for (w = root; w; w = w->next) { + if (unlikely(w->exposed && w->processes)) + send_SET(w->name, w->openfds.inotifies); + } + send_END(); + + send_BEGIN(type, "fds_eventfds", dt); + for (w = root; w; w = w->next) { + if (unlikely(w->exposed && w->processes)) + send_SET(w->name, w->openfds.eventfds); + } + send_END(); + + send_BEGIN(type, "fds_timerfds", dt); + for (w = root; w; w = w->next) { + if (unlikely(w->exposed && w->processes)) + send_SET(w->name, w->openfds.timerfds); + } + send_END(); + + send_BEGIN(type, "fds_signalfds", dt); + for (w = root; w; w = w->next) { + if (unlikely(w->exposed && w->processes)) + send_SET(w->name, w->openfds.signalfds); + } + send_END(); + + send_BEGIN(type, "fds_eventpolls", dt); + for (w = root; w; w = w->next) { + if (unlikely(w->exposed && w->processes)) + send_SET(w->name, w->openfds.eventpolls); + } + send_END(); + + send_BEGIN(type, "fds_other", dt); + for (w = root; w; w = w->next) { + if (unlikely(w->exposed && w->processes)) + send_SET(w->name, w->openfds.other); + } + send_END(); } } @@ -3958,7 +4115,23 @@ static void send_charts_updates_to_netdata(struct target *root, const char *type #endif if(enable_file_charts) { - fprintf(stdout, "CHART %s.files '' '%s Open Files' 'open files' disk %s.files stacked 20050 %d\n", type, + fprintf(stdout, "CHART %s.fds_open_limit '' '%s Open File Descriptors Limit' '%%' fds %s.fds_open_limit line 20050 %d\n", type, + title, type, update_every); + for (w = root; w; w = w->next) { + if (unlikely(w->exposed)) + fprintf(stdout, "DIMENSION %s '' absolute 1 100\n", w->name); + } + APPS_PLUGIN_FUNCTIONS(); + + fprintf(stdout, "CHART %s.fds_open '' '%s Open File Descriptors' 'fds' fds %s.fds_open stacked 20051 %d\n", type, + title, type, update_every); + for (w = root; w; w = w->next) { + if (unlikely(w->exposed)) + fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name); + } + APPS_PLUGIN_FUNCTIONS(); + + fprintf(stdout, "CHART %s.fds_files '' '%s Open Files' 'fds' fds %s.fds_files stacked 20052 %d\n", type, title, type, update_every); for (w = root; w; w = w->next) { if (unlikely(w->exposed)) @@ -3966,7 +4139,7 @@ static void send_charts_updates_to_netdata(struct target *root, const char *type } APPS_PLUGIN_FUNCTIONS(); - fprintf(stdout, "CHART %s.sockets '' '%s Open Sockets' 'open sockets' net %s.sockets stacked 20051 %d\n", + fprintf(stdout, "CHART %s.fds_sockets '' '%s Open Sockets' 'fds' fds %s.fds_sockets stacked 20053 %d\n", type, title, type, update_every); for (w = root; w; w = w->next) { if (unlikely(w->exposed)) @@ -3974,13 +4147,61 @@ static void send_charts_updates_to_netdata(struct target *root, const char *type } APPS_PLUGIN_FUNCTIONS(); - fprintf(stdout, "CHART %s.pipes '' '%s Pipes' 'open pipes' processes %s.pipes stacked 20053 %d\n", type, + fprintf(stdout, "CHART %s.fds_pipes '' '%s Pipes' 'fds' fds %s.fds_pipes stacked 20054 %d\n", type, title, type, update_every); for (w = root; w; w = w->next) { if (unlikely(w->exposed)) fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name); } APPS_PLUGIN_FUNCTIONS(); + + fprintf(stdout, "CHART %s.fds_inotifies '' '%s iNotify File Descriptors' 'fds' fds %s.fds_inotifies stacked 20055 %d\n", type, + title, type, update_every); + for (w = root; w; w = w->next) { + if (unlikely(w->exposed)) + fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name); + } + APPS_PLUGIN_FUNCTIONS(); + + fprintf(stdout, "CHART %s.fds_eventfds '' '%s Event File Descriptors' 'fds' fds %s.fds_eventfds stacked 20056 %d\n", type, + title, type, update_every); + for (w = root; w; w = w->next) { + if (unlikely(w->exposed)) + fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name); + } + APPS_PLUGIN_FUNCTIONS(); + + fprintf(stdout, "CHART %s.fds_timerfds '' '%s Timer File Descriptors' 'fds' fds %s.fds_timerfds stacked 20057 %d\n", type, + title, type, update_every); + for (w = root; w; w = w->next) { + if (unlikely(w->exposed)) + fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name); + } + APPS_PLUGIN_FUNCTIONS(); + + fprintf(stdout, "CHART %s.fds_signalfds '' '%s Signal File Descriptors' 'fds' fds %s.fds_signalfds stacked 20058 %d\n", type, + title, type, update_every); + for (w = root; w; w = w->next) { + if (unlikely(w->exposed)) + fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name); + } + APPS_PLUGIN_FUNCTIONS(); + + fprintf(stdout, "CHART %s.fds_eventpolls '' '%s Event Poll File Descriptors' 'fds' fds %s.fds_eventpolls stacked 20059 %d\n", type, + title, type, update_every); + for (w = root; w; w = w->next) { + if (unlikely(w->exposed)) + fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name); + } + APPS_PLUGIN_FUNCTIONS(); + + fprintf(stdout, "CHART %s.fds_other '' '%s Other File Descriptors' 'fds' fds %s.fds_other stacked 20060 %d\n", type, + title, type, update_every); + for (w = root; w; w = w->next) { + if (unlikely(w->exposed)) + fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name); + } + APPS_PLUGIN_FUNCTIONS(); } } @@ -4122,6 +4343,10 @@ static void parse_args(int argc, char **argv) enable_detailed_uptime_charts = 1; continue; } + if(strcmp("with-function-cmdline", argv[i]) == 0) { + enable_function_cmdline = 1; + continue; + } if(strcmp("-h", argv[i]) == 0 || strcmp("--help", argv[i]) == 0) { fprintf(stderr, @@ -4139,6 +4364,11 @@ static void parse_args(int argc, char **argv) "\n" " debug enable debugging (lot of output)\n" "\n" + " with-function-cmdline enable reporting the complete command line for processes\n" + " it includes the command and passed arguments\n" + " it may include sensitive data such as passwords and tokens\n" + " enabling this could be a security risk\n" + "\n" " with-childs\n" " without-childs enable / disable aggregating exited\n" " children resources into parents\n" @@ -4177,35 +4407,35 @@ static void parse_args(int argc, char **argv) exit(1); } - error("Cannot understand option %s", argv[i]); + netdata_log_error("Cannot understand option %s", argv[i]); exit(1); } if(freq > 0) update_every = freq; if(read_apps_groups_conf(user_config_dir, "groups")) { - info("Cannot read process groups configuration file '%s/apps_groups.conf'. Will try '%s/apps_groups.conf'", user_config_dir, stock_config_dir); + netdata_log_info("Cannot read process groups configuration file '%s/apps_groups.conf'. Will try '%s/apps_groups.conf'", user_config_dir, stock_config_dir); if(read_apps_groups_conf(stock_config_dir, "groups")) { - error("Cannot read process groups '%s/apps_groups.conf'. There are no internal defaults. Failing.", stock_config_dir); + netdata_log_error("Cannot read process groups '%s/apps_groups.conf'. There are no internal defaults. Failing.", stock_config_dir); exit(1); } else - info("Loaded config file '%s/apps_groups.conf'", stock_config_dir); + netdata_log_info("Loaded config file '%s/apps_groups.conf'", stock_config_dir); } else - info("Loaded config file '%s/apps_groups.conf'", user_config_dir); + netdata_log_info("Loaded config file '%s/apps_groups.conf'", user_config_dir); } static int am_i_running_as_root() { uid_t uid = getuid(), euid = geteuid(); if(uid == 0 || euid == 0) { - if(debug_enabled) info("I am running with escalated privileges, uid = %u, euid = %u.", uid, euid); + if(debug_enabled) netdata_log_info("I am running with escalated privileges, uid = %u, euid = %u.", uid, euid); return 1; } - if(debug_enabled) info("I am not running with escalated privileges, uid = %u, euid = %u.", uid, euid); + if(debug_enabled) netdata_log_info("I am not running with escalated privileges, uid = %u, euid = %u.", uid, euid); return 0; } @@ -4213,40 +4443,40 @@ static int am_i_running_as_root() { static int check_capabilities() { cap_t caps = cap_get_proc(); if(!caps) { - error("Cannot get current capabilities."); + netdata_log_error("Cannot get current capabilities."); return 0; } else if(debug_enabled) - info("Received my capabilities from the system."); + netdata_log_info("Received my capabilities from the system."); 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."); + netdata_log_error("Cannot find if CAP_DAC_READ_SEARCH is effective."); ret = 0; } else { if(cfv != CAP_SET) { - error("apps.plugin should run with CAP_DAC_READ_SEARCH."); + netdata_log_error("apps.plugin should run with CAP_DAC_READ_SEARCH."); ret = 0; } else if(debug_enabled) - info("apps.plugin runs with CAP_DAC_READ_SEARCH."); + netdata_log_info("apps.plugin runs with CAP_DAC_READ_SEARCH."); } cfv = CAP_CLEAR; if(cap_get_flag(caps, CAP_SYS_PTRACE, CAP_EFFECTIVE, &cfv) == -1) { - error("Cannot find if CAP_SYS_PTRACE is effective."); + netdata_log_error("Cannot find if CAP_SYS_PTRACE is effective."); ret = 0; } else { if(cfv != CAP_SET) { - error("apps.plugin should run with CAP_SYS_PTRACE."); + netdata_log_error("apps.plugin should run with CAP_SYS_PTRACE."); ret = 0; } else if(debug_enabled) - info("apps.plugin runs with CAP_SYS_PTRACE."); + netdata_log_info("apps.plugin runs with CAP_SYS_PTRACE."); } cap_free(caps); @@ -4356,32 +4586,6 @@ static void apps_plugin_function_processes_help(const char *transaction) { pluginsd_function_result_end_to_stdout(); } -#define add_table_field(wb, key, name, visible, type, visualization, transform, decimal_points, units, max, sort, sortable, sticky, unique_key, pointer_to, summary, range) do { \ - buffer_json_member_add_object(wb, key); \ - buffer_json_member_add_uint64(wb, "index", fields_added); \ - buffer_json_member_add_boolean(wb, "unique_key", unique_key); \ - buffer_json_member_add_string(wb, "name", name); \ - buffer_json_member_add_boolean(wb, "visible", visible); \ - buffer_json_member_add_string(wb, "type", type); \ - buffer_json_member_add_string_or_omit(wb, "units", (char*)(units)); \ - buffer_json_member_add_string(wb, "visualization", visualization); \ - buffer_json_member_add_object(wb, "value_options"); \ - buffer_json_member_add_string_or_omit(wb, "units", (char*)(units)); \ - buffer_json_member_add_string(wb, "transform", transform); \ - buffer_json_member_add_uint64(wb, "decimal_points", decimal_points); \ - buffer_json_object_close(wb); \ - if(!isnan((NETDATA_DOUBLE)(max))) \ - buffer_json_member_add_double(wb, "max", (NETDATA_DOUBLE)(max)); \ - buffer_json_member_add_string_or_omit(wb, "pointer_to", (char *)(pointer_to)); \ - buffer_json_member_add_string(wb, "sort", sort); \ - buffer_json_member_add_boolean(wb, "sortable", sortable); \ - buffer_json_member_add_boolean(wb, "sticky", sticky); \ - buffer_json_member_add_string(wb, "summary", summary); \ - buffer_json_member_add_string(wb, "filter", (range)?"range":"multiselect"); \ - buffer_json_object_close(wb); \ - fields_added++; \ -} while(0) - #define add_value_field_llu_with_max(wb, key, value) do { \ unsigned long long _tmp = (value); \ key ## _max = (rows == 0) ? (_tmp) : MAX(key ## _max, _tmp); \ @@ -4398,7 +4602,7 @@ static void apps_plugin_function_processes(const char *transaction, char *functi struct pid_stat *p; char *words[PLUGINSD_MAX_WORDS] = { NULL }; - size_t num_words = pluginsd_split_words(function, words, PLUGINSD_MAX_WORDS); + size_t num_words = quoted_strings_splitter_pluginsd(function, words, PLUGINSD_MAX_WORDS); struct target *category = NULL, *user = NULL, *group = NULL; const char *process_name = NULL; @@ -4488,6 +4692,7 @@ static void apps_plugin_function_processes(const char *transaction, char *functi , Shared_max = 0.0 , Swap_max = 0.0 , Memory_max = 0.0 + , FDsLimitPercent_max = 0.0 ; unsigned long long @@ -4553,7 +4758,7 @@ static void apps_plugin_function_processes(const char *transaction, char *functi rows++; - buffer_json_add_array_item_array(wb); + buffer_json_add_array_item_array(wb); // for each pid // IMPORTANT! // THE ORDER SHOULD BE THE SAME WITH THE FIELDS! @@ -4564,10 +4769,10 @@ static void apps_plugin_function_processes(const char *transaction, char *functi // cmd buffer_json_add_array_item_string(wb, p->comm); -#ifdef NETDATA_DEV_MODE // cmdline - buffer_json_add_array_item_string(wb, (p->cmdline && *p->cmdline) ? p->cmdline : p->comm); -#endif + if (enable_function_cmdline) { + buffer_json_add_array_item_string(wb, (p->cmdline && *p->cmdline) ? p->cmdline : p->comm); + } // ppid buffer_json_add_array_item_uint64(wb, p->ppid); @@ -4633,7 +4838,8 @@ static void apps_plugin_function_processes(const char *transaction, char *functi add_value_field_llu_with_max(wb, TMajFlt, (p->majflt + p->cmajflt) / RATES_DETAIL); // open file descriptors - add_value_field_llu_with_max(wb, FDs, p->openfds.files + p->openfds.pipes + p->openfds.sockets + p->openfds.inotifies + p->openfds.eventfds + p->openfds.timerfds + p->openfds.signalfds + p->openfds.eventpolls + p->openfds.other); + add_value_field_ndd_with_max(wb, FDsLimitPercent, p->openfds_limits_percent); + add_value_field_llu_with_max(wb, FDs, pid_openfds_sum(p)); add_value_field_llu_with_max(wb, Files, p->openfds.files); add_value_field_llu_with_max(wb, Pipes, p->openfds.pipes); add_value_field_llu_with_max(wb, Sockets, p->openfds.sockets); @@ -4644,99 +4850,311 @@ static void apps_plugin_function_processes(const char *transaction, char *functi add_value_field_llu_with_max(wb, EvPollFDs, p->openfds.eventpolls); add_value_field_llu_with_max(wb, OtherFDs, p->openfds.other); + // processes, threads, uptime add_value_field_llu_with_max(wb, Processes, p->children_count); add_value_field_llu_with_max(wb, Threads, p->num_threads); add_value_field_llu_with_max(wb, Uptime, p->uptime); - buffer_json_array_close(wb); + buffer_json_array_close(wb); // for each pid } - buffer_json_array_close(wb); + buffer_json_array_close(wb); // data buffer_json_member_add_object(wb, "columns"); { - int fields_added = 0; + int field_id = 0; // IMPORTANT! // THE ORDER SHOULD BE THE SAME WITH THE VALUES! - add_table_field(wb, "PID", "Process ID", true, "integer", "value", "number", 0, NULL, NAN, "ascending", true, true, true, NULL, "count_unique", false); - add_table_field(wb, "Cmd", "Process Name", true, "string", "value", "none", 0, NULL, NAN, "ascending", true, true, false, NULL, "count_unique", false); + // wb, key, name, visible, type, visualization, transform, decimal_points, units, max, sort, sortable, sticky, unique_key, pointer_to, summary, range + buffer_rrdf_table_add_field(wb, field_id++, "PID", "Process ID", RRDF_FIELD_TYPE_INTEGER, + RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NUMBER, 0, NULL, NAN, + RRDF_FIELD_SORT_ASCENDING, NULL, RRDF_FIELD_SUMMARY_COUNT, + RRDF_FIELD_FILTER_MULTISELECT, + RRDF_FIELD_OPTS_VISIBLE | RRDF_FIELD_OPTS_STICKY | + RRDF_FIELD_OPTS_UNIQUE_KEY, NULL); + + buffer_rrdf_table_add_field(wb, field_id++, "Cmd", "Process Name", RRDF_FIELD_TYPE_STRING, + RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NONE, 0, NULL, NAN, + RRDF_FIELD_SORT_ASCENDING, NULL, RRDF_FIELD_SUMMARY_COUNT, + RRDF_FIELD_FILTER_MULTISELECT, + RRDF_FIELD_OPTS_VISIBLE | RRDF_FIELD_OPTS_STICKY, NULL); + + if (enable_function_cmdline) { + buffer_rrdf_table_add_field(wb, field_id++, "CmdLine", "Command Line", RRDF_FIELD_TYPE_STRING, + RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NONE, 0, + NULL, NAN, RRDF_FIELD_SORT_ASCENDING, NULL, RRDF_FIELD_SUMMARY_COUNT, + RRDF_FIELD_FILTER_MULTISELECT, + RRDF_FIELD_OPTS_NONE, NULL); + } -#ifdef NETDATA_DEV_MODE - add_table_field(wb, "CmdLine", "Command Line", false, "detail-string:Cmd", "value", "none", 0, NULL, NAN, "ascending", true, false, false, NULL, "count_unique", false); -#endif - add_table_field(wb, "PPID", "Parent Process ID", false, "integer", "value", "number", 0, NULL, NAN, "ascending", true, false, false, "PID", "count_unique", false); - add_table_field(wb, "Category", "Category (apps_groups.conf)", true, "string", "value", "none", 0, NULL, NAN, "ascending", true, true, false, NULL, "count_unique", false); - add_table_field(wb, "User", "User Owner", true, "string", "value", "none", 0, NULL, NAN, "ascending", true, false, false, NULL, "count_unique", false); - add_table_field(wb, "Uid", "User ID", false, "integer", "value", "number", 0, NULL, NAN, "ascending", true, false, false, NULL, "count_unique", false); - add_table_field(wb, "Group", "Group Owner", false, "string", "value", "none", 0, NULL, NAN, "ascending", true, false, false, NULL, "count_unique", false); - add_table_field(wb, "Gid", "Group ID", false, "integer", "value", "number", 0, NULL, NAN, "ascending", true, false, false, NULL, "count_unique", false); + buffer_rrdf_table_add_field(wb, field_id++, "PPID", "Parent Process ID", RRDF_FIELD_TYPE_INTEGER, + RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NUMBER, 0, NULL, + NAN, RRDF_FIELD_SORT_ASCENDING, "PID", RRDF_FIELD_SUMMARY_COUNT, + RRDF_FIELD_FILTER_MULTISELECT, + RRDF_FIELD_OPTS_NONE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "Category", "Category (apps_groups.conf)", RRDF_FIELD_TYPE_STRING, + RRDF_FIELD_VISUAL_VALUE, + RRDF_FIELD_TRANSFORM_NONE, + 0, NULL, NAN, RRDF_FIELD_SORT_ASCENDING, NULL, RRDF_FIELD_SUMMARY_COUNT, + RRDF_FIELD_FILTER_MULTISELECT, + RRDF_FIELD_OPTS_VISIBLE | RRDF_FIELD_OPTS_STICKY, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "User", "User Owner", RRDF_FIELD_TYPE_STRING, + RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NONE, 0, NULL, NAN, + RRDF_FIELD_SORT_ASCENDING, NULL, RRDF_FIELD_SUMMARY_COUNT, + RRDF_FIELD_FILTER_MULTISELECT, + RRDF_FIELD_OPTS_VISIBLE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "Uid", "User ID", RRDF_FIELD_TYPE_INTEGER, RRDF_FIELD_VISUAL_VALUE, + RRDF_FIELD_TRANSFORM_NUMBER, 0, NULL, NAN, + RRDF_FIELD_SORT_ASCENDING, NULL, RRDF_FIELD_SUMMARY_COUNT, + RRDF_FIELD_FILTER_MULTISELECT, + RRDF_FIELD_OPTS_NONE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "Group", "Group Owner", RRDF_FIELD_TYPE_STRING, + RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NONE, 0, NULL, NAN, + RRDF_FIELD_SORT_ASCENDING, NULL, RRDF_FIELD_SUMMARY_COUNT, + RRDF_FIELD_FILTER_MULTISELECT, + RRDF_FIELD_OPTS_NONE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "Gid", "Group ID", RRDF_FIELD_TYPE_INTEGER, RRDF_FIELD_VISUAL_VALUE, + RRDF_FIELD_TRANSFORM_NUMBER, 0, NULL, NAN, + RRDF_FIELD_SORT_ASCENDING, NULL, RRDF_FIELD_SUMMARY_COUNT, + RRDF_FIELD_FILTER_MULTISELECT, + RRDF_FIELD_OPTS_NONE, NULL); // CPU utilization - add_table_field(wb, "CPU", "Total CPU Time (100% = 1 core)", true, "bar-with-integer", "bar", "number", 2, "%", CPU_max, "descending", true, false, false, NULL, "sum", true); - add_table_field(wb, "UserCPU", "User CPU time (100% = 1 core)", false, "bar-with-integer", "bar", "number", 2, "%", UserCPU_max, "descending", true, false, false, NULL, "sum", true); - add_table_field(wb, "SysCPU", "System CPU Time (100% = 1 core)", false, "bar-with-integer", "bar", "number", 2, "%", SysCPU_max, "descending", true, false, false, NULL, "sum", true); - add_table_field(wb, "GuestCPU", "Guest CPU Time (100% = 1 core)", false, "bar-with-integer", "bar", "number", 2, "%", GuestCPU_max, "descending", true, false, false, NULL, "sum", true); - add_table_field(wb, "CUserCPU", "Children User CPU Time (100% = 1 core)", false, "bar-with-integer", "bar", "number", 2, "%", CUserCPU_max, "descending", true, false, false, NULL, "sum", true); - add_table_field(wb, "CSysCPU", "Children System CPU Time (100% = 1 core)", false, "bar-with-integer", "bar", "number", 2, "%", CSysCPU_max, "descending", true, false, false, NULL, "sum", true); - add_table_field(wb, "CGuestCPU", "Children Guest CPU Time (100% = 1 core)", false, "bar-with-integer", "bar", "number", 2, "%", CGuestCPU_max, "descending", true, false, false, NULL, "sum", true); + buffer_rrdf_table_add_field(wb, field_id++, "CPU", "Total CPU Time (100% = 1 core)", + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, RRDF_FIELD_VISUAL_BAR, + RRDF_FIELD_TRANSFORM_NUMBER, 2, "%", CPU_max, RRDF_FIELD_SORT_DESCENDING, NULL, + RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_VISIBLE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "UserCPU", "User CPU time (100% = 1 core)", + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, + RRDF_FIELD_VISUAL_BAR, RRDF_FIELD_TRANSFORM_NUMBER, 2, "%", UserCPU_max, + RRDF_FIELD_SORT_DESCENDING, NULL, RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_NONE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "SysCPU", "System CPU Time (100% = 1 core)", + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, + RRDF_FIELD_VISUAL_BAR, RRDF_FIELD_TRANSFORM_NUMBER, 2, "%", SysCPU_max, + RRDF_FIELD_SORT_DESCENDING, NULL, RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_NONE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "GuestCPU", "Guest CPU Time (100% = 1 core)", + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, + RRDF_FIELD_VISUAL_BAR, RRDF_FIELD_TRANSFORM_NUMBER, 2, "%", GuestCPU_max, + RRDF_FIELD_SORT_DESCENDING, NULL, RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_NONE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "CUserCPU", "Children User CPU Time (100% = 1 core)", + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, RRDF_FIELD_VISUAL_BAR, + RRDF_FIELD_TRANSFORM_NUMBER, 2, "%", CUserCPU_max, RRDF_FIELD_SORT_DESCENDING, NULL, + RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_NONE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "CSysCPU", "Children System CPU Time (100% = 1 core)", + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, RRDF_FIELD_VISUAL_BAR, + RRDF_FIELD_TRANSFORM_NUMBER, 2, "%", CSysCPU_max, RRDF_FIELD_SORT_DESCENDING, NULL, + RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_NONE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "CGuestCPU", "Children Guest CPU Time (100% = 1 core)", + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, RRDF_FIELD_VISUAL_BAR, + RRDF_FIELD_TRANSFORM_NUMBER, 2, "%", CGuestCPU_max, RRDF_FIELD_SORT_DESCENDING, + NULL, + RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_RANGE, RRDF_FIELD_OPTS_NONE, NULL); // CPU context switches - add_table_field(wb, "vCtxSwitch", "Voluntary Context Switches", false, "bar-with-integer", "bar", "number", 2, "switches/s", VoluntaryCtxtSwitches_max, "descending", true, false, false, NULL, "sum", true); - add_table_field(wb, "iCtxSwitch", "Involuntary Context Switches", false, "bar-with-integer", "bar", "number", 2, "switches/s", NonVoluntaryCtxtSwitches_max, "descending", true, false, false, NULL, "sum", true); + buffer_rrdf_table_add_field(wb, field_id++, "vCtxSwitch", "Voluntary Context Switches", + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, + RRDF_FIELD_VISUAL_BAR, RRDF_FIELD_TRANSFORM_NUMBER, 2, "switches/s", + VoluntaryCtxtSwitches_max, RRDF_FIELD_SORT_DESCENDING, NULL, + RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_RANGE, RRDF_FIELD_OPTS_NONE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "iCtxSwitch", "Involuntary Context Switches", + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, + RRDF_FIELD_VISUAL_BAR, RRDF_FIELD_TRANSFORM_NUMBER, 2, "switches/s", + NonVoluntaryCtxtSwitches_max, RRDF_FIELD_SORT_DESCENDING, NULL, + RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_RANGE, RRDF_FIELD_OPTS_NONE, NULL); // memory - if(MemTotal) - add_table_field(wb, "Memory", "Memory Percentage", true, "bar-with-integer", "bar", "number", 2, "%", 100.0, "descending", true, false, false, NULL, "sum", true); - - add_table_field(wb, "Resident", "Resident Set Size", true, "bar-with-integer", "bar", "number", 2, "MiB", RSS_max, "descending", true, false, false, NULL, "sum", true); - add_table_field(wb, "Shared", "Shared Pages", true, "bar-with-integer", "bar", "number", 2, "MiB", Shared_max, "descending", true, false, false, NULL, "sum", true); - add_table_field(wb, "Virtual", "Virtual Memory Size", true, "bar-with-integer", "bar", "number", 2, "MiB", VMSize_max, "descending", true, false, false, NULL, "sum", true); - add_table_field(wb, "Swap", "Swap Memory", false, "bar-with-integer", "bar", "number", 2, "MiB", Swap_max, "descending", true, false, false, NULL, "sum", true); + if (MemTotal) + buffer_rrdf_table_add_field(wb, field_id++, "Memory", "Memory Percentage", RRDF_FIELD_TYPE_BAR_WITH_INTEGER, + RRDF_FIELD_VISUAL_BAR, + RRDF_FIELD_TRANSFORM_NUMBER, 2, "%", 100.0, RRDF_FIELD_SORT_DESCENDING, NULL, + RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_VISIBLE, NULL); + + buffer_rrdf_table_add_field(wb, field_id++, "Resident", "Resident Set Size", RRDF_FIELD_TYPE_BAR_WITH_INTEGER, + RRDF_FIELD_VISUAL_BAR, + RRDF_FIELD_TRANSFORM_NUMBER, + 2, "MiB", RSS_max, RRDF_FIELD_SORT_DESCENDING, NULL, RRDF_FIELD_SUMMARY_SUM, + RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_VISIBLE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "Shared", "Shared Pages", RRDF_FIELD_TYPE_BAR_WITH_INTEGER, + RRDF_FIELD_VISUAL_BAR, RRDF_FIELD_TRANSFORM_NUMBER, 2, + "MiB", Shared_max, RRDF_FIELD_SORT_DESCENDING, NULL, RRDF_FIELD_SUMMARY_SUM, + RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_VISIBLE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "Virtual", "Virtual Memory Size", RRDF_FIELD_TYPE_BAR_WITH_INTEGER, + RRDF_FIELD_VISUAL_BAR, + RRDF_FIELD_TRANSFORM_NUMBER, 2, "MiB", VMSize_max, RRDF_FIELD_SORT_DESCENDING, NULL, + RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_VISIBLE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "Swap", "Swap Memory", RRDF_FIELD_TYPE_BAR_WITH_INTEGER, + RRDF_FIELD_VISUAL_BAR, RRDF_FIELD_TRANSFORM_NUMBER, 2, + "MiB", + Swap_max, RRDF_FIELD_SORT_DESCENDING, NULL, RRDF_FIELD_SUMMARY_SUM, + RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_NONE, NULL); // Physical I/O - add_table_field(wb, "PReads", "Physical I/O Reads", true, "bar-with-integer", "bar", "number", 2, "KiB/s", PReads_max, "descending", true, false, false, NULL, "sum", true); - add_table_field(wb, "PWrites", "Physical I/O Writes", true, "bar-with-integer", "bar", "number", 2, "KiB/s", PWrites_max, "descending", true, false, false, NULL, "sum", true); + buffer_rrdf_table_add_field(wb, field_id++, "PReads", "Physical I/O Reads", RRDF_FIELD_TYPE_BAR_WITH_INTEGER, + RRDF_FIELD_VISUAL_BAR, RRDF_FIELD_TRANSFORM_NUMBER, + 2, "KiB/s", PReads_max, RRDF_FIELD_SORT_DESCENDING, NULL, RRDF_FIELD_SUMMARY_SUM, + RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_VISIBLE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "PWrites", "Physical I/O Writes", RRDF_FIELD_TYPE_BAR_WITH_INTEGER, + RRDF_FIELD_VISUAL_BAR, + RRDF_FIELD_TRANSFORM_NUMBER, 2, "KiB/s", PWrites_max, RRDF_FIELD_SORT_DESCENDING, + NULL, RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_VISIBLE, NULL); // Logical I/O #ifndef __FreeBSD__ - add_table_field(wb, "LReads", "Logical I/O Reads", true, "bar-with-integer", "bar", "number", 2, "KiB/s", LReads_max, "descending", true, false, false, NULL, "sum", true); - add_table_field(wb, "LWrites", "Logical I/O Writes", true, "bar-with-integer", "bar", "number", 2, "KiB/s", LWrites_max, "descending", true, false, false, NULL, "sum", true); + buffer_rrdf_table_add_field(wb, field_id++, "LReads", "Logical I/O Reads", RRDF_FIELD_TYPE_BAR_WITH_INTEGER, + RRDF_FIELD_VISUAL_BAR, RRDF_FIELD_TRANSFORM_NUMBER, + 2, "KiB/s", LReads_max, RRDF_FIELD_SORT_DESCENDING, NULL, RRDF_FIELD_SUMMARY_SUM, + RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_VISIBLE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "LWrites", "Logical I/O Writes", RRDF_FIELD_TYPE_BAR_WITH_INTEGER, + RRDF_FIELD_VISUAL_BAR, + RRDF_FIELD_TRANSFORM_NUMBER, + 2, "KiB/s", LWrites_max, RRDF_FIELD_SORT_DESCENDING, NULL, RRDF_FIELD_SUMMARY_SUM, + RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_VISIBLE, NULL); #endif // I/O calls - add_table_field(wb, "RCalls", "I/O Read Calls", true, "bar-with-integer", "bar", "number", 2, "calls/s", RCalls_max, "descending", true, false, false, NULL, "sum", true); - add_table_field(wb, "WCalls", "I/O Write Calls", true, "bar-with-integer", "bar", "number", 2, "calls/s", WCalls_max, "descending", true, false, false, NULL, "sum", true); + buffer_rrdf_table_add_field(wb, field_id++, "RCalls", "I/O Read Calls", RRDF_FIELD_TYPE_BAR_WITH_INTEGER, + RRDF_FIELD_VISUAL_BAR, RRDF_FIELD_TRANSFORM_NUMBER, 2, + "calls/s", RCalls_max, RRDF_FIELD_SORT_DESCENDING, NULL, RRDF_FIELD_SUMMARY_SUM, + RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_VISIBLE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "WCalls", "I/O Write Calls", RRDF_FIELD_TYPE_BAR_WITH_INTEGER, + RRDF_FIELD_VISUAL_BAR, RRDF_FIELD_TRANSFORM_NUMBER, 2, + "calls/s", WCalls_max, RRDF_FIELD_SORT_DESCENDING, NULL, RRDF_FIELD_SUMMARY_SUM, + RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_VISIBLE, NULL); // minor page faults - add_table_field(wb, "MinFlt", "Minor Page Faults/s", false, "bar-with-integer", "bar", "number", 2, "pgflts/s", MinFlt_max, "descending", true, false, false, NULL, "sum", true); - add_table_field(wb, "CMinFlt", "Children Minor Page Faults/s", false, "bar-with-integer", "bar", "number", 2, "pgflts/s", CMinFlt_max, "descending", true, false, false, NULL, "sum", true); - add_table_field(wb, "TMinFlt", "Total Minor Page Faults/s", false, "bar-with-integer", "bar", "number", 2, "pgflts/s", TMinFlt_max, "descending", true, false, false, NULL, "sum", true); + buffer_rrdf_table_add_field(wb, field_id++, "MinFlt", "Minor Page Faults/s", RRDF_FIELD_TYPE_BAR_WITH_INTEGER, + RRDF_FIELD_VISUAL_BAR, + RRDF_FIELD_TRANSFORM_NUMBER, + 2, "pgflts/s", MinFlt_max, RRDF_FIELD_SORT_DESCENDING, NULL, RRDF_FIELD_SUMMARY_SUM, + RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_NONE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "CMinFlt", "Children Minor Page Faults/s", + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, + RRDF_FIELD_VISUAL_BAR, + RRDF_FIELD_TRANSFORM_NUMBER, 2, "pgflts/s", CMinFlt_max, RRDF_FIELD_SORT_DESCENDING, + NULL, RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_NONE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "TMinFlt", "Total Minor Page Faults/s", + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, RRDF_FIELD_VISUAL_BAR, + RRDF_FIELD_TRANSFORM_NUMBER, 2, "pgflts/s", TMinFlt_max, RRDF_FIELD_SORT_DESCENDING, + NULL, RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_NONE, NULL); // major page faults - add_table_field(wb, "MajFlt", "Major Page Faults/s", false, "bar-with-integer", "bar", "number", 2, "pgflts/s", MajFlt_max, "descending", true, false, false, NULL, "sum", true); - add_table_field(wb, "CMajFlt", "Children Major Page Faults/s", false, "bar-with-integer", "bar", "number", 2, "pgflts/s", CMajFlt_max, "descending", true, false, false, NULL, "sum", true); - add_table_field(wb, "TMajFlt", "Total Major Page Faults/s", true, "bar-with-integer", "bar", "number", 2, "pgflts/s", TMajFlt_max, "descending", true, false, false, NULL, "sum", true); + buffer_rrdf_table_add_field(wb, field_id++, "MajFlt", "Major Page Faults/s", RRDF_FIELD_TYPE_BAR_WITH_INTEGER, + RRDF_FIELD_VISUAL_BAR, + RRDF_FIELD_TRANSFORM_NUMBER, + 2, "pgflts/s", MajFlt_max, RRDF_FIELD_SORT_DESCENDING, NULL, RRDF_FIELD_SUMMARY_SUM, + RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_NONE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "CMajFlt", "Children Major Page Faults/s", + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, + RRDF_FIELD_VISUAL_BAR, + RRDF_FIELD_TRANSFORM_NUMBER, 2, "pgflts/s", CMajFlt_max, RRDF_FIELD_SORT_DESCENDING, + NULL, RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_NONE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "TMajFlt", "Total Major Page Faults/s", + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, RRDF_FIELD_VISUAL_BAR, + RRDF_FIELD_TRANSFORM_NUMBER, 2, "pgflts/s", TMajFlt_max, RRDF_FIELD_SORT_DESCENDING, + NULL, RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_VISIBLE, NULL); // open file descriptors - add_table_field(wb, "FDs", "All Open File Descriptors", true, "bar-with-integer", "bar", "number", 0, "fds", FDs_max, "descending", true, false, false, NULL, "sum", true); - add_table_field(wb, "Files", "Open Files", true, "bar-with-integer", "bar", "number", 0, "fds", Files_max, "descending", true, false, false, NULL, "sum", true); - add_table_field(wb, "Pipes", "Open Pipes", true, "bar-with-integer", "bar", "number", 0, "fds", Pipes_max, "descending", true, false, false, NULL, "sum", true); - add_table_field(wb, "Sockets", "Open Sockets", true, "bar-with-integer", "bar", "number", 0, "fds", Sockets_max, "descending", true, false, false, NULL, "sum", true); - add_table_field(wb, "iNotiFDs", "Open iNotify Descriptors", false, "bar-with-integer", "bar", "number", 0, "fds", iNotiFDs_max, "descending", true, false, false, NULL, "sum", true); - add_table_field(wb, "EventFDs", "Open Event Descriptors", false, "bar-with-integer", "bar", "number", 0, "fds", EventFDs_max, "descending", true, false, false, NULL, "sum", true); - add_table_field(wb, "TimerFDs", "Open Timer Descriptors", false, "bar-with-integer", "bar", "number", 0, "fds", TimerFDs_max, "descending", true, false, false, NULL, "sum", true); - add_table_field(wb, "SigFDs", "Open Signal Descriptors", false, "bar-with-integer", "bar", "number", 0, "fds", SigFDs_max, "descending", true, false, false, NULL, "sum", true); - add_table_field(wb, "EvPollFDs", "Open Event Poll Descriptors", false, "bar-with-integer", "bar", "number", 0, "fds", EvPollFDs_max, "descending", true, false, false, NULL, "sum", true); - add_table_field(wb, "OtherFDs", "Other Open Descriptors", false, "bar-with-integer", "bar", "number", 0, "fds", OtherFDs_max, "descending", true, false, false, NULL, "sum", true); + buffer_rrdf_table_add_field(wb, field_id++, "FDsLimitPercent", "Percentage of Open Descriptors vs Limits", + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, RRDF_FIELD_VISUAL_BAR, + RRDF_FIELD_TRANSFORM_NUMBER, 2, "%", FDsLimitPercent_max, RRDF_FIELD_SORT_DESCENDING, NULL, + RRDF_FIELD_SUMMARY_MAX, RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_NONE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "FDs", "All Open File Descriptors", + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, RRDF_FIELD_VISUAL_BAR, + RRDF_FIELD_TRANSFORM_NUMBER, 0, "fds", FDs_max, RRDF_FIELD_SORT_DESCENDING, NULL, + RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_VISIBLE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "Files", "Open Files", RRDF_FIELD_TYPE_BAR_WITH_INTEGER, + RRDF_FIELD_VISUAL_BAR, RRDF_FIELD_TRANSFORM_NUMBER, 0, + "fds", + Files_max, RRDF_FIELD_SORT_DESCENDING, NULL, RRDF_FIELD_SUMMARY_SUM, + RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_VISIBLE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "Pipes", "Open Pipes", RRDF_FIELD_TYPE_BAR_WITH_INTEGER, + RRDF_FIELD_VISUAL_BAR, RRDF_FIELD_TRANSFORM_NUMBER, 0, + "fds", + Pipes_max, RRDF_FIELD_SORT_DESCENDING, NULL, RRDF_FIELD_SUMMARY_SUM, + RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_VISIBLE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "Sockets", "Open Sockets", RRDF_FIELD_TYPE_BAR_WITH_INTEGER, + RRDF_FIELD_VISUAL_BAR, RRDF_FIELD_TRANSFORM_NUMBER, 0, + "fds", Sockets_max, RRDF_FIELD_SORT_DESCENDING, NULL, RRDF_FIELD_SUMMARY_SUM, + RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_VISIBLE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "iNotiFDs", "Open iNotify Descriptors", + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, RRDF_FIELD_VISUAL_BAR, + RRDF_FIELD_TRANSFORM_NUMBER, 0, "fds", iNotiFDs_max, RRDF_FIELD_SORT_DESCENDING, + NULL, RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_NONE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "EventFDs", "Open Event Descriptors", + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, RRDF_FIELD_VISUAL_BAR, + RRDF_FIELD_TRANSFORM_NUMBER, 0, "fds", EventFDs_max, RRDF_FIELD_SORT_DESCENDING, + NULL, RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_NONE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "TimerFDs", "Open Timer Descriptors", + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, RRDF_FIELD_VISUAL_BAR, + RRDF_FIELD_TRANSFORM_NUMBER, 0, "fds", TimerFDs_max, RRDF_FIELD_SORT_DESCENDING, + NULL, RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_NONE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "SigFDs", "Open Signal Descriptors", + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, RRDF_FIELD_VISUAL_BAR, + RRDF_FIELD_TRANSFORM_NUMBER, 0, "fds", SigFDs_max, RRDF_FIELD_SORT_DESCENDING, NULL, + RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_NONE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "EvPollFDs", "Open Event Poll Descriptors", + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, + RRDF_FIELD_VISUAL_BAR, RRDF_FIELD_TRANSFORM_NUMBER, 0, "fds", EvPollFDs_max, + RRDF_FIELD_SORT_DESCENDING, NULL, RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_NONE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "OtherFDs", "Other Open Descriptors", + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, RRDF_FIELD_VISUAL_BAR, + RRDF_FIELD_TRANSFORM_NUMBER, 0, "fds", OtherFDs_max, RRDF_FIELD_SORT_DESCENDING, + NULL, RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_NONE, NULL); // processes, threads, uptime - add_table_field(wb, "Processes", "Processes", true, "bar-with-integer", "bar", "number", 0, "processes", Processes_max, "descending", true, false, false, NULL, "sum", true); - add_table_field(wb, "Threads", "Threads", true, "bar-with-integer", "bar", "number", 0, "threads", Threads_max, "descending", true, false, false, NULL, "sum", true); - add_table_field(wb, "Uptime", "Uptime in seconds", true, "duration", "bar", "duration", 2, "seconds", Uptime_max, "descending", true, false, false, NULL, "max", true); - } - buffer_json_object_close(wb); + buffer_rrdf_table_add_field(wb, field_id++, "Processes", "Processes", RRDF_FIELD_TYPE_BAR_WITH_INTEGER, + RRDF_FIELD_VISUAL_BAR, RRDF_FIELD_TRANSFORM_NUMBER, 0, + "processes", Processes_max, RRDF_FIELD_SORT_DESCENDING, NULL, + RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_VISIBLE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "Threads", "Threads", RRDF_FIELD_TYPE_BAR_WITH_INTEGER, + RRDF_FIELD_VISUAL_BAR, RRDF_FIELD_TRANSFORM_NUMBER, 0, + "threads", Threads_max, RRDF_FIELD_SORT_DESCENDING, NULL, RRDF_FIELD_SUMMARY_SUM, + RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_VISIBLE, NULL); + buffer_rrdf_table_add_field(wb, field_id++, "Uptime", "Uptime in seconds", RRDF_FIELD_TYPE_DURATION, + RRDF_FIELD_VISUAL_BAR, RRDF_FIELD_TRANSFORM_DURATION, 2, + "seconds", Uptime_max, RRDF_FIELD_SORT_DESCENDING, NULL, RRDF_FIELD_SUMMARY_MAX, + RRDF_FIELD_FILTER_RANGE, + RRDF_FIELD_OPTS_VISIBLE, NULL); + } + buffer_json_object_close(wb); // columns buffer_json_member_add_string(wb, "default_sort_column", "CPU"); @@ -4953,6 +5371,20 @@ static void apps_plugin_function_processes(const char *transaction, char *functi } buffer_json_object_close(wb); // charts + buffer_json_member_add_array(wb, "default_charts"); + { + buffer_json_add_array_item_array(wb); + buffer_json_add_array_item_string(wb, "CPU"); + buffer_json_add_array_item_string(wb, "Category"); + buffer_json_array_close(wb); + + buffer_json_add_array_item_array(wb); + buffer_json_add_array_item_string(wb, "Memory"); + buffer_json_add_array_item_string(wb, "Category"); + buffer_json_array_close(wb); + } + buffer_json_array_close(wb); + buffer_json_member_add_object(wb, "group_by"); { // group by PID @@ -5026,7 +5458,7 @@ void *reader_main(void *arg __maybe_unused) { while(!apps_plugin_exit && (s = fgets(buffer, PLUGINSD_LINE_MAX, stdin))) { char *words[PLUGINSD_MAX_WORDS] = { NULL }; - size_t num_words = pluginsd_split_words(buffer, words, PLUGINSD_MAX_WORDS); + size_t num_words = quoted_strings_splitter_pluginsd(buffer, words, PLUGINSD_MAX_WORDS); const char *keyword = get_word(words, num_words, 0); @@ -5036,7 +5468,7 @@ void *reader_main(void *arg __maybe_unused) { char *function = get_word(words, num_words, 3); if(!transaction || !*transaction || !timeout_s || !*timeout_s || !function || !*function) { - error("Received incomplete %s (transaction = '%s', timeout = '%s', function = '%s'). Ignoring it.", + netdata_log_error("Received incomplete %s (transaction = '%s', timeout = '%s', function = '%s'). Ignoring it.", keyword, transaction?transaction:"(unset)", timeout_s?timeout_s:"(unset)", @@ -5062,12 +5494,12 @@ void *reader_main(void *arg __maybe_unused) { } } else - error("Received unknown command: %s", keyword?keyword:"(unset)"); + netdata_log_error("Received unknown command: %s", keyword?keyword:"(unset)"); } if(!s || feof(stdin) || ferror(stdin)) { apps_plugin_exit = true; - error("Received error on stdin."); + netdata_log_error("Received error on stdin."); } exit(1); @@ -5107,23 +5539,23 @@ int main(int argc, char **argv) { user_config_dir = getenv("NETDATA_USER_CONFIG_DIR"); if(user_config_dir == NULL) { - // info("NETDATA_CONFIG_DIR is not passed from netdata"); + // netdata_log_info("NETDATA_CONFIG_DIR is not passed from netdata"); user_config_dir = CONFIG_DIR; } - // else info("Found NETDATA_USER_CONFIG_DIR='%s'", user_config_dir); + // else netdata_log_info("Found NETDATA_USER_CONFIG_DIR='%s'", user_config_dir); stock_config_dir = getenv("NETDATA_STOCK_CONFIG_DIR"); if(stock_config_dir == NULL) { - // info("NETDATA_CONFIG_DIR is not passed from netdata"); + // netdata_log_info("NETDATA_CONFIG_DIR is not passed from netdata"); stock_config_dir = LIBCONFIG_DIR; } - // else info("Found NETDATA_USER_CONFIG_DIR='%s'", user_config_dir); + // else netdata_log_info("Found NETDATA_USER_CONFIG_DIR='%s'", user_config_dir); #ifdef NETDATA_INTERNAL_CHECKS if(debug_flags != 0) { struct rlimit rl = { RLIM_INFINITY, RLIM_INFINITY }; if(setrlimit(RLIMIT_CORE, &rl) != 0) - info("Cannot request unlimited core dumps for debugging... Proceeding anyway..."); + netdata_log_info("Cannot request unlimited core dumps for debugging... Proceeding anyway..."); #ifdef HAVE_SYS_PRCTL_H prctl(PR_SET_DUMPABLE, 1, 0, 0, 0); #endif @@ -5147,14 +5579,14 @@ int main(int argc, char **argv) { if(!check_capabilities() && !am_i_running_as_root() && !check_proc_1_io()) { uid_t uid = getuid(), euid = geteuid(); #ifdef HAVE_CAPABILITY - error("apps.plugin should either run as root (now running with uid %u, euid %u) or have special capabilities. " + netdata_log_error("apps.plugin should either run as root (now running with uid %u, euid %u) or have special capabilities. " "Without these, apps.plugin cannot report disk I/O utilization of other processes. " "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("apps.plugin should either run as root (now running with uid %u, euid %u) or have special capabilities. " + netdata_log_error("apps.plugin should either run as root (now running with uid %u, euid %u) or have special capabilities. " "Without these, apps.plugin cannot report disk I/O utilization of other processes. " "Your system does not support capabilities. " "To enable setuid to root run: sudo chown root:netdata %s; sudo chmod 4750 %s; " @@ -5163,7 +5595,7 @@ int main(int argc, char **argv) { #endif } - info("started on pid %d", getpid()); + netdata_log_info("started on pid %d", getpid()); snprintfz(all_user_ids.filename, FILENAME_MAX, "%s/etc/passwd", netdata_configured_host_prefix); debug_log("passwd file: '%s'", all_user_ids.filename); @@ -5215,14 +5647,13 @@ int main(int argc, char **argv) { get_MemTotal(); if(!collect_data_for_all_processes()) { - error("Cannot collect /proc data for running processes. Disabling apps.plugin..."); + netdata_log_error("Cannot collect /proc data for running processes. Disabling apps.plugin..."); printf("DISABLE\n"); netdata_mutex_unlock(&mutex); netdata_thread_cancel(reader_thread); exit(1); } - currentmaxfds = 0; calculate_netdata_statistics(); normalize_utilization(apps_groups_root_target); diff --git a/collectors/apps.plugin/metrics.csv b/collectors/apps.plugin/metrics.csv index e1ca34340..afda7a860 100644 --- a/collectors/apps.plugin/metrics.csv +++ b/collectors/apps.plugin/metrics.csv @@ -1,81 +1,81 @@ metric,scope,dimensions,unit,description,chart_type,labels,plugin,module -system.processes_state,,"running, sleeping_interruptible, sleeping_uninterruptible, zombie, stopped",processes,"System Processes State",line,,apps.plugin, -apps.cpu,,a dimension per app group,percentage,"Apps CPU Time (100% = 1 core)",stacked,,apps.plugin, -apps.cpu_user,,a dimension per app group,percentage,"Apps CPU User Time (100% = 1 core)",stacked,,apps.plugin, -apps.cpu_system,,a dimension per app group,percentage,"Apps CPU System Time (100% = 1 core)",stacked,,apps.plugin, -apps.cpu_guest,,a dimension per app group,percentage,"Apps CPU Guest Time (100% = 1 core)",stacked,,apps.plugin, -apps.mem,,a dimension per app group,MiB,"Apps Real Memory (w/o shared)",stacked,,apps.plugin, -apps.rss,,a dimension per app group,MiB,"Apps Resident Set Size (w/shared)",stacked,,apps.plugin, -apps.vmem,,a dimension per app group,MiB,"Apps Virtual Memory Size",stacked,,apps.plugin, -apps.swap,,a dimension per app group,MiB,"Apps Swap Memory",stacked,,apps.plugin, -apps.major_faults,,a dimension per app group,"page faults/s","Apps Major Page Faults (swap read)",stacked,,apps.plugin, -apps.minor_faults,,a dimension per app group,"page faults/s","Apps Minor Page Faults (swap read)",stacked,,apps.plugin, -apps.preads,,a dimension per app group,"KiB/s","Apps Disk Reads",stacked,,apps.plugin, -apps.pwrites,,a dimension per app group,"KiB/s","Apps Disk Writes",stacked,,apps.plugin, -apps.lreads,,a dimension per app group,"KiB/s","Apps Disk Logical Reads",stacked,,apps.plugin, -apps.lwrites,,a dimension per app group,"KiB/s","Apps I/O Logical Writes",stacked,,apps.plugin, -apps.threads,,a dimension per app group,threads,"Apps Threads",stacked,,apps.plugin, -apps.processes,,a dimension per app group,processes,"Apps Processes",stacked,,apps.plugin, -apps.voluntary_ctxt_switches,,a dimension per app group,processes,"Apps Voluntary Context Switches",stacked,,apps.plugin, -apps.involuntary_ctxt_switches,,a dimension per app group,processes,"Apps Involuntary Context Switches",stacked,,apps.plugin, -apps.uptime,,a dimension per app group,seconds,"Apps Carried Over Uptime",line,,apps.plugin, -apps.uptime_min,,a dimension per app group,seconds,"Apps Minimum Uptime",line,,apps.plugin, -apps.uptime_avg,,a dimension per app group,seconds,"Apps Average Uptime",line,,apps.plugin, -apps.uptime_max,,a dimension per app group,seconds,"Apps Maximum Uptime",line,,apps.plugin, -apps.files,,a dimension per app group,"open files","Apps Open Files",stacked,,apps.plugin, -apps.sockets,,a dimension per app group,"open sockets","Apps Open Sockets",stacked,,apps.plugin, -apps.pipes,,a dimension per app group,"open pipes","Apps Open Pipes",stacked,,apps.plugin, -groups.cpu,,a dimension per user group,percentage,"User Groups CPU Time (100% = 1 core)",stacked,,apps.plugin, -groups.cpu_user,,a dimension per user group,percentage,"User Groups CPU User Time (100% = 1 core)",stacked,,apps.plugin, -groups.cpu_system,,a dimension per user group,percentage,"User Groups CPU System Time (100% = 1 core)",stacked,,apps.plugin, -groups.cpu_guest,,a dimension per user group,percentage,"User Groups CPU Guest Time (100% = 1 core)",stacked,,apps.plugin, -groups.mem,,a dimension per user group,MiB,"User Groups Real Memory (w/o shared)",stacked,,apps.plugin, -groups.rss,,a dimension per user group,MiB,"User Groups Resident Set Size (w/shared)",stacked,,apps.plugin, -groups.vmem,,a dimension per user group,MiB,"User Groups Virtual Memory Size",stacked,,apps.plugin, -groups.swap,,a dimension per user group,MiB,"User Groups Swap Memory",stacked,,apps.plugin, -groups.major_faults,,a dimension per user group,"page faults/s","User Groups Major Page Faults (swap read)",stacked,,apps.plugin, -groups.minor_faults,,a dimension per user group,"page faults/s","User Groups Page Faults (swap read)",stacked,,apps.plugin, -groups.preads,,a dimension per user group,"KiB/s","User Groups Disk Reads",stacked,,apps.plugin, -groups.pwrites,,a dimension per user group,"KiB/s","User Groups Disk Writes",stacked,,apps.plugin, -groups.lreads,,a dimension per user group,"KiB/s","User Groups Disk Logical Reads",stacked,,apps.plugin, -groups.lwrites,,a dimension per user group,"KiB/s","User Groups I/O Logical Writes",stacked,,apps.plugin, -groups.threads,,a dimension per user group,threads,"User Groups Threads",stacked,,apps.plugin, -groups.processes,,a dimension per user group,processes,"User Groups Processes",stacked,,apps.plugin, -groups.voluntary_ctxt_switches,,a dimension per app group,processes,"User Groups Voluntary Context Switches",stacked,,apps.plugin, -groups.involuntary_ctxt_switches,,a dimension per app group,processes,"User Groups Involuntary Context Switches",stacked,,apps.plugin, -groups.uptime,,a dimension per user group,seconds,"User Groups Carried Over Uptime",line,,apps.plugin, -groups.uptime_min,,a dimension per user group,seconds,"User Groups Minimum Uptime",line,,apps.plugin, -groups.uptime_avg,,a dimension per user group,seconds,"User Groups Average Uptime",line,,apps.plugin, -groups.uptime_max,,a dimension per user group,seconds,"User Groups Maximum Uptime",line,,apps.plugin, -groups.files,,a dimension per user group,"open files","User Groups Open Files",stacked,,apps.plugin, -groups.sockets,,a dimension per user group,"open sockets","User Groups Open Sockets",stacked,,apps.plugin, -groups.pipes,,a dimension per user group,"open pipes","User Groups Open Pipes",stacked,,apps.plugin, -users.cpu,,a dimension per user,percentage,"Users CPU Time (100% = 1 core)",stacked,,apps.plugin, -users.cpu_user,,a dimension per user,percentage,"Users CPU User Time (100% = 1 core)",stacked,,apps.plugin, -users.cpu_system,,a dimension per user,percentage,"Users CPU System Time (100% = 1 core)",stacked,,apps.plugin, -users.cpu_guest,,a dimension per user,percentage,"Users CPU Guest Time (100% = 1 core)",stacked,,apps.plugin, -users.mem,,a dimension per user,MiB,"Users Real Memory (w/o shared)",stacked,,apps.plugin, -users.rss,,a dimension per user,MiB,"Users Resident Set Size (w/shared)",stacked,,apps.plugin, -users.vmem,,a dimension per user,MiB,"Users Virtual Memory Size",stacked,,apps.plugin, -users.swap,,a dimension per user,MiB,"Users Swap Memory",stacked,,apps.plugin, -users.major_faults,,a dimension per user,"page faults/s","Users Major Page Faults (swap read)",stacked,,apps.plugin, -users.minor_faults,,a dimension per user,"page faults/s","Users Page Faults (swap read)",stacked,,apps.plugin, -users.preads,,a dimension per user,"KiB/s","Users Disk Reads",stacked,,apps.plugin, -users.pwrites,,a dimension per user,"KiB/s","Users Disk Writes",stacked,,apps.plugin, -users.lreads,,a dimension per user,"KiB/s","Users Disk Logical Reads",stacked,,apps.plugin, -users.lwrites,,a dimension per user,"KiB/s","Users I/O Logical Writes",stacked,,apps.plugin, -users.threads,,a dimension per user,threads,"Users Threads",stacked,,apps.plugin, -users.processes,,a dimension per user,processes,"Users Processes",stacked,,apps.plugin, -users.voluntary_ctxt_switches,,a dimension per app group,processes,"Users Voluntary Context Switches",stacked,,apps.plugin, -users.involuntary_ctxt_switches,,a dimension per app group,processes,"Users Involuntary Context Switches",stacked,,apps.plugin, -users.uptime,,a dimension per user,seconds,"Users Carried Over Uptime",line,,apps.plugin, -users.uptime_min,,a dimension per user,seconds,"Users Minimum Uptime",line,,apps.plugin, -users.uptime_avg,,a dimension per user,seconds,"Users Average Uptime",line,,apps.plugin, -users.uptime_max,,a dimension per user,seconds,"Users Maximum Uptime",line,,apps.plugin, -users.files,,a dimension per user,"open files","Users Open Files",stacked,,apps.plugin, -users.sockets,,a dimension per user,"open sockets","Users Open Sockets",stacked,,apps.plugin, -users.pipes,,a dimension per user,"open pipes","Users Open Pipes",stacked,,apps.plugin, -netdata.apps_cpu,,"user, system",milliseconds/s,"Apps Plugin CPU",stacked,,apps.plugin, -netdata.apps_sizes,,"calls, files, filenames, inode_changes, link_changes, pids, fds, targets, new_pids",files/s,"Apps Plugin Files",line,,apps.plugin, -netdata.apps_fix,,"utime, stime, gtime, minflt, majflt",percentage,"Apps Plugin Normalization Ratios",line,,apps.plugin, -netdata.apps_children_fix,,"utime, stime, gtime, minflt, majflt",percentage,"Apps Plugin Exited Children Normalization Ratios",line,,apps.plugin,
\ No newline at end of file +system.processes_state,,"running, sleeping_interruptible, sleeping_uninterruptible, zombie, stopped",processes,"System Processes State",line,,apps.plugin,system +apps.cpu,,a dimension per app group,percentage,"Apps CPU Time (100% = 1 core)",stacked,,apps.plugin,apps +apps.cpu_user,,a dimension per app group,percentage,"Apps CPU User Time (100% = 1 core)",stacked,,apps.plugin,apps +apps.cpu_system,,a dimension per app group,percentage,"Apps CPU System Time (100% = 1 core)",stacked,,apps.plugin,apps +apps.cpu_guest,,a dimension per app group,percentage,"Apps CPU Guest Time (100% = 1 core)",stacked,,apps.plugin,apps +apps.mem,,a dimension per app group,MiB,"Apps Real Memory (w/o shared)",stacked,,apps.plugin,apps +apps.rss,,a dimension per app group,MiB,"Apps Resident Set Size (w/shared)",stacked,,apps.plugin,apps +apps.vmem,,a dimension per app group,MiB,"Apps Virtual Memory Size",stacked,,apps.plugin,apps +apps.swap,,a dimension per app group,MiB,"Apps Swap Memory",stacked,,apps.plugin,apps +apps.major_faults,,a dimension per app group,"page faults/s","Apps Major Page Faults (swap read)",stacked,,apps.plugin,apps +apps.minor_faults,,a dimension per app group,"page faults/s","Apps Minor Page Faults (swap read)",stacked,,apps.plugin,apps +apps.preads,,a dimension per app group,"KiB/s","Apps Disk Reads",stacked,,apps.plugin,apps +apps.pwrites,,a dimension per app group,"KiB/s","Apps Disk Writes",stacked,,apps.plugin,apps +apps.lreads,,a dimension per app group,"KiB/s","Apps Disk Logical Reads",stacked,,apps.plugin,apps +apps.lwrites,,a dimension per app group,"KiB/s","Apps I/O Logical Writes",stacked,,apps.plugin,apps +apps.threads,,a dimension per app group,threads,"Apps Threads",stacked,,apps.plugin,apps +apps.processes,,a dimension per app group,processes,"Apps Processes",stacked,,apps.plugin,apps +apps.voluntary_ctxt_switches,,a dimension per app group,processes,"Apps Voluntary Context Switches",stacked,,apps.plugin,apps +apps.involuntary_ctxt_switches,,a dimension per app group,processes,"Apps Involuntary Context Switches",stacked,,apps.plugin,apps +apps.uptime,,a dimension per app group,seconds,"Apps Carried Over Uptime",line,,apps.plugin,apps +apps.uptime_min,,a dimension per app group,seconds,"Apps Minimum Uptime",line,,apps.plugin,apps +apps.uptime_avg,,a dimension per app group,seconds,"Apps Average Uptime",line,,apps.plugin,apps +apps.uptime_max,,a dimension per app group,seconds,"Apps Maximum Uptime",line,,apps.plugin,apps +apps.files,,a dimension per app group,"open files","Apps Open Files",stacked,,apps.plugin,apps +apps.sockets,,a dimension per app group,"open sockets","Apps Open Sockets",stacked,,apps.plugin,apps +apps.pipes,,a dimension per app group,"open pipes","Apps Open Pipes",stacked,,apps.plugin,apps +groups.cpu,,a dimension per user group,percentage,"User Groups CPU Time (100% = 1 core)",stacked,,apps.plugin,groups +groups.cpu_user,,a dimension per user group,percentage,"User Groups CPU User Time (100% = 1 core)",stacked,,apps.plugin,groups +groups.cpu_system,,a dimension per user group,percentage,"User Groups CPU System Time (100% = 1 core)",stacked,,apps.plugin,groups +groups.cpu_guest,,a dimension per user group,percentage,"User Groups CPU Guest Time (100% = 1 core)",stacked,,apps.plugin,groups +groups.mem,,a dimension per user group,MiB,"User Groups Real Memory (w/o shared)",stacked,,apps.plugin,groups +groups.rss,,a dimension per user group,MiB,"User Groups Resident Set Size (w/shared)",stacked,,apps.plugin,groups +groups.vmem,,a dimension per user group,MiB,"User Groups Virtual Memory Size",stacked,,apps.plugin,groups +groups.swap,,a dimension per user group,MiB,"User Groups Swap Memory",stacked,,apps.plugin,groups +groups.major_faults,,a dimension per user group,"page faults/s","User Groups Major Page Faults (swap read)",stacked,,apps.plugin,groups +groups.minor_faults,,a dimension per user group,"page faults/s","User Groups Page Faults (swap read)",stacked,,apps.plugin,groups +groups.preads,,a dimension per user group,"KiB/s","User Groups Disk Reads",stacked,,apps.plugin,groups +groups.pwrites,,a dimension per user group,"KiB/s","User Groups Disk Writes",stacked,,apps.plugin,groups +groups.lreads,,a dimension per user group,"KiB/s","User Groups Disk Logical Reads",stacked,,apps.plugin,groups +groups.lwrites,,a dimension per user group,"KiB/s","User Groups I/O Logical Writes",stacked,,apps.plugin,groups +groups.threads,,a dimension per user group,threads,"User Groups Threads",stacked,,apps.plugin,groups +groups.processes,,a dimension per user group,processes,"User Groups Processes",stacked,,apps.plugin,groups +groups.voluntary_ctxt_switches,,a dimension per app group,processes,"User Groups Voluntary Context Switches",stacked,,apps.plugin,groups +groups.involuntary_ctxt_switches,,a dimension per app group,processes,"User Groups Involuntary Context Switches",stacked,,apps.plugin,groups +groups.uptime,,a dimension per user group,seconds,"User Groups Carried Over Uptime",line,,apps.plugin,groups +groups.uptime_min,,a dimension per user group,seconds,"User Groups Minimum Uptime",line,,apps.plugin,groups +groups.uptime_avg,,a dimension per user group,seconds,"User Groups Average Uptime",line,,apps.plugin,groups +groups.uptime_max,,a dimension per user group,seconds,"User Groups Maximum Uptime",line,,apps.plugin,groups +groups.files,,a dimension per user group,"open files","User Groups Open Files",stacked,,apps.plugin,groups +groups.sockets,,a dimension per user group,"open sockets","User Groups Open Sockets",stacked,,apps.plugin,groups +groups.pipes,,a dimension per user group,"open pipes","User Groups Open Pipes",stacked,,apps.plugin,groups +users.cpu,,a dimension per user,percentage,"Users CPU Time (100% = 1 core)",stacked,,apps.plugin,users +users.cpu_user,,a dimension per user,percentage,"Users CPU User Time (100% = 1 core)",stacked,,apps.plugin,users +users.cpu_system,,a dimension per user,percentage,"Users CPU System Time (100% = 1 core)",stacked,,apps.plugin,users +users.cpu_guest,,a dimension per user,percentage,"Users CPU Guest Time (100% = 1 core)",stacked,,apps.plugin,users +users.mem,,a dimension per user,MiB,"Users Real Memory (w/o shared)",stacked,,apps.plugin,users +users.rss,,a dimension per user,MiB,"Users Resident Set Size (w/shared)",stacked,,apps.plugin,users +users.vmem,,a dimension per user,MiB,"Users Virtual Memory Size",stacked,,apps.plugin,users +users.swap,,a dimension per user,MiB,"Users Swap Memory",stacked,,apps.plugin,users +users.major_faults,,a dimension per user,"page faults/s","Users Major Page Faults (swap read)",stacked,,apps.plugin,users +users.minor_faults,,a dimension per user,"page faults/s","Users Page Faults (swap read)",stacked,,apps.plugin,users +users.preads,,a dimension per user,"KiB/s","Users Disk Reads",stacked,,apps.plugin,users +users.pwrites,,a dimension per user,"KiB/s","Users Disk Writes",stacked,,apps.plugin,users +users.lreads,,a dimension per user,"KiB/s","Users Disk Logical Reads",stacked,,apps.plugin,users +users.lwrites,,a dimension per user,"KiB/s","Users I/O Logical Writes",stacked,,apps.plugin,users +users.threads,,a dimension per user,threads,"Users Threads",stacked,,apps.plugin,users +users.processes,,a dimension per user,processes,"Users Processes",stacked,,apps.plugin,users +users.voluntary_ctxt_switches,,a dimension per app group,processes,"Users Voluntary Context Switches",stacked,,apps.plugin,users +users.involuntary_ctxt_switches,,a dimension per app group,processes,"Users Involuntary Context Switches",stacked,,apps.plugin,users +users.uptime,,a dimension per user,seconds,"Users Carried Over Uptime",line,,apps.plugin,users +users.uptime_min,,a dimension per user,seconds,"Users Minimum Uptime",line,,apps.plugin,users +users.uptime_avg,,a dimension per user,seconds,"Users Average Uptime",line,,apps.plugin,users +users.uptime_max,,a dimension per user,seconds,"Users Maximum Uptime",line,,apps.plugin,users +users.files,,a dimension per user,"open files","Users Open Files",stacked,,apps.plugin,users +users.sockets,,a dimension per user,"open sockets","Users Open Sockets",stacked,,apps.plugin,users +users.pipes,,a dimension per user,"open pipes","Users Open Pipes",stacked,,apps.plugin,users +netdata.apps_cpu,,"user, system",milliseconds/s,"Apps Plugin CPU",stacked,,apps.plugin,netdata +netdata.apps_sizes,,"calls, files, filenames, inode_changes, link_changes, pids, fds, targets, new_pids",files/s,"Apps Plugin Files",line,,apps.plugin,netdata +netdata.apps_fix,,"utime, stime, gtime, minflt, majflt",percentage,"Apps Plugin Normalization Ratios",line,,apps.plugin,netdata +netdata.apps_children_fix,,"utime, stime, gtime, minflt, majflt",percentage,"Apps Plugin Exited Children Normalization Ratios",line,,apps.plugin,netdata
\ No newline at end of file diff --git a/collectors/apps.plugin/multi_metadata.yaml b/collectors/apps.plugin/multi_metadata.yaml new file mode 100644 index 000000000..2bdb3dbf8 --- /dev/null +++ b/collectors/apps.plugin/multi_metadata.yaml @@ -0,0 +1,662 @@ +name: apps.plugin +modules: + # removed system.processes_state + - meta: + plugin_name: apps.plugin + module_name: apps + monitored_instance: + name: Applications + link: '' + categories: [] + icon_filename: '' + related_resources: + integrations: + list: [] + info_provided_to_referring_integrations: + description: '' + keywords: + - applications + - processes + - os + - host monitoring + most_popular: false + overview: + data_collection: + metrics_description: '' + method_description: '' + supported_platforms: + include: [] + exclude: [] + multi-instance: true + additional_permissions: + description: '' + default_behavior: + auto_detection: + description: '' + limits: + description: '' + performance_impact: + description: '' + setup: + prerequisites: + list: [] + configuration: + file: + name: '' + description: '' + options: + description: '' + folding: + title: '' + enabled: true + list: [] + examples: + folding: + enabled: true + title: '' + list: [] + troubleshooting: + problems: + list: [] + alerts: [] + metrics: + folding: + title: Metrics + enabled: false + description: "" + availability: [] + scopes: + - name: global + description: "" + labels: [] + metrics: + - name: apps.cpu + description: Apps CPU Time (100% = 1 core) + unit: "percentage" + chart_type: stacked + dimensions: + - name: a dimension per app group + - name: apps.cpu_user + description: Apps CPU User Time (100% = 1 core) + unit: "percentage" + chart_type: stacked + dimensions: + - name: a dimension per app group + - name: apps.cpu_system + description: Apps CPU System Time (100% = 1 core) + unit: "percentage" + chart_type: stacked + dimensions: + - name: a dimension per app group + - name: apps.cpu_guest + description: Apps CPU Guest Time (100% = 1 core) + unit: "percentage" + chart_type: stacked + dimensions: + - name: a dimension per app group + - name: apps.mem + description: Apps Real Memory (w/o shared) + unit: "MiB" + chart_type: stacked + dimensions: + - name: a dimension per app group + - name: apps.rss + description: Apps Resident Set Size (w/shared) + unit: "MiB" + chart_type: stacked + dimensions: + - name: a dimension per app group + - name: apps.vmem + description: Apps Virtual Memory Size + unit: "MiB" + chart_type: stacked + dimensions: + - name: a dimension per app group + - name: apps.swap + description: Apps Swap Memory + unit: "MiB" + chart_type: stacked + dimensions: + - name: a dimension per app group + - name: apps.major_faults + description: Apps Major Page Faults (swap read) + unit: "page faults/s" + chart_type: stacked + dimensions: + - name: a dimension per app group + - name: apps.minor_faults + description: Apps Minor Page Faults (swap read) + unit: "page faults/s" + chart_type: stacked + dimensions: + - name: a dimension per app group + - name: apps.preads + description: Apps Disk Reads + unit: "KiB/s" + chart_type: stacked + dimensions: + - name: a dimension per app group + - name: apps.pwrites + description: Apps Disk Writes + unit: "KiB/s" + chart_type: stacked + dimensions: + - name: a dimension per app group + - name: apps.lreads + description: Apps Disk Logical Reads + unit: "KiB/s" + chart_type: stacked + dimensions: + - name: a dimension per app group + - name: apps.lwrites + description: Apps I/O Logical Writes + unit: "KiB/s" + chart_type: stacked + dimensions: + - name: a dimension per app group + - name: apps.threads + description: Apps Threads + unit: "threads" + chart_type: stacked + dimensions: + - name: a dimension per app group + - name: apps.processes + description: Apps Processes + unit: "processes" + chart_type: stacked + dimensions: + - name: a dimension per app group + - name: apps.voluntary_ctxt_switches + description: Apps Voluntary Context Switches + unit: "processes" + chart_type: stacked + dimensions: + - name: a dimension per app group + - name: apps.involuntary_ctxt_switches + description: Apps Involuntary Context Switches + unit: "processes" + chart_type: stacked + dimensions: + - name: a dimension per app group + - name: apps.uptime + description: Apps Carried Over Uptime + unit: "seconds" + chart_type: line + dimensions: + - name: a dimension per app group + - name: apps.uptime_min + description: Apps Minimum Uptime + unit: "seconds" + chart_type: line + dimensions: + - name: a dimension per app group + - name: apps.uptime_avg + description: Apps Average Uptime + unit: "seconds" + chart_type: line + dimensions: + - name: a dimension per app group + - name: apps.uptime_max + description: Apps Maximum Uptime + unit: "seconds" + chart_type: line + dimensions: + - name: a dimension per app group + - name: apps.files + description: Apps Open Files + unit: "open files" + chart_type: stacked + dimensions: + - name: a dimension per app group + - name: apps.sockets + description: Apps Open Sockets + unit: "open sockets" + chart_type: stacked + dimensions: + - name: a dimension per app group + - name: apps.pipes + description: Apps Open Pipes + unit: "open pipes" + chart_type: stacked + dimensions: + - name: a dimension per app group + - meta: + plugin_name: apps.plugin + module_name: groups + monitored_instance: + name: User Groups + link: '' + categories: [] + icon_filename: '' + related_resources: + integrations: + list: [] + info_provided_to_referring_integrations: + description: '' + keywords: + - groups + - processes + - user auditing + - authorization + - os + - host monitoring + most_popular: false + overview: + data_collection: + metrics_description: '' + method_description: '' + supported_platforms: + include: [] + exclude: [] + multi-instance: true + additional_permissions: + description: '' + default_behavior: + auto_detection: + description: '' + limits: + description: '' + performance_impact: + description: '' + setup: + prerequisites: + list: [] + configuration: + file: + name: '' + description: '' + options: + description: '' + folding: + title: '' + enabled: true + list: [] + examples: + folding: + enabled: true + title: '' + list: [] + troubleshooting: + problems: + list: [] + alerts: [] + metrics: + folding: + title: Metrics + enabled: false + description: "" + availability: [] + scopes: + - name: global + description: "" + labels: [] + metrics: + - name: groups.cpu + description: User Groups CPU Time (100% = 1 core) + unit: "percentage" + chart_type: stacked + dimensions: + - name: a dimension per user group + - name: groups.cpu_user + description: User Groups CPU User Time (100% = 1 core) + unit: "percentage" + chart_type: stacked + dimensions: + - name: a dimension per user group + - name: groups.cpu_system + description: User Groups CPU System Time (100% = 1 core) + unit: "percentage" + chart_type: stacked + dimensions: + - name: a dimension per user group + - name: groups.cpu_guest + description: User Groups CPU Guest Time (100% = 1 core) + unit: "percentage" + chart_type: stacked + dimensions: + - name: a dimension per user group + - name: groups.mem + description: User Groups Real Memory (w/o shared) + unit: "MiB" + chart_type: stacked + dimensions: + - name: a dimension per user group + - name: groups.rss + description: User Groups Resident Set Size (w/shared) + unit: "MiB" + chart_type: stacked + dimensions: + - name: a dimension per user group + - name: groups.vmem + description: User Groups Virtual Memory Size + unit: "MiB" + chart_type: stacked + dimensions: + - name: a dimension per user group + - name: groups.swap + description: User Groups Swap Memory + unit: "MiB" + chart_type: stacked + dimensions: + - name: a dimension per user group + - name: groups.major_faults + description: User Groups Major Page Faults (swap read) + unit: "page faults/s" + chart_type: stacked + dimensions: + - name: a dimension per user group + - name: groups.minor_faults + description: User Groups Page Faults (swap read) + unit: "page faults/s" + chart_type: stacked + dimensions: + - name: a dimension per user group + - name: groups.preads + description: User Groups Disk Reads + unit: "KiB/s" + chart_type: stacked + dimensions: + - name: a dimension per user group + - name: groups.pwrites + description: User Groups Disk Writes + unit: "KiB/s" + chart_type: stacked + dimensions: + - name: a dimension per user group + - name: groups.lreads + description: User Groups Disk Logical Reads + unit: "KiB/s" + chart_type: stacked + dimensions: + - name: a dimension per user group + - name: groups.lwrites + description: User Groups I/O Logical Writes + unit: "KiB/s" + chart_type: stacked + dimensions: + - name: a dimension per user group + - name: groups.threads + description: User Groups Threads + unit: "threads" + chart_type: stacked + dimensions: + - name: a dimension per user group + - name: groups.processes + description: User Groups Processes + unit: "processes" + chart_type: stacked + dimensions: + - name: a dimension per user group + - name: groups.voluntary_ctxt_switches + description: User Groups Voluntary Context Switches + unit: "processes" + chart_type: stacked + dimensions: + - name: a dimension per app group + - name: groups.involuntary_ctxt_switches + description: User Groups Involuntary Context Switches + unit: "processes" + chart_type: stacked + dimensions: + - name: a dimension per app group + - name: groups.uptime + description: User Groups Carried Over Uptime + unit: "seconds" + chart_type: line + dimensions: + - name: a dimension per user group + - name: groups.uptime_min + description: User Groups Minimum Uptime + unit: "seconds" + chart_type: line + dimensions: + - name: a dimension per user group + - name: groups.uptime_avg + description: User Groups Average Uptime + unit: "seconds" + chart_type: line + dimensions: + - name: a dimension per user group + - name: groups.uptime_max + description: User Groups Maximum Uptime + unit: "seconds" + chart_type: line + dimensions: + - name: a dimension per user group + - name: groups.files + description: User Groups Open Files + unit: "open files" + chart_type: stacked + dimensions: + - name: a dimension per user group + - name: groups.sockets + description: User Groups Open Sockets + unit: "open sockets" + chart_type: stacked + dimensions: + - name: a dimension per user group + - name: groups.pipes + description: User Groups Open Pipes + unit: "open pipes" + chart_type: stacked + dimensions: + - name: a dimension per user group + - meta: + plugin_name: apps.plugin + module_name: users + monitored_instance: + name: Users + link: '' + categories: [] + icon_filename: '' + related_resources: + integrations: + list: [] + info_provided_to_referring_integrations: + description: '' + keywords: + - users + - processes + - os + - host monitoring + most_popular: false + overview: + data_collection: + metrics_description: '' + method_description: '' + supported_platforms: + include: [] + exclude: [] + multi-instance: true + additional_permissions: + description: '' + default_behavior: + auto_detection: + description: '' + limits: + description: '' + performance_impact: + description: '' + setup: + prerequisites: + list: [] + configuration: + file: + name: '' + description: '' + options: + description: '' + folding: + title: '' + enabled: true + list: [] + examples: + folding: + enabled: true + title: '' + list: [] + troubleshooting: + problems: + list: [] + alerts: [] + metrics: + folding: + title: Metrics + enabled: false + description: "" + availability: [] + scopes: + - name: global + description: "" + labels: [] + metrics: + - name: users.cpu + description: Users CPU Time (100% = 1 core) + unit: "percentage" + chart_type: stacked + dimensions: + - name: a dimension per user + - name: users.cpu_user + description: Users CPU User Time (100% = 1 core) + unit: "percentage" + chart_type: stacked + dimensions: + - name: a dimension per user + - name: users.cpu_system + description: Users CPU System Time (100% = 1 core) + unit: "percentage" + chart_type: stacked + dimensions: + - name: a dimension per user + - name: users.cpu_guest + description: Users CPU Guest Time (100% = 1 core) + unit: "percentage" + chart_type: stacked + dimensions: + - name: a dimension per user + - name: users.mem + description: Users Real Memory (w/o shared) + unit: "MiB" + chart_type: stacked + dimensions: + - name: a dimension per user + - name: users.rss + description: Users Resident Set Size (w/shared) + unit: "MiB" + chart_type: stacked + dimensions: + - name: a dimension per user + - name: users.vmem + description: Users Virtual Memory Size + unit: "MiB" + chart_type: stacked + dimensions: + - name: a dimension per user + - name: users.swap + description: Users Swap Memory + unit: "MiB" + chart_type: stacked + dimensions: + - name: a dimension per user + - name: users.major_faults + description: Users Major Page Faults (swap read) + unit: "page faults/s" + chart_type: stacked + dimensions: + - name: a dimension per user + - name: users.minor_faults + description: Users Page Faults (swap read) + unit: "page faults/s" + chart_type: stacked + dimensions: + - name: a dimension per user + - name: users.preads + description: Users Disk Reads + unit: "KiB/s" + chart_type: stacked + dimensions: + - name: a dimension per user + - name: users.pwrites + description: Users Disk Writes + unit: "KiB/s" + chart_type: stacked + dimensions: + - name: a dimension per user + - name: users.lreads + description: Users Disk Logical Reads + unit: "KiB/s" + chart_type: stacked + dimensions: + - name: a dimension per user + - name: users.lwrites + description: Users I/O Logical Writes + unit: "KiB/s" + chart_type: stacked + dimensions: + - name: a dimension per user + - name: users.threads + description: Users Threads + unit: "threads" + chart_type: stacked + dimensions: + - name: a dimension per user + - name: users.processes + description: Users Processes + unit: "processes" + chart_type: stacked + dimensions: + - name: a dimension per user + - name: users.voluntary_ctxt_switches + description: Users Voluntary Context Switches + unit: "processes" + chart_type: stacked + dimensions: + - name: a dimension per app group + - name: users.involuntary_ctxt_switches + description: Users Involuntary Context Switches + unit: "processes" + chart_type: stacked + dimensions: + - name: a dimension per app group + - name: users.uptime + description: Users Carried Over Uptime + unit: "seconds" + chart_type: line + dimensions: + - name: a dimension per user + - name: users.uptime_min + description: Users Minimum Uptime + unit: "seconds" + chart_type: line + dimensions: + - name: a dimension per user + - name: users.uptime_avg + description: Users Average Uptime + unit: "seconds" + chart_type: line + dimensions: + - name: a dimension per user + - name: users.uptime_max + description: Users Maximum Uptime + unit: "seconds" + chart_type: line + dimensions: + - name: a dimension per user + - name: users.files + description: Users Open Files + unit: "open files" + chart_type: stacked + dimensions: + - name: a dimension per user + - name: users.sockets + description: Users Open Sockets + unit: "open sockets" + chart_type: stacked + dimensions: + - name: a dimension per user + - name: users.pipes + description: Users Open Pipes + unit: "open pipes" + chart_type: stacked + dimensions: + - name: a dimension per user |