#
# The apps.plugin displays charts with information about the processes running.
# This config allows grouping processes together, so that several processes
-# will be reported together.
+# will be reported as one.
#
# Only groups in this file are reported. All other processes will be reported
# as 'other'.
#
# The format is:
#
-# group_name: process1 process2 process3 ...
+# group: process1 process2 process3 ...
#
-# The process names are the same to the ones returned by: ps -e
-# or /proc/PID/stat, or in case of substring mode: /proc/PID/cmdline
+# Each group can be given multiple times, to add more processes to it.
+#
+# The process names are the ones returned by:
+#
+# - ps -e or /proc/PID/stat
+# - in case of substring mode (see below): /proc/PID/cmdline
#
# To add process names with spaces, enclose them in quotes (single or double)
-# example: 'Plex Media Serv' "my other process"
+# example: 'Plex Media Serv' "my other process".
#
# Wildcard support:
-# You can add an asterisk (*) at the beginning and/or the end of a process name:
-# *name suffix mode: will search for processes ending with 'name' (/proc/PID/stat)
-# name* prefix mode: will search for processes beginning with 'name' (/proc/PID/stat)
-# *name* substring mode: will search for 'name' in the whole command line (/proc/PID/cmdline)
+# You can add an asterisk (*) at the beginning and/or the end of a process:
+#
+# *name suffix mode: will search for processes ending with 'name'
+# (/proc/PID/stat)
+#
+# name* prefix mode: will search for processes beginning with 'name'
+# (/proc/PID/stat)
+#
+# *name* substring mode: will search for 'name' in the whole command line
+# (/proc/PID/cmdline)
#
# If you enter even just one *name* (substring), apps.plugin will process
# /proc/PID/cmdline for all processes, just once (when they are first seen).
#
-# To add process names with single quotes, enclose them in double quotes
+# To add processes with single quotes, enclose them in double quotes
# example: "process with this ' single quote"
#
-# To add process names with double quotes, enclose them in single quotes:
+# To add processes with double quotes, enclose them in single quotes:
# example: 'process with this " double quote'
#
-# If a group name starts with a -, the dimension will be hidden (cpu chart only)
+# If a group or process name starts with a -, the dimension will be hidden
+# (cpu chart only).
#
-# If any process name starts with a +, debugging will be enabled for it
+# If a process starts with a +, debugging will be enabled for it
# (debugging produces a lot of output - do not enable it in production systems)
#
# You can add any number of groups you like. Only the ones found running will
pbx: asterisk safe_asterisk *vicidial*
sip: opensips* stund
-murmur: murmurd
-xmpp: *vines* *prosody*
+
+# -----------------------------------------------------------------------------
+# chat
+
+chat: irssi *vines* *prosody* murmurd
# -----------------------------------------------------------------------------
# monitoring
# -----------------------------------------------------------------------------
# installation / compilation / debugging
-build: cc1 cc1plus as gcc* ld make automake autoconf autoreconf git valgrind*
+build: cc1 cc1plus as gcc* cppcheck ld make cmake automake autoconf autoreconf
+build: git gdb valgrind*
# -----------------------------------------------------------------------------
# antivirus
# -----------------------------------------------------------------------------
# torrent clients
-torrents: *deluge* transmission* *SickBeard*
+torrents: *deluge* transmission* *SickBeard* *CouchPotato*
# -----------------------------------------------------------------------------
# backup servers and clients
ups: upsmon upsd */nut/*
# -----------------------------------------------------------------------------
-# Kernel / System
+# media players, servers, clients
-system: systemd* udisks* udevd* *udevd connmand ipv6_addrconf dbus-* inetd xinetd mdadm polkitd acpid uuidd
-kernel: kthreadd kauditd lockd khelper kdevtmpfs khungtaskd rpciod fsnotify_mark kthrotld deferwq scsi_*
-ksmd: ksmd
+media: mplayer vlc xine mediatomb omxplayer* kodi* xbmc* mediacenter eventlircd
+media: mpd minidlnad mt-daapd avahi* Plex*
# -----------------------------------------------------------------------------
-# media players, servers, clients
+# X
-media: mplayer vlc xine mediatomb omxplayer* kodi* xbmc* mediacenter eventlircd mpd minidlnad mt-daapd avahi* Plex*
+X: X Xorg xinit lightdm xdm pulseaudio gkrellm xfwm4 xfdesktop xfce* Thunar
+X: xfsettingsd xfconfd gnome-* gdm gconf* dconf* xfconf* *gvfs gvfs* kdm slim
+X: evolution-* firefox chromium opera epiphany WebKit*
# -----------------------------------------------------------------------------
-# X
+# Kernel / System
+
+ksmd: ksmd
+
+system: systemd* udisks* udevd* *udevd connmand ipv6_addrconf dbus-* rtkit*
+system: inetd xinetd mdadm polkitd acpid uuidd packagekitd upowerd colord
+system: accounts-daemon
-X: X lightdm xdm pulseaudio gkrellm xfwm4 xfdesktop xfce* Thunar xfsettingsd xfconfd gnome-* gdm gconfd-2 *gvfsd gvfsd* kdm slim
+kernel: kthreadd kauditd lockd khelper kdevtmpfs khungtaskd rpciod
+kernel: fsnotify_mark kthrotld deferwq scsi_*
# -----------------------------------------------------------------------------
# other application servers
crsproxy: crsproxy
sidekiq: *sidekiq*
java: java
-chat: irssi
ipfs: ipfs
// find or create a new target
// there are targets that are just aggregated to other target (the second argument)
-struct target *get_apps_groups_target(const char *id, struct target *target) {
- int tdebug = 0, thidden = 0, ends_with = 0;
+struct target *get_apps_groups_target(const char *id, struct target *target, const char *name) {
+ int tdebug = 0, thidden = target?target->hidden:0, ends_with = 0;
const char *nid = id;
+ // extract the options
while(nid[0] == '-' || nid[0] == '+' || nid[0] == '*') {
if(nid[0] == '-') thidden = 1;
if(nid[0] == '+') tdebug = 1;
}
uint32_t hash = simple_hash(id);
+ // find if it already exists
struct target *w, *last = apps_groups_root_target;
for(w = apps_groups_root_target ; w ; w = w->next) {
if(w->idhash == hash && strncmp(nid, w->id, MAX_NAME) == 0)
last = w;
}
+ // find an existing target
+ if(unlikely(!target)) {
+ while(*name == '-') {
+ if(*name == '-') thidden = 1;
+ name++;
+ }
+ for(target = apps_groups_root_target ; target ; target = target->next) {
+ if(!target->target && strcmp(name, target->name) == 0)
+ break;
+ }
+ if(unlikely(debug)) {
+ if(unlikely(target))
+ fprintf(stderr, "apps.plugin: REUSING TARGET NAME '%s' on ID '%s'\n", target->name, target->id);
+ else
+ fprintf(stderr, "apps.plugin: NEW TARGET NAME '%s' on ID '%s'\n", name, id);
+ }
+ }
+
+ if(target && target->target)
+ fatal("Internal Error: request to link process '%s' to target '%s' which is linked to target '%s'", id, target->id, target->target->id);
+
w = callocz(sizeof(struct target), 1);
strncpyz(w->id, nid, MAX_NAME);
w->idhash = simple_hash(w->id);
- strncpyz(w->name, nid, MAX_NAME);
+ if(unlikely(!target))
+ // copy the name
+ strncpyz(w->name, name, MAX_NAME);
+ else
+ // copy the id
+ strncpyz(w->name, nid, MAX_NAME);
strncpyz(w->compare, nid, MAX_COMPARE_NAME);
size_t len = strlen(w->compare);
fprintf(stderr, "apps.plugin: ADDING TARGET ID '%s', process name '%s' (%s), aggregated on target '%s', options: %s %s\n"
, w->id
, w->compare, (w->starts_with && w->ends_with)?"substring":((w->starts_with)?"prefix":((w->ends_with)?"suffix":"exact"))
- , w->target?w->target->id:w->id
+ , w->target?w->target->name:w->name
, (w->hidden)?"hidden":"-"
, (w->debug)?"debug":"-"
);
}
// read the apps_groups.conf file
-int read_apps_groups_conf(const char *name)
+int read_apps_groups_conf(const char *file)
{
char filename[FILENAME_MAX + 1];
- snprintfz(filename, FILENAME_MAX, "%s/apps_%s.conf", config_dir, name);
+ snprintfz(filename, FILENAME_MAX, "%s/apps_%s.conf", config_dir, file);
if(unlikely(debug))
fprintf(stderr, "apps.plugin: process groups file: '%s'\n", filename);
for(line = 0; line < lines ;line++) {
unsigned long word, words = procfile_linewords(ff, line);
- struct target *w = NULL;
+ if(!words) continue;
+
+ char *name = procfile_lineword(ff, line, 0);
+ if(!name || !*name) continue;
- char *t = procfile_lineword(ff, line, 0);
- if(!t || !*t) continue;
+ // find a possibly existing target
+ struct target *w = NULL;
+ // loop through all words, skipping the first one (the name)
for(word = 0; word < words ;word++) {
char *s = procfile_lineword(ff, line, word);
if(!s || !*s) continue;
if(*s == '#') break;
- if(t == s) continue;
+ // is this the first word? skip it
+ if(s == name) continue;
- struct target *n = get_apps_groups_target(s, w);
+ // add this target
+ struct target *n = get_apps_groups_target(s, w, name);
if(!n) {
error("Cannot create target '%s' (line %lu, word %lu)", s, line, word);
continue;
}
- if(!w) w = n;
- }
-
- if(w) {
- int tdebug = 0, thidden = 0;
-
- while(t[0] == '-' || t[0] == '+') {
- if(t[0] == '-') thidden = 1;
- if(t[0] == '+') tdebug = 1;
- t++;
- }
-
- strncpyz(w->name, t, MAX_NAME);
- w->hidden = thidden;
- w->debug = tdebug;
-
- if(unlikely(debug))
- fprintf(stderr, "apps.plugin: AGGREGATION TARGET NAME '%s' on ID '%s', process name '%s' (%s), aggregated on target '%s', options: %s %s\n"
- , w->name
- , w->id
- , w->compare, (w->starts_with && w->ends_with)?"substring":((w->starts_with)?"prefix":((w->ends_with)?"suffix":"exact"))
- , w->target?w->target->id:w->id
- , (w->hidden)?"hidden":"-"
- , (w->debug)?"debug":"-"
- );
+ // just some optimization
+ // to avoid searching for a target for each process
+ if(!w) w = n->target?n->target:n;
}
}
procfile_close(ff);
- apps_groups_default_target = get_apps_groups_target("p+!o@w#e$i^r&7*5(-i)l-o_", NULL); // match nothing
+ apps_groups_default_target = get_apps_groups_target("p+!o@w#e$i^r&7*5(-i)l-o_", NULL, "other"); // match nothing
if(!apps_groups_default_target)
- error("Cannot create default target");
- else
- strncpyz(apps_groups_default_target->name, "other", MAX_NAME);
+ fatal("Cannot create default target");
+
+ // allow the user to override group 'other'
+ if(apps_groups_default_target->target)
+ apps_groups_default_target = apps_groups_default_target->target;
return 0;
}