From: Florian Forster Date: Fri, 10 May 2013 07:04:27 +0000 (+0200) Subject: cgroups plugin: Rename the "cgroups_cpuacct" plugin. X-Git-Tag: collectd-5.4.0~47 X-Git-Url: https://git.octo.it/?a=commitdiff_plain;h=9e1b0c68677c537343cbe8b057ed4ecd52db8164;p=collectd.git cgroups plugin: Rename the "cgroups_cpuacct" plugin. The new name is sufficient and much easier to type / remember. --- diff --git a/configure.in b/configure.in index 7a25a0d3..7e5407cf 100644 --- a/configure.in +++ b/configure.in @@ -4630,6 +4630,7 @@ dependency_error="no" plugin_ascent="no" plugin_battery="no" plugin_bind="no" +plugin_cgroups="no" plugin_conntrack="no" plugin_contextswitch="no" plugin_cpu="no" @@ -4673,6 +4674,7 @@ then plugin_battery="yes" plugin_conntrack="yes" plugin_contextswitch="yes" + plugin_cgroups="yes" plugin_cpu="yes" plugin_cpufreq="yes" plugin_disk="yes" @@ -4956,7 +4958,7 @@ AC_PLUGIN([csv], [yes], [CSV output plugin]) AC_PLUGIN([curl], [$with_libcurl], [CURL generic web statistics]) AC_PLUGIN([curl_json], [$plugin_curl_json], [CouchDB statistics]) AC_PLUGIN([curl_xml], [$plugin_curl_xml], [CURL generic xml statistics]) -AC_PLUGIN([cgroups_cpuacct], [yes], [CGroups CPU usage accounting]) +AC_PLUGIN([cgroups], [$plugin_cgroups], [CGroups CPU usage accounting]) AC_PLUGIN([dbi], [$with_libdbi], [General database statistics]) AC_PLUGIN([df], [$plugin_df], [Filesystem usage statistics]) AC_PLUGIN([disk], [$plugin_disk], [Disk usage statistics]) @@ -5287,7 +5289,7 @@ Configuration: bind . . . . . . . . $enable_bind conntrack . . . . . . $enable_conntrack contextswitch . . . . $enable_contextswitch - cgroups_cpuacct . . . $enable_cgroups_cpuacct + cgroups . . . . . . . $enable_cgroups cpu . . . . . . . . . $enable_cpu cpufreq . . . . . . . $enable_cpufreq csv . . . . . . . . . $enable_csv diff --git a/src/Makefile.am b/src/Makefile.am index 494b343b..1f57e523 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -230,12 +230,12 @@ collectd_LDADD += "-dlopen" bind.la collectd_DEPENDENCIES += bind.la endif -if BUILD_PLUGIN_CGROUPS_CPUACCT -pkglib_LTLIBRARIES += cgroups_cpuacct.la -cgroups_cpuacct_la_SOURCES = cgroups_cpuacct.c utils_mount.c utils_mount.h -cgroups_cpuacct_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" cgroups_cpuacct.la -collectd_DEPENDENCIES += cgroups_cpuacct.la +if BUILD_PLUGIN_CGROUPS +pkglib_LTLIBRARIES += cgroups.la +cgroups_la_SOURCES = cgroups.c utils_mount.c utils_mount.h +cgroups_la_LDFLAGS = -module -avoid-version +collectd_LDADD += "-dlopen" cgroups.la +collectd_DEPENDENCIES += cgroups.la endif if BUILD_PLUGIN_CONNTRACK diff --git a/src/cgroups.c b/src/cgroups.c new file mode 100644 index 00000000..ffb1740a --- /dev/null +++ b/src/cgroups.c @@ -0,0 +1,251 @@ +/** + * collectd - src/cgroups.c + * Copyright (C) 2011 Michael Stapelberg + * Copyright (C) 2013 Florian Forster + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; only version 2 of the license is applicable. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: + * Michael Stapelberg + * Florian Forster + **/ + +#include "collectd.h" +#include "common.h" +#include "plugin.h" +#include "configfile.h" +#include "utils_mount.h" +#include "utils_ignorelist.h" + +static char const *config_keys[] = +{ + "CGroup", + "IgnoreSelected" +}; +static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); + +static ignorelist_t *il_cgroup = NULL; + +__attribute__ ((nonnull(1))) +__attribute__ ((nonnull(2))) +static void cgroups_submit_one (char const *plugin_instance, + char const *type_instance, value_t value) +{ + value_list_t vl = VALUE_LIST_INIT; + + vl.values = &value; + vl.values_len = 1; + sstrncpy (vl.host, hostname_g, sizeof (vl.host)); + sstrncpy (vl.plugin, "cgroups", sizeof (vl.plugin)); + sstrncpy (vl.plugin_instance, plugin_instance, + sizeof (vl.plugin_instance)); + sstrncpy (vl.type, "cpu", sizeof (vl.type)); + sstrncpy (vl.type_instance, type_instance, + sizeof (vl.type_instance)); + + plugin_dispatch_values (&vl); +} /* void cgroups_submit_one */ + +/* + * This callback reads the user/system CPU time for each cgroup. + */ +static int read_cpuacct_procs (const char *dirname, char const *cgroup_name, + void *user_data) +{ + char abs_path[PATH_MAX]; + struct stat statbuf; + char buf[1024]; + int status; + + FILE *fh; + + if (ignorelist_match (il_cgroup, cgroup_name)) + return (0); + + ssnprintf (abs_path, sizeof (abs_path), "%s/%s", dirname, cgroup_name); + + status = lstat (abs_path, &statbuf); + if (status != 0) + { + ERROR ("cgroups plugin: stat (\"%s\") failed.", + abs_path); + return (-1); + } + + /* We are only interested in directories, so skip everything else. */ + if (!S_ISDIR (statbuf.st_mode)) + return (0); + + ssnprintf (abs_path, sizeof (abs_path), "%s/%s/cpuacct.stat", + dirname, cgroup_name); + fh = fopen (abs_path, "r"); + if (fh == NULL) + { + char errbuf[1024]; + ERROR ("cgroups pluign: fopen (\"%s\") failed: %s", + abs_path, + sstrerror (errno, errbuf, sizeof (errbuf))); + return (-1); + } + + while (fgets (buf, sizeof (buf), fh) != NULL) + { + char *fields[8]; + int numfields = 0; + char *key; + size_t key_len; + value_t value; + + /* Expected format: + * + * user: 12345 + * system: 23456 + */ + strstripnewline (buf); + numfields = strsplit (buf, fields, STATIC_ARRAY_SIZE (fields)); + if (numfields != 2) + continue; + + key = fields[0]; + key_len = strlen (key); + if (key_len < 2) + continue; + + /* Strip colon off the first column */ + if (key[key_len - 1] != ':') + continue; + key[key_len - 1] = 0; + + status = parse_value (fields[1], &value, DS_TYPE_DERIVE); + if (status != 0) + continue; + + cgroups_submit_one (cgroup_name, key, value); + } + + fclose (fh); + return (0); +} /* int read_cpuacct_procs */ + +/* + * Gets called for every file/folder in /sys/fs/cgroup/cpu,cpuacct (or + * whereever cpuacct is mounted on the system). Calls walk_directory with the + * read_cpuacct_procs callback on every folder it finds, such as "system". + */ +static int read_cpuacct_root (const char *dirname, const char *filename, + void *user_data) +{ + char abs_path[PATH_MAX]; + struct stat statbuf; + int status; + + ssnprintf (abs_path, sizeof (abs_path), "%s/%s", dirname, filename); + + status = lstat (abs_path, &statbuf); + if (status != 0) + { + ERROR ("cgroups plugin: stat (%s) failed.", abs_path); + return (-1); + } + + if (S_ISDIR (statbuf.st_mode)) + { + status = walk_directory (abs_path, read_cpuacct_procs, + /* user_data = */ NULL, + /* include_hidden = */ 0); + return (status); + } + + return (0); +} + +static int cgroups_init (void) +{ + if (il_cgroup == NULL) + il_cgroup = ignorelist_create (1); + + return (0); +} + +static int cgroups_config (const char *key, const char *value) +{ + cgroups_init (); + + if (strcasecmp (key, "CGroup") == 0) + { + if (ignorelist_add (il_cgroup, value)) + return (1); + return (0); + } + else if (strcasecmp (key, "IgnoreSelected") == 0) + { + if (IS_TRUE (value)) + ignorelist_set_invert (il_cgroup, 0); + else + ignorelist_set_invert (il_cgroup, 1); + return (0); + } + + return (-1); +} + +static int cgroups_read (void) +{ + cu_mount_t *mnt_list; + cu_mount_t *mnt_ptr; + _Bool cgroup_found = 0; + + mnt_list = NULL; + if (cu_mount_getlist (&mnt_list) == NULL) + { + ERROR ("cgroups plugin: cu_mount_getlist failed."); + return (-1); + } + + for (mnt_ptr = mnt_list; mnt_ptr != NULL; mnt_ptr = mnt_ptr->next) + { + /* Find the cgroup mountpoint which contains the cpuacct + * controller. */ + if (strcmp(mnt_ptr->type, "cgroup") != 0 || + !cu_mount_getoptionvalue(mnt_ptr->options, "cpuacct")) + continue; + + walk_directory (mnt_ptr->dir, read_cpuacct_root, + /* user_data = */ NULL, + /* include_hidden = */ 0); + cgroup_found = 1; + /* It doesn't make sense to check other cpuacct mount-points + * (if any), they contain the same data. */ + break; + } + + cu_mount_freelist (mnt_list); + + if (!cgroup_found) + { + WARNING ("cgroups plugin: Unable to find cgroup " + "mount-point with the \"cpuacct\" option."); + return (-1); + } + + return (0); +} /* int cgroup_read */ + +void module_register (void) +{ + plugin_register_config ("cgroups", cgroups_config, + config_keys, config_keys_num); + plugin_register_init ("cgroups", cgroups_init); + plugin_register_read ("cgroups", cgroups_read); +} /* void module_register */ diff --git a/src/cgroups_cpuacct.c b/src/cgroups_cpuacct.c deleted file mode 100644 index f4503894..00000000 --- a/src/cgroups_cpuacct.c +++ /dev/null @@ -1,249 +0,0 @@ -/** - * collectd - src/cgroups_cpuacct.c - * Copyright (C) 2011 Michael Stapelberg - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; only version 2 of the license is applicable. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Authors: - * Michael Stapelberg - **/ - -#include "collectd.h" -#include "common.h" -#include "plugin.h" -#include "configfile.h" -#include "utils_mount.h" -#include "utils_ignorelist.h" - -static char const *config_keys[] = -{ - "CGroup", - "IgnoreSelected" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); - -static ignorelist_t *il_cgroup = NULL; - -__attribute__ ((nonnull(1))) -__attribute__ ((nonnull(2))) -static void cgroups_submit_one (char const *plugin_instance, - char const *type_instance, value_t value) -{ - value_list_t vl = VALUE_LIST_INIT; - - vl.values = &value; - vl.values_len = 1; - sstrncpy (vl.host, hostname_g, sizeof (vl.host)); - sstrncpy (vl.plugin, "cgroups_cpuacct", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, plugin_instance, - sizeof (vl.plugin_instance)); - sstrncpy (vl.type, "cpu", sizeof (vl.type)); - sstrncpy (vl.type_instance, type_instance, - sizeof (vl.type_instance)); - - plugin_dispatch_values (&vl); -} /* void cgroups_submit_one */ - -/* - * This callback reads the user/system CPU time for each cgroup. - */ -static int read_cpuacct_procs (const char *dirname, char const *cgroup_name, - void *user_data) -{ - char abs_path[PATH_MAX]; - struct stat statbuf; - char buf[1024]; - int status; - - FILE *fh; - - if (ignorelist_match (il_cgroup, cgroup_name)) - return (0); - - ssnprintf (abs_path, sizeof (abs_path), "%s/%s", dirname, cgroup_name); - - status = lstat (abs_path, &statbuf); - if (status != 0) - { - ERROR ("cgroups_cpuacct plugin: stat (\"%s\") failed.", - abs_path); - return (-1); - } - - /* We are only interested in directories, so skip everything else. */ - if (!S_ISDIR (statbuf.st_mode)) - return (0); - - ssnprintf (abs_path, sizeof (abs_path), "%s/%s/cpuacct.stat", - dirname, cgroup_name); - fh = fopen (abs_path, "r"); - if (fh == NULL) - { - char errbuf[1024]; - ERROR ("cgroups_cpuacct pluign: fopen (\"%s\") failed: %s", - abs_path, - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - while (fgets (buf, sizeof (buf), fh) != NULL) - { - char *fields[8]; - int numfields = 0; - char *key; - size_t key_len; - value_t value; - - /* Expected format: - * - * user: 12345 - * system: 23456 - */ - strstripnewline (buf); - numfields = strsplit (buf, fields, STATIC_ARRAY_SIZE (fields)); - if (numfields != 2) - continue; - - key = fields[0]; - key_len = strlen (key); - if (key_len < 2) - continue; - - /* Strip colon off the first column */ - if (key[key_len - 1] != ':') - continue; - key[key_len - 1] = 0; - - status = parse_value (fields[1], &value, DS_TYPE_DERIVE); - if (status != 0) - continue; - - cgroups_submit_one (cgroup_name, key, value); - } - - fclose (fh); - return (0); -} /* int read_cpuacct_procs */ - -/* - * Gets called for every file/folder in /sys/fs/cgroup/cpu,cpuacct (or - * whereever cpuacct is mounted on the system). Calls walk_directory with the - * read_cpuacct_procs callback on every folder it finds, such as "system". - */ -static int read_cpuacct_root (const char *dirname, const char *filename, - void *user_data) -{ - char abs_path[PATH_MAX]; - struct stat statbuf; - int status; - - ssnprintf (abs_path, sizeof (abs_path), "%s/%s", dirname, filename); - - status = lstat (abs_path, &statbuf); - if (status != 0) - { - ERROR ("cgroups_cpuacct plugin: stat (%s) failed.", abs_path); - return (-1); - } - - if (S_ISDIR (statbuf.st_mode)) - { - status = walk_directory (abs_path, read_cpuacct_procs, - /* user_data = */ NULL, - /* include_hidden = */ 0); - return (status); - } - - return (0); -} - -static int cgroups_init (void) -{ - if (il_cgroup == NULL) - il_cgroup = ignorelist_create (1); - - return (0); -} - -static int cgroups_config (const char *key, const char *value) -{ - cgroups_init (); - - if (strcasecmp (key, "CGroup") == 0) - { - if (ignorelist_add (il_cgroup, value)) - return (1); - return (0); - } - else if (strcasecmp (key, "IgnoreSelected") == 0) - { - if (IS_TRUE (value)) - ignorelist_set_invert (il_cgroup, 0); - else - ignorelist_set_invert (il_cgroup, 1); - return (0); - } - - return (-1); -} - -static int cgroups_read (void) -{ - cu_mount_t *mnt_list; - cu_mount_t *mnt_ptr; - _Bool cgroup_found = 0; - - mnt_list = NULL; - if (cu_mount_getlist (&mnt_list) == NULL) - { - ERROR ("cgroups_cpuacct plugin: cu_mount_getlist failed."); - return (-1); - } - - for (mnt_ptr = mnt_list; mnt_ptr != NULL; mnt_ptr = mnt_ptr->next) - { - /* Find the cgroup mountpoint which contains the cpuacct - * controller. */ - if (strcmp(mnt_ptr->type, "cgroup") != 0 || - !cu_mount_getoptionvalue(mnt_ptr->options, "cpuacct")) - continue; - - walk_directory (mnt_ptr->dir, read_cpuacct_root, - /* user_data = */ NULL, - /* include_hidden = */ 0); - cgroup_found = 1; - /* It doesn't make sense to check other cpuacct mount-points - * (if any), they contain the same data. */ - break; - } - - cu_mount_freelist (mnt_list); - - if (!cgroup_found) - { - WARNING ("cgroups_cpuacct plugin: Unable to find cgroup " - "mount-point with the \"cpuacct\" option."); - return (-1); - } - - return (0); -} /* int cgroup_read */ - -void module_register (void) -{ - plugin_register_config ("cgroups_cpuacct", cgroups_config, - config_keys, config_keys_num); - plugin_register_init ("cgroups_cpuacct", cgroups_init); - plugin_register_read ("cgroups_cpuacct", cgroups_read); -} /* void module_register */ diff --git a/src/collectd.conf.in b/src/collectd.conf.in index 736c9741..511244ef 100644 --- a/src/collectd.conf.in +++ b/src/collectd.conf.in @@ -72,7 +72,7 @@ #@BUILD_PLUGIN_BIND_TRUE@LoadPlugin bind #@BUILD_PLUGIN_CONNTRACK_TRUE@LoadPlugin conntrack #@BUILD_PLUGIN_CONTEXTSWITCH_TRUE@LoadPlugin contextswitch -#@BUILD_PLUGIN_CGROUPS_CPUACCT_TRUE@LoadPlugin cgroups_cpuacct +#@BUILD_PLUGIN_CGROUPS_TRUE@LoadPlugin cgroups @BUILD_PLUGIN_CPU_TRUE@@BUILD_PLUGIN_CPU_TRUE@LoadPlugin cpu #@BUILD_PLUGIN_CPUFREQ_TRUE@LoadPlugin cpufreq @LOAD_PLUGIN_CSV@LoadPlugin csv diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod index d28810f3..c5d4f19f 100644 --- a/src/collectd.conf.pod +++ b/src/collectd.conf.pod @@ -852,7 +852,7 @@ By default no detailed zone information is collected. =back -=head2 Plugin C +=head2 Plugin C This plugin collects the CPU user/system time for each I by reading the F files in the first cpuacct-mountpoint (typically