./PaxHeaders.11991/collectd-5.4.00000644037772200116100000000013212204120750014430 xustar000000000000000030 mtime=1376821736.922319538 30 atime=1376821741.930399461 30 ctime=1376821741.930399461 collectd-5.4.0/0000755037772200116100000000000012204120750013114 5ustar00octoeng00000000000000collectd-5.4.0/PaxHeaders.11991/TODO0000644037772200116100000000013212204120331015033 xustar000000000000000030 mtime=1376821465.045972991 30 atime=1376821477.194167546 30 ctime=1376821741.930399461 collectd-5.4.0/TODO0000644037772200116100000000164412204120331013604 0ustar00octoeng00000000000000* Finalize the onewire plugin. * Custom notification messages? * Implement moving-average calculation for the threshold stuff. src/battery.c: commend not working code. Wishlist: * Port nfs module to solaris * Port tape module to Linux * Port the apple_sensors plugin to Linux/PPC. * Maybe look into porting the serial module * Build Darwin package * Maybe let the network plugin configure whether or not notifications should be sent/received. * Maybe find a way for processes connected to the unixsock plugin to receive notifications, too. http://developer.apple.com/documentation/DeviceDrivers/Conceptual/AccessingHardware/AH_IOKitLib_API/chapter_5_section_1.html http://developer.apple.com/documentation/DeviceDrivers/Conceptual/IOKitFundamentals/index.html#//apple_ref/doc/uid/TP0000011 http://www.gauchosoft.com/Software/X%20Resource%20Graph/ http://johannes.sipsolutions.net/PowerBook/Apple_Motion_Sensor_Specification/ collectd-5.4.0/PaxHeaders.11991/NEWS0000644037772200116100000000013212204120331015042 xustar000000000000000030 mtime=1376821465.045972991 30 atime=1376821465.045972991 30 ctime=1376821741.930399461 collectd-5.4.0/NEWS0000644037772200116100000000000012204120331013574 0ustar00octoeng00000000000000collectd-5.4.0/PaxHeaders.11991/src0000644037772200116100000000013212204120755015067 xustar000000000000000030 mtime=1376821741.422391353 30 atime=1376821741.934399524 30 ctime=1376821741.934399524 collectd-5.4.0/src/0000755037772200116100000000000012204120755013710 5ustar00octoeng00000000000000collectd-5.4.0/src/PaxHeaders.11991/onewire.c0000644037772200116100000000013212204120331016746 xustar000000000000000030 mtime=1376821465.081973567 30 atime=1376821477.222167995 30 ctime=1376821741.934399524 collectd-5.4.0/src/onewire.c0000644037772200116100000001730512204120331015520 0ustar00octoeng00000000000000/** * collectd - src/owfs.c * Copyright (C) 2008 Florian octo 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: * Florian octo Forster **/ #include "collectd.h" #include "common.h" #include "plugin.h" #include "utils_ignorelist.h" #include #define OW_FAMILY_LENGTH 8 #define OW_FAMILY_MAX_FEATURES 2 struct ow_family_features_s { char family[OW_FAMILY_LENGTH]; struct { char filename[DATA_MAX_NAME_LEN]; char type[DATA_MAX_NAME_LEN]; char type_instance[DATA_MAX_NAME_LEN]; } features[OW_FAMILY_MAX_FEATURES]; size_t features_num; }; typedef struct ow_family_features_s ow_family_features_t; /* see http://owfs.sourceforge.net/ow_table.html for a list of families */ static ow_family_features_t ow_family_features[] = { { /* family = */ "10.", { { /* filename = */ "temperature", /* type = */ "temperature", /* type_instance = */ "" } }, /* features_num = */ 1 } }; static int ow_family_features_num = STATIC_ARRAY_SIZE (ow_family_features); static char *device_g = NULL; static cdtime_t ow_interval = 0; static const char *config_keys[] = { "Device", "IgnoreSelected", "Sensor", "Interval" }; static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); static ignorelist_t *sensor_list; static int cow_load_config (const char *key, const char *value) { if (sensor_list == NULL) sensor_list = ignorelist_create (1); if (strcasecmp (key, "Sensor") == 0) { if (ignorelist_add (sensor_list, value)) { ERROR ("sensors plugin: " "Cannot add value to ignorelist."); return (1); } } else if (strcasecmp (key, "IgnoreSelected") == 0) { ignorelist_set_invert (sensor_list, 1); if (IS_TRUE (value)) ignorelist_set_invert (sensor_list, 0); } else if (strcasecmp (key, "Device") == 0) { char *temp; temp = strdup (value); if (temp == NULL) { ERROR ("onewire plugin: strdup failed."); return (1); } sfree (device_g); device_g = temp; } else if (strcasecmp ("Interval", key) == 0) { double tmp; tmp = atof (value); if (tmp > 0.0) ow_interval = DOUBLE_TO_CDTIME_T (tmp); else ERROR ("onewire plugin: Invalid `Interval' setting: %s", value); } else { return (-1); } return (0); } static int cow_read_values (const char *path, const char *name, const ow_family_features_t *family_info) { value_t values[1]; value_list_t vl = VALUE_LIST_INIT; int success = 0; size_t i; if (sensor_list != NULL) { DEBUG ("onewire plugin: Checking ignorelist for `%s'", name); if (ignorelist_match (sensor_list, name) != 0) return 0; } vl.values = values; vl.values_len = 1; sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "onewire", sizeof (vl.plugin)); sstrncpy (vl.plugin_instance, name, sizeof (vl.plugin_instance)); for (i = 0; i < family_info->features_num; i++) { char *buffer; size_t buffer_size; int status; char file[4096]; char *endptr; snprintf (file, sizeof (file), "%s/%s", path, family_info->features[i].filename); file[sizeof (file) - 1] = 0; buffer = NULL; buffer_size = 0; status = OW_get (file, &buffer, &buffer_size); if (status < 0) { ERROR ("onewire plugin: OW_get (%s/%s) failed. status = %#x;", path, family_info->features[i].filename, status); return (-1); } endptr = NULL; values[0].gauge = strtod (buffer, &endptr); if (endptr == NULL) { ERROR ("onewire plugin: Buffer is not a number: %s", buffer); status = -1; continue; } sstrncpy (vl.type, family_info->features[i].type, sizeof (vl.type)); sstrncpy (vl.type_instance, family_info->features[i].type_instance, sizeof (vl.type_instance)); plugin_dispatch_values (&vl); success++; free (buffer); } /* for (i = 0; i < features_num; i++) */ return ((success > 0) ? 0 : -1); } /* int cow_read_values */ /* Forward declaration so the recursion below works */ static int cow_read_bus (const char *path); /* * cow_read_ds2409 * * Handles: * - DS2409 - MicroLAN Coupler */ static int cow_read_ds2409 (const char *path) { char subpath[4096]; int status; status = ssnprintf (subpath, sizeof (subpath), "%s/main", path); if ((status > 0) && (status < sizeof (subpath))) cow_read_bus (subpath); status = ssnprintf (subpath, sizeof (subpath), "%s/aux", path); if ((status > 0) && (status < sizeof (subpath))) cow_read_bus (subpath); return (0); } /* int cow_read_ds2409 */ static int cow_read_bus (const char *path) { char *buffer; size_t buffer_size; int status; char *buffer_ptr; char *dummy; char *saveptr; char subpath[4096]; status = OW_get (path, &buffer, &buffer_size); if (status < 0) { ERROR ("onewire plugin: OW_get (%s) failed. status = %#x;", path, status); return (-1); } DEBUG ("onewire plugin: OW_get (%s) returned: %s", path, buffer); dummy = buffer; saveptr = NULL; while ((buffer_ptr = strtok_r (dummy, ",/", &saveptr)) != NULL) { int i; dummy = NULL; if (strcmp ("/", path) == 0) status = ssnprintf (subpath, sizeof (subpath), "/%s", buffer_ptr); else status = ssnprintf (subpath, sizeof (subpath), "%s/%s", path, buffer_ptr); if ((status <= 0) || (status >= sizeof (subpath))) continue; for (i = 0; i < ow_family_features_num; i++) { if (strncmp (ow_family_features[i].family, buffer_ptr, strlen (ow_family_features[i].family)) != 0) continue; cow_read_values (subpath, buffer_ptr + strlen (ow_family_features[i].family), ow_family_features + i); break; } if (i < ow_family_features_num) continue; /* DS2409 */ if (strncmp ("1F.", buffer_ptr, strlen ("1F.")) == 0) { cow_read_ds2409 (subpath); continue; } } /* while (strtok_r) */ free (buffer); return (0); } /* int cow_read_bus */ static int cow_read (user_data_t *ud __attribute__((unused))) { return (cow_read_bus ("/")); } /* int cow_read */ static int cow_shutdown (void) { OW_finish (); ignorelist_free (sensor_list); return (0); } /* int cow_shutdown */ static int cow_init (void) { int status; struct timespec cb_interval; if (device_g == NULL) { ERROR ("onewire plugin: cow_init: No device configured."); return (-1); } status = (int) OW_init (device_g); if (status != 0) { ERROR ("onewire plugin: OW_init(%s) failed: %i.", device_g, status); return (1); } CDTIME_T_TO_TIMESPEC (ow_interval, &cb_interval); plugin_register_complex_read (/* group = */ NULL, "onewire", cow_read, (ow_interval != 0) ? &cb_interval : NULL, /* user data = */ NULL); plugin_register_shutdown ("onewire", cow_shutdown); return (0); } /* int cow_init */ void module_register (void) { plugin_register_init ("onewire", cow_init); plugin_register_config ("onewire", cow_load_config, config_keys, config_keys_num); } /* vim: set sw=2 sts=2 ts=8 et fdm=marker cindent : */ collectd-5.4.0/src/PaxHeaders.11991/utils_ignorelist.h0000644037772200116100000000013212204120331020702 xustar000000000000000030 mtime=1376821465.089973696 30 atime=1376821477.230168122 30 ctime=1376821741.938399588 collectd-5.4.0/src/utils_ignorelist.h0000644037772200116100000000344512204120331017454 0ustar00octoeng00000000000000/** * collectd - src/utils_ignorelist.h * Copyright (C) 2006 Lubos Stanek * * This program is free software; you can redistribute it and/ * or modify it under the terms of the GNU General Public Li- * cence as published by the Free Software Foundation; either * version 2 of the Licence, or any later version. * * This program is distributed in the hope that it will be use- * ful, but WITHOUT ANY WARRANTY; without even the implied war- * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public Licence for more details. * * You should have received a copy of the GNU General Public * Licence along with this program; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, * USA. * * Authors: * Lubos Stanek **/ /** * ignorelist handles plugin's list of configured collectable * entries with global ignore action **/ #ifndef UTILS_IGNORELIST_H #define UTILS_IGNORELIST_H 1 #include "collectd.h" #if HAVE_REGEX_H # include #endif /* public prototypes */ struct ignorelist_s; typedef struct ignorelist_s ignorelist_t; /* * create the ignorelist_t with known ignore state * return pointer to ignorelist_t */ ignorelist_t *ignorelist_create (int invert); /* * free memory used by ignorelist_t */ void ignorelist_free (ignorelist_t *il); /* * set ignore state of the ignorelist_t */ void ignorelist_set_invert (ignorelist_t *il, int invert); /* * append entry to ignorelist_t * returns zero on success, non-zero upon failure. */ int ignorelist_add (ignorelist_t *il, const char *entry); /* * check list for entry * return 1 for ignored entry */ int ignorelist_match (ignorelist_t *il, const char *entry); #endif /* UTILS_IGNORELIST_H */ collectd-5.4.0/src/PaxHeaders.11991/iptables.c0000644037772200116100000000013212204120331017101 xustar000000000000000030 mtime=1376821465.073973439 30 atime=1376821477.218167931 30 ctime=1376821741.938399588 collectd-5.4.0/src/iptables.c0000644037772200116100000003146412204120331015655 0ustar00octoeng00000000000000/** * collectd - src/iptables.c * Copyright (C) 2007 Sjoerd van der Berg * Copyright (C) 2007-2010 Florian octo Forster * Copyright (C) 2009 Marco Chiappero * * 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; either version 2 of the License, or (at your * option) any later version. * * 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: * Sjoerd van der Berg * Florian Forster * Marco Chiappero **/ #include "collectd.h" #include "common.h" #include "plugin.h" #include "configfile.h" #include #include #include /* * iptc_handle_t was available before libiptc was officially available as a * shared library. Note, that when the shared lib was introduced, the API and * ABI have changed slightly: * 'iptc_handle_t' used to be 'struct iptc_handle *' and most functions used * 'iptc_handle_t *' as an argument. Now, most functions use 'struct * iptc_handle *' (thus removing one level of pointer indirection). * * HAVE_IPTC_HANDLE_T is used to determine which API ought to be used. While * this is somewhat hacky, I didn't find better way to solve that :-/ * -tokkee */ #ifndef HAVE_IPTC_HANDLE_T typedef struct iptc_handle iptc_handle_t; #endif #ifndef HAVE_IP6TC_HANDLE_T typedef struct ip6tc_handle ip6tc_handle_t; #endif /* * (Module-)Global variables */ /* * Config format should be `Chain table chainname', * e. g. `Chain mangle incoming' */ static const char *config_keys[] = { "Chain", "Chain6" }; static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); /* Each table/chain combo that will be queried goes into this list */ enum protocol_version_e { IPV4, IPV6 }; typedef enum protocol_version_e protocol_version_t; #ifndef XT_TABLE_MAXNAMELEN # define XT_TABLE_MAXNAMELEN 32 #endif typedef struct { protocol_version_t ip_version; char table[XT_TABLE_MAXNAMELEN]; char chain[XT_TABLE_MAXNAMELEN]; union { int num; char *comment; } rule; enum { RTYPE_NUM, RTYPE_COMMENT, RTYPE_COMMENT_ALL } rule_type; char name[64]; } ip_chain_t; static ip_chain_t **chain_list = NULL; static int chain_num = 0; static int iptables_config (const char *key, const char *value) { /* int ip_value; */ protocol_version_t ip_version = 0; if (strcasecmp (key, "Chain") == 0) ip_version = IPV4; else if (strcasecmp (key, "Chain6") == 0) ip_version = IPV6; if (( ip_version == IPV4 ) || ( ip_version == IPV6 )) { ip_chain_t temp, *final, **list; char *table; int table_len; char *chain; int chain_len; char *value_copy; char *fields[4]; int fields_num; memset (&temp, 0, sizeof (temp)); value_copy = strdup (value); if (value_copy == NULL) { char errbuf[1024]; ERROR ("strdup failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (1); } /* * Time to fill the temp element * Examine value string, it should look like: * Chain[6] [ [name]] */ /* set IPv4 or IPv6 */ temp.ip_version = ip_version; /* Chain
[ [name]] */ fields_num = strsplit (value_copy, fields, 4); if (fields_num < 2) { free (value_copy); return (1); } table = fields[0]; chain = fields[1]; table_len = strlen (table) + 1; if ((unsigned int)table_len > sizeof(temp.table)) { ERROR ("Table `%s' too long.", table); free (value_copy); return (1); } sstrncpy (temp.table, table, table_len); chain_len = strlen (chain) + 1; if ((unsigned int)chain_len > sizeof(temp.chain)) { ERROR ("Chain `%s' too long.", chain); free (value_copy); return (1); } sstrncpy (temp.chain, chain, chain_len); if (fields_num >= 3) { char *comment = fields[2]; int rule = atoi (comment); if (rule) { temp.rule.num = rule; temp.rule_type = RTYPE_NUM; } else { temp.rule.comment = strdup (comment); if (temp.rule.comment == NULL) { free (value_copy); return (1); } temp.rule_type = RTYPE_COMMENT; } } else { temp.rule_type = RTYPE_COMMENT_ALL; } if (fields_num >= 4) sstrncpy (temp.name, fields[3], sizeof (temp.name)); free (value_copy); value_copy = NULL; table = NULL; chain = NULL; list = (ip_chain_t **) realloc (chain_list, (chain_num + 1) * sizeof (ip_chain_t *)); if (list == NULL) { char errbuf[1024]; ERROR ("realloc failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (1); } chain_list = list; final = (ip_chain_t *) malloc( sizeof(temp) ); if (final == NULL) { char errbuf[1024]; ERROR ("malloc failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (1); } memcpy (final, &temp, sizeof (temp)); chain_list[chain_num] = final; chain_num++; DEBUG ("Chain #%i: table = %s; chain = %s;", chain_num, final->table, final->chain); } else { return (-1); } return (0); } /* int iptables_config */ static int submit6_match (const struct ip6t_entry_match *match, const struct ip6t_entry *entry, const ip_chain_t *chain, int rule_num) { int status; value_t values[1]; value_list_t vl = VALUE_LIST_INIT; /* Select the rules to collect */ if (chain->rule_type == RTYPE_NUM) { if (chain->rule.num != rule_num) return (0); } else { if (strcmp (match->u.user.name, "comment") != 0) return (0); if ((chain->rule_type == RTYPE_COMMENT) && (strcmp (chain->rule.comment, (char *) match->data) != 0)) return (0); } vl.values = values; vl.values_len = 1; sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "ip6tables", sizeof (vl.plugin)); status = ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance), "%s-%s", chain->table, chain->chain); if ((status < 1) || ((unsigned int)status >= sizeof (vl.plugin_instance))) return (0); if (chain->name[0] != '\0') { sstrncpy (vl.type_instance, chain->name, sizeof (vl.type_instance)); } else { if (chain->rule_type == RTYPE_NUM) ssnprintf (vl.type_instance, sizeof (vl.type_instance), "%i", chain->rule.num); else sstrncpy (vl.type_instance, (char *) match->data, sizeof (vl.type_instance)); } sstrncpy (vl.type, "ipt_bytes", sizeof (vl.type)); values[0].derive = (derive_t) entry->counters.bcnt; plugin_dispatch_values (&vl); sstrncpy (vl.type, "ipt_packets", sizeof (vl.type)); values[0].derive = (derive_t) entry->counters.pcnt; plugin_dispatch_values (&vl); return (0); } /* int submit_match */ /* This needs to return `int' for IPT_MATCH_ITERATE to work. */ static int submit_match (const struct ipt_entry_match *match, const struct ipt_entry *entry, const ip_chain_t *chain, int rule_num) { int status; value_t values[1]; value_list_t vl = VALUE_LIST_INIT; /* Select the rules to collect */ if (chain->rule_type == RTYPE_NUM) { if (chain->rule.num != rule_num) return (0); } else { if (strcmp (match->u.user.name, "comment") != 0) return (0); if ((chain->rule_type == RTYPE_COMMENT) && (strcmp (chain->rule.comment, (char *) match->data) != 0)) return (0); } vl.values = values; vl.values_len = 1; sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "iptables", sizeof (vl.plugin)); status = ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance), "%s-%s", chain->table, chain->chain); if ((status < 1) || ((unsigned int)status >= sizeof (vl.plugin_instance))) return (0); if (chain->name[0] != '\0') { sstrncpy (vl.type_instance, chain->name, sizeof (vl.type_instance)); } else { if (chain->rule_type == RTYPE_NUM) ssnprintf (vl.type_instance, sizeof (vl.type_instance), "%i", chain->rule.num); else sstrncpy (vl.type_instance, (char *) match->data, sizeof (vl.type_instance)); } sstrncpy (vl.type, "ipt_bytes", sizeof (vl.type)); values[0].derive = (derive_t) entry->counters.bcnt; plugin_dispatch_values (&vl); sstrncpy (vl.type, "ipt_packets", sizeof (vl.type)); values[0].derive = (derive_t) entry->counters.pcnt; plugin_dispatch_values (&vl); return (0); } /* int submit_match */ /* ipv6 submit_chain */ static void submit6_chain( ip6tc_handle_t *handle, ip_chain_t *chain ) { const struct ip6t_entry *entry; int rule_num; /* Find first rule for chain and use the iterate macro */ entry = ip6tc_first_rule( chain->chain, handle ); if (entry == NULL) { DEBUG ("ip6tc_first_rule failed: %s", ip6tc_strerror (errno)); return; } rule_num = 1; while (entry) { if (chain->rule_type == RTYPE_NUM) { submit6_match (NULL, entry, chain, rule_num); } else { IP6T_MATCH_ITERATE( entry, submit6_match, entry, chain, rule_num ); } entry = ip6tc_next_rule( entry, handle ); rule_num++; } /* while (entry) */ } /* ipv4 submit_chain */ static void submit_chain( iptc_handle_t *handle, ip_chain_t *chain ) { const struct ipt_entry *entry; int rule_num; /* Find first rule for chain and use the iterate macro */ entry = iptc_first_rule( chain->chain, handle ); if (entry == NULL) { DEBUG ("iptc_first_rule failed: %s", iptc_strerror (errno)); return; } rule_num = 1; while (entry) { if (chain->rule_type == RTYPE_NUM) { submit_match (NULL, entry, chain, rule_num); } else { IPT_MATCH_ITERATE( entry, submit_match, entry, chain, rule_num ); } entry = iptc_next_rule( entry, handle ); rule_num++; } /* while (entry) */ } static int iptables_read (void) { int i; int num_failures = 0; ip_chain_t *chain; /* Init the iptc handle structure and query the correct table */ for (i = 0; i < chain_num; i++) { chain = chain_list[i]; if (!chain) { DEBUG ("iptables plugin: chain == NULL"); continue; } if ( chain->ip_version == IPV4 ) { #ifdef HAVE_IPTC_HANDLE_T iptc_handle_t _handle; iptc_handle_t *handle = &_handle; *handle = iptc_init (chain->table); #else iptc_handle_t *handle; handle = iptc_init (chain->table); #endif if (!handle) { ERROR ("iptables plugin: iptc_init (%s) failed: %s", chain->table, iptc_strerror (errno)); num_failures++; continue; } submit_chain (handle, chain); iptc_free (handle); } else if ( chain->ip_version == IPV6 ) { #ifdef HAVE_IP6TC_HANDLE_T ip6tc_handle_t _handle; ip6tc_handle_t *handle = &_handle; *handle = ip6tc_init (chain->table); #else ip6tc_handle_t *handle; handle = ip6tc_init (chain->table); #endif if (!handle) { ERROR ("iptables plugin: ip6tc_init (%s) failed: %s", chain->table, ip6tc_strerror (errno)); num_failures++; continue; } submit6_chain (handle, chain); ip6tc_free (handle); } else num_failures++; } /* for (i = 0 .. chain_num) */ return ((num_failures < chain_num) ? 0 : -1); } /* int iptables_read */ static int iptables_shutdown (void) { int i; for (i = 0; i < chain_num; i++) { if ((chain_list[i] != NULL) && (chain_list[i]->rule_type == RTYPE_COMMENT)) { sfree (chain_list[i]->rule.comment); } sfree (chain_list[i]); } sfree (chain_list); return (0); } /* int iptables_shutdown */ void module_register (void) { plugin_register_config ("iptables", iptables_config, config_keys, config_keys_num); plugin_register_read ("iptables", iptables_read); plugin_register_shutdown ("iptables", iptables_shutdown); } /* void module_register */ /* * vim:shiftwidth=4:softtabstop=4:tabstop=8 */ collectd-5.4.0/src/PaxHeaders.11991/utils_cmd_getval.c0000644037772200116100000000013212204120331020623 xustar000000000000000030 mtime=1376821465.089973696 30 atime=1376821477.230168122 30 ctime=1376821741.942399652 collectd-5.4.0/src/utils_cmd_getval.c0000644037772200116100000000767612204120331017407 0ustar00octoeng00000000000000/** * collectd - src/utils_cms_getval.c * Copyright (C) 2008 Florian octo 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 * * Author: * Florian octo Forster **/ #include "collectd.h" #include "common.h" #include "plugin.h" #include "utils_cache.h" #include "utils_parse_option.h" #define print_to_socket(fh, ...) \ if (fprintf (fh, __VA_ARGS__) < 0) { \ char errbuf[1024]; \ WARNING ("handle_getval: failed to write to socket #%i: %s", \ fileno (fh), sstrerror (errno, errbuf, sizeof (errbuf))); \ return -1; \ } int handle_getval (FILE *fh, char *buffer) { char *command; char *identifier; char *identifier_copy; char *hostname; char *plugin; char *plugin_instance; char *type; char *type_instance; gauge_t *values; size_t values_num; const data_set_t *ds; int status; size_t i; if ((fh == NULL) || (buffer == NULL)) return (-1); DEBUG ("utils_cmd_getval: handle_getval (fh = %p, buffer = %s);", (void *) fh, buffer); command = NULL; status = parse_string (&buffer, &command); if (status != 0) { print_to_socket (fh, "-1 Cannot parse command.\n"); return (-1); } assert (command != NULL); if (strcasecmp ("GETVAL", command) != 0) { print_to_socket (fh, "-1 Unexpected command: `%s'.\n", command); return (-1); } identifier = NULL; status = parse_string (&buffer, &identifier); if (status != 0) { print_to_socket (fh, "-1 Cannot parse identifier.\n"); return (-1); } assert (identifier != NULL); if (*buffer != 0) { print_to_socket (fh, "-1 Garbage after end of command: %s\n", buffer); return (-1); } /* parse_identifier() modifies its first argument, * returning pointers into it */ identifier_copy = sstrdup (identifier); status = parse_identifier (identifier_copy, &hostname, &plugin, &plugin_instance, &type, &type_instance); if (status != 0) { DEBUG ("handle_getval: Cannot parse identifier `%s'.", identifier); print_to_socket (fh, "-1 Cannot parse identifier `%s'.\n", identifier); sfree (identifier_copy); return (-1); } ds = plugin_get_ds (type); if (ds == NULL) { DEBUG ("handle_getval: plugin_get_ds (%s) == NULL;", type); print_to_socket (fh, "-1 Type `%s' is unknown.\n", type); sfree (identifier_copy); return (-1); } values = NULL; values_num = 0; status = uc_get_rate_by_name (identifier, &values, &values_num); if (status != 0) { print_to_socket (fh, "-1 No such value\n"); sfree (identifier_copy); return (-1); } if ((size_t) ds->ds_num != values_num) { ERROR ("ds[%s]->ds_num = %i, " "but uc_get_rate_by_name returned %u values.", ds->type, ds->ds_num, (unsigned int) values_num); print_to_socket (fh, "-1 Error reading value from cache.\n"); sfree (values); sfree (identifier_copy); return (-1); } print_to_socket (fh, "%u Value%s found\n", (unsigned int) values_num, (values_num == 1) ? "" : "s"); for (i = 0; i < values_num; i++) { print_to_socket (fh, "%s=", ds->ds[i].name); if (isnan (values[i])) { print_to_socket (fh, "NaN\n"); } else { print_to_socket (fh, "%12e\n", values[i]); } } sfree (values); sfree (identifier_copy); return (0); } /* int handle_getval */ /* vim: set sw=2 sts=2 ts=8 : */ collectd-5.4.0/src/PaxHeaders.11991/uptime.c0000644037772200116100000000013212204120331016601 xustar000000000000000030 mtime=1376821465.085973632 30 atime=1376821477.226168058 30 ctime=1376821741.942399652 collectd-5.4.0/src/uptime.c0000644037772200116100000001374712204120331015361 0ustar00octoeng00000000000000/** * collectd - src/uptime.c * Copyright (C) 2009 Marco Chiappero * * 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: * Marco Chiappero **/ #include "collectd.h" #include "common.h" #include "plugin.h" #if KERNEL_LINUX # define STAT_FILE "/proc/stat" /* Using /proc filesystem to retrieve the boot time, Linux only. */ /* #endif KERNEL_LINUX */ #elif HAVE_LIBKSTAT /* Using kstats chain to retrieve the boot time on Solaris / OpenSolaris systems */ /* #endif HAVE_LIBKSTAT */ #elif HAVE_SYS_SYSCTL_H # include /* Using sysctl interface to retrieve the boot time on *BSD / Darwin / OS X systems */ /* #endif HAVE_SYS_SYSCTL_H */ #elif HAVE_PERFSTAT # include # include /* Using perfstat_cpu_total to retrive the boot time in AIX */ /* #endif HAVE_PERFSTAT */ #else # error "No applicable input method." #endif /* * Global variables */ /* boottime always used, no OS distinction */ static time_t boottime; #if HAVE_LIBKSTAT extern kstat_ctl_t *kc; #endif /* #endif HAVE_LIBKSTAT */ static void uptime_submit (gauge_t uptime) { value_t values[1]; value_list_t vl = VALUE_LIST_INIT; values[0].gauge = uptime; vl.values = values; vl.values_len = 1; sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "uptime", sizeof (vl.plugin)); sstrncpy (vl.type, "uptime", sizeof (vl.type)); plugin_dispatch_values (&vl); } static int uptime_init (void) /* {{{ */ { /* * On most unix systems the uptime is calculated by looking at the boot * time (stored in unix time, since epoch) and the current one. We are * going to do the same, reading the boot time value while executing * the uptime_init function (there is no need to read, every time the * plugin_read is called, a value that won't change). However, since * uptime_init is run only once, if the function fails in retrieving * the boot time, the plugin is unregistered and there is no chance to * try again later. Nevertheless, this is very unlikely to happen. */ #if KERNEL_LINUX unsigned long starttime; char buffer[1024]; int ret; FILE *fh; ret = 0; fh = fopen (STAT_FILE, "r"); if (fh == NULL) { char errbuf[1024]; ERROR ("uptime plugin: Cannot open "STAT_FILE": %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } while (fgets (buffer, 1024, fh) != NULL) { /* look for the btime string and read the value */ ret = sscanf (buffer, "btime %lu", &starttime); /* avoid further loops if btime has been found and read * correctly (hopefully) */ if (ret == 1) break; } fclose (fh); /* loop done, check if no value has been found/read */ if (ret != 1) { ERROR ("uptime plugin: No value read from "STAT_FILE""); return (-1); } boottime = (time_t) starttime; if (boottime == 0) { ERROR ("uptime plugin: btime read from "STAT_FILE", " "but `boottime' is zero!"); return (-1); } /* #endif KERNEL_LINUX */ #elif HAVE_LIBKSTAT kstat_t *ksp; kstat_named_t *knp; ksp = NULL; knp = NULL; /* kstats chain already opened by update_kstat (using *kc), verify everything went fine. */ if (kc == NULL) { ERROR ("uptime plugin: kstat chain control structure not available."); return (-1); } ksp = kstat_lookup (kc, "unix", 0, "system_misc"); if (ksp == NULL) { ERROR ("uptime plugin: Cannot find unix:0:system_misc kstat."); return (-1); } if (kstat_read (kc, ksp, NULL) < 0) { ERROR ("uptime plugin: kstat_read failed."); return (-1); } knp = (kstat_named_t *) kstat_data_lookup (ksp, "boot_time"); if (knp == NULL) { ERROR ("uptime plugin: kstat_data_lookup (boot_time) failed."); return (-1); } boottime = (time_t) knp->value.ui32; if (boottime == 0) { ERROR ("uptime plugin: kstat_data_lookup returned success, " "but `boottime' is zero!"); return (-1); } /* #endif HAVE_LIBKSTAT */ # elif HAVE_SYS_SYSCTL_H struct timeval boottv; size_t boottv_len; int status; int mib[2]; mib[0] = CTL_KERN; mib[1] = KERN_BOOTTIME; boottv_len = sizeof (boottv); memset (&boottv, 0, boottv_len); status = sysctl (mib, STATIC_ARRAY_SIZE (mib), &boottv, &boottv_len, /* new_value = */ NULL, /* new_length = */ 0); if (status != 0) { char errbuf[1024]; ERROR ("uptime plugin: No value read from sysctl interface: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } boottime = boottv.tv_sec; if (boottime == 0) { ERROR ("uptime plugin: sysctl(3) returned success, " "but `boottime' is zero!"); return (-1); } /* #endif HAVE_SYS_SYSCTL_H */ #elif HAVE_PERFSTAT int status; perfstat_cpu_total_t cputotal; int hertz; status = perfstat_cpu_total(NULL, &cputotal, sizeof(perfstat_cpu_total_t), 1); if (status < 0) { char errbuf[1024]; ERROR ("uptime plugin: perfstat_cpu_total: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } hertz = sysconf(_SC_CLK_TCK); if (hertz <= 0) hertz = HZ; boottime = time(NULL) - cputotal.lbolt / hertz; #endif /* HAVE_PERFSTAT */ return (0); } /* }}} int uptime_init */ static int uptime_read (void) { gauge_t uptime; time_t elapsed; /* calculate the ammount of time elapsed since boot, AKA uptime */ elapsed = time (NULL) - boottime; uptime = (gauge_t) elapsed; uptime_submit (uptime); return (0); } void module_register (void) { plugin_register_init ("uptime", uptime_init); plugin_register_read ("uptime", uptime_read); } /* void module_register */ collectd-5.4.0/src/PaxHeaders.11991/utils_format_json.c0000644037772200116100000000013212204120331021037 xustar000000000000000030 mtime=1376821465.089973696 30 atime=1376821477.230168122 30 ctime=1376821741.942399652 collectd-5.4.0/src/utils_format_json.c0000644037772200116100000002727412204120331017617 0ustar00octoeng00000000000000/** * collectd - src/utils_format_json.c * Copyright (C) 2009 Florian octo 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: * Florian octo Forster **/ #include "collectd.h" #include "plugin.h" #include "common.h" #include "utils_cache.h" #include "utils_format_json.h" static int escape_string (char *buffer, size_t buffer_size, /* {{{ */ const char *string) { size_t src_pos; size_t dst_pos; if ((buffer == NULL) || (string == NULL)) return (-EINVAL); if (buffer_size < 3) return (-ENOMEM); dst_pos = 0; #define BUFFER_ADD(c) do { \ if (dst_pos >= (buffer_size - 1)) { \ buffer[buffer_size - 1] = 0; \ return (-ENOMEM); \ } \ buffer[dst_pos] = (c); \ dst_pos++; \ } while (0) /* Escape special characters */ BUFFER_ADD ('"'); for (src_pos = 0; string[src_pos] != 0; src_pos++) { if ((string[src_pos] == '"') || (string[src_pos] == '\\')) { BUFFER_ADD ('\\'); BUFFER_ADD (string[src_pos]); } else if (string[src_pos] <= 0x001F) BUFFER_ADD ('?'); else BUFFER_ADD (string[src_pos]); } /* for */ BUFFER_ADD ('"'); buffer[dst_pos] = 0; #undef BUFFER_ADD return (0); } /* }}} int escape_string */ static int values_to_json (char *buffer, size_t buffer_size, /* {{{ */ const data_set_t *ds, const value_list_t *vl, int store_rates) { size_t offset = 0; int i; gauge_t *rates = NULL; memset (buffer, 0, buffer_size); #define BUFFER_ADD(...) do { \ int status; \ status = ssnprintf (buffer + offset, buffer_size - offset, \ __VA_ARGS__); \ if (status < 1) \ { \ sfree(rates); \ return (-1); \ } \ else if (((size_t) status) >= (buffer_size - offset)) \ { \ sfree(rates); \ return (-ENOMEM); \ } \ else \ offset += ((size_t) status); \ } while (0) BUFFER_ADD ("["); for (i = 0; i < ds->ds_num; i++) { if (i > 0) BUFFER_ADD (","); if (ds->ds[i].type == DS_TYPE_GAUGE) { if(isfinite (vl->values[i].gauge)) BUFFER_ADD ("%g", vl->values[i].gauge); else BUFFER_ADD ("null"); } else if (store_rates) { if (rates == NULL) rates = uc_get_rate (ds, vl); if (rates == NULL) { WARNING ("utils_format_json: uc_get_rate failed."); sfree(rates); return (-1); } if(isfinite (rates[i])) BUFFER_ADD ("%g", rates[i]); else BUFFER_ADD ("null"); } else if (ds->ds[i].type == DS_TYPE_COUNTER) BUFFER_ADD ("%llu", vl->values[i].counter); else if (ds->ds[i].type == DS_TYPE_DERIVE) BUFFER_ADD ("%"PRIi64, vl->values[i].derive); else if (ds->ds[i].type == DS_TYPE_ABSOLUTE) BUFFER_ADD ("%"PRIu64, vl->values[i].absolute); else { ERROR ("format_json: Unknown data source type: %i", ds->ds[i].type); sfree (rates); return (-1); } } /* for ds->ds_num */ BUFFER_ADD ("]"); #undef BUFFER_ADD DEBUG ("format_json: values_to_json: buffer = %s;", buffer); sfree(rates); return (0); } /* }}} int values_to_json */ static int dstypes_to_json (char *buffer, size_t buffer_size, /* {{{ */ const data_set_t *ds) { size_t offset = 0; int i; memset (buffer, 0, buffer_size); #define BUFFER_ADD(...) do { \ int status; \ status = ssnprintf (buffer + offset, buffer_size - offset, \ __VA_ARGS__); \ if (status < 1) \ return (-1); \ else if (((size_t) status) >= (buffer_size - offset)) \ return (-ENOMEM); \ else \ offset += ((size_t) status); \ } while (0) BUFFER_ADD ("["); for (i = 0; i < ds->ds_num; i++) { if (i > 0) BUFFER_ADD (","); BUFFER_ADD ("\"%s\"", DS_TYPE_TO_STRING (ds->ds[i].type)); } /* for ds->ds_num */ BUFFER_ADD ("]"); #undef BUFFER_ADD DEBUG ("format_json: dstypes_to_json: buffer = %s;", buffer); return (0); } /* }}} int dstypes_to_json */ static int dsnames_to_json (char *buffer, size_t buffer_size, /* {{{ */ const data_set_t *ds) { size_t offset = 0; int i; memset (buffer, 0, buffer_size); #define BUFFER_ADD(...) do { \ int status; \ status = ssnprintf (buffer + offset, buffer_size - offset, \ __VA_ARGS__); \ if (status < 1) \ return (-1); \ else if (((size_t) status) >= (buffer_size - offset)) \ return (-ENOMEM); \ else \ offset += ((size_t) status); \ } while (0) BUFFER_ADD ("["); for (i = 0; i < ds->ds_num; i++) { if (i > 0) BUFFER_ADD (","); BUFFER_ADD ("\"%s\"", ds->ds[i].name); } /* for ds->ds_num */ BUFFER_ADD ("]"); #undef BUFFER_ADD DEBUG ("format_json: dsnames_to_json: buffer = %s;", buffer); return (0); } /* }}} int dsnames_to_json */ static int meta_data_to_json (char *buffer, size_t buffer_size, /* {{{ */ meta_data_t *meta) { size_t offset = 0; char **keys = NULL; int keys_num; int status; int i; memset (buffer, 0, buffer_size); #define BUFFER_ADD(...) do { \ status = ssnprintf (buffer + offset, buffer_size - offset, \ __VA_ARGS__); \ if (status < 1) \ return (-1); \ else if (((size_t) status) >= (buffer_size - offset)) \ return (-ENOMEM); \ else \ offset += ((size_t) status); \ } while (0) keys_num = meta_data_toc (meta, &keys); for (i = 0; i < keys_num; ++i) { int type; char *key = keys[i]; type = meta_data_type (meta, key); if (type == MD_TYPE_STRING) { char *value = NULL; if (meta_data_get_string (meta, key, &value) == 0) { char temp[512] = ""; escape_string (temp, sizeof (temp), value); sfree (value); BUFFER_ADD (",\"%s\":%s", key, temp); } } else if (type == MD_TYPE_SIGNED_INT) { int64_t value = 0; if (meta_data_get_signed_int (meta, key, &value) == 0) BUFFER_ADD (",\"%s\":%"PRIi64, key, value); } else if (type == MD_TYPE_UNSIGNED_INT) { uint64_t value = 0; if (meta_data_get_unsigned_int (meta, key, &value) == 0) BUFFER_ADD (",\"%s\":%"PRIu64, key, value); } else if (type == MD_TYPE_DOUBLE) { double value = 0.0; if (meta_data_get_double (meta, key, &value) == 0) BUFFER_ADD (",\"%s\":%f", key, value); } else if (type == MD_TYPE_BOOLEAN) { _Bool value = 0; if (meta_data_get_boolean (meta, key, &value) == 0) BUFFER_ADD (",\"%s\":%s", key, value ? "true" : "false"); } free (key); } /* for (keys) */ free (keys); if (offset <= 0) return (ENOENT); buffer[0] = '{'; /* replace leading ',' */ BUFFER_ADD ("}"); #undef BUFFER_ADD return (0); } /* int meta_data_to_json */ static int value_list_to_json (char *buffer, size_t buffer_size, /* {{{ */ const data_set_t *ds, const value_list_t *vl, int store_rates) { char temp[512]; size_t offset = 0; int status; memset (buffer, 0, buffer_size); #define BUFFER_ADD(...) do { \ status = ssnprintf (buffer + offset, buffer_size - offset, \ __VA_ARGS__); \ if (status < 1) \ return (-1); \ else if (((size_t) status) >= (buffer_size - offset)) \ return (-ENOMEM); \ else \ offset += ((size_t) status); \ } while (0) /* All value lists have a leading comma. The first one will be replaced with * a square bracket in `format_json_finalize'. */ BUFFER_ADD (",{"); status = values_to_json (temp, sizeof (temp), ds, vl, store_rates); if (status != 0) return (status); BUFFER_ADD ("\"values\":%s", temp); status = dstypes_to_json (temp, sizeof (temp), ds); if (status != 0) return (status); BUFFER_ADD (",\"dstypes\":%s", temp); status = dsnames_to_json (temp, sizeof (temp), ds); if (status != 0) return (status); BUFFER_ADD (",\"dsnames\":%s", temp); BUFFER_ADD (",\"time\":%.3f", CDTIME_T_TO_DOUBLE (vl->time)); BUFFER_ADD (",\"interval\":%.3f", CDTIME_T_TO_DOUBLE (vl->interval)); #define BUFFER_ADD_KEYVAL(key, value) do { \ status = escape_string (temp, sizeof (temp), (value)); \ if (status != 0) \ return (status); \ BUFFER_ADD (",\"%s\":%s", (key), temp); \ } while (0) BUFFER_ADD_KEYVAL ("host", vl->host); BUFFER_ADD_KEYVAL ("plugin", vl->plugin); BUFFER_ADD_KEYVAL ("plugin_instance", vl->plugin_instance); BUFFER_ADD_KEYVAL ("type", vl->type); BUFFER_ADD_KEYVAL ("type_instance", vl->type_instance); if (vl->meta != NULL) { char meta_buffer[buffer_size]; memset (meta_buffer, 0, sizeof (meta_buffer)); status = meta_data_to_json (meta_buffer, sizeof (meta_buffer), vl->meta); if (status != 0) return (status); BUFFER_ADD (",\"meta\":%s", meta_buffer); } /* if (vl->meta != NULL) */ BUFFER_ADD ("}"); #undef BUFFER_ADD_KEYVAL #undef BUFFER_ADD DEBUG ("format_json: value_list_to_json: buffer = %s;", buffer); return (0); } /* }}} int value_list_to_json */ static int format_json_value_list_nocheck (char *buffer, /* {{{ */ size_t *ret_buffer_fill, size_t *ret_buffer_free, const data_set_t *ds, const value_list_t *vl, int store_rates, size_t temp_size) { char temp[temp_size]; int status; status = value_list_to_json (temp, sizeof (temp), ds, vl, store_rates); if (status != 0) return (status); temp_size = strlen (temp); memcpy (buffer + (*ret_buffer_fill), temp, temp_size + 1); (*ret_buffer_fill) += temp_size; (*ret_buffer_free) -= temp_size; return (0); } /* }}} int format_json_value_list_nocheck */ int format_json_initialize (char *buffer, /* {{{ */ size_t *ret_buffer_fill, size_t *ret_buffer_free) { size_t buffer_fill; size_t buffer_free; if ((buffer == NULL) || (ret_buffer_fill == NULL) || (ret_buffer_free == NULL)) return (-EINVAL); buffer_fill = *ret_buffer_fill; buffer_free = *ret_buffer_free; buffer_free = buffer_fill + buffer_free; buffer_fill = 0; if (buffer_free < 3) return (-ENOMEM); memset (buffer, 0, buffer_free); *ret_buffer_fill = buffer_fill; *ret_buffer_free = buffer_free; return (0); } /* }}} int format_json_initialize */ int format_json_finalize (char *buffer, /* {{{ */ size_t *ret_buffer_fill, size_t *ret_buffer_free) { size_t pos; if ((buffer == NULL) || (ret_buffer_fill == NULL) || (ret_buffer_free == NULL)) return (-EINVAL); if (*ret_buffer_free < 2) return (-ENOMEM); /* Replace the leading comma added in `value_list_to_json' with a square * bracket. */ if (buffer[0] != ',') return (-EINVAL); buffer[0] = '['; pos = *ret_buffer_fill; buffer[pos] = ']'; buffer[pos+1] = 0; (*ret_buffer_fill)++; (*ret_buffer_free)--; return (0); } /* }}} int format_json_finalize */ int format_json_value_list (char *buffer, /* {{{ */ size_t *ret_buffer_fill, size_t *ret_buffer_free, const data_set_t *ds, const value_list_t *vl, int store_rates) { if ((buffer == NULL) || (ret_buffer_fill == NULL) || (ret_buffer_free == NULL) || (ds == NULL) || (vl == NULL)) return (-EINVAL); if (*ret_buffer_free < 3) return (-ENOMEM); return (format_json_value_list_nocheck (buffer, ret_buffer_fill, ret_buffer_free, ds, vl, store_rates, (*ret_buffer_free) - 2)); } /* }}} int format_json_value_list */ /* vim: set sw=2 sts=2 et fdm=marker : */ collectd-5.4.0/src/PaxHeaders.11991/collectdctl.pod0000644037772200116100000000013212204120331020132 xustar000000000000000030 mtime=1376821465.069973376 30 atime=1376821477.210167802 30 ctime=1376821741.946399716 collectd-5.4.0/src/collectdctl.pod0000644037772200116100000001133612204120331016702 0ustar00octoeng00000000000000=encoding UTF-8 =head1 NAME collectdctl - Control interface for collectd =head1 SYNOPSIS collectdctl I<[options]> IcommandE> I<[command options]> =head1 DESCRIPTION collectdctl provides a control interface for collectd, which may be used to interact with the daemon using the C. =head1 OPTIONS collectdctl supports the following options: =over 4 =item B<-s> I Path to the UNIX socket opened by collectd's C. Default: /var/run/collectd-unixsock =item B<-h> Display usage information and exit. =back =head1 AVAILABLE COMMANDS The following commands are supported: =over 4 =item B IidentifierE> Query the latest collected value identified by the specified IidentifierE> (see below). The value-list associated with that data-set is returned as a list of key-value-pairs, each on its own line. Keys and values are separated by the equal sign (C<=>). =item B [BIsecondsE>] [BInameE>] [BIidE>] Flush the daemon. This is useful, e.Eg., to make sure that the latest values have been written to the respective RRD file before graphing them or copying them to somewhere else. The following options are supported by the flush command: =over 4 =item BIsecondsE> Flush values older than the specified timeout (in seconds) only. =item BInameE> Flush the specified plugin only. I.Ee., data cached by the specified plugin is written to disk (or network or whatever), if the plugin supports that operation. Example: B. =item BIidE> If this option is present, only the data specified by the specified identifier (see below) will be flushed. Note that this option is not supported by all plugins (e.Eg., the C plugin does not support this). =back The B and B options may be specified more than once. In that case, all combinations of specified plugins and identifiers will be flushed only. =item B Returns a list of all values (by their identifier) available to the C plugin. Each value is printed on its own line. I.Ee., this command returns a list of valid identifiers that may be used with the other commands. =item B IidentifierE> [BIsecondsE>] Ivalue-list(s)E> Submit one or more values (identified by IidentifierE>, see below) to the daemon which will then dispatch them to the write plugins. B specifies the interval (in seconds) used to collect the values following that option. It defaults to the default of the running collectd instance receiving the data. Multiple Ivalue-list(s)E> (see below) may be specified. Each of them will be submitted to the daemon. The values have to match the data-set definition specified by the type as given in the identifier (see L for details). =back =head1 IDENTIFIERS An identifier has the following format: [I/]I[-I]/I[-I] Examples: somehost/cpu-0/cpu-idle uptime/uptime otherhost/memory/memory-used Hostname defaults to the local (non-fully qualified) hostname if omitted. No error is returned if the specified identifier does not exist (this is a limitation in the C library). =head1 VALUE-LIST A value list describes one data-set as handled by collectd. It is a colon (C<:>) separated list of the time and the values. Each value is either given as an integer if the data-type is a counter, or as a double if the data-type is a gauge value. A literal C is interpreted as an undefined gauge value. The number of values and the data-types have to match the type specified in the identifier (see L for details). The time is specified as epoch (i.Ee., standard UNIX time) or as a literal C which will be interpreted as now. =head1 EXAMPLES =over 4 =item C Flushes all CPU wait RRD values of the first CPU of the local host. I.Ee., writes all pending RRD updates of that data-source to disk. =item C Query the latest number of logged in users on all hosts known to the local collectd instance. =back =head1 SEE ALSO L, L, L, L =head1 AUTHOR collectd has been written by Florian Forster Eocto at verplant.orgE and many contributors (see `AUTHORS'). collectdctl has been written by Håkon J Dugstad Johnsen Ehakon-dugstad.johnsenEatEtelenor.comE and Sebastian Harl Esh at tokkee.orgE. =cut collectd-5.4.0/src/PaxHeaders.11991/write_mongodb.c0000644037772200116100000000013212204120331020135 xustar000000000000000030 mtime=1376821465.093973759 30 atime=1376821477.230168122 30 ctime=1376821741.946399716 collectd-5.4.0/src/write_mongodb.c0000644037772200116100000002473512204120331016714 0ustar00octoeng00000000000000/** * collectd - src/write_mongodb.c * Copyright (C) 2010-2013 Florian Forster * Copyright (C) 2010 Akkarit Sangpetch * Copyright (C) 2012 Chris Lundquist * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Authors: * Florian Forster * Akkarit Sangpetch * Chris Lundquist **/ #include "collectd.h" #include "plugin.h" #include "common.h" #include "configfile.h" #include "utils_cache.h" #include #if HAVE_STDINT_H # define MONGO_HAVE_STDINT 1 #else # define MONGO_USE_LONG_LONG_INT 1 #endif #include struct wm_node_s { char name[DATA_MAX_NAME_LEN]; char *host; int port; int timeout; /* Authentication information */ char *db; char *user; char *passwd; _Bool store_rates; mongo conn[1]; pthread_mutex_t lock; }; typedef struct wm_node_s wm_node_t; /* * Functions */ static bson *wm_create_bson (const data_set_t *ds, /* {{{ */ const value_list_t *vl, _Bool store_rates) { bson *ret; gauge_t *rates; int i; ret = bson_create (); if (ret == NULL) { ERROR ("write_mongodb plugin: bson_create failed."); return (NULL); } if (store_rates) { rates = uc_get_rate (ds, vl); if (rates == NULL) { ERROR ("write_mongodb plugin: uc_get_rate() failed."); return (NULL); } } else { rates = NULL; } bson_init (ret); bson_append_date (ret, "time", (bson_date_t) CDTIME_T_TO_MS (vl->time)); bson_append_string (ret, "host", vl->host); bson_append_string (ret, "plugin", vl->plugin); bson_append_string (ret, "plugin_instance", vl->plugin_instance); bson_append_string (ret, "type", vl->type); bson_append_string (ret, "type_instance", vl->type_instance); bson_append_start_array (ret, "values"); /* {{{ */ for (i = 0; i < ds->ds_num; i++) { char key[16]; ssnprintf (key, sizeof (key), "%i", i); if (ds->ds[i].type == DS_TYPE_GAUGE) bson_append_double(ret, key, vl->values[i].gauge); else if (store_rates) bson_append_double(ret, key, (double) rates[i]); else if (ds->ds[i].type == DS_TYPE_COUNTER) bson_append_long(ret, key, vl->values[i].counter); else if (ds->ds[i].type == DS_TYPE_DERIVE) bson_append_long(ret, key, vl->values[i].derive); else if (ds->ds[i].type == DS_TYPE_ABSOLUTE) bson_append_long(ret, key, vl->values[i].absolute); else assert (23 == 42); } bson_append_finish_array (ret); /* }}} values */ bson_append_start_array (ret, "dstypes"); /* {{{ */ for (i = 0; i < ds->ds_num; i++) { char key[16]; ssnprintf (key, sizeof (key), "%i", i); if (store_rates) bson_append_string (ret, key, "gauge"); else bson_append_string (ret, key, DS_TYPE_TO_STRING (ds->ds[i].type)); } bson_append_finish_array (ret); /* }}} dstypes */ bson_append_start_array (ret, "dsnames"); /* {{{ */ for (i = 0; i < ds->ds_num; i++) { char key[16]; ssnprintf (key, sizeof (key), "%i", i); bson_append_string (ret, key, ds->ds[i].name); } bson_append_finish_array (ret); /* }}} dsnames */ bson_finish (ret); sfree (rates); return (ret); } /* }}} bson *wm_create_bson */ static int wm_write (const data_set_t *ds, /* {{{ */ const value_list_t *vl, user_data_t *ud) { wm_node_t *node = ud->data; char collection_name[512]; bson *bson_record; int status; ssnprintf (collection_name, sizeof (collection_name), "collectd.%s", vl->plugin); bson_record = wm_create_bson (ds, vl, node->store_rates); if (bson_record == NULL) return (ENOMEM); pthread_mutex_lock (&node->lock); if (!mongo_is_connected (node->conn)) { INFO ("write_mongodb plugin: Connecting to [%s]:%i", (node->host != NULL) ? node->host : "localhost", (node->port != 0) ? node->port : MONGO_DEFAULT_PORT); status = mongo_connect (node->conn, node->host, node->port); if (status != MONGO_OK) { ERROR ("write_mongodb plugin: Connecting to [%s]:%i failed.", (node->host != NULL) ? node->host : "localhost", (node->port != 0) ? node->port : MONGO_DEFAULT_PORT); mongo_destroy (node->conn); pthread_mutex_unlock (&node->lock); return (-1); } if ((node->db != NULL) && (node->user != NULL) && (node->passwd != NULL)) { status = mongo_cmd_authenticate (node->conn, node->db, node->user, node->passwd); if (status != MONGO_OK) { ERROR ("write_mongodb plugin: Authenticating to [%s]%i for database " "\"%s\" as user \"%s\" failed.", (node->host != NULL) ? node->host : "localhost", (node->port != 0) ? node->port : MONGO_DEFAULT_PORT, node->db, node->user); mongo_destroy (node->conn); pthread_mutex_unlock (&node->lock); return (-1); } } if (node->timeout > 0) { status = mongo_set_op_timeout (node->conn, node->timeout); if (status != MONGO_OK) { WARNING ("write_mongodb plugin: mongo_set_op_timeout(%i) failed: %s", node->timeout, node->conn->errstr); } } } /* Assert if the connection has been established */ assert (mongo_is_connected (node->conn)); #if MONGO_MINOR >= 6 /* There was an API change in 0.6.0 as linked below */ /* https://github.com/mongodb/mongo-c-driver/blob/master/HISTORY.md */ status = mongo_insert (node->conn, collection_name, bson_record, NULL); #else status = mongo_insert (node->conn, collection_name, bson_record); #endif if (status != MONGO_OK) { ERROR ( "write_mongodb plugin: error inserting record: %d", node->conn->err); if (node->conn->err != MONGO_BSON_INVALID) ERROR ("write_mongodb plugin: %s", node->conn->errstr); else ERROR ("write_mongodb plugin: Invalid BSON structure, error = %#x", (unsigned int) bson_record->err); /* Disconnect except on data errors. */ if ((node->conn->err != MONGO_BSON_INVALID) && (node->conn->err != MONGO_BSON_NOT_FINISHED)) mongo_destroy (node->conn); } pthread_mutex_unlock (&node->lock); /* free our resource as not to leak memory */ bson_dispose (bson_record); return (0); } /* }}} int wm_write */ static void wm_config_free (void *ptr) /* {{{ */ { wm_node_t *node = ptr; if (node == NULL) return; if (mongo_is_connected (node->conn)) mongo_destroy (node->conn); sfree (node->host); sfree (node); } /* }}} void wm_config_free */ static int wm_config_node (oconfig_item_t *ci) /* {{{ */ { wm_node_t *node; int status; int i; node = malloc (sizeof (*node)); if (node == NULL) return (ENOMEM); memset (node, 0, sizeof (*node)); mongo_init (node->conn); node->host = NULL; node->store_rates = 1; pthread_mutex_init (&node->lock, /* attr = */ NULL); status = cf_util_get_string_buffer (ci, node->name, sizeof (node->name)); if (status != 0) { sfree (node); return (status); } for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("Host", child->key) == 0) status = cf_util_get_string (child, &node->host); else if (strcasecmp ("Port", child->key) == 0) { status = cf_util_get_port_number (child); if (status > 0) { node->port = status; status = 0; } } else if (strcasecmp ("Timeout", child->key) == 0) status = cf_util_get_int (child, &node->timeout); else if (strcasecmp ("StoreRates", child->key) == 0) status = cf_util_get_boolean (child, &node->store_rates); else if (strcasecmp ("Database", child->key) == 0) status = cf_util_get_string (child, &node->db); else if (strcasecmp ("User", child->key) == 0) status = cf_util_get_string (child, &node->user); else if (strcasecmp ("Password", child->key) == 0) status = cf_util_get_string (child, &node->passwd); else WARNING ("write_mongodb plugin: Ignoring unknown config option \"%s\".", child->key); if (status != 0) break; } /* for (i = 0; i < ci->children_num; i++) */ if ((node->db != NULL) || (node->user != NULL) || (node->passwd != NULL)) { if ((node->db == NULL) || (node->user == NULL) || (node->passwd == NULL)) { WARNING ("write_mongodb plugin: Authentication requires the " "\"Database\", \"User\" and \"Password\" options to be specified, " "but at last one of them is missing. Authentication will NOT be " "used."); sfree (node->db); sfree (node->user); sfree (node->passwd); } } if (status == 0) { char cb_name[DATA_MAX_NAME_LEN]; user_data_t ud; ssnprintf (cb_name, sizeof (cb_name), "write_mongodb/%s", node->name); ud.data = node; ud.free_func = wm_config_free; status = plugin_register_write (cb_name, wm_write, &ud); INFO ("write_mongodb plugin: registered write plugin %s %d",cb_name,status); } if (status != 0) wm_config_free (node); return (status); } /* }}} int wm_config_node */ static int wm_config (oconfig_item_t *ci) /* {{{ */ { int i; for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("Node", child->key) == 0) wm_config_node (child); else WARNING ("write_mongodb plugin: Ignoring unknown " "configuration option \"%s\" at top level.", child->key); } return (0); } /* }}} int wm_config */ void module_register (void) { plugin_register_complex_config ("write_mongodb", wm_config); } /* vim: set sw=2 sts=2 tw=78 et fdm=marker : */ collectd-5.4.0/src/PaxHeaders.11991/utils_avltree.c0000644037772200116100000000013212204120331020160 xustar000000000000000030 mtime=1376821465.085973632 30 atime=1376821477.226168058 30 ctime=1376821741.946399716 collectd-5.4.0/src/utils_avltree.c0000644037772200116100000003174212204120331016733 0ustar00octoeng00000000000000/** * collectd - src/utils_avltree.c * Copyright (C) 2006,2007 Florian octo 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; either version 2 of the License, or (at your * option) any later version. * * 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: * Florian octo Forster **/ #include "config.h" #include #include #include #include #include "utils_avltree.h" #define BALANCE(n) ((((n)->left == NULL) ? 0 : (n)->left->height) \ - (((n)->right == NULL) ? 0 : (n)->right->height)) /* * private data types */ struct c_avl_node_s { void *key; void *value; int height; struct c_avl_node_s *left; struct c_avl_node_s *right; struct c_avl_node_s *parent; }; typedef struct c_avl_node_s c_avl_node_t; struct c_avl_tree_s { c_avl_node_t *root; int (*compare) (const void *, const void *); int size; }; struct c_avl_iterator_s { c_avl_tree_t *tree; c_avl_node_t *node; }; /* * private functions */ #if 0 static void verify_tree (c_avl_node_t *n) { if (n == NULL) return; verify_tree (n->left); verify_tree (n->right); assert ((BALANCE (n) >= -1) && (BALANCE (n) <= 1)); assert ((n->parent == NULL) || (n->parent->right == n) || (n->parent->left == n)); } /* void verify_tree */ #else # define verify_tree(n) /**/ #endif static void free_node (c_avl_node_t *n) { if (n == NULL) return; if (n->left != NULL) free_node (n->left); if (n->right != NULL) free_node (n->right); free (n); } static int calc_height (c_avl_node_t *n) { int height_left; int height_right; if (n == NULL) return (0); height_left = (n->left == NULL) ? 0 : n->left->height; height_right = (n->right == NULL) ? 0 : n->right->height; return (((height_left > height_right) ? height_left : height_right) + 1); } /* int calc_height */ static c_avl_node_t *search (c_avl_tree_t *t, const void *key) { c_avl_node_t *n; int cmp; n = t->root; while (n != NULL) { cmp = t->compare (key, n->key); if (cmp == 0) return (n); else if (cmp < 0) n = n->left; else n = n->right; } return (NULL); } /* (x) (y) * / \ / \ * (y) /\ /\ (x) * / \ /_c\ ==> / a\ / \ * /\ /\ /____\/\ /\ * / a\ /_b\ /_b\ /_c\ * /____\ */ static c_avl_node_t *rotate_right (c_avl_tree_t *t, c_avl_node_t *x) { c_avl_node_t *p; c_avl_node_t *y; c_avl_node_t *b; p = x->parent; y = x->left; b = y->right; x->left = b; if (b != NULL) b->parent = x; x->parent = y; y->right = x; y->parent = p; assert ((p == NULL) || (p->left == x) || (p->right == x)); if (p == NULL) t->root = y; else if (p->left == x) p->left = y; else p->right = y; x->height = calc_height (x); y->height = calc_height (y); return (y); } /* void rotate_left */ /* * (x) (y) * / \ / \ * /\ (y) (x) /\ * /_a\ / \ ==> / \ / c\ * /\ /\ /\ /\/____\ * /_b\ / c\ /_a\ /_b\ * /____\ */ static c_avl_node_t *rotate_left (c_avl_tree_t *t, c_avl_node_t *x) { c_avl_node_t *p; c_avl_node_t *y; c_avl_node_t *b; p = x->parent; y = x->right; b = y->left; x->right = b; if (b != NULL) b->parent = x; x->parent = y; y->left = x; y->parent = p; assert ((p == NULL) || (p->left == x) || (p->right == x)); if (p == NULL) t->root = y; else if (p->left == x) p->left = y; else p->right = y; x->height = calc_height (x); y->height = calc_height (y); return (y); } /* void rotate_left */ static c_avl_node_t *rotate_left_right (c_avl_tree_t *t, c_avl_node_t *x) { rotate_left (t, x->left); return (rotate_right (t, x)); } /* void rotate_left_right */ static c_avl_node_t *rotate_right_left (c_avl_tree_t *t, c_avl_node_t *x) { rotate_right (t, x->right); return (rotate_left (t, x)); } /* void rotate_right_left */ static void rebalance (c_avl_tree_t *t, c_avl_node_t *n) { int b_top; int b_bottom; while (n != NULL) { b_top = BALANCE (n); assert ((b_top >= -2) && (b_top <= 2)); if (b_top == -2) { assert (n->right != NULL); b_bottom = BALANCE (n->right); assert ((b_bottom >= -1) || (b_bottom <= 1)); if (b_bottom == 1) n = rotate_right_left (t, n); else n = rotate_left (t, n); } else if (b_top == 2) { assert (n->left != NULL); b_bottom = BALANCE (n->left); assert ((b_bottom >= -1) || (b_bottom <= 1)); if (b_bottom == -1) n = rotate_left_right (t, n); else n = rotate_right (t, n); } else { int height = calc_height (n); if (height == n->height) break; n->height = height; } assert (n->height == calc_height (n)); n = n->parent; } /* while (n != NULL) */ } /* void rebalance */ static c_avl_node_t *c_avl_node_next (c_avl_node_t *n) { c_avl_node_t *r; /* return node */ if (n == NULL) { return (NULL); } /* If we can't descent any further, we have to backtrack to the first * parent that's bigger than we, i. e. who's _left_ child we are. */ if (n->right == NULL) { r = n->parent; while ((r != NULL) && (r->parent != NULL)) { if (r->left == n) break; n = r; r = n->parent; } /* n->right == NULL && r == NULL => t is root and has no next * r->left != n => r->right = n => r->parent == NULL */ if ((r == NULL) || (r->left != n)) { assert ((r == NULL) || (r->parent == NULL)); return (NULL); } else { assert (r->left == n); return (r); } } else { r = n->right; while (r->left != NULL) r = r->left; } return (r); } /* c_avl_node_t *c_avl_node_next */ static c_avl_node_t *c_avl_node_prev (c_avl_node_t *n) { c_avl_node_t *r; /* return node */ if (n == NULL) { return (NULL); } /* If we can't descent any further, we have to backtrack to the first * parent that's smaller than we, i. e. who's _right_ child we are. */ if (n->left == NULL) { r = n->parent; while ((r != NULL) && (r->parent != NULL)) { if (r->right == n) break; n = r; r = n->parent; } /* n->left == NULL && r == NULL => t is root and has no next * r->right != n => r->left = n => r->parent == NULL */ if ((r == NULL) || (r->right != n)) { assert ((r == NULL) || (r->parent == NULL)); return (NULL); } else { assert (r->right == n); return (r); } } else { r = n->left; while (r->right != NULL) r = r->right; } return (r); } /* c_avl_node_t *c_avl_node_prev */ static int _remove (c_avl_tree_t *t, c_avl_node_t *n) { assert ((t != NULL) && (n != NULL)); if ((n->left != NULL) && (n->right != NULL)) { c_avl_node_t *r; /* replacement node */ if (BALANCE (n) > 0) /* left subtree is higher */ { assert (n->left != NULL); r = c_avl_node_prev (n); } else /* right subtree is higher */ { assert (n->right != NULL); r = c_avl_node_next (n); } assert ((r->left == NULL) || (r->right == NULL)); /* copy content */ n->key = r->key; n->value = r->value; n = r; } assert ((n->left == NULL) || (n->right == NULL)); if ((n->left == NULL) && (n->right == NULL)) { /* Deleting a leave is easy */ if (n->parent == NULL) { assert (t->root == n); t->root = NULL; } else { assert ((n->parent->left == n) || (n->parent->right == n)); if (n->parent->left == n) n->parent->left = NULL; else n->parent->right = NULL; rebalance (t, n->parent); } free_node (n); } else if (n->left == NULL) { assert (BALANCE (n) == -1); assert ((n->parent == NULL) || (n->parent->left == n) || (n->parent->right == n)); if (n->parent == NULL) { assert (t->root == n); t->root = n->right; } else if (n->parent->left == n) { n->parent->left = n->right; } else { n->parent->right = n->right; } n->right->parent = n->parent; if (n->parent != NULL) rebalance (t, n->parent); n->right = NULL; free_node (n); } else if (n->right == NULL) { assert (BALANCE (n) == 1); assert ((n->parent == NULL) || (n->parent->left == n) || (n->parent->right == n)); if (n->parent == NULL) { assert (t->root == n); t->root = n->left; } else if (n->parent->left == n) { n->parent->left = n->left; } else { n->parent->right = n->left; } n->left->parent = n->parent; if (n->parent != NULL) rebalance (t, n->parent); n->left = NULL; free_node (n); } else { assert (0); } return (0); } /* void *_remove */ /* * public functions */ c_avl_tree_t *c_avl_create (int (*compare) (const void *, const void *)) { c_avl_tree_t *t; if (compare == NULL) return (NULL); if ((t = (c_avl_tree_t *) malloc (sizeof (c_avl_tree_t))) == NULL) return (NULL); t->root = NULL; t->compare = compare; t->size = 0; return (t); } void c_avl_destroy (c_avl_tree_t *t) { if (t == NULL) return; free_node (t->root); free (t); } int c_avl_insert (c_avl_tree_t *t, void *key, void *value) { c_avl_node_t *new; c_avl_node_t *nptr; int cmp; if ((new = (c_avl_node_t *) malloc (sizeof (c_avl_node_t))) == NULL) return (-1); new->key = key; new->value = value; new->height = 1; new->left = NULL; new->right = NULL; if (t->root == NULL) { new->parent = NULL; t->root = new; t->size = 1; return (0); } nptr = t->root; while (42) { cmp = t->compare (nptr->key, new->key); if (cmp == 0) { free_node (new); return (1); } else if (cmp < 0) { /* nptr < new */ if (nptr->right == NULL) { nptr->right = new; new->parent = nptr; rebalance (t, nptr); break; } else { nptr = nptr->right; } } else /* if (cmp > 0) */ { /* nptr > new */ if (nptr->left == NULL) { nptr->left = new; new->parent = nptr; rebalance (t, nptr); break; } else { nptr = nptr->left; } } } /* while (42) */ verify_tree (t->root); ++t->size; return (0); } /* int c_avl_insert */ int c_avl_remove (c_avl_tree_t *t, const void *key, void **rkey, void **rvalue) { c_avl_node_t *n; int status; assert (t != NULL); n = search (t, key); if (n == NULL) return (-1); if (rkey != NULL) *rkey = n->key; if (rvalue != NULL) *rvalue = n->value; status = _remove (t, n); verify_tree (t->root); --t->size; return (status); } /* void *c_avl_remove */ int c_avl_get (c_avl_tree_t *t, const void *key, void **value) { c_avl_node_t *n; assert (t != NULL); n = search (t, key); if (n == NULL) return (-1); if (value != NULL) *value = n->value; return (0); } int c_avl_pick (c_avl_tree_t *t, void **key, void **value) { c_avl_node_t *n; c_avl_node_t *p; if ((key == NULL) || (value == NULL)) return (-1); if (t->root == NULL) return (-1); n = t->root; while ((n->left != NULL) || (n->right != NULL)) { int height_left = (n->left == NULL) ? 0 : n->left->height; int height_right = (n->right == NULL) ? 0 : n->right->height; if (height_left > height_right) n = n->left; else n = n->right; } p = n->parent; if (p == NULL) t->root = NULL; else if (p->left == n) p->left = NULL; else p->right = NULL; *key = n->key; *value = n->value; free_node (n); rebalance (t, p); return (0); } /* int c_avl_pick */ c_avl_iterator_t *c_avl_get_iterator (c_avl_tree_t *t) { c_avl_iterator_t *iter; if (t == NULL) return (NULL); iter = (c_avl_iterator_t *) malloc (sizeof (c_avl_iterator_t)); if (iter == NULL) return (NULL); memset (iter, '\0', sizeof (c_avl_iterator_t)); iter->tree = t; return (iter); } /* c_avl_iterator_t *c_avl_get_iterator */ int c_avl_iterator_next (c_avl_iterator_t *iter, void **key, void **value) { c_avl_node_t *n; if ((iter == NULL) || (key == NULL) || (value == NULL)) return (-1); if (iter->node == NULL) { for (n = iter->tree->root; n != NULL; n = n->left) if (n->left == NULL) break; iter->node = n; } else { n = c_avl_node_next (iter->node); } if (n == NULL) return (-1); iter->node = n; *key = n->key; *value = n->value; return (0); } /* int c_avl_iterator_next */ int c_avl_iterator_prev (c_avl_iterator_t *iter, void **key, void **value) { c_avl_node_t *n; if ((iter == NULL) || (key == NULL) || (value == NULL)) return (-1); if (iter->node == NULL) { for (n = iter->tree->root; n != NULL; n = n->left) if (n->right == NULL) break; iter->node = n; } else { n = c_avl_node_prev (iter->node); } if (n == NULL) return (-1); iter->node = n; *key = n->key; *value = n->value; return (0); } /* int c_avl_iterator_prev */ void c_avl_iterator_destroy (c_avl_iterator_t *iter) { free (iter); } int c_avl_size (c_avl_tree_t *t) { if (t == NULL) return (0); return (t->size); } collectd-5.4.0/src/PaxHeaders.11991/table.c0000644037772200116100000000013212204120331016365 xustar000000000000000030 mtime=1376821465.085973632 30 atime=1376821477.226168058 30 ctime=1376821741.950399779 collectd-5.4.0/src/table.c0000644037772200116100000003054112204120331015134 0ustar00octoeng00000000000000/** * collectd - src/table.c * Copyright (C) 2009 Sebastian Harl * * 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: * Sebastian Harl **/ /* * This module provides generic means to parse and dispatch tabular data. */ #include "collectd.h" #include "common.h" #include "configfile.h" #include "plugin.h" #define log_err(...) ERROR ("table plugin: " __VA_ARGS__) #define log_warn(...) WARNING ("table plugin: " __VA_ARGS__) /* * private data types */ typedef struct { char *type; char *instance_prefix; int *instances; size_t instances_num; int *values; size_t values_num; const data_set_t *ds; } tbl_result_t; typedef struct { char *file; char *sep; char *instance; tbl_result_t *results; size_t results_num; size_t max_colnum; } tbl_t; static void tbl_result_setup (tbl_result_t *res) { res->type = NULL; res->instance_prefix = NULL; res->instances = NULL; res->instances_num = 0; res->values = NULL; res->values_num = 0; res->ds = NULL; } /* tbl_result_setup */ static void tbl_result_clear (tbl_result_t *res) { sfree (res->type); sfree (res->instance_prefix); sfree (res->instances); res->instances_num = 0; sfree (res->values); res->values_num = 0; res->ds = NULL; } /* tbl_result_clear */ static void tbl_setup (tbl_t *tbl, char *file) { tbl->file = sstrdup (file); tbl->sep = NULL; tbl->instance = NULL; tbl->results = NULL; tbl->results_num = 0; tbl->max_colnum = 0; } /* tbl_setup */ static void tbl_clear (tbl_t *tbl) { size_t i; sfree (tbl->file); sfree (tbl->sep); sfree (tbl->instance); for (i = 0; i < tbl->results_num; ++i) tbl_result_clear (tbl->results + i); sfree (tbl->results); tbl->results_num = 0; tbl->max_colnum = 0; } /* tbl_clear */ static tbl_t *tables; static size_t tables_num; /* * configuration handling */ static int tbl_config_set_s (char *name, char **var, oconfig_item_t *ci) { if ((1 != ci->values_num) || (OCONFIG_TYPE_STRING != ci->values[0].type)) { log_err ("\"%s\" expects a single string argument.", name); return 1; } sfree (*var); *var = sstrdup (ci->values[0].value.string); return 0; } /* tbl_config_set_separator */ static int tbl_config_append_array_i (char *name, int **var, size_t *len, oconfig_item_t *ci) { int *tmp; size_t i; if (1 > ci->values_num) { log_err ("\"%s\" expects at least one argument.", name); return 1; } for (i = 0; i < ci->values_num; ++i) { if (OCONFIG_TYPE_NUMBER != ci->values[i].type) { log_err ("\"%s\" expects numerical arguments only.", name); return 1; } } *len += ci->values_num; tmp = (int *)realloc (*var, *len * sizeof (**var)); if (NULL == tmp) { char errbuf[1024]; log_err ("realloc failed: %s.", sstrerror (errno, errbuf, sizeof (errbuf))); return -1; } *var = tmp; for (i = *len - ci->values_num; i < *len; ++i) (*var)[i] = (int)ci->values[i].value.number; return 0; } /* tbl_config_append_array_s */ static int tbl_config_result (tbl_t *tbl, oconfig_item_t *ci) { tbl_result_t *res; int status = 0; size_t i; if (0 != ci->values_num) { log_err (" does not expect any arguments."); return 1; } res = (tbl_result_t *)realloc (tbl->results, (tbl->results_num + 1) * sizeof (*tbl->results)); if (NULL == tbl) { char errbuf[1024]; log_err ("realloc failed: %s.", sstrerror (errno, errbuf, sizeof (errbuf))); return -1; } tbl->results = res; ++tbl->results_num; res = tbl->results + tbl->results_num - 1; tbl_result_setup (res); for (i = 0; i < ci->children_num; ++i) { oconfig_item_t *c = ci->children + i; if (0 == strcasecmp (c->key, "Type")) tbl_config_set_s (c->key, &res->type, c); else if (0 == strcasecmp (c->key, "InstancePrefix")) tbl_config_set_s (c->key, &res->instance_prefix, c); else if (0 == strcasecmp (c->key, "InstancesFrom")) tbl_config_append_array_i (c->key, &res->instances, &res->instances_num, c); else if (0 == strcasecmp (c->key, "ValuesFrom")) tbl_config_append_array_i (c->key, &res->values, &res->values_num, c); else log_warn ("Ignoring unknown config key \"%s\" " " in .", c->key); } if (NULL == res->type) { log_err ("No \"Type\" option specified for " "in table \"%s\".", tbl->file); status = 1; } if (NULL == res->values) { log_err ("No \"ValuesFrom\" option specified for " "in table \"%s\".", tbl->file); status = 1; } if (0 != status) { tbl_result_clear (res); --tbl->results_num; return status; } return 0; } /* tbl_config_result */ static int tbl_config_table (oconfig_item_t *ci) { tbl_t *tbl; int status = 0; size_t i; if ((1 != ci->values_num) || (OCONFIG_TYPE_STRING != ci->values[0].type)) { log_err ("
expects a single string argument."); return 1; } tbl = (tbl_t *)realloc (tables, (tables_num + 1) * sizeof (*tables)); if (NULL == tbl) { char errbuf[1024]; log_err ("realloc failed: %s.", sstrerror (errno, errbuf, sizeof (errbuf))); return -1; } tables = tbl; ++tables_num; tbl = tables + tables_num - 1; tbl_setup (tbl, ci->values[0].value.string); for (i = 0; i < ci->children_num; ++i) { oconfig_item_t *c = ci->children + i; if (0 == strcasecmp (c->key, "Separator")) tbl_config_set_s (c->key, &tbl->sep, c); else if (0 == strcasecmp (c->key, "Instance")) tbl_config_set_s (c->key, &tbl->instance, c); else if (0 == strcasecmp (c->key, "Result")) tbl_config_result (tbl, c); else log_warn ("Ignoring unknown config key \"%s\" " "in
.", c->key, tbl->file); } if (NULL == tbl->sep) { log_err ("Table \"%s\" does not specify any separator.", tbl->file); status = 1; } strunescape (tbl->sep, strlen (tbl->sep) + 1); if (NULL == tbl->instance) { tbl->instance = sstrdup (tbl->file); replace_special (tbl->instance, strlen (tbl->instance)); } if (NULL == tbl->results) { log_err ("Table \"%s\" does not specify any (valid) results.", tbl->file); status = 1; } if (0 != status) { tbl_clear (tbl); --tables_num; return status; } for (i = 0; i < tbl->results_num; ++i) { tbl_result_t *res = tbl->results + i; size_t j; for (j = 0; j < res->instances_num; ++j) if (res->instances[j] > tbl->max_colnum) tbl->max_colnum = res->instances[j]; for (j = 0; j < res->values_num; ++j) if (res->values[j] > tbl->max_colnum) tbl->max_colnum = res->values[j]; } return 0; } /* tbl_config_table */ static int tbl_config (oconfig_item_t *ci) { size_t i; for (i = 0; i < ci->children_num; ++i) { oconfig_item_t *c = ci->children + i; if (0 == strcasecmp (c->key, "Table")) tbl_config_table (c); else log_warn ("Ignoring unknown config key \"%s\".", c->key); } return 0; } /* tbl_config */ /* * result handling */ static int tbl_prepare (tbl_t *tbl) { size_t i; for (i = 0; i < tbl->results_num; ++i) { tbl_result_t *res = tbl->results + i; res->ds = plugin_get_ds (res->type); if (NULL == res->ds) { log_err ("Unknown type \"%s\". See types.db(5) for details.", res->type); return -1; } if (res->values_num != (size_t)res->ds->ds_num) { log_err ("Invalid type \"%s\". Expected %zu data source%s, " "got %i.", res->type, res->values_num, (1 == res->values_num) ? "" : "s", res->ds->ds_num); return -1; } } return 0; } /* tbl_prepare */ static int tbl_finish (tbl_t *tbl) { size_t i; for (i = 0; i < tbl->results_num; ++i) tbl->results[i].ds = NULL; return 0; } /* tbl_finish */ static int tbl_result_dispatch (tbl_t *tbl, tbl_result_t *res, char **fields, size_t fields_num) { value_list_t vl = VALUE_LIST_INIT; value_t values[res->values_num]; size_t i; assert (NULL != res->ds); assert (res->values_num == res->ds->ds_num); for (i = 0; i < res->values_num; ++i) { char *value; assert (res->values[i] < fields_num); value = fields[res->values[i]]; if (0 != parse_value (value, &values[i], res->ds->ds[i].type)) return -1; } vl.values = values; vl.values_len = STATIC_ARRAY_SIZE (values); sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "table", sizeof (vl.plugin)); sstrncpy (vl.plugin_instance, tbl->instance, sizeof (vl.plugin_instance)); sstrncpy (vl.type, res->type, sizeof (vl.type)); if (0 == res->instances_num) { if (NULL != res->instance_prefix) sstrncpy (vl.type_instance, res->instance_prefix, sizeof (vl.type_instance)); } else { char *instances[res->instances_num]; char instances_str[DATA_MAX_NAME_LEN]; for (i = 0; i < res->instances_num; ++i) { assert (res->instances[i] < fields_num); instances[i] = fields[res->instances[i]]; } strjoin (instances_str, sizeof (instances_str), instances, STATIC_ARRAY_SIZE (instances), "-"); instances_str[sizeof (instances_str) - 1] = '\0'; vl.type_instance[sizeof (vl.type_instance) - 1] = '\0'; if (NULL == res->instance_prefix) strncpy (vl.type_instance, instances_str, sizeof (vl.type_instance)); else snprintf (vl.type_instance, sizeof (vl.type_instance), "%s-%s", res->instance_prefix, instances_str); if ('\0' != vl.type_instance[sizeof (vl.type_instance) - 1]) { vl.type_instance[sizeof (vl.type_instance) - 1] = '\0'; log_warn ("Truncated type instance: %s.", vl.type_instance); } } plugin_dispatch_values (&vl); return 0; } /* tbl_result_dispatch */ static int tbl_parse_line (tbl_t *tbl, char *line, size_t len) { char *fields[tbl->max_colnum + 1]; char *ptr, *saveptr; size_t i; i = 0; ptr = line; saveptr = NULL; while (NULL != (fields[i] = strtok_r (ptr, tbl->sep, &saveptr))) { ptr = NULL; ++i; if (i > tbl->max_colnum) break; } if (i <= tbl->max_colnum) { log_err ("Not enough columns in line " "(expected at least %zu, got %zu).", tbl->max_colnum + 1, i); return -1; } for (i = 0; i < tbl->results_num; ++i) if (0 != tbl_result_dispatch (tbl, tbl->results + i, fields, STATIC_ARRAY_SIZE (fields))) { log_err ("Failed to dispatch result."); continue; } return 0; } /* tbl_parse_line */ static int tbl_read_table (tbl_t *tbl) { FILE *fh; char buf[4096]; fh = fopen (tbl->file, "r"); if (NULL == fh) { char errbuf[1024]; log_err ("Failed to open file \"%s\": %s.", tbl->file, sstrerror (errno, errbuf, sizeof (errbuf))); return -1; } buf[sizeof (buf) - 1] = '\0'; while (NULL != fgets (buf, sizeof (buf), fh)) { if ('\0' != buf[sizeof (buf) - 1]) { buf[sizeof (buf) - 1] = '\0'; log_err ("Table %s: Truncated line: %s", tbl->file, buf); } if (0 != tbl_parse_line (tbl, buf, sizeof (buf))) { log_err ("Table %s: Failed to parse line: %s", tbl->file, buf); continue; } } if (0 != ferror (fh)) { char errbuf[1024]; log_err ("Failed to read from file \"%s\": %s.", tbl->file, sstrerror (errno, errbuf, sizeof (errbuf))); fclose (fh); return -1; } fclose (fh); return 0; } /* tbl_read_table */ /* * collectd callbacks */ static int tbl_read (void) { int status = -1; size_t i; if (0 == tables_num) return 0; for (i = 0; i < tables_num; ++i) { tbl_t *tbl = tables + i; if (0 != tbl_prepare (tbl)) { log_err ("Failed to prepare and parse table \"%s\".", tbl->file); continue; } if (0 == tbl_read_table (tbl)) status = 0; tbl_finish (tbl); } return status; } /* tbl_read */ static int tbl_shutdown (void) { size_t i; for (i = 0; i < tables_num; ++i) tbl_clear (&tables[i]); sfree (tables); return 0; } /* tbl_shutdown */ static int tbl_init (void) { if (0 == tables_num) return 0; plugin_register_read ("table", tbl_read); plugin_register_shutdown ("table", tbl_shutdown); return 0; } /* tbl_init */ void module_register (void) { plugin_register_complex_config ("table", tbl_config); plugin_register_init ("table", tbl_init); } /* module_register */ /* vim: set sw=4 ts=4 tw=78 noexpandtab : */ collectd-5.4.0/src/PaxHeaders.11991/collectd-java.pod0000644037772200116100000000013212204120331020346 xustar000000000000000030 mtime=1376821465.061973248 30 atime=1376821477.206167738 30 ctime=1376821741.950399779 collectd-5.4.0/src/collectd-java.pod0000644037772200116100000004730412204120331017122 0ustar00octoeng00000000000000=encoding UTF-8 =head1 NAME collectd-java - Documentation of collectd's "java plugin" =head1 SYNOPSIS LoadPlugin "java" JVMArg "-verbose:jni" JVMArg "-Djava.class.path=/opt/collectd/lib/collectd/bindings/java" LoadPlugin "org.collectd.java.Foobar" # To be parsed by the plugin =head1 DESCRIPTION The I plugin embeds a I (JVM) into I and provides a Java interface to part of collectd's API. This makes it possible to write additions to the daemon in Java. This plugin is similar in nature to, but shares no code with, the I plugin by Sebastian Harl, see L for details. =head1 CONFIGURATION A short outline of this plugin's configuration can be seen in L<"SYNOPSIS"> above. For a complete list of all configuration options and their semantics please read L>. =head1 OVERVIEW When writing additions for collectd in Java, the underlying C base is mostly hidden from you. All complex data types are converted to their Java counterparts before they're passed to your functions. These Java classes reside in the I namespace. The I plugin will create one object of each class configured with the B option. The constructor of this class can then register "callback methods", i.Ee. methods that will be called by the daemon when appropriate. The available classes are: =over 4 =item B All API functions exported to Java are implemented as static functions of this class. See L<"EXPORTED API FUNCTIONS"> below. =item B Corresponds to C, defined in F. =item B Corresponds to C, defined in F. =item B Corresponds to C, defined in F. =item B Corresponds to C, defined in F. =item B Corresponds to C, defined in F. =item B Corresponds to C, defined in F. =back In the remainder of this document, we'll use the short form of these names, for example B. In order to be able to use these abbreviated names, you need to B the classes. =head1 EXPORTED API FUNCTIONS All collectd API functions that are available to Java plugins are implemented as Istatic> functions of the B class. This makes calling these functions pretty straight forward. For example, to send an error message to the daemon, you'd do something like this: Collectd.logError ("That wasn't chicken!"); The following are the currently exported functions. =head2 registerConfig Signature: I B (I name, I object); Registers the B function of I with the daemon. Returns zero upon success and non-zero when an error occurred. See L<"config callback"> below. =head2 registerInit Signature: I B (I name, I object); Registers the B function of I with the daemon. Returns zero upon success and non-zero when an error occurred. See L<"init callback"> below. =head2 registerRead Signature: I B (I name, I object) Registers the B function of I with the daemon. Returns zero upon success and non-zero when an error occurred. See L<"read callback"> below. =head2 registerWrite Signature: I B (I name, I object) Registers the B function of I with the daemon. Returns zero upon success and non-zero when an error occurred. See L<"write callback"> below. =head2 registerFlush Signature: I B (I name, I object) Registers the B function of I with the daemon. Returns zero upon success and non-zero when an error occurred. See L<"flush callback"> below. =head2 registerShutdown Signature: I B (I name, I object); Registers the B function of I with the daemon. Returns zero upon success and non-zero when an error occurred. See L<"shutdown callback"> below. =head2 registerLog Signature: I B (I name, I object); Registers the B function of I with the daemon. Returns zero upon success and non-zero when an error occurred. See L<"log callback"> below. =head2 registerNotification Signature: I B (I name, I object); Registers the B function of I with the daemon. Returns zero upon success and non-zero when an error occurred. See L<"notification callback"> below. =head2 registerMatch Signature: I B (I name, I object); Registers the B function of I with the daemon. Returns zero upon success and non-zero when an error occurred. See L<"match callback"> below. =head2 registerTarget Signature: I B (I name, I object); Registers the B function of I with the daemon. Returns zero upon success and non-zero when an error occurred. See L<"target callback"> below. =head2 dispatchValues Signature: I B (I) Passes the values represented by the B object to the C function of the daemon. The "data set" (or list of "data sources") associated with the object are ignored, because C will automatically lookup the required data set. It is therefore absolutely okay to leave this blank. Returns zero upon success or non-zero upon failure. =head2 getDS Signature: I B (I) Returns the appropriate I or B if the type is not defined. =head2 logError Signature: I B (I) Sends a log message with severity B to the daemon. =head2 logWarning Signature: I B (I) Sends a log message with severity B to the daemon. =head2 logNotice Signature: I B (I) Sends a log message with severity B to the daemon. =head2 logInfo Signature: I B (I) Sends a log message with severity B to the daemon. =head2 logDebug Signature: I B (I) Sends a log message with severity B to the daemon. =head1 REGISTERING CALLBACKS When starting up, collectd creates an object of each configured class. The constructor of this class should then register "callbacks" with the daemon, using the appropriate static functions in B, see L<"EXPORTED API FUNCTIONS"> above. To register a callback, the object being passed to one of the register functions must implement an appropriate interface, which are all in the B namespace. A constructor may register any number of these callbacks, even none. An object without callback methods is never actively called by collectd, but may still call the exported API functions. One could, for example, start a new thread in the constructor and dispatch (submit to the daemon) values asynchronously, whenever one is available. Each callback method is now explained in more detail: =head2 config callback Interface: B Signature: I B (I ci) This method is passed a B object, if both, method and configuration, are available. B is the root of a tree representing the configuration for this plugin. The root itself is the representation of the BPluginE/E> block, so in next to all cases the children of the root are the first interesting objects. To signal success, this method has to return zero. Anything else will be considered an error condition and the plugin will be disabled entirely. See L<"registerConfig"> above. =head2 init callback Interface: B Signature: I B () This method is called after the configuration has been handled. It is supposed to set up the plugin. e.Eg. start threads, open connections, or check if can do anything useful at all. To signal success, this method has to return zero. Anything else will be considered an error condition and the plugin will be disabled entirely. See L<"registerInit"> above. =head2 read callback Interface: B Signature: I B () This method is called periodically and is supposed to gather statistics in whatever fashion. These statistics are represented as a B object and sent to the daemon using L. To signal success, this method has to return zero. Anything else will be considered an error condition and cause an appropriate message to be logged. Currently, returning non-zero does not have any other effects. In particular, Java "read"-methods are not suspended for increasing intervals like C "read"-functions. See L<"registerRead"> above. =head2 write callback Interface: B Signature: I B (I vl) This method is called whenever a value is dispatched to the daemon. The corresponding C "write"-functions are passed a C, so they can decide which values are absolute values (gauge) and which are counter values. To get the corresponding CDataSourceE>, call the B method of the B object. To signal success, this method has to return zero. Anything else will be considered an error condition and cause an appropriate message to be logged. See L<"registerWrite"> above. =head2 flush callback Interface: B Signature: I B (I timeout, I identifier) This method is called when the daemon received a flush command. This can either be done using the C signal (see L) or using the I plugin (see L). If I is greater than zero, only values older than this number of seconds should be flushed. To signal that all values should be flushed regardless of age, this argument is set to a negative number. The I specifies which value should be flushed. If it is not possible to flush one specific value, flush all values. To signal that all values should be flushed, this argument is set to I. To signal success, this method has to return zero. Anything else will be considered an error condition and cause an appropriate message to be logged. See L<"registerFlush"> above. =head2 shutdown callback Interface: B Signature: I B () This method is called when the daemon is shutting down. You should not rely on the destructor to clean up behind the object but use this function instead. To signal success, this method has to return zero. Anything else will be considered an error condition and cause an appropriate message to be logged. See L<"registerShutdown"> above. =head2 log callback Interface: B Signature: I B (I severity, I message) This callback can be used to receive log messages from the daemon. The argument I is one of: =over 4 =item * org.collectd.api.Collectd.LOG_ERR =item * org.collectd.api.Collectd.LOG_WARNING =item * org.collectd.api.Collectd.LOG_NOTICE =item * org.collectd.api.Collectd.LOG_INFO =item * org.collectd.api.Collectd.LOG_DEBUG =back The function does not return any value. See L<"registerLog"> above. =head2 notification callback Interface: B Signature: I B (I n) This callback can be used to receive notifications from the daemon. To signal success, this method has to return zero. Anything else will be considered an error condition and cause an appropriate message to be logged. See L<"registerNotification"> above. =head2 match callback The match (and target, see L<"target callback"> below) callbacks work a bit different from the other callbacks above: You don't register a match callback with the daemon directly, but you register a function which, when called, creates an appropriate object. The object creating the "match" objects is called "match factory". See L<"registerMatch"> above. =head3 Factory object Interface: B Signature: I B (I ci); Called by the daemon to create "match" objects. Returns: A new object which implements the B interface. =head3 Match object Interface: B Signature: I B (I ds, I vl); Called when processing a chain to determine whether or not a I matches. How values are matches is up to the implementing class. Has to return one of: =over 4 =item * B =item * B =back =head2 target callback The target (and match, see L<"match callback"> above) callbacks work a bit different from the other callbacks above: You don't register a target callback with the daemon directly, but you register a function which, when called, creates an appropriate object. The object creating the "target" objects is called "target factory". See L<"registerTarget"> above. =head3 Factory object Interface: B Signature: I B (I ci); Called by the daemon to create "target" objects. Returns: A new object which implements the B interface. =head3 Target object Interface: B Signature: I B (I ds, I vl); Called when processing a chain to perform some action. The action performed is up to the implementing class. Has to return one of: =over 4 =item * B =item * B =item * B =back =head1 EXAMPLE This short example demonstrates how to register a read callback with the daemon: import org.collectd.api.Collectd; import org.collectd.api.ValueList; import org.collectd.api.CollectdReadInterface; public class Foobar implements CollectdReadInterface { public Foobar () { Collectd.registerRead ("Foobar", this); } public int read () { ValueList vl; /* Do something... */ Collectd.dispatchValues (vl); } } =head1 PLUGINS The following plugins are implemented in I. Both, the B option and the B block must be inside the BPluginEjavaE> block (see above). =head2 GenericJMX plugin The GenericJMX plugin reads I (MBeans) from an I using JMX. JMX is a generic framework to provide and query various management information. The interface is used by Java processes to provide internal statistics as well as by the I (JVM) to provide information about the memory used, threads and so on. The configuration of the I consists of two blocks: I blocks that define a mapping of MBean attributes to the “types†used by I, and I blocks which define the parameters needed to connect to an I and what data to collect. The configuration of the I is similar in nature, in case you know it. =head3 MBean blocks I blocks specify what data is retrieved from I and how that data is mapped on the I data types. The block requires one string argument, a name. This name is used in the I blocks (see below) to refer to a specific I block. Therefore, the names must be unique. The following options are recognized within I blocks: =over 4 =item B I Sets the pattern which is used to retrieve I from the I. If more than one MBean is returned you should use the B option (see below) to make the identifiers unique. See also: L =item B I Prefixes the generated I with I. I<(optional)> =item B I The I used by JMX to identify I include so called I<“propertiesâ€> which are basically key-value-pairs. If the given object name is not unique and multiple MBeans are returned, the values of those properties usually differ. You can use this option to build the I from the appropriate property values. This option is optional and may be repeated to generate the I from multiple property values. =item Bvalue /E> blocks The I blocks map one or more attributes of an I to a value list in I. There must be at least one Value block within each I block. =over 4 =item B type Sets the data set used within I to handle the values of the I attribute. =item B I Works like the option of the same name directly beneath the I block, but sets the type instance instead. I<(optional)> =item B I Works like the option of the same name directly beneath the I block, but sets the type instance instead. I<(optional)> =item B
B|B Set this to true if the returned attribute is a I. If set to true, the keys within the I is appended to the I. =item B I Sets the name of the attribute from which to read the value. You can access the keys of composite types by using a dot to concatenate the key name to the attribute name. For example: “attrib0.key42â€. If B
is set to B I must point to a I, otherwise it must point to a numeric type. =back =back =head3 Connection blocks Connection blocks specify I to connect to an I and what data to retrieve. The following configuration options are available: =over 4 =item B I Host name used when dispatching the values to I. The option sets this field only, it is I used to connect to anything and doesn't need to be a real, resolvable name. =item B I Specifies how the I can be reached. Any string accepted by the I is valid. See also: L =item B I Use I to authenticate to the server. If not configured, “monitorRole†will be used. =item B I Use I to authenticate to the server. If not given, unauthenticated access is used. =item B I Prefixes the generated I with I. If a second I is specified in a referenced I block, the prefix specified in the I block will appear at the beginning of the I, the prefix specified in the I block will be appended to it. =item B I Configures which of the I blocks to use with this connection. May be repeated to collect multiple I from this server. =back =head1 SEE ALSO L, L, L, L =head1 AUTHOR Florian Forster EoctoEatEverplant.orgE collectd-5.4.0/src/PaxHeaders.11991/filter_chain.c0000644037772200116100000000013212204120331017725 xustar000000000000000030 mtime=1376821465.069973376 30 atime=1376821477.214167866 30 ctime=1376821741.950399779 collectd-5.4.0/src/filter_chain.c0000644037772200116100000006037412204120331016503 0ustar00octoeng00000000000000/** * collectd - src/filter_chain.h * Copyright (C) 2008-2010 Florian octo 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: * Florian octo Forster **/ #include "collectd.h" #include "configfile.h" #include "plugin.h" #include "utils_complain.h" #include "common.h" #include "filter_chain.h" /* * Data types */ /* List of matches, used in fc_rule_t and for the global `match_list_head' * variable. */ struct fc_match_s; typedef struct fc_match_s fc_match_t; /* {{{ */ struct fc_match_s { char name[DATA_MAX_NAME_LEN]; match_proc_t proc; void *user_data; fc_match_t *next; }; /* }}} */ /* List of targets, used in fc_rule_t and for the global `target_list_head' * variable. */ struct fc_target_s; typedef struct fc_target_s fc_target_t; /* {{{ */ struct fc_target_s { char name[DATA_MAX_NAME_LEN]; void *user_data; target_proc_t proc; fc_target_t *next; }; /* }}} */ /* List of rules, used in fc_chain_t */ struct fc_rule_s; typedef struct fc_rule_s fc_rule_t; /* {{{ */ struct fc_rule_s { char name[DATA_MAX_NAME_LEN]; fc_match_t *matches; fc_target_t *targets; fc_rule_t *next; }; /* }}} */ /* List of chains, used for `chain_list_head' */ struct fc_chain_s /* {{{ */ { char name[DATA_MAX_NAME_LEN]; fc_rule_t *rules; fc_target_t *targets; fc_chain_t *next; }; /* }}} */ /* * Global variables */ static fc_match_t *match_list_head; static fc_target_t *target_list_head; static fc_chain_t *chain_list_head; /* * Private functions */ static void fc_free_matches (fc_match_t *m) /* {{{ */ { if (m == NULL) return; if (m->proc.destroy != NULL) (*m->proc.destroy) (&m->user_data); else if (m->user_data != NULL) { ERROR ("Filter subsystem: fc_free_matches: There is user data, but no " "destroy functions has been specified. " "Memory will probably be lost!"); } if (m->next != NULL) fc_free_matches (m->next); free (m); } /* }}} void fc_free_matches */ static void fc_free_targets (fc_target_t *t) /* {{{ */ { if (t == NULL) return; if (t->proc.destroy != NULL) (*t->proc.destroy) (&t->user_data); else if (t->user_data != NULL) { ERROR ("Filter subsystem: fc_free_targets: There is user data, but no " "destroy functions has been specified. " "Memory will probably be lost!"); } if (t->next != NULL) fc_free_targets (t->next); free (t); } /* }}} void fc_free_targets */ static void fc_free_rules (fc_rule_t *r) /* {{{ */ { if (r == NULL) return; fc_free_matches (r->matches); fc_free_targets (r->targets); if (r->next != NULL) fc_free_rules (r->next); free (r); } /* }}} void fc_free_rules */ static void fc_free_chains (fc_chain_t *c) /* {{{ */ { if (c == NULL) return; fc_free_rules (c->rules); fc_free_targets (c->targets); if (c->next != NULL) fc_free_chains (c->next); free (c); } /* }}} void fc_free_chains */ static char *fc_strdup (const char *orig) /* {{{ */ { size_t sz; char *dest; if (orig == NULL) return (NULL); sz = strlen (orig) + 1; dest = (char *) malloc (sz); if (dest == NULL) return (NULL); memcpy (dest, orig, sz); return (dest); } /* }}} char *fc_strdup */ /* * Configuration. * * The configuration looks somewhat like this: * * * * * Plugin "^mysql$" * Type "^mysql_command$" * TypeInstance "^show_" * * * * * * * Plugin "rrdtool" * * */ static int fc_config_add_match (fc_match_t **matches_head, /* {{{ */ oconfig_item_t *ci) { fc_match_t *m; fc_match_t *ptr; int status; if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { WARNING ("Filter subsystem: `Match' blocks require " "exactly one string argument."); return (-1); } ptr = match_list_head; while (ptr != NULL) { if (strcasecmp (ptr->name, ci->values[0].value.string) == 0) break; ptr = ptr->next; } if (ptr == NULL) { WARNING ("Filter subsystem: Cannot find a \"%s\" match. " "Did you load the appropriate plugin?", ci->values[0].value.string); return (-1); } m = (fc_match_t *) malloc (sizeof (*m)); if (m == NULL) { ERROR ("fc_config_add_match: malloc failed."); return (-1); } memset (m, 0, sizeof (*m)); sstrncpy (m->name, ptr->name, sizeof (m->name)); memcpy (&m->proc, &ptr->proc, sizeof (m->proc)); m->user_data = NULL; m->next = NULL; if (m->proc.create != NULL) { status = (*m->proc.create) (ci, &m->user_data); if (status != 0) { WARNING ("Filter subsystem: Failed to create a %s match.", m->name); fc_free_matches (m); return (-1); } } if (*matches_head != NULL) { ptr = *matches_head; while (ptr->next != NULL) ptr = ptr->next; ptr->next = m; } else { *matches_head = m; } return (0); } /* }}} int fc_config_add_match */ static int fc_config_add_target (fc_target_t **targets_head, /* {{{ */ oconfig_item_t *ci) { fc_target_t *t; fc_target_t *ptr; int status; if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { WARNING ("Filter subsystem: `Target' blocks require " "exactly one string argument."); return (-1); } ptr = target_list_head; while (ptr != NULL) { if (strcasecmp (ptr->name, ci->values[0].value.string) == 0) break; ptr = ptr->next; } if (ptr == NULL) { WARNING ("Filter subsystem: Cannot find a \"%s\" target. " "Did you load the appropriate plugin?", ci->values[0].value.string); return (-1); } t = (fc_target_t *) malloc (sizeof (*t)); if (t == NULL) { ERROR ("fc_config_add_target: malloc failed."); return (-1); } memset (t, 0, sizeof (*t)); sstrncpy (t->name, ptr->name, sizeof (t->name)); memcpy (&t->proc, &ptr->proc, sizeof (t->proc)); t->user_data = NULL; t->next = NULL; if (t->proc.create != NULL) { status = (*t->proc.create) (ci, &t->user_data); if (status != 0) { WARNING ("Filter subsystem: Failed to create a %s target.", t->name); fc_free_targets (t); return (-1); } } else { t->user_data = NULL; } if (*targets_head != NULL) { ptr = *targets_head; while (ptr->next != NULL) ptr = ptr->next; ptr->next = t; } else { *targets_head = t; } return (0); } /* }}} int fc_config_add_target */ static int fc_config_add_rule (fc_chain_t *chain, /* {{{ */ oconfig_item_t *ci) { fc_rule_t *rule; char rule_name[2*DATA_MAX_NAME_LEN] = "Unnamed rule"; int status = 0; int i; if (ci->values_num > 1) { WARNING ("Filter subsystem: `Rule' blocks have at most one argument."); return (-1); } else if ((ci->values_num == 1) && (ci->values[0].type != OCONFIG_TYPE_STRING)) { WARNING ("Filter subsystem: `Rule' blocks expect one string argument " "or no argument at all."); return (-1); } rule = (fc_rule_t *) malloc (sizeof (*rule)); if (rule == NULL) { ERROR ("fc_config_add_rule: malloc failed."); return (-1); } memset (rule, 0, sizeof (*rule)); rule->next = NULL; if (ci->values_num == 1) { sstrncpy (rule->name, ci->values[0].value.string, sizeof (rule->name)); ssnprintf (rule_name, sizeof (rule_name), "Rule \"%s\"", ci->values[0].value.string); } for (i = 0; i < ci->children_num; i++) { oconfig_item_t *option = ci->children + i; status = 0; if (strcasecmp ("Match", option->key) == 0) status = fc_config_add_match (&rule->matches, option); else if (strcasecmp ("Target", option->key) == 0) status = fc_config_add_target (&rule->targets, option); else { WARNING ("Filter subsystem: %s: Option `%s' not allowed " "inside a block.", rule_name, option->key); status = -1; } if (status != 0) break; } /* for (ci->children) */ /* Additional sanity checking. */ while (status == 0) { if (rule->targets == NULL) { WARNING ("Filter subsystem: %s: No target has been specified.", rule_name); status = -1; break; } break; } /* while (status == 0) */ if (status != 0) { fc_free_rules (rule); return (-1); } if (chain->rules != NULL) { fc_rule_t *ptr; ptr = chain->rules; while (ptr->next != NULL) ptr = ptr->next; ptr->next = rule; } else { chain->rules = rule; } return (0); } /* }}} int fc_config_add_rule */ static int fc_config_add_chain (const oconfig_item_t *ci) /* {{{ */ { fc_chain_t *chain; int status = 0; int i; if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { WARNING ("Filter subsystem: blocks require exactly one " "string argument."); return (-1); } chain = (fc_chain_t *) malloc (sizeof (*chain)); if (chain == NULL) { ERROR ("fc_config_add_chain: malloc failed."); return (-1); } memset (chain, 0, sizeof (*chain)); sstrncpy (chain->name, ci->values[0].value.string, sizeof (chain->name)); chain->rules = NULL; chain->targets = NULL; chain->next = NULL; for (i = 0; i < ci->children_num; i++) { oconfig_item_t *option = ci->children + i; status = 0; if (strcasecmp ("Rule", option->key) == 0) status = fc_config_add_rule (chain, option); else if (strcasecmp ("Target", option->key) == 0) status = fc_config_add_target (&chain->targets, option); else { WARNING ("Filter subsystem: Chain %s: Option `%s' not allowed " "inside a block.", chain->name, option->key); status = -1; } if (status != 0) break; } /* for (ci->children) */ if (status != 0) { fc_free_chains (chain); return (-1); } if (chain_list_head != NULL) { fc_chain_t *ptr; ptr = chain_list_head; while (ptr->next != NULL) ptr = ptr->next; ptr->next = chain; } else { chain_list_head = chain; } return (0); } /* }}} int fc_config_add_chain */ /* * Built-in target "jump" * * Prefix `bit' like `_b_uilt-_i_n _t_arget' */ static int fc_bit_jump_create (const oconfig_item_t *ci, /* {{{ */ void **user_data) { oconfig_item_t *ci_chain; if (ci->children_num != 1) { ERROR ("Filter subsystem: The built-in target `jump' needs exactly " "one `Chain' argument!"); return (-1); } ci_chain = ci->children; if (strcasecmp ("Chain", ci_chain->key) != 0) { ERROR ("Filter subsystem: The built-in target `jump' does not " "support the configuration option `%s'.", ci_chain->key); return (-1); } if ((ci_chain->values_num != 1) || (ci_chain->values[0].type != OCONFIG_TYPE_STRING)) { ERROR ("Filter subsystem: Built-in target `jump': The `Chain' option " "needs exactly one string argument."); return (-1); } *user_data = fc_strdup (ci_chain->values[0].value.string); if (*user_data == NULL) { ERROR ("fc_bit_jump_create: fc_strdup failed."); return (-1); } return (0); } /* }}} int fc_bit_jump_create */ static int fc_bit_jump_destroy (void **user_data) /* {{{ */ { if (user_data != NULL) { free (*user_data); *user_data = NULL; } return (0); } /* }}} int fc_bit_jump_destroy */ static int fc_bit_jump_invoke (const data_set_t *ds, /* {{{ */ value_list_t *vl, notification_meta_t __attribute__((unused)) **meta, void **user_data) { char *chain_name; fc_chain_t *chain; int status; chain_name = *user_data; for (chain = chain_list_head; chain != NULL; chain = chain->next) if (strcasecmp (chain_name, chain->name) == 0) break; if (chain == NULL) { ERROR ("Filter subsystem: Built-in target `jump': There is no chain " "named `%s'.", chain_name); return (-1); } status = fc_process_chain (ds, vl, chain); if (status < 0) return (status); else if (status == FC_TARGET_STOP) return (FC_TARGET_STOP); else return (FC_TARGET_CONTINUE); } /* }}} int fc_bit_jump_invoke */ static int fc_bit_stop_invoke (const data_set_t __attribute__((unused)) *ds, /* {{{ */ value_list_t __attribute__((unused)) *vl, notification_meta_t __attribute__((unused)) **meta, void __attribute__((unused)) **user_data) { return (FC_TARGET_STOP); } /* }}} int fc_bit_stop_invoke */ static int fc_bit_return_invoke (const data_set_t __attribute__((unused)) *ds, /* {{{ */ value_list_t __attribute__((unused)) *vl, notification_meta_t __attribute__((unused)) **meta, void __attribute__((unused)) **user_data) { return (FC_TARGET_RETURN); } /* }}} int fc_bit_return_invoke */ static int fc_bit_write_create (const oconfig_item_t *ci, /* {{{ */ void **user_data) { int i; char **plugin_list; size_t plugin_list_len; plugin_list = NULL; plugin_list_len = 0; for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; char **temp; int j; if (strcasecmp ("Plugin", child->key) != 0) { ERROR ("Filter subsystem: The built-in target `write' does not " "support the configuration option `%s'.", child->key); continue; } for (j = 0; j < child->values_num; j++) { if (child->values[j].type != OCONFIG_TYPE_STRING) { ERROR ("Filter subsystem: Built-in target `write': " "The `Plugin' option accepts only string arguments."); continue; } temp = (char **) realloc (plugin_list, (plugin_list_len + 2) * (sizeof (*plugin_list))); if (temp == NULL) { ERROR ("fc_bit_write_create: realloc failed."); continue; } plugin_list = temp; plugin_list[plugin_list_len] = fc_strdup (child->values[j].value.string); if (plugin_list[plugin_list_len] == NULL) { ERROR ("fc_bit_write_create: fc_strdup failed."); continue; } plugin_list_len++; plugin_list[plugin_list_len] = NULL; } /* for (j = 0; j < child->values_num; j++) */ } /* for (i = 0; i < ci->children_num; i++) */ *user_data = plugin_list; return (0); } /* }}} int fc_bit_write_create */ static int fc_bit_write_destroy (void **user_data) /* {{{ */ { char **plugin_list; size_t i; if ((user_data == NULL) || (*user_data == NULL)) return (0); plugin_list = *user_data; for (i = 0; plugin_list[i] != NULL; i++) free (plugin_list[i]); free (plugin_list); return (0); } /* }}} int fc_bit_write_destroy */ static int fc_bit_write_invoke (const data_set_t *ds, /* {{{ */ value_list_t *vl, notification_meta_t __attribute__((unused)) **meta, void **user_data) { char **plugin_list; int status; plugin_list = NULL; if (user_data != NULL) plugin_list = *user_data; if ((plugin_list == NULL) || (plugin_list[0] == NULL)) { static c_complain_t enoent_complaint = C_COMPLAIN_INIT_STATIC; status = plugin_write (/* plugin = */ NULL, ds, vl); if (status == ENOENT) { /* in most cases this is a permanent error, so use the complain * mechanism rather than spamming the logs */ c_complain (LOG_INFO, &enoent_complaint, "Filter subsystem: Built-in target `write': Dispatching value to " "all write plugins failed with status %i (ENOENT). " "Most likely this means you didn't load any write plugins.", status); } else if (status != 0) { INFO ("Filter subsystem: Built-in target `write': Dispatching value to " "all write plugins failed with status %i.", status); } else { assert (status == 0); c_release (LOG_INFO, &enoent_complaint, "Filter subsystem: " "Built-in target `write': Some write plugin is back to normal " "operation. `write' succeeded."); } } else { size_t i; for (i = 0; plugin_list[i] != NULL; i++) { status = plugin_write (plugin_list[i], ds, vl); if (status != 0) { INFO ("Filter subsystem: Built-in target `write': Dispatching value to " "the `%s' plugin failed with status %i.", plugin_list[i], status); } } /* for (i = 0; plugin_list[i] != NULL; i++) */ } return (FC_TARGET_CONTINUE); } /* }}} int fc_bit_write_invoke */ static int fc_init_once (void) /* {{{ */ { static int done = 0; target_proc_t tproc; if (done != 0) return (0); memset (&tproc, 0, sizeof (tproc)); tproc.create = fc_bit_jump_create; tproc.destroy = fc_bit_jump_destroy; tproc.invoke = fc_bit_jump_invoke; fc_register_target ("jump", tproc); memset (&tproc, 0, sizeof (tproc)); tproc.create = NULL; tproc.destroy = NULL; tproc.invoke = fc_bit_stop_invoke; fc_register_target ("stop", tproc); memset (&tproc, 0, sizeof (tproc)); tproc.create = NULL; tproc.destroy = NULL; tproc.invoke = fc_bit_return_invoke; fc_register_target ("return", tproc); memset (&tproc, 0, sizeof (tproc)); tproc.create = fc_bit_write_create; tproc.destroy = fc_bit_write_destroy; tproc.invoke = fc_bit_write_invoke; fc_register_target ("write", tproc); done++; return (0); } /* }}} int fc_init_once */ /* * Public functions */ /* Add a match to list of available matches. */ int fc_register_match (const char *name, match_proc_t proc) /* {{{ */ { fc_match_t *m; DEBUG ("fc_register_match (%s);", name); m = (fc_match_t *) malloc (sizeof (*m)); if (m == NULL) return (-ENOMEM); memset (m, 0, sizeof (*m)); sstrncpy (m->name, name, sizeof (m->name)); memcpy (&m->proc, &proc, sizeof (m->proc)); m->next = NULL; if (match_list_head == NULL) { match_list_head = m; } else { fc_match_t *ptr; ptr = match_list_head; while (ptr->next != NULL) ptr = ptr->next; ptr->next = m; } return (0); } /* }}} int fc_register_match */ /* Add a target to list of available targets. */ int fc_register_target (const char *name, target_proc_t proc) /* {{{ */ { fc_target_t *t; DEBUG ("fc_register_target (%s);", name); t = (fc_target_t *) malloc (sizeof (*t)); if (t == NULL) return (-ENOMEM); memset (t, 0, sizeof (*t)); sstrncpy (t->name, name, sizeof (t->name)); memcpy (&t->proc, &proc, sizeof (t->proc)); t->next = NULL; if (target_list_head == NULL) { target_list_head = t; } else { fc_target_t *ptr; ptr = target_list_head; while (ptr->next != NULL) ptr = ptr->next; ptr->next = t; } return (0); } /* }}} int fc_register_target */ fc_chain_t *fc_chain_get_by_name (const char *chain_name) /* {{{ */ { fc_chain_t *chain; if (chain_name == NULL) return (NULL); for (chain = chain_list_head; chain != NULL; chain = chain->next) if (strcasecmp (chain_name, chain->name) == 0) return (chain); return (NULL); } /* }}} int fc_chain_get_by_name */ int fc_process_chain (const data_set_t *ds, value_list_t *vl, /* {{{ */ fc_chain_t *chain) { fc_rule_t *rule; fc_target_t *target; int status; if (chain == NULL) return (-1); DEBUG ("fc_process_chain (chain = %s);", chain->name); status = FC_TARGET_CONTINUE; for (rule = chain->rules; rule != NULL; rule = rule->next) { fc_match_t *match; if (rule->name[0] != 0) { DEBUG ("fc_process_chain (%s): Testing the `%s' rule.", chain->name, rule->name); } /* N. B.: rule->matches may be NULL. */ for (match = rule->matches; match != NULL; match = match->next) { /* FIXME: Pass the meta-data to match targets here (when implemented). */ status = (*match->proc.match) (ds, vl, /* meta = */ NULL, &match->user_data); if (status < 0) { WARNING ("fc_process_chain (%s): A match failed.", chain->name); break; } else if (status != FC_MATCH_MATCHES) break; } /* for-loop has been aborted: Either error or no match. */ if (match != NULL) { status = FC_TARGET_CONTINUE; continue; } if (rule->name[0] != 0) { DEBUG ("fc_process_chain (%s): Rule `%s' matches.", chain->name, rule->name); } for (target = rule->targets; target != NULL; target = target->next) { /* If we get here, all matches have matched the value. Execute the * target. */ /* FIXME: Pass the meta-data to match targets here (when implemented). */ status = (*target->proc.invoke) (ds, vl, /* meta = */ NULL, &target->user_data); if (status < 0) { WARNING ("fc_process_chain (%s): A target failed.", chain->name); continue; } else if (status == FC_TARGET_CONTINUE) continue; else if (status == FC_TARGET_STOP) break; else if (status == FC_TARGET_RETURN) break; else { WARNING ("fc_process_chain (%s): Unknown return value " "from target `%s': %i", chain->name, target->name, status); } } if ((status == FC_TARGET_STOP) || (status == FC_TARGET_RETURN)) { if (rule->name[0] != 0) { DEBUG ("fc_process_chain (%s): Rule `%s' signaled " "the %s condition.", chain->name, rule->name, (status == FC_TARGET_STOP) ? "stop" : "return"); } break; } else { status = FC_TARGET_CONTINUE; } } /* for (rule) */ if (status == FC_TARGET_STOP) return (FC_TARGET_STOP); else if (status == FC_TARGET_RETURN) return (FC_TARGET_CONTINUE); /* for-loop has been aborted: A target returned `FC_TARGET_STOP' */ if (rule != NULL) return (FC_TARGET_CONTINUE); DEBUG ("fc_process_chain (%s): Executing the default targets.", chain->name); status = FC_TARGET_CONTINUE; for (target = chain->targets; target != NULL; target = target->next) { /* If we get here, all matches have matched the value. Execute the * target. */ /* FIXME: Pass the meta-data to match targets here (when implemented). */ status = (*target->proc.invoke) (ds, vl, /* meta = */ NULL, &target->user_data); if (status < 0) { WARNING ("fc_process_chain (%s): The default target failed.", chain->name); } else if (status == FC_TARGET_CONTINUE) continue; else if (status == FC_TARGET_STOP) break; else if (status == FC_TARGET_RETURN) break; else { WARNING ("fc_process_chain (%s): Unknown return value " "from target `%s': %i", chain->name, target->name, status); } } if ((status == FC_TARGET_STOP) || (status == FC_TARGET_RETURN)) { assert (target != NULL); DEBUG ("fc_process_chain (%s): Default target `%s' signaled " "the %s condition.", chain->name, target->name, (status == FC_TARGET_STOP) ? "stop" : "return"); if (status == FC_TARGET_STOP) return (FC_TARGET_STOP); else return (FC_TARGET_CONTINUE); } DEBUG ("fc_process_chain (%s): Signaling `continue' at end of chain.", chain->name); return (FC_TARGET_CONTINUE); } /* }}} int fc_process_chain */ /* Iterate over all rules in the chain and execute all targets for which all * matches match. */ int fc_default_action (const data_set_t *ds, value_list_t *vl) /* {{{ */ { /* FIXME: Pass the meta-data to match targets here (when implemented). */ return (fc_bit_write_invoke (ds, vl, /* meta = */ NULL, /* user_data = */ NULL)); } /* }}} int fc_default_action */ int fc_configure (const oconfig_item_t *ci) /* {{{ */ { fc_init_once (); if (ci == NULL) return (-EINVAL); if (strcasecmp ("Chain", ci->key) == 0) return (fc_config_add_chain (ci)); WARNING ("Filter subsystem: Unknown top level config option `%s'.", ci->key); return (-1); } /* }}} int fc_configure */ /* vim: set sw=2 sts=2 et fdm=marker : */ collectd-5.4.0/src/PaxHeaders.11991/utils_time.h0000644037772200116100000000013212204120331017461 xustar000000000000000030 mtime=1376821465.089973696 30 atime=1376821477.230168122 30 ctime=1376821741.950399779 collectd-5.4.0/src/utils_time.h0000644037772200116100000000631612204120331016233 0ustar00octoeng00000000000000/** * collectd - src/utils_time.h * Copyright (C) 2010 Florian octo 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: * Florian octo Forster **/ #ifndef UTILS_TIME_H #define UTILS_TIME_H 1 #include "collectd.h" /* * "cdtime_t" is a 64bit unsigned integer. The time is stored at a 2^-30 second * resolution, i.e. the most significant 34 bit are used to store the time in * seconds, the least significant bits store the sub-second part in something * very close to nanoseconds. *The* big advantage of storing time in this * manner is that comparing times and calculating differences is as simple as * it is with "time_t", i.e. a simple integer comparison / subtraction works. */ /* * cdtime_t is defined in "collectd.h" */ /* typedef uint64_t cdtime_t; */ /* 2^30 = 1073741824 */ #define TIME_T_TO_CDTIME_T(t) (((cdtime_t) (t)) * 1073741824) #define CDTIME_T_TO_TIME_T(t) ((time_t) ((t) / 1073741824)) #define CDTIME_T_TO_DOUBLE(t) (((double) (t)) / 1073741824.0) #define DOUBLE_TO_CDTIME_T(d) ((cdtime_t) ((d) * 1073741824.0)) #define MS_TO_CDTIME_T(ms) ((cdtime_t) (((double) (ms)) * 1073741.824)) #define CDTIME_T_TO_MS(t) ((long) (((double) (t)) / 1073741.824)) #define US_TO_CDTIME_T(us) ((cdtime_t) (((double) (us)) * 1073.741824)) #define CDTIME_T_TO_US(t) ((suseconds_t) (((double) (t)) / 1073.741824)) #define NS_TO_CDTIME_T(ns) ((cdtime_t) (((double) (ns)) * 1.073741824)) #define CDTIME_T_TO_NS(t) ((long) (((double) (t)) / 1.073741824)) #define CDTIME_T_TO_TIMEVAL(cdt,tvp) do { \ (tvp)->tv_sec = CDTIME_T_TO_TIME_T (cdt); \ (tvp)->tv_usec = CDTIME_T_TO_US ((cdt) % 1073741824); \ } while (0) #define TIMEVAL_TO_CDTIME_T(tv) (TIME_T_TO_CDTIME_T ((tv)->tv_sec) \ + US_TO_CDTIME_T ((tv)->tv_usec)) #define CDTIME_T_TO_TIMESPEC(cdt,tsp) do { \ (tsp)->tv_sec = CDTIME_T_TO_TIME_T (cdt); \ (tsp)->tv_nsec = CDTIME_T_TO_NS ((cdt) % 1073741824); \ } while (0) #define TIMESPEC_TO_CDTIME_T(ts) (TIME_T_TO_CDTIME_T ((ts)->tv_sec) \ + NS_TO_CDTIME_T ((ts)->tv_nsec)) cdtime_t cdtime (void); /* format a cdtime_t value in ISO 8601 format: * returns the number of characters written to the string (not including the * terminating null byte or 0 on error; the function ensures that the string * is null terminated */ size_t cdtime_to_iso8601 (char *s, size_t max, cdtime_t t); #endif /* UTILS_TIME_H */ /* vim: set sw=2 sts=2 et : */ collectd-5.4.0/src/PaxHeaders.11991/cpu.c0000644037772200116100000000013212204120331016065 xustar000000000000000030 mtime=1376821465.069973376 30 atime=1376821477.214167866 30 ctime=1376821741.954399843 collectd-5.4.0/src/cpu.c0000644037772200116100000003615412204120331014642 0ustar00octoeng00000000000000/** * collectd - src/cpu.c * Copyright (C) 2005-2010 Florian octo Forster * Copyright (C) 2008 Oleg King * Copyright (C) 2009 Simon Kuhnle * Copyright (C) 2009 Manuel Sanmartin * * 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: * Florian octo Forster * Oleg King * Simon Kuhnle * Manuel Sanmartin **/ #include "collectd.h" #include "common.h" #include "plugin.h" #ifdef HAVE_MACH_KERN_RETURN_H # include #endif #ifdef HAVE_MACH_MACH_INIT_H # include #endif #ifdef HAVE_MACH_HOST_PRIV_H # include #endif #if HAVE_MACH_MACH_ERROR_H # include #endif #ifdef HAVE_MACH_PROCESSOR_INFO_H # include #endif #ifdef HAVE_MACH_PROCESSOR_H # include #endif #ifdef HAVE_MACH_VM_MAP_H # include #endif #ifdef HAVE_LIBKSTAT # include #endif /* HAVE_LIBKSTAT */ #if (defined(HAVE_SYSCTL) && HAVE_SYSCTL) \ || (defined(HAVE_SYSCTLBYNAME) && HAVE_SYSCTLBYNAME) # ifdef HAVE_SYS_SYSCTL_H # include # endif # ifdef HAVE_SYS_DKSTAT_H # include # endif # if !defined(CP_USER) || !defined(CP_NICE) || !defined(CP_SYS) || !defined(CP_INTR) || !defined(CP_IDLE) || !defined(CPUSTATES) # define CP_USER 0 # define CP_NICE 1 # define CP_SYS 2 # define CP_INTR 3 # define CP_IDLE 4 # define CPUSTATES 5 # endif #endif /* HAVE_SYSCTL || HAVE_SYSCTLBYNAME */ #if HAVE_SYSCTL # if defined(CTL_HW) && defined(HW_NCPU) \ && defined(CTL_KERN) && defined(KERN_CPTIME) && defined(CPUSTATES) # define CAN_USE_SYSCTL 1 # else # define CAN_USE_SYSCTL 0 # endif #else # define CAN_USE_SYSCTL 0 #endif #if HAVE_STATGRAB_H # include #endif # ifdef HAVE_PERFSTAT # include # include # endif /* HAVE_PERFSTAT */ #if !PROCESSOR_CPU_LOAD_INFO && !KERNEL_LINUX && !HAVE_LIBKSTAT \ && !CAN_USE_SYSCTL && !HAVE_SYSCTLBYNAME && !HAVE_LIBSTATGRAB && !HAVE_PERFSTAT # error "No applicable input method." #endif #ifdef PROCESSOR_CPU_LOAD_INFO static mach_port_t port_host; static processor_port_array_t cpu_list; static mach_msg_type_number_t cpu_list_len; #if PROCESSOR_TEMPERATURE static int cpu_temp_retry_counter = 0; static int cpu_temp_retry_step = 1; static int cpu_temp_retry_max = 1; #endif /* PROCESSOR_TEMPERATURE */ /* #endif PROCESSOR_CPU_LOAD_INFO */ #elif defined(KERNEL_LINUX) /* no variables needed */ /* #endif KERNEL_LINUX */ #elif defined(HAVE_LIBKSTAT) /* colleague tells me that Sun doesn't sell systems with more than 100 or so CPUs.. */ # define MAX_NUMCPU 256 extern kstat_ctl_t *kc; static kstat_t *ksp[MAX_NUMCPU]; static int numcpu; /* #endif HAVE_LIBKSTAT */ #elif CAN_USE_SYSCTL static int numcpu; /* #endif CAN_USE_SYSCTL */ #elif defined(HAVE_SYSCTLBYNAME) static int numcpu; # ifdef HAVE_SYSCTL_KERN_CP_TIMES static int maxcpu; # endif /* HAVE_SYSCTL_KERN_CP_TIMES */ /* #endif HAVE_SYSCTLBYNAME */ #elif defined(HAVE_LIBSTATGRAB) /* no variables needed */ /* #endif HAVE_LIBSTATGRAB */ #elif defined(HAVE_PERFSTAT) static perfstat_cpu_t *perfcpu; static int numcpu; static int pnumcpu; #endif /* HAVE_PERFSTAT */ static int init (void) { #if PROCESSOR_CPU_LOAD_INFO || PROCESSOR_TEMPERATURE kern_return_t status; port_host = mach_host_self (); /* FIXME: Free `cpu_list' if it's not NULL */ if ((status = host_processors (port_host, &cpu_list, &cpu_list_len)) != KERN_SUCCESS) { ERROR ("cpu plugin: host_processors returned %i", (int) status); cpu_list_len = 0; return (-1); } DEBUG ("host_processors returned %i %s", (int) cpu_list_len, cpu_list_len == 1 ? "processor" : "processors"); INFO ("cpu plugin: Found %i processor%s.", (int) cpu_list_len, cpu_list_len == 1 ? "" : "s"); cpu_temp_retry_max = 86400 / CDTIME_T_TO_TIME_T (plugin_get_interval ()); /* #endif PROCESSOR_CPU_LOAD_INFO */ #elif defined(HAVE_LIBKSTAT) kstat_t *ksp_chain; numcpu = 0; if (kc == NULL) return (-1); /* Solaris doesn't count linear.. *sigh* */ for (numcpu = 0, ksp_chain = kc->kc_chain; (numcpu < MAX_NUMCPU) && (ksp_chain != NULL); ksp_chain = ksp_chain->ks_next) if (strncmp (ksp_chain->ks_module, "cpu_stat", 8) == 0) ksp[numcpu++] = ksp_chain; /* #endif HAVE_LIBKSTAT */ #elif CAN_USE_SYSCTL size_t numcpu_size; int mib[2] = {CTL_HW, HW_NCPU}; int status; numcpu = 0; numcpu_size = sizeof (numcpu); status = sysctl (mib, STATIC_ARRAY_SIZE (mib), &numcpu, &numcpu_size, NULL, 0); if (status == -1) { char errbuf[1024]; WARNING ("cpu plugin: sysctl: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } /* #endif CAN_USE_SYSCTL */ #elif defined (HAVE_SYSCTLBYNAME) size_t numcpu_size; numcpu_size = sizeof (numcpu); if (sysctlbyname ("hw.ncpu", &numcpu, &numcpu_size, NULL, 0) < 0) { char errbuf[1024]; WARNING ("cpu plugin: sysctlbyname(hw.ncpu): %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } #ifdef HAVE_SYSCTL_KERN_CP_TIMES numcpu_size = sizeof (maxcpu); if (sysctlbyname("kern.smp.maxcpus", &maxcpu, &numcpu_size, NULL, 0) < 0) { char errbuf[1024]; WARNING ("cpu plugin: sysctlbyname(kern.smp.maxcpus): %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } #else if (numcpu != 1) NOTICE ("cpu: Only one processor supported when using `sysctlbyname' (found %i)", numcpu); #endif /* #endif HAVE_SYSCTLBYNAME */ #elif defined(HAVE_LIBSTATGRAB) /* nothing to initialize */ /* #endif HAVE_LIBSTATGRAB */ #elif defined(HAVE_PERFSTAT) /* nothing to initialize */ #endif /* HAVE_PERFSTAT */ return (0); } /* int init */ static void submit (int cpu_num, const char *type_instance, derive_t value) { value_t values[1]; value_list_t vl = VALUE_LIST_INIT; values[0].derive = value; vl.values = values; vl.values_len = 1; sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "cpu", sizeof (vl.plugin)); ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance), "%i", cpu_num); sstrncpy (vl.type, "cpu", sizeof (vl.type)); sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); plugin_dispatch_values (&vl); } static int cpu_read (void) { #if PROCESSOR_CPU_LOAD_INFO || PROCESSOR_TEMPERATURE int cpu; kern_return_t status; #if PROCESSOR_CPU_LOAD_INFO processor_cpu_load_info_data_t cpu_info; mach_msg_type_number_t cpu_info_len; #endif #if PROCESSOR_TEMPERATURE processor_info_data_t cpu_temp; mach_msg_type_number_t cpu_temp_len; #endif host_t cpu_host; for (cpu = 0; cpu < cpu_list_len; cpu++) { #if PROCESSOR_CPU_LOAD_INFO cpu_host = 0; cpu_info_len = PROCESSOR_BASIC_INFO_COUNT; if ((status = processor_info (cpu_list[cpu], PROCESSOR_CPU_LOAD_INFO, &cpu_host, (processor_info_t) &cpu_info, &cpu_info_len)) != KERN_SUCCESS) { ERROR ("cpu plugin: processor_info failed with status %i", (int) status); continue; } if (cpu_info_len < CPU_STATE_MAX) { ERROR ("cpu plugin: processor_info returned only %i elements..", cpu_info_len); continue; } submit (cpu, "user", (derive_t) cpu_info.cpu_ticks[CPU_STATE_USER]); submit (cpu, "nice", (derive_t) cpu_info.cpu_ticks[CPU_STATE_NICE]); submit (cpu, "system", (derive_t) cpu_info.cpu_ticks[CPU_STATE_SYSTEM]); submit (cpu, "idle", (derive_t) cpu_info.cpu_ticks[CPU_STATE_IDLE]); #endif /* PROCESSOR_CPU_LOAD_INFO */ #if PROCESSOR_TEMPERATURE /* * Not all Apple computers do have this ability. To minimize * the messages sent to the syslog we do an exponential * stepback if `processor_info' fails. We still try ~once a day * though.. */ if (cpu_temp_retry_counter > 0) { cpu_temp_retry_counter--; continue; } cpu_temp_len = PROCESSOR_INFO_MAX; status = processor_info (cpu_list[cpu], PROCESSOR_TEMPERATURE, &cpu_host, cpu_temp, &cpu_temp_len); if (status != KERN_SUCCESS) { ERROR ("cpu plugin: processor_info failed: %s", mach_error_string (status)); cpu_temp_retry_counter = cpu_temp_retry_step; cpu_temp_retry_step *= 2; if (cpu_temp_retry_step > cpu_temp_retry_max) cpu_temp_retry_step = cpu_temp_retry_max; continue; } if (cpu_temp_len != 1) { DEBUG ("processor_info (PROCESSOR_TEMPERATURE) returned %i elements..?", (int) cpu_temp_len); continue; } cpu_temp_retry_counter = 0; cpu_temp_retry_step = 1; #endif /* PROCESSOR_TEMPERATURE */ } /* #endif PROCESSOR_CPU_LOAD_INFO */ #elif defined(KERNEL_LINUX) int cpu; derive_t user, nice, syst, idle; derive_t wait, intr, sitr; /* sitr == soft interrupt */ FILE *fh; char buf[1024]; char *fields[9]; int numfields; if ((fh = fopen ("/proc/stat", "r")) == NULL) { char errbuf[1024]; ERROR ("cpu plugin: fopen (/proc/stat) failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } while (fgets (buf, 1024, fh) != NULL) { if (strncmp (buf, "cpu", 3)) continue; if ((buf[3] < '0') || (buf[3] > '9')) continue; numfields = strsplit (buf, fields, 9); if (numfields < 5) continue; cpu = atoi (fields[0] + 3); user = atoll (fields[1]); nice = atoll (fields[2]); syst = atoll (fields[3]); idle = atoll (fields[4]); submit (cpu, "user", user); submit (cpu, "nice", nice); submit (cpu, "system", syst); submit (cpu, "idle", idle); if (numfields >= 8) { wait = atoll (fields[5]); intr = atoll (fields[6]); sitr = atoll (fields[7]); submit (cpu, "wait", wait); submit (cpu, "interrupt", intr); submit (cpu, "softirq", sitr); if (numfields >= 9) submit (cpu, "steal", atoll (fields[8])); } } fclose (fh); /* #endif defined(KERNEL_LINUX) */ #elif defined(HAVE_LIBKSTAT) int cpu; derive_t user, syst, idle, wait; static cpu_stat_t cs; if (kc == NULL) return (-1); for (cpu = 0; cpu < numcpu; cpu++) { if (kstat_read (kc, ksp[cpu], &cs) == -1) continue; /* error message? */ idle = (derive_t) cs.cpu_sysinfo.cpu[CPU_IDLE]; user = (derive_t) cs.cpu_sysinfo.cpu[CPU_USER]; syst = (derive_t) cs.cpu_sysinfo.cpu[CPU_KERNEL]; wait = (derive_t) cs.cpu_sysinfo.cpu[CPU_WAIT]; submit (ksp[cpu]->ks_instance, "user", user); submit (ksp[cpu]->ks_instance, "system", syst); submit (ksp[cpu]->ks_instance, "idle", idle); submit (ksp[cpu]->ks_instance, "wait", wait); } /* #endif defined(HAVE_LIBKSTAT) */ #elif CAN_USE_SYSCTL uint64_t cpuinfo[numcpu][CPUSTATES]; size_t cpuinfo_size; int status; int i; if (numcpu < 1) { ERROR ("cpu plugin: Could not determine number of " "installed CPUs using sysctl(3)."); return (-1); } memset (cpuinfo, 0, sizeof (cpuinfo)); #if defined(KERN_CPTIME2) if (numcpu > 1) { for (i = 0; i < numcpu; i++) { int mib[] = {CTL_KERN, KERN_CPTIME2, i}; cpuinfo_size = sizeof (cpuinfo[0]); status = sysctl (mib, STATIC_ARRAY_SIZE (mib), cpuinfo[i], &cpuinfo_size, NULL, 0); if (status == -1) { char errbuf[1024]; ERROR ("cpu plugin: sysctl failed: %s.", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } } } else #endif /* defined(KERN_CPTIME2) */ { int mib[] = {CTL_KERN, KERN_CPTIME}; long cpuinfo_tmp[CPUSTATES]; cpuinfo_size = sizeof(cpuinfo_tmp); status = sysctl (mib, STATIC_ARRAY_SIZE (mib), &cpuinfo_tmp, &cpuinfo_size, NULL, 0); if (status == -1) { char errbuf[1024]; ERROR ("cpu plugin: sysctl failed: %s.", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } for(i = 0; i < CPUSTATES; i++) { cpuinfo[0][i] = cpuinfo_tmp[i]; } } for (i = 0; i < numcpu; i++) { submit (i, "user", cpuinfo[i][CP_USER]); submit (i, "nice", cpuinfo[i][CP_NICE]); submit (i, "system", cpuinfo[i][CP_SYS]); submit (i, "idle", cpuinfo[i][CP_IDLE]); submit (i, "interrupt", cpuinfo[i][CP_INTR]); } /* #endif CAN_USE_SYSCTL */ #elif defined(HAVE_SYSCTLBYNAME) && defined(HAVE_SYSCTL_KERN_CP_TIMES) long cpuinfo[maxcpu][CPUSTATES]; size_t cpuinfo_size; int i; memset (cpuinfo, 0, sizeof (cpuinfo)); cpuinfo_size = sizeof (cpuinfo); if (sysctlbyname("kern.cp_times", &cpuinfo, &cpuinfo_size, NULL, 0) < 0) { char errbuf[1024]; ERROR ("cpu plugin: sysctlbyname failed: %s.", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } for (i = 0; i < numcpu; i++) { submit (i, "user", cpuinfo[i][CP_USER]); submit (i, "nice", cpuinfo[i][CP_NICE]); submit (i, "system", cpuinfo[i][CP_SYS]); submit (i, "idle", cpuinfo[i][CP_IDLE]); submit (i, "interrupt", cpuinfo[i][CP_INTR]); } /* #endif HAVE_SYSCTL_KERN_CP_TIMES */ #elif defined(HAVE_SYSCTLBYNAME) long cpuinfo[CPUSTATES]; size_t cpuinfo_size; cpuinfo_size = sizeof (cpuinfo); if (sysctlbyname("kern.cp_time", &cpuinfo, &cpuinfo_size, NULL, 0) < 0) { char errbuf[1024]; ERROR ("cpu plugin: sysctlbyname failed: %s.", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } submit (0, "user", cpuinfo[CP_USER]); submit (0, "nice", cpuinfo[CP_NICE]); submit (0, "system", cpuinfo[CP_SYS]); submit (0, "idle", cpuinfo[CP_IDLE]); submit (0, "interrupt", cpuinfo[CP_INTR]); /* #endif HAVE_SYSCTLBYNAME */ #elif defined(HAVE_LIBSTATGRAB) sg_cpu_stats *cs; cs = sg_get_cpu_stats (); if (cs == NULL) { ERROR ("cpu plugin: sg_get_cpu_stats failed."); return (-1); } submit (0, "idle", (derive_t) cs->idle); submit (0, "nice", (derive_t) cs->nice); submit (0, "swap", (derive_t) cs->swap); submit (0, "system", (derive_t) cs->kernel); submit (0, "user", (derive_t) cs->user); submit (0, "wait", (derive_t) cs->iowait); /* #endif HAVE_LIBSTATGRAB */ #elif defined(HAVE_PERFSTAT) perfstat_id_t id; int i, cpus; numcpu = perfstat_cpu(NULL, NULL, sizeof(perfstat_cpu_t), 0); if(numcpu == -1) { char errbuf[1024]; WARNING ("cpu plugin: perfstat_cpu: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } if (pnumcpu != numcpu || perfcpu == NULL) { if (perfcpu != NULL) free(perfcpu); perfcpu = malloc(numcpu * sizeof(perfstat_cpu_t)); } pnumcpu = numcpu; id.name[0] = '\0'; if ((cpus = perfstat_cpu(&id, perfcpu, sizeof(perfstat_cpu_t), numcpu)) < 0) { char errbuf[1024]; WARNING ("cpu plugin: perfstat_cpu: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } for (i = 0; i < cpus; i++) { submit (i, "idle", (derive_t) perfcpu[i].idle); submit (i, "system", (derive_t) perfcpu[i].sys); submit (i, "user", (derive_t) perfcpu[i].user); submit (i, "wait", (derive_t) perfcpu[i].wait); } #endif /* HAVE_PERFSTAT */ return (0); } void module_register (void) { plugin_register_init ("cpu", init); plugin_register_read ("cpu", cpu_read); } /* void module_register */ collectd-5.4.0/src/PaxHeaders.11991/utils_subst.c0000644037772200116100000000013212204120331017656 xustar000000000000000030 mtime=1376821465.089973696 30 atime=1376821477.230168122 30 ctime=1376821741.954399843 collectd-5.4.0/src/utils_subst.c0000644037772200116100000000660512204120331016431 0ustar00octoeng00000000000000/** * collectd - src/utils_subst.c * Copyright (C) 2008 Sebastian Harl * * 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: * Sebastian "tokkee" Harl **/ /* * This module provides functions for string substitution. */ #include "collectd.h" #include "common.h" char *subst (char *buf, size_t buflen, const char *string, int off1, int off2, const char *replacement) { char *buf_ptr = buf; size_t len = buflen; if ((NULL == buf) || (0 >= buflen) || (NULL == string) || (0 > off1) || (0 > off2) || (off1 > off2) || (NULL == replacement)) return NULL; sstrncpy (buf_ptr, string, ((size_t)off1 + 1 > buflen) ? buflen : (size_t)off1 + 1); buf_ptr += off1; len -= off1; if (0 >= len) return buf; sstrncpy (buf_ptr, replacement, len); buf_ptr += strlen (replacement); len -= strlen (replacement); if (0 >= len) return buf; sstrncpy (buf_ptr, string + off2, len); return buf; } /* subst */ char *asubst (const char *string, int off1, int off2, const char *replacement) { char *buf; int len; char *ret; if ((NULL == string) || (0 > off1) || (0 > off2) || (off1 > off2) || (NULL ==replacement)) return NULL; len = off1 + strlen (replacement) + strlen (string) - off2 + 1; buf = (char *)malloc (len); if (NULL == buf) return NULL; ret = subst (buf, len, string, off1, off2, replacement); if (NULL == ret) free (buf); return ret; } /* asubst */ char *subst_string (char *buf, size_t buflen, const char *string, const char *needle, const char *replacement) { char *temp; size_t needle_len; size_t i; if ((buf == NULL) || (string == NULL) || (needle == NULL) || (replacement == NULL)) return (NULL); temp = (char *) malloc (buflen); if (temp == NULL) { ERROR ("subst_string: malloc failed."); return (NULL); } needle_len = strlen (needle); strncpy (buf, string, buflen); /* Limit the loop to prevent endless loops. */ for (i = 0; i < buflen; i++) { char *begin_ptr; size_t begin; /* Find `needle' in `buf'. */ begin_ptr = strstr (buf, needle); if (begin_ptr == NULL) break; /* Calculate the start offset. */ begin = begin_ptr - buf; /* Substitute the region using `subst'. The result is stored in * `temp'. */ begin_ptr = subst (temp, buflen, buf, begin, begin + needle_len, replacement); if (begin_ptr == NULL) { WARNING ("subst_string: subst failed."); break; } /* Copy the new string in `temp' to `buf' for the next round. */ strncpy (buf, temp, buflen); } if (i >= buflen) { WARNING ("subst_string: Loop exited after %zu iterations: " "string = %s; needle = %s; replacement = %s;", i, string, needle, replacement); } sfree (temp); return (buf); } /* char *subst_string */ /* vim: set sw=4 ts=4 tw=78 noexpandtab : */ collectd-5.4.0/src/PaxHeaders.11991/common.c0000644037772200116100000000013212204120331016566 xustar000000000000000030 mtime=1376821465.069973376 30 atime=1376821477.210167802 30 ctime=1376821741.958399908 collectd-5.4.0/src/common.c0000644037772200116100000007747512204120331015356 0ustar00octoeng00000000000000/** * collectd - src/common.c * Copyright (C) 2005-2010 Florian octo 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: * Florian octo Forster * Niki W. Waibel * Sebastian Harl * MichaÅ‚ MirosÅ‚aw **/ #if HAVE_CONFIG_H # include "config.h" #endif #include "collectd.h" #include "common.h" #include "plugin.h" #include "utils_cache.h" #if HAVE_PTHREAD_H # include #endif #ifdef HAVE_MATH_H # include #endif /* for getaddrinfo */ #include #include #include #if HAVE_NETINET_IN_H # include #endif /* for ntohl and htonl */ #if HAVE_ARPA_INET_H # include #endif #ifdef HAVE_LIBKSTAT extern kstat_ctl_t *kc; #endif #if !HAVE_GETPWNAM_R static pthread_mutex_t getpwnam_r_lock = PTHREAD_MUTEX_INITIALIZER; #endif #if !HAVE_STRERROR_R static pthread_mutex_t strerror_r_lock = PTHREAD_MUTEX_INITIALIZER; #endif char *sstrncpy (char *dest, const char *src, size_t n) { strncpy (dest, src, n); dest[n - 1] = '\0'; return (dest); } /* char *sstrncpy */ int ssnprintf (char *dest, size_t n, const char *format, ...) { int ret = 0; va_list ap; va_start (ap, format); ret = vsnprintf (dest, n, format, ap); dest[n - 1] = '\0'; va_end (ap); return (ret); } /* int ssnprintf */ char *ssnprintf_alloc (char const *format, ...) /* {{{ */ { char static_buffer[1024] = ""; char *alloc_buffer; size_t alloc_buffer_size; int status; va_list ap; /* Try printing into the static buffer. In many cases it will be * sufficiently large and we can simply return a strdup() of this * buffer. */ va_start (ap, format); status = vsnprintf (static_buffer, sizeof (static_buffer), format, ap); va_end (ap); if (status < 0) return (NULL); /* "status" does not include the null byte. */ alloc_buffer_size = (size_t) (status + 1); if (alloc_buffer_size <= sizeof (static_buffer)) return (strdup (static_buffer)); /* Allocate a buffer large enough to hold the string. */ alloc_buffer = malloc (alloc_buffer_size); if (alloc_buffer == NULL) return (NULL); memset (alloc_buffer, 0, alloc_buffer_size); /* Print again into this new buffer. */ va_start (ap, format); status = vsnprintf (alloc_buffer, alloc_buffer_size, format, ap); va_end (ap); if (status < 0) { sfree (alloc_buffer); return (NULL); } return (alloc_buffer); } /* }}} char *ssnprintf_alloc */ char *sstrdup (const char *s) { char *r; size_t sz; if (s == NULL) return (NULL); /* Do not use `strdup' here, because it's not specified in POSIX. It's * ``only'' an XSI extension. */ sz = strlen (s) + 1; r = (char *) malloc (sizeof (char) * sz); if (r == NULL) { ERROR ("sstrdup: Out of memory."); exit (3); } memcpy (r, s, sizeof (char) * sz); return (r); } /* char *sstrdup */ /* Even though Posix requires "strerror_r" to return an "int", * some systems (e.g. the GNU libc) return a "char *" _and_ * ignore the second argument ... -tokkee */ char *sstrerror (int errnum, char *buf, size_t buflen) { buf[0] = '\0'; #if !HAVE_STRERROR_R { char *temp; pthread_mutex_lock (&strerror_r_lock); temp = strerror (errnum); sstrncpy (buf, temp, buflen); pthread_mutex_unlock (&strerror_r_lock); } /* #endif !HAVE_STRERROR_R */ #elif STRERROR_R_CHAR_P { char *temp; temp = strerror_r (errnum, buf, buflen); if (buf[0] == '\0') { if ((temp != NULL) && (temp != buf) && (temp[0] != '\0')) sstrncpy (buf, temp, buflen); else sstrncpy (buf, "strerror_r did not return " "an error message", buflen); } } /* #endif STRERROR_R_CHAR_P */ #else if (strerror_r (errnum, buf, buflen) != 0) { ssnprintf (buf, buflen, "Error #%i; " "Additionally, strerror_r failed.", errnum); } #endif /* STRERROR_R_CHAR_P */ return (buf); } /* char *sstrerror */ void *smalloc (size_t size) { void *r; if ((r = malloc (size)) == NULL) { ERROR ("Not enough memory."); exit (3); } return (r); } /* void *smalloc */ #if 0 void sfree (void **ptr) { if (ptr == NULL) return; if (*ptr != NULL) free (*ptr); *ptr = NULL; } #endif ssize_t sread (int fd, void *buf, size_t count) { char *ptr; size_t nleft; ssize_t status; ptr = (char *) buf; nleft = count; while (nleft > 0) { status = read (fd, (void *) ptr, nleft); if ((status < 0) && ((errno == EAGAIN) || (errno == EINTR))) continue; if (status < 0) return (status); if (status == 0) { DEBUG ("Received EOF from fd %i. " "Closing fd and returning error.", fd); close (fd); return (-1); } assert ((0 > status) || (nleft >= (size_t)status)); nleft = nleft - status; ptr = ptr + status; } return (0); } ssize_t swrite (int fd, const void *buf, size_t count) { const char *ptr; size_t nleft; ssize_t status; ptr = (const char *) buf; nleft = count; while (nleft > 0) { status = write (fd, (const void *) ptr, nleft); if ((status < 0) && ((errno == EAGAIN) || (errno == EINTR))) continue; if (status < 0) return (status); nleft = nleft - status; ptr = ptr + status; } return (0); } int strsplit (char *string, char **fields, size_t size) { size_t i; char *ptr; char *saveptr; i = 0; ptr = string; saveptr = NULL; while ((fields[i] = strtok_r (ptr, " \t\r\n", &saveptr)) != NULL) { ptr = NULL; i++; if (i >= size) break; } return ((int) i); } int strjoin (char *dst, size_t dst_len, char **fields, size_t fields_num, const char *sep) { size_t field_len; size_t sep_len; int i; memset (dst, '\0', dst_len); if (fields_num <= 0) return (-1); sep_len = 0; if (sep != NULL) sep_len = strlen (sep); for (i = 0; i < (int)fields_num; i++) { if ((i > 0) && (sep_len > 0)) { if (dst_len <= sep_len) return (-1); strncat (dst, sep, dst_len); dst_len -= sep_len; } field_len = strlen (fields[i]); if (dst_len <= field_len) return (-1); strncat (dst, fields[i], dst_len); dst_len -= field_len; } return (strlen (dst)); } int strsubstitute (char *str, char c_from, char c_to) { int ret; if (str == NULL) return (-1); ret = 0; while (*str != '\0') { if (*str == c_from) { *str = c_to; ret++; } str++; } return (ret); } /* int strsubstitute */ int strunescape (char *buf, size_t buf_len) { size_t i; for (i = 0; (i < buf_len) && (buf[i] != '\0'); ++i) { if (buf[i] != '\\') continue; if ((i >= buf_len) || (buf[i + 1] == '\0')) { ERROR ("string unescape: backslash found at end of string."); return (-1); } switch (buf[i + 1]) { case 't': buf[i] = '\t'; break; case 'n': buf[i] = '\n'; break; case 'r': buf[i] = '\r'; break; default: buf[i] = buf[i + 1]; break; } memmove (buf + i + 1, buf + i + 2, buf_len - i - 2); } return (0); } /* int strunescape */ size_t strstripnewline (char *buffer) { size_t buffer_len = strlen (buffer); while (buffer_len > 0) { if ((buffer[buffer_len - 1] != '\n') && (buffer[buffer_len - 1] != '\r')) break; buffer[buffer_len] = 0; buffer_len--; } return (buffer_len); } /* size_t strstripnewline */ int escape_slashes (char *buf, int buf_len) { int i; if (strcmp (buf, "/") == 0) { if (buf_len < 5) return (-1); strncpy (buf, "root", buf_len); return (0); } if (buf_len <= 1) return (0); /* Move one to the left */ if (buf[0] == '/') memmove (buf, buf + 1, buf_len - 1); for (i = 0; i < buf_len - 1; i++) { if (buf[i] == '\0') break; else if (buf[i] == '/') buf[i] = '_'; } buf[i] = '\0'; return (0); } /* int escape_slashes */ void replace_special (char *buffer, size_t buffer_size) { size_t i; for (i = 0; i < buffer_size; i++) { if (buffer[i] == 0) return; if ((!isalnum ((int) buffer[i])) && (buffer[i] != '-')) buffer[i] = '_'; } } /* void replace_special */ int timeval_cmp (struct timeval tv0, struct timeval tv1, struct timeval *delta) { struct timeval *larger; struct timeval *smaller; int status; NORMALIZE_TIMEVAL (tv0); NORMALIZE_TIMEVAL (tv1); if ((tv0.tv_sec == tv1.tv_sec) && (tv0.tv_usec == tv1.tv_usec)) { if (delta != NULL) { delta->tv_sec = 0; delta->tv_usec = 0; } return (0); } if ((tv0.tv_sec < tv1.tv_sec) || ((tv0.tv_sec == tv1.tv_sec) && (tv0.tv_usec < tv1.tv_usec))) { larger = &tv1; smaller = &tv0; status = -1; } else { larger = &tv0; smaller = &tv1; status = 1; } if (delta != NULL) { delta->tv_sec = larger->tv_sec - smaller->tv_sec; if (smaller->tv_usec <= larger->tv_usec) delta->tv_usec = larger->tv_usec - smaller->tv_usec; else { --delta->tv_sec; delta->tv_usec = 1000000 + larger->tv_usec - smaller->tv_usec; } } assert ((delta == NULL) || ((0 <= delta->tv_usec) && (delta->tv_usec < 1000000))); return (status); } /* int timeval_cmp */ int check_create_dir (const char *file_orig) { struct stat statbuf; char file_copy[512]; char dir[512]; int dir_len = 512; char *fields[16]; int fields_num; char *ptr; char *saveptr; int last_is_file = 1; int path_is_absolute = 0; size_t len; int i; /* * Sanity checks first */ if (file_orig == NULL) return (-1); if ((len = strlen (file_orig)) < 1) return (-1); else if (len >= sizeof (file_copy)) return (-1); /* * If `file_orig' ends in a slash the last component is a directory, * otherwise it's a file. Act accordingly.. */ if (file_orig[len - 1] == '/') last_is_file = 0; if (file_orig[0] == '/') path_is_absolute = 1; /* * Create a copy for `strtok_r' to destroy */ sstrncpy (file_copy, file_orig, sizeof (file_copy)); /* * Break into components. This will eat up several slashes in a row and * remove leading and trailing slashes.. */ ptr = file_copy; saveptr = NULL; fields_num = 0; while ((fields[fields_num] = strtok_r (ptr, "/", &saveptr)) != NULL) { ptr = NULL; fields_num++; if (fields_num >= 16) break; } /* * For each component, do.. */ for (i = 0; i < (fields_num - last_is_file); i++) { /* * Do not create directories that start with a dot. This * prevents `../../' attacks and other likely malicious * behavior. */ if (fields[i][0] == '.') { ERROR ("Cowardly refusing to create a directory that " "begins with a `.' (dot): `%s'", file_orig); return (-2); } /* * Join the components together again */ dir[0] = '/'; if (strjoin (dir + path_is_absolute, dir_len - path_is_absolute, fields, i + 1, "/") < 0) { ERROR ("strjoin failed: `%s', component #%i", file_orig, i); return (-1); } while (42) { if ((stat (dir, &statbuf) == -1) && (lstat (dir, &statbuf) == -1)) { if (errno == ENOENT) { if (mkdir (dir, S_IRWXU | S_IRWXG | S_IRWXO) == 0) break; /* this might happen, if a different thread created * the directory in the meantime * => call stat() again to check for S_ISDIR() */ if (EEXIST == errno) continue; char errbuf[1024]; ERROR ("check_create_dir: mkdir (%s): %s", dir, sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } else { char errbuf[1024]; ERROR ("check_create_dir: stat (%s): %s", dir, sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } } else if (!S_ISDIR (statbuf.st_mode)) { ERROR ("check_create_dir: `%s' exists but is not " "a directory!", dir); return (-1); } break; } } return (0); } /* check_create_dir */ #ifdef HAVE_LIBKSTAT int get_kstat (kstat_t **ksp_ptr, char *module, int instance, char *name) { char ident[128]; *ksp_ptr = NULL; if (kc == NULL) return (-1); ssnprintf (ident, sizeof (ident), "%s,%i,%s", module, instance, name); *ksp_ptr = kstat_lookup (kc, module, instance, name); if (*ksp_ptr == NULL) { ERROR ("get_kstat: Cound not find kstat %s", ident); return (-1); } if ((*ksp_ptr)->ks_type != KSTAT_TYPE_NAMED) { ERROR ("get_kstat: kstat %s has wrong type", ident); *ksp_ptr = NULL; return (-1); } #ifdef assert assert (*ksp_ptr != NULL); assert ((*ksp_ptr)->ks_type == KSTAT_TYPE_NAMED); #endif if (kstat_read (kc, *ksp_ptr, NULL) == -1) { ERROR ("get_kstat: kstat %s could not be read", ident); return (-1); } if ((*ksp_ptr)->ks_type != KSTAT_TYPE_NAMED) { ERROR ("get_kstat: kstat %s has wrong type", ident); return (-1); } return (0); } long long get_kstat_value (kstat_t *ksp, char *name) { kstat_named_t *kn; long long retval = -1LL; if (ksp == NULL) { ERROR ("get_kstat_value (\"%s\"): ksp is NULL.", name); return (-1LL); } else if (ksp->ks_type != KSTAT_TYPE_NAMED) { ERROR ("get_kstat_value (\"%s\"): ksp->ks_type (%#x) " "is not KSTAT_TYPE_NAMED (%#x).", name, (unsigned int) ksp->ks_type, (unsigned int) KSTAT_TYPE_NAMED); return (-1LL); } if ((kn = (kstat_named_t *) kstat_data_lookup (ksp, name)) == NULL) return (-1LL); if (kn->data_type == KSTAT_DATA_INT32) retval = (long long) kn->value.i32; else if (kn->data_type == KSTAT_DATA_UINT32) retval = (long long) kn->value.ui32; else if (kn->data_type == KSTAT_DATA_INT64) retval = (long long) kn->value.i64; /* According to ANSI C99 `long long' must hold at least 64 bits */ else if (kn->data_type == KSTAT_DATA_UINT64) retval = (long long) kn->value.ui64; /* XXX: Might overflow! */ else WARNING ("get_kstat_value: Not a numeric value: %s", name); return (retval); } #endif /* HAVE_LIBKSTAT */ #ifndef HAVE_HTONLL unsigned long long ntohll (unsigned long long n) { #if BYTE_ORDER == BIG_ENDIAN return (n); #else return (((unsigned long long) ntohl (n)) << 32) + ntohl (n >> 32); #endif } /* unsigned long long ntohll */ unsigned long long htonll (unsigned long long n) { #if BYTE_ORDER == BIG_ENDIAN return (n); #else return (((unsigned long long) htonl (n)) << 32) + htonl (n >> 32); #endif } /* unsigned long long htonll */ #endif /* HAVE_HTONLL */ #if FP_LAYOUT_NEED_NOTHING /* Well, we need nothing.. */ /* #endif FP_LAYOUT_NEED_NOTHING */ #elif FP_LAYOUT_NEED_ENDIANFLIP || FP_LAYOUT_NEED_INTSWAP # if FP_LAYOUT_NEED_ENDIANFLIP # define FP_CONVERT(A) ((((uint64_t)(A) & 0xff00000000000000LL) >> 56) | \ (((uint64_t)(A) & 0x00ff000000000000LL) >> 40) | \ (((uint64_t)(A) & 0x0000ff0000000000LL) >> 24) | \ (((uint64_t)(A) & 0x000000ff00000000LL) >> 8) | \ (((uint64_t)(A) & 0x00000000ff000000LL) << 8) | \ (((uint64_t)(A) & 0x0000000000ff0000LL) << 24) | \ (((uint64_t)(A) & 0x000000000000ff00LL) << 40) | \ (((uint64_t)(A) & 0x00000000000000ffLL) << 56)) # else # define FP_CONVERT(A) ((((uint64_t)(A) & 0xffffffff00000000LL) >> 32) | \ (((uint64_t)(A) & 0x00000000ffffffffLL) << 32)) # endif double ntohd (double d) { union { uint8_t byte[8]; uint64_t integer; double floating; } ret; ret.floating = d; /* NAN in x86 byte order */ if ((ret.byte[0] == 0x00) && (ret.byte[1] == 0x00) && (ret.byte[2] == 0x00) && (ret.byte[3] == 0x00) && (ret.byte[4] == 0x00) && (ret.byte[5] == 0x00) && (ret.byte[6] == 0xf8) && (ret.byte[7] == 0x7f)) { return (NAN); } else { uint64_t tmp; tmp = ret.integer; ret.integer = FP_CONVERT (tmp); return (ret.floating); } } /* double ntohd */ double htond (double d) { union { uint8_t byte[8]; uint64_t integer; double floating; } ret; if (isnan (d)) { ret.byte[0] = ret.byte[1] = ret.byte[2] = ret.byte[3] = 0x00; ret.byte[4] = ret.byte[5] = 0x00; ret.byte[6] = 0xf8; ret.byte[7] = 0x7f; return (ret.floating); } else { uint64_t tmp; ret.floating = d; tmp = FP_CONVERT (ret.integer); ret.integer = tmp; return (ret.floating); } } /* double htond */ #endif /* FP_LAYOUT_NEED_ENDIANFLIP || FP_LAYOUT_NEED_INTSWAP */ int format_name (char *ret, int ret_len, const char *hostname, const char *plugin, const char *plugin_instance, const char *type, const char *type_instance) { char *buffer; size_t buffer_size; buffer = ret; buffer_size = (size_t) ret_len; #define APPEND(str) do { \ size_t l = strlen (str); \ if (l >= buffer_size) \ return (ENOBUFS); \ memcpy (buffer, (str), l); \ buffer += l; buffer_size -= l; \ } while (0) assert (plugin != NULL); assert (type != NULL); APPEND (hostname); APPEND ("/"); APPEND (plugin); if ((plugin_instance != NULL) && (plugin_instance[0] != 0)) { APPEND ("-"); APPEND (plugin_instance); } APPEND ("/"); APPEND (type); if ((type_instance != NULL) && (type_instance[0] != 0)) { APPEND ("-"); APPEND (type_instance); } assert (buffer_size > 0); buffer[0] = 0; #undef APPEND return (0); } /* int format_name */ int format_values (char *ret, size_t ret_len, /* {{{ */ const data_set_t *ds, const value_list_t *vl, _Bool store_rates) { size_t offset = 0; int status; int i; gauge_t *rates = NULL; assert (0 == strcmp (ds->type, vl->type)); memset (ret, 0, ret_len); #define BUFFER_ADD(...) do { \ status = ssnprintf (ret + offset, ret_len - offset, \ __VA_ARGS__); \ if (status < 1) \ { \ sfree (rates); \ return (-1); \ } \ else if (((size_t) status) >= (ret_len - offset)) \ { \ sfree (rates); \ return (-1); \ } \ else \ offset += ((size_t) status); \ } while (0) BUFFER_ADD ("%.3f", CDTIME_T_TO_DOUBLE (vl->time)); for (i = 0; i < ds->ds_num; i++) { if (ds->ds[i].type == DS_TYPE_GAUGE) BUFFER_ADD (":%f", vl->values[i].gauge); else if (store_rates) { if (rates == NULL) rates = uc_get_rate (ds, vl); if (rates == NULL) { WARNING ("format_values: " "uc_get_rate failed."); return (-1); } BUFFER_ADD (":%g", rates[i]); } else if (ds->ds[i].type == DS_TYPE_COUNTER) BUFFER_ADD (":%llu", vl->values[i].counter); else if (ds->ds[i].type == DS_TYPE_DERIVE) BUFFER_ADD (":%"PRIi64, vl->values[i].derive); else if (ds->ds[i].type == DS_TYPE_ABSOLUTE) BUFFER_ADD (":%"PRIu64, vl->values[i].absolute); else { ERROR ("format_values plugin: Unknown data source type: %i", ds->ds[i].type); sfree (rates); return (-1); } } /* for ds->ds_num */ #undef BUFFER_ADD sfree (rates); return (0); } /* }}} int format_values */ int parse_identifier (char *str, char **ret_host, char **ret_plugin, char **ret_plugin_instance, char **ret_type, char **ret_type_instance) { char *hostname = NULL; char *plugin = NULL; char *plugin_instance = NULL; char *type = NULL; char *type_instance = NULL; hostname = str; if (hostname == NULL) return (-1); plugin = strchr (hostname, '/'); if (plugin == NULL) return (-1); *plugin = '\0'; plugin++; type = strchr (plugin, '/'); if (type == NULL) return (-1); *type = '\0'; type++; plugin_instance = strchr (plugin, '-'); if (plugin_instance != NULL) { *plugin_instance = '\0'; plugin_instance++; } type_instance = strchr (type, '-'); if (type_instance != NULL) { *type_instance = '\0'; type_instance++; } *ret_host = hostname; *ret_plugin = plugin; *ret_plugin_instance = plugin_instance; *ret_type = type; *ret_type_instance = type_instance; return (0); } /* int parse_identifier */ int parse_identifier_vl (const char *str, value_list_t *vl) /* {{{ */ { char str_copy[6 * DATA_MAX_NAME_LEN]; char *host = NULL; char *plugin = NULL; char *plugin_instance = NULL; char *type = NULL; char *type_instance = NULL; int status; if ((str == NULL) || (vl == NULL)) return (EINVAL); sstrncpy (str_copy, str, sizeof (str_copy)); status = parse_identifier (str_copy, &host, &plugin, &plugin_instance, &type, &type_instance); if (status != 0) return (status); sstrncpy (vl->host, host, sizeof (vl->host)); sstrncpy (vl->plugin, plugin, sizeof (vl->plugin)); sstrncpy (vl->plugin_instance, (plugin_instance != NULL) ? plugin_instance : "", sizeof (vl->plugin_instance)); sstrncpy (vl->type, type, sizeof (vl->type)); sstrncpy (vl->type_instance, (type_instance != NULL) ? type_instance : "", sizeof (vl->type_instance)); return (0); } /* }}} int parse_identifier_vl */ int parse_value (const char *value_orig, value_t *ret_value, int ds_type) { char *value; char *endptr = NULL; size_t value_len; if (value_orig == NULL) return (EINVAL); value = strdup (value_orig); if (value == NULL) return (ENOMEM); value_len = strlen (value); while ((value_len > 0) && isspace ((int) value[value_len - 1])) { value[value_len - 1] = 0; value_len--; } switch (ds_type) { case DS_TYPE_COUNTER: ret_value->counter = (counter_t) strtoull (value, &endptr, 0); break; case DS_TYPE_GAUGE: ret_value->gauge = (gauge_t) strtod (value, &endptr); break; case DS_TYPE_DERIVE: ret_value->derive = (derive_t) strtoll (value, &endptr, 0); break; case DS_TYPE_ABSOLUTE: ret_value->absolute = (absolute_t) strtoull (value, &endptr, 0); break; default: sfree (value); ERROR ("parse_value: Invalid data source type: %i.", ds_type); return -1; } if (value == endptr) { sfree (value); ERROR ("parse_value: Failed to parse string as %s: %s.", DS_TYPE_TO_STRING (ds_type), value); return -1; } else if ((NULL != endptr) && ('\0' != *endptr)) INFO ("parse_value: Ignoring trailing garbage \"%s\" after %s value. " "Input string was \"%s\".", endptr, DS_TYPE_TO_STRING (ds_type), value_orig); sfree (value); return 0; } /* int parse_value */ int parse_values (char *buffer, value_list_t *vl, const data_set_t *ds) { int i; char *dummy; char *ptr; char *saveptr; i = -1; dummy = buffer; saveptr = NULL; while ((ptr = strtok_r (dummy, ":", &saveptr)) != NULL) { dummy = NULL; if (i >= vl->values_len) { /* Make sure i is invalid. */ i = vl->values_len + 1; break; } if (i == -1) { if (strcmp ("N", ptr) == 0) vl->time = cdtime (); else { char *endptr = NULL; double tmp; errno = 0; tmp = strtod (ptr, &endptr); if ((errno != 0) /* Overflow */ || (endptr == ptr) /* Invalid string */ || (endptr == NULL) /* This should not happen */ || (*endptr != 0)) /* Trailing chars */ return (-1); vl->time = DOUBLE_TO_CDTIME_T (tmp); } } else { if ((strcmp ("U", ptr) == 0) && (ds->ds[i].type == DS_TYPE_GAUGE)) vl->values[i].gauge = NAN; else if (0 != parse_value (ptr, &vl->values[i], ds->ds[i].type)) return -1; } i++; } /* while (strtok_r) */ if ((ptr != NULL) || (i != vl->values_len)) return (-1); return (0); } /* int parse_values */ #if !HAVE_GETPWNAM_R int getpwnam_r (const char *name, struct passwd *pwbuf, char *buf, size_t buflen, struct passwd **pwbufp) { int status = 0; struct passwd *pw; memset (pwbuf, '\0', sizeof (struct passwd)); pthread_mutex_lock (&getpwnam_r_lock); do { pw = getpwnam (name); if (pw == NULL) { status = (errno != 0) ? errno : ENOENT; break; } #define GETPWNAM_COPY_MEMBER(member) \ if (pw->member != NULL) \ { \ int len = strlen (pw->member); \ if (len >= buflen) \ { \ status = ENOMEM; \ break; \ } \ sstrncpy (buf, pw->member, buflen); \ pwbuf->member = buf; \ buf += (len + 1); \ buflen -= (len + 1); \ } GETPWNAM_COPY_MEMBER(pw_name); GETPWNAM_COPY_MEMBER(pw_passwd); GETPWNAM_COPY_MEMBER(pw_gecos); GETPWNAM_COPY_MEMBER(pw_dir); GETPWNAM_COPY_MEMBER(pw_shell); pwbuf->pw_uid = pw->pw_uid; pwbuf->pw_gid = pw->pw_gid; if (pwbufp != NULL) *pwbufp = pwbuf; } while (0); pthread_mutex_unlock (&getpwnam_r_lock); return (status); } /* int getpwnam_r */ #endif /* !HAVE_GETPWNAM_R */ int notification_init (notification_t *n, int severity, const char *message, const char *host, const char *plugin, const char *plugin_instance, const char *type, const char *type_instance) { memset (n, '\0', sizeof (notification_t)); n->severity = severity; if (message != NULL) sstrncpy (n->message, message, sizeof (n->message)); if (host != NULL) sstrncpy (n->host, host, sizeof (n->host)); if (plugin != NULL) sstrncpy (n->plugin, plugin, sizeof (n->plugin)); if (plugin_instance != NULL) sstrncpy (n->plugin_instance, plugin_instance, sizeof (n->plugin_instance)); if (type != NULL) sstrncpy (n->type, type, sizeof (n->type)); if (type_instance != NULL) sstrncpy (n->type_instance, type_instance, sizeof (n->type_instance)); return (0); } /* int notification_init */ int walk_directory (const char *dir, dirwalk_callback_f callback, void *user_data, int include_hidden) { struct dirent *ent; DIR *dh; int success; int failure; success = 0; failure = 0; if ((dh = opendir (dir)) == NULL) { char errbuf[1024]; ERROR ("walk_directory: Cannot open '%s': %s", dir, sstrerror (errno, errbuf, sizeof (errbuf))); return -1; } while ((ent = readdir (dh)) != NULL) { int status; if (include_hidden) { if ((strcmp (".", ent->d_name) == 0) || (strcmp ("..", ent->d_name) == 0)) continue; } else /* if (!include_hidden) */ { if (ent->d_name[0]=='.') continue; } status = (*callback) (dir, ent->d_name, user_data); if (status != 0) failure++; else success++; } closedir (dh); if ((success == 0) && (failure > 0)) return (-1); return (0); } ssize_t read_file_contents (const char *filename, char *buf, size_t bufsize) { FILE *fh; ssize_t ret; fh = fopen (filename, "r"); if (fh == NULL) return (-1); ret = (ssize_t) fread (buf, 1, bufsize, fh); if ((ret == 0) && (ferror (fh) != 0)) { ERROR ("read_file_contents: Reading file \"%s\" failed.", filename); ret = -1; } fclose(fh); return (ret); } counter_t counter_diff (counter_t old_value, counter_t new_value) { counter_t diff; if (old_value > new_value) { if (old_value <= 4294967295U) diff = (4294967295U - old_value) + new_value; else diff = (18446744073709551615ULL - old_value) + new_value; } else { diff = new_value - old_value; } return (diff); } /* counter_t counter_diff */ int rate_to_value (value_t *ret_value, gauge_t rate, /* {{{ */ rate_to_value_state_t *state, int ds_type, cdtime_t t) { gauge_t delta_gauge; cdtime_t delta_t; if (ds_type == DS_TYPE_GAUGE) { state->last_value.gauge = rate; state->last_time = t; *ret_value = state->last_value; return (0); } /* Counter and absolute can't handle negative rates. Reset "last time" * to zero, so that the next valid rate will re-initialize the * structure. */ if ((rate < 0.0) && ((ds_type == DS_TYPE_COUNTER) || (ds_type == DS_TYPE_ABSOLUTE))) { memset (state, 0, sizeof (*state)); return (EINVAL); } /* Another invalid state: The time is not increasing. */ if (t <= state->last_time) { memset (state, 0, sizeof (*state)); return (EINVAL); } delta_t = t - state->last_time; delta_gauge = (rate * CDTIME_T_TO_DOUBLE (delta_t)) + state->residual; /* Previous value is invalid. */ if (state->last_time == 0) /* {{{ */ { if (ds_type == DS_TYPE_DERIVE) { state->last_value.derive = (derive_t) rate; state->residual = rate - ((gauge_t) state->last_value.derive); } else if (ds_type == DS_TYPE_COUNTER) { state->last_value.counter = (counter_t) rate; state->residual = rate - ((gauge_t) state->last_value.counter); } else if (ds_type == DS_TYPE_ABSOLUTE) { state->last_value.absolute = (absolute_t) rate; state->residual = rate - ((gauge_t) state->last_value.absolute); } else { assert (23 == 42); } state->last_time = t; return (EAGAIN); } /* }}} */ if (ds_type == DS_TYPE_DERIVE) { derive_t delta_derive = (derive_t) delta_gauge; state->last_value.derive += delta_derive; state->residual = delta_gauge - ((gauge_t) delta_derive); } else if (ds_type == DS_TYPE_COUNTER) { counter_t delta_counter = (counter_t) delta_gauge; state->last_value.counter += delta_counter; state->residual = delta_gauge - ((gauge_t) delta_counter); } else if (ds_type == DS_TYPE_ABSOLUTE) { absolute_t delta_absolute = (absolute_t) delta_gauge; state->last_value.absolute = delta_absolute; state->residual = delta_gauge - ((gauge_t) delta_absolute); } else { assert (23 == 42); } state->last_time = t; *ret_value = state->last_value; return (0); } /* }}} value_t rate_to_value */ int service_name_to_port_number (const char *service_name) { struct addrinfo *ai_list; struct addrinfo *ai_ptr; struct addrinfo ai_hints; int status; int service_number; if (service_name == NULL) return (-1); ai_list = NULL; memset (&ai_hints, 0, sizeof (ai_hints)); ai_hints.ai_family = AF_UNSPEC; status = getaddrinfo (/* node = */ NULL, service_name, &ai_hints, &ai_list); if (status != 0) { ERROR ("service_name_to_port_number: getaddrinfo failed: %s", gai_strerror (status)); return (-1); } service_number = -1; for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) { if (ai_ptr->ai_family == AF_INET) { struct sockaddr_in *sa; sa = (void *) ai_ptr->ai_addr; service_number = (int) ntohs (sa->sin_port); } else if (ai_ptr->ai_family == AF_INET6) { struct sockaddr_in6 *sa; sa = (void *) ai_ptr->ai_addr; service_number = (int) ntohs (sa->sin6_port); } if ((service_number > 0) && (service_number <= 65535)) break; } freeaddrinfo (ai_list); if ((service_number > 0) && (service_number <= 65535)) return (service_number); return (-1); } /* int service_name_to_port_number */ int strtoderive (const char *string, derive_t *ret_value) /* {{{ */ { derive_t tmp; char *endptr; if ((string == NULL) || (ret_value == NULL)) return (EINVAL); errno = 0; endptr = NULL; tmp = (derive_t) strtoll (string, &endptr, /* base = */ 0); if ((endptr == string) || (errno != 0)) return (-1); *ret_value = tmp; return (0); } /* }}} int strtoderive */ int strarray_add (char ***ret_array, size_t *ret_array_len, char const *str) /* {{{ */ { char **array; size_t array_len = *ret_array_len; if (str == NULL) return (EINVAL); array = realloc (*ret_array, (array_len + 1) * sizeof (*array)); if (array == NULL) return (ENOMEM); *ret_array = array; array[array_len] = strdup (str); if (array[array_len] == NULL) return (ENOMEM); array_len++; *ret_array_len = array_len; return (0); } /* }}} int strarray_add */ void strarray_free (char **array, size_t array_len) /* {{{ */ { size_t i; for (i = 0; i < array_len; i++) sfree (array[i]); sfree (array); } /* }}} void strarray_free */ collectd-5.4.0/src/PaxHeaders.11991/match_hashed.c0000644037772200116100000000013212204120331017706 xustar000000000000000030 mtime=1376821465.077973503 30 atime=1376821477.218167931 30 ctime=1376821741.958399908 collectd-5.4.0/src/match_hashed.c0000644037772200116100000001070112204120331016451 0ustar00octoeng00000000000000/** * collectd - src/match_hashed.c * Copyright (C) 2009 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: * Florian Forster **/ #include "collectd.h" #include "common.h" #include "utils_cache.h" #include "filter_chain.h" /* * private data types */ struct mh_hash_match_s { uint32_t match; uint32_t total; }; typedef struct mh_hash_match_s mh_hash_match_t; struct mh_match_s; typedef struct mh_match_s mh_match_t; struct mh_match_s { mh_hash_match_t *matches; size_t matches_num; }; /* * internal helper functions */ static int mh_config_match (const oconfig_item_t *ci, /* {{{ */ mh_match_t *m) { mh_hash_match_t *tmp; if ((ci->values_num != 2) || (ci->values[0].type != OCONFIG_TYPE_NUMBER) || (ci->values[1].type != OCONFIG_TYPE_NUMBER)) { ERROR ("hashed match: The `Match' option requires " "exactly two numeric arguments."); return (-1); } if ((ci->values[0].value.number < 0) || (ci->values[1].value.number < 0)) { ERROR ("hashed match: The arguments of the `Match' " "option must be positive."); return (-1); } tmp = realloc (m->matches, sizeof (*tmp) * (m->matches_num + 1)); if (tmp == NULL) { ERROR ("hashed match: realloc failed."); return (-1); } m->matches = tmp; tmp = m->matches + m->matches_num; tmp->match = (uint32_t) (ci->values[0].value.number + .5); tmp->total = (uint32_t) (ci->values[1].value.number + .5); if (tmp->match >= tmp->total) { ERROR ("hashed match: The first argument of the `Match' option " "must be smaller than the second argument."); return (-1); } assert (tmp->total != 0); m->matches_num++; return (0); } /* }}} int mh_config_match */ static int mh_create (const oconfig_item_t *ci, void **user_data) /* {{{ */ { mh_match_t *m; int i; m = (mh_match_t *) malloc (sizeof (*m)); if (m == NULL) { ERROR ("mh_create: malloc failed."); return (-ENOMEM); } memset (m, 0, sizeof (*m)); for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("Match", child->key) == 0) mh_config_match (child, m); else ERROR ("hashed match: No such config option: %s", child->key); } if (m->matches_num == 0) { sfree (m->matches); sfree (m); ERROR ("hashed match: No matches were configured. Not creating match."); return (-1); } *user_data = m; return (0); } /* }}} int mh_create */ static int mh_destroy (void **user_data) /* {{{ */ { mh_match_t *mh; if ((user_data == NULL) || (*user_data == NULL)) return (0); mh = *user_data; sfree (mh->matches); sfree (mh); return (0); } /* }}} int mh_destroy */ static int mh_match (const data_set_t __attribute__((unused)) *ds, /* {{{ */ const value_list_t *vl, notification_meta_t __attribute__((unused)) **meta, void **user_data) { mh_match_t *m; uint32_t hash_val; const char *host_ptr; size_t i; if ((user_data == NULL) || (*user_data == NULL)) return (-1); m = *user_data; hash_val = 0; for (host_ptr = vl->host; *host_ptr != 0; host_ptr++) { /* 2184401929 is some appropriately sized prime number. */ hash_val = (hash_val * UINT32_C (2184401929)) + ((uint32_t) *host_ptr); } DEBUG ("hashed match: host = %s; hash_val = %"PRIu32";", vl->host, hash_val); for (i = 0; i < m->matches_num; i++) if ((hash_val % m->matches[i].total) == m->matches[i].match) return (FC_MATCH_MATCHES); return (FC_MATCH_NO_MATCH); } /* }}} int mh_match */ void module_register (void) { match_proc_t mproc; memset (&mproc, 0, sizeof (mproc)); mproc.create = mh_create; mproc.destroy = mh_destroy; mproc.match = mh_match; fc_register_match ("hashed", mproc); } /* module_register */ /* vim: set sw=2 sts=2 tw=78 et fdm=marker : */ collectd-5.4.0/src/PaxHeaders.11991/match_timediff.c0000644037772200116100000000013212204120331020241 xustar000000000000000030 mtime=1376821465.077973503 30 atime=1376821477.218167931 30 ctime=1376821741.962399972 collectd-5.4.0/src/match_timediff.c0000644037772200116100000000652012204120331017010 0ustar00octoeng00000000000000/** * collectd - src/match_timediff.c * Copyright (C) 2008,2009 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: * Florian Forster **/ #include "collectd.h" #include "common.h" #include "utils_cache.h" #include "filter_chain.h" #define SATISFY_ALL 0 #define SATISFY_ANY 1 /* * private data types */ struct mt_match_s; typedef struct mt_match_s mt_match_t; struct mt_match_s { cdtime_t future; cdtime_t past; }; /* * internal helper functions */ static int mt_create (const oconfig_item_t *ci, void **user_data) /* {{{ */ { mt_match_t *m; int status; int i; m = (mt_match_t *) malloc (sizeof (*m)); if (m == NULL) { ERROR ("mt_create: malloc failed."); return (-ENOMEM); } memset (m, 0, sizeof (*m)); m->future = 0; m->past = 0; status = 0; for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("Future", child->key) == 0) status = cf_util_get_cdtime (child, &m->future); else if (strcasecmp ("Past", child->key) == 0) status = cf_util_get_cdtime (child, &m->past); else { ERROR ("timediff match: The `%s' configuration option is not " "understood and will be ignored.", child->key); status = 0; } if (status != 0) break; } /* Additional sanity-checking */ while (status == 0) { if ((m->future == 0) && (m->past == 0)) { ERROR ("timediff match: Either `Future' or `Past' must be configured. " "This match will be ignored."); status = -1; } break; } if (status != 0) { free (m); return (status); } *user_data = m; return (0); } /* }}} int mt_create */ static int mt_destroy (void **user_data) /* {{{ */ { if (user_data != NULL) { sfree (*user_data); } return (0); } /* }}} int mt_destroy */ static int mt_match (const data_set_t __attribute__((unused)) *ds, /* {{{ */ const value_list_t *vl, notification_meta_t __attribute__((unused)) **meta, void **user_data) { mt_match_t *m; cdtime_t now; if ((user_data == NULL) || (*user_data == NULL)) return (-1); m = *user_data; now = cdtime (); if (m->future != 0) { if (vl->time >= (now + m->future)) return (FC_MATCH_MATCHES); } if (m->past != 0) { if (vl->time <= (now - m->past)) return (FC_MATCH_MATCHES); } return (FC_MATCH_NO_MATCH); } /* }}} int mt_match */ void module_register (void) { match_proc_t mproc; memset (&mproc, 0, sizeof (mproc)); mproc.create = mt_create; mproc.destroy = mt_destroy; mproc.match = mt_match; fc_register_match ("timediff", mproc); } /* module_register */ /* vim: set sw=2 sts=2 tw=78 et fdm=marker : */ collectd-5.4.0/src/PaxHeaders.11991/hddtemp.c0000644037772200116100000000013212204120331016723 xustar000000000000000030 mtime=1376821465.073973439 30 atime=1376821477.218167931 30 ctime=1376821741.962399972 collectd-5.4.0/src/hddtemp.c0000644037772200116100000001571412204120331015477 0ustar00octoeng00000000000000/** * collectd - src/hddtemp.c * Copyright (C) 2005,2006 Vincent Stehlé * Copyright (C) 2006-2010 Florian octo Forster * Copyright (C) 2008 Sebastian Harl * * 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; either version 2 of the License, or (at your * option) any later version. * * 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: * Vincent Stehlé * Florian octo Forster * Sebastian Harl * * TODO: * Do a pass, some day, and spare some memory. We consume too much for now * in string buffers and the like. * **/ #include "collectd.h" #include "common.h" #include "plugin.h" #include "configfile.h" # include # include # include # include # include /* for basename */ #if HAVE_LINUX_MAJOR_H # include #endif #define HDDTEMP_DEF_HOST "127.0.0.1" #define HDDTEMP_DEF_PORT "7634" static const char *config_keys[] = { "Host", "Port" }; static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); static char *hddtemp_host = NULL; static char hddtemp_port[16]; /* * NAME * hddtemp_query_daemon * * DESCRIPTION * Connect to the hddtemp daemon and receive data. * * ARGUMENTS: * `buffer' The buffer where we put the received ascii string. * `buffer_size' Size of the buffer * * RETURN VALUE: * >= 0 if ok, < 0 otherwise. * * NOTES: * Example of possible strings, as received from daemon: * |/dev/hda|ST340014A|36|C| * |/dev/hda|ST380011A|46|C||/dev/hdd|ST340016A|SLP|*| * * FIXME: * we need to create a new socket each time. Is there another way? * Hm, maybe we can re-use the `sockaddr' structure? -octo */ static int hddtemp_query_daemon (char *buffer, int buffer_size) { int fd; ssize_t status; int buffer_fill; const char *host; const char *port; struct addrinfo ai_hints; struct addrinfo *ai_list, *ai_ptr; int ai_return; memset (&ai_hints, '\0', sizeof (ai_hints)); ai_hints.ai_flags = 0; #ifdef AI_ADDRCONFIG ai_hints.ai_flags |= AI_ADDRCONFIG; #endif ai_hints.ai_family = PF_UNSPEC; ai_hints.ai_socktype = SOCK_STREAM; ai_hints.ai_protocol = IPPROTO_TCP; host = hddtemp_host; if (host == NULL) host = HDDTEMP_DEF_HOST; port = hddtemp_port; if (strlen (port) == 0) port = HDDTEMP_DEF_PORT; if ((ai_return = getaddrinfo (host, port, &ai_hints, &ai_list)) != 0) { char errbuf[1024]; ERROR ("hddtemp plugin: getaddrinfo (%s, %s): %s", host, port, (ai_return == EAI_SYSTEM) ? sstrerror (errno, errbuf, sizeof (errbuf)) : gai_strerror (ai_return)); return (-1); } fd = -1; for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) { /* create our socket descriptor */ fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol); if (fd < 0) { char errbuf[1024]; ERROR ("hddtemp plugin: socket: %s", sstrerror (errno, errbuf, sizeof (errbuf))); continue; } /* connect to the hddtemp daemon */ if (connect (fd, (struct sockaddr *) ai_ptr->ai_addr, ai_ptr->ai_addrlen)) { char errbuf[1024]; INFO ("hddtemp plugin: connect (%s, %s) failed: %s", host, port, sstrerror (errno, errbuf, sizeof (errbuf))); close (fd); fd = -1; continue; } /* A socket could be opened and connecting succeeded. We're * done. */ break; } freeaddrinfo (ai_list); if (fd < 0) { ERROR ("hddtemp plugin: Could not connect to daemon."); return (-1); } /* receive data from the hddtemp daemon */ memset (buffer, '\0', buffer_size); buffer_fill = 0; while ((status = read (fd, buffer + buffer_fill, buffer_size - buffer_fill)) != 0) { if (status == -1) { char errbuf[1024]; if ((errno == EAGAIN) || (errno == EINTR)) continue; ERROR ("hddtemp plugin: Error reading from socket: %s", sstrerror (errno, errbuf, sizeof (errbuf))); close (fd); return (-1); } buffer_fill += status; if (buffer_fill >= buffer_size) break; } if (buffer_fill >= buffer_size) { buffer[buffer_size - 1] = '\0'; WARNING ("hddtemp plugin: Message from hddtemp has been " "truncated."); } else if (buffer_fill == 0) { WARNING ("hddtemp plugin: Peer has unexpectedly shut down " "the socket. Buffer: `%s'", buffer); close (fd); return (-1); } close (fd); return (0); } static int hddtemp_config (const char *key, const char *value) { if (strcasecmp (key, "Host") == 0) { if (hddtemp_host != NULL) free (hddtemp_host); hddtemp_host = strdup (value); } else if (strcasecmp (key, "Port") == 0) { int port = (int) (atof (value)); if ((port > 0) && (port <= 65535)) ssnprintf (hddtemp_port, sizeof (hddtemp_port), "%i", port); else sstrncpy (hddtemp_port, value, sizeof (hddtemp_port)); } else { return (-1); } return (0); } static void hddtemp_submit (char *type_instance, double value) { value_t values[1]; value_list_t vl = VALUE_LIST_INIT; values[0].gauge = value; vl.values = values; vl.values_len = 1; sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "hddtemp", sizeof (vl.plugin)); sstrncpy (vl.type, "temperature", sizeof (vl.type)); sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); plugin_dispatch_values (&vl); } static int hddtemp_read (void) { char buf[1024]; char *fields[128]; char *ptr; char *saveptr; int num_fields; int num_disks; int i; /* get data from daemon */ if (hddtemp_query_daemon (buf, sizeof (buf)) < 0) return (-1); /* NB: strtok_r will eat up "||" and leading "|"'s */ num_fields = 0; ptr = buf; saveptr = NULL; while ((fields[num_fields] = strtok_r (ptr, "|", &saveptr)) != NULL) { ptr = NULL; num_fields++; if (num_fields >= 128) break; } num_disks = num_fields / 4; for (i = 0; i < num_disks; i++) { char *name; double temperature; char *mode; mode = fields[4*i + 3]; name = basename (fields[4*i + 0]); /* Skip non-temperature information */ if (mode[0] != 'C' && mode[0] != 'F') continue; temperature = atof (fields[4*i + 2]); /* Convert farenheit to celsius */ if (mode[0] == 'F') temperature = (temperature - 32.0) * 5.0 / 9.0; hddtemp_submit (name, temperature); } return (0); } /* int hddtemp_read */ /* module_register Register collectd plugin. */ void module_register (void) { plugin_register_config ("hddtemp", hddtemp_config, config_keys, config_keys_num); plugin_register_read ("hddtemp", hddtemp_read); } collectd-5.4.0/src/PaxHeaders.11991/vserver.c0000644037772200116100000000013212204120331016772 xustar000000000000000030 mtime=1376821465.089973696 30 atime=1376821477.230168122 30 ctime=1376821741.962399972 collectd-5.4.0/src/vserver.c0000644037772200116100000002112412204120331015536 0ustar00octoeng00000000000000/** * collectd - src/vserver.c * Copyright (C) 2006,2007 Sebastian Harl * Copyright (C) 2007-2010 Florian octo 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: * Sebastian Harl * Florian octo Forster **/ #include "collectd.h" #include "common.h" #include "plugin.h" #include #include #define BUFSIZE 512 #define PROCDIR "/proc/virtual" #if !KERNEL_LINUX # error "No applicable input method." #endif static int pagesize = 0; static int vserver_init (void) { /* XXX Should we check for getpagesize () in configure? * What's the right thing to do, if there is no getpagesize ()? */ pagesize = getpagesize (); return (0); } /* static void vserver_init(void) */ static void traffic_submit (const char *plugin_instance, const char *type_instance, derive_t rx, derive_t tx) { value_t values[2]; value_list_t vl = VALUE_LIST_INIT; values[0].derive = rx; values[1].derive = tx; vl.values = values; vl.values_len = STATIC_ARRAY_SIZE (values); sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "vserver", sizeof (vl.plugin)); sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance)); sstrncpy (vl.type, "if_octets", sizeof (vl.type)); sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); plugin_dispatch_values (&vl); } /* void traffic_submit */ static void load_submit (const char *plugin_instance, gauge_t snum, gauge_t mnum, gauge_t lnum) { value_t values[3]; value_list_t vl = VALUE_LIST_INIT; values[0].gauge = snum; values[1].gauge = mnum; values[2].gauge = lnum; vl.values = values; vl.values_len = STATIC_ARRAY_SIZE (values); sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "vserver", sizeof (vl.plugin)); sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance)); sstrncpy (vl.type, "load", sizeof (vl.type)); plugin_dispatch_values (&vl); } static void submit_gauge (const char *plugin_instance, const char *type, const char *type_instance, gauge_t value) { value_t values[1]; value_list_t vl = VALUE_LIST_INIT; values[0].gauge = value; vl.values = values; vl.values_len = STATIC_ARRAY_SIZE (values); sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "vserver", sizeof (vl.plugin)); sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance)); sstrncpy (vl.type, type, sizeof (vl.type)); sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); plugin_dispatch_values (&vl); } /* void submit_gauge */ static derive_t vserver_get_sock_bytes(const char *s) { value_t v; int status; while (s[0] != '/') ++s; /* Remove '/' */ ++s; status = parse_value (s, &v, DS_TYPE_DERIVE); if (status != 0) return (-1); return (v.derive); } static int vserver_read (void) { #if NAME_MAX < 1024 # define DIRENT_BUFFER_SIZE (sizeof (struct dirent) + 1024 + 1) #else # define DIRENT_BUFFER_SIZE (sizeof (struct dirent) + NAME_MAX + 1) #endif DIR *proc; struct dirent *dent; /* 42 */ char dirent_buffer[DIRENT_BUFFER_SIZE]; errno = 0; proc = opendir (PROCDIR); if (proc == NULL) { char errbuf[1024]; ERROR ("vserver plugin: fopen (%s): %s", PROCDIR, sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } while (42) { int len; char file[BUFSIZE]; FILE *fh; char buffer[BUFSIZE]; struct stat statbuf; char *cols[4]; int status; status = readdir_r (proc, (struct dirent *) dirent_buffer, &dent); if (status != 0) { char errbuf[4096]; ERROR ("vserver plugin: readdir_r failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); closedir (proc); return (-1); } else if (dent == NULL) { /* end of directory */ break; } if (dent->d_name[0] == '.') continue; len = ssnprintf (file, sizeof (file), PROCDIR "/%s", dent->d_name); if ((len < 0) || (len >= BUFSIZE)) continue; status = stat (file, &statbuf); if (status != 0) { char errbuf[4096]; WARNING ("vserver plugin: stat (%s) failed: %s", file, sstrerror (errno, errbuf, sizeof (errbuf))); continue; } if (!S_ISDIR (statbuf.st_mode)) continue; /* socket message accounting */ len = ssnprintf (file, sizeof (file), PROCDIR "/%s/cacct", dent->d_name); if ((len < 0) || ((size_t) len >= sizeof (file))) continue; if (NULL == (fh = fopen (file, "r"))) { char errbuf[1024]; ERROR ("Cannot open '%s': %s", file, sstrerror (errno, errbuf, sizeof (errbuf))); } while ((fh != NULL) && (NULL != fgets (buffer, BUFSIZE, fh))) { derive_t rx; derive_t tx; char *type_instance; if (strsplit (buffer, cols, 4) < 4) continue; if (0 == strcmp (cols[0], "UNIX:")) type_instance = "unix"; else if (0 == strcmp (cols[0], "INET:")) type_instance = "inet"; else if (0 == strcmp (cols[0], "INET6:")) type_instance = "inet6"; else if (0 == strcmp (cols[0], "OTHER:")) type_instance = "other"; else if (0 == strcmp (cols[0], "UNSPEC:")) type_instance = "unspec"; else continue; rx = vserver_get_sock_bytes (cols[1]); tx = vserver_get_sock_bytes (cols[2]); /* cols[3] == errors */ traffic_submit (dent->d_name, type_instance, rx, tx); } /* while (fgets) */ if (fh != NULL) { fclose (fh); fh = NULL; } /* thread information and load */ len = ssnprintf (file, sizeof (file), PROCDIR "/%s/cvirt", dent->d_name); if ((len < 0) || ((size_t) len >= sizeof (file))) continue; if (NULL == (fh = fopen (file, "r"))) { char errbuf[1024]; ERROR ("Cannot open '%s': %s", file, sstrerror (errno, errbuf, sizeof (errbuf))); } while ((fh != NULL) && (NULL != fgets (buffer, BUFSIZE, fh))) { int n = strsplit (buffer, cols, 4); if (2 == n) { char *type_instance; gauge_t value; if (0 == strcmp (cols[0], "nr_threads:")) type_instance = "total"; else if (0 == strcmp (cols[0], "nr_running:")) type_instance = "running"; else if (0 == strcmp (cols[0], "nr_unintr:")) type_instance = "uninterruptable"; else if (0 == strcmp (cols[0], "nr_onhold:")) type_instance = "onhold"; else continue; value = atof (cols[1]); submit_gauge (dent->d_name, "vs_threads", type_instance, value); } else if (4 == n) { if (0 == strcmp (cols[0], "loadavg:")) { gauge_t snum = atof (cols[1]); gauge_t mnum = atof (cols[2]); gauge_t lnum = atof (cols[3]); load_submit (dent->d_name, snum, mnum, lnum); } } } /* while (fgets) */ if (fh != NULL) { fclose (fh); fh = NULL; } /* processes and memory usage */ len = ssnprintf (file, sizeof (file), PROCDIR "/%s/limit", dent->d_name); if ((len < 0) || ((size_t) len >= sizeof (file))) continue; if (NULL == (fh = fopen (file, "r"))) { char errbuf[1024]; ERROR ("Cannot open '%s': %s", file, sstrerror (errno, errbuf, sizeof (errbuf))); } while ((fh != NULL) && (NULL != fgets (buffer, BUFSIZE, fh))) { char *type = "vs_memory"; char *type_instance; gauge_t value; if (strsplit (buffer, cols, 2) < 2) continue; if (0 == strcmp (cols[0], "PROC:")) { type = "vs_processes"; type_instance = ""; value = atof (cols[1]); } else { if (0 == strcmp (cols[0], "VM:")) type_instance = "vm"; else if (0 == strcmp (cols[0], "VML:")) type_instance = "vml"; else if (0 == strcmp (cols[0], "RSS:")) type_instance = "rss"; else if (0 == strcmp (cols[0], "ANON:")) type_instance = "anon"; else continue; value = atof (cols[1]) * pagesize; } submit_gauge (dent->d_name, type, type_instance, value); } /* while (fgets) */ if (fh != NULL) { fclose (fh); fh = NULL; } } /* while (readdir) */ closedir (proc); return (0); } /* int vserver_read */ void module_register (void) { plugin_register_init ("vserver", vserver_init); plugin_register_read ("vserver", vserver_read); } /* void module_register(void) */ /* vim: set ts=4 sw=4 noexpandtab : */ collectd-5.4.0/src/PaxHeaders.11991/utils_db_query.c0000644037772200116100000000013212204120331020330 xustar000000000000000030 mtime=1376821465.089973696 30 atime=1376821477.230168122 30 ctime=1376821741.966400036 collectd-5.4.0/src/utils_db_query.c0000644037772200116100000006232612204120331017105 0ustar00octoeng00000000000000/** * collectd - src/utils_db_query.c * Copyright (C) 2008,2009 Florian octo 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: * Florian octo Forster **/ #include "collectd.h" #include "common.h" #include "plugin.h" #include "configfile.h" #include "utils_db_query.h" /* * Data types */ struct udb_result_s; /* {{{ */ typedef struct udb_result_s udb_result_t; struct udb_result_s { char *type; char *instance_prefix; char **instances; size_t instances_num; char **values; size_t values_num; udb_result_t *next; }; /* }}} */ struct udb_query_s /* {{{ */ { char *name; char *statement; void *user_data; unsigned int min_version; unsigned int max_version; udb_result_t *results; }; /* }}} */ struct udb_result_preparation_area_s /* {{{ */ { const data_set_t *ds; size_t *instances_pos; size_t *values_pos; char **instances_buffer; char **values_buffer; struct udb_result_preparation_area_s *next; }; /* }}} */ typedef struct udb_result_preparation_area_s udb_result_preparation_area_t; struct udb_query_preparation_area_s /* {{{ */ { size_t column_num; char *host; char *plugin; char *db_name; cdtime_t interval; udb_result_preparation_area_t *result_prep_areas; }; /* }}} */ /* * Config Private functions */ static int udb_config_set_string (char **ret_string, /* {{{ */ oconfig_item_t *ci) { char *string; if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { WARNING ("db query utils: The `%s' config option " "needs exactly one string argument.", ci->key); return (-1); } string = strdup (ci->values[0].value.string); if (string == NULL) { ERROR ("db query utils: strdup failed."); return (-1); } if (*ret_string != NULL) free (*ret_string); *ret_string = string; return (0); } /* }}} int udb_config_set_string */ static int udb_config_add_string (char ***ret_array, /* {{{ */ size_t *ret_array_len, oconfig_item_t *ci) { char **array; size_t array_len; int i; if (ci->values_num < 1) { WARNING ("db query utils: The `%s' config option " "needs at least one argument.", ci->key); return (-1); } for (i = 0; i < ci->values_num; i++) { if (ci->values[i].type != OCONFIG_TYPE_STRING) { WARNING ("db query utils: Argument %i to the `%s' option " "is not a string.", i + 1, ci->key); return (-1); } } array_len = *ret_array_len; array = (char **) realloc (*ret_array, sizeof (char *) * (array_len + ci->values_num)); if (array == NULL) { ERROR ("db query utils: realloc failed."); return (-1); } *ret_array = array; for (i = 0; i < ci->values_num; i++) { array[array_len] = strdup (ci->values[i].value.string); if (array[array_len] == NULL) { ERROR ("db query utils: strdup failed."); *ret_array_len = array_len; return (-1); } array_len++; } *ret_array_len = array_len; return (0); } /* }}} int udb_config_add_string */ static int udb_config_set_uint (unsigned int *ret_value, /* {{{ */ oconfig_item_t *ci) { double tmp; if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) { WARNING ("db query utils: The `%s' config option " "needs exactly one numeric argument.", ci->key); return (-1); } tmp = ci->values[0].value.number; if ((tmp < 0.0) || (tmp > ((double) UINT_MAX))) return (-ERANGE); *ret_value = (unsigned int) (tmp + .5); return (0); } /* }}} int udb_config_set_uint */ /* * Result private functions */ static int udb_result_submit (udb_result_t *r, /* {{{ */ udb_result_preparation_area_t *r_area, udb_query_t const *q, udb_query_preparation_area_t *q_area) { value_list_t vl = VALUE_LIST_INIT; size_t i; assert (r != NULL); assert (r_area->ds != NULL); assert (((size_t) r_area->ds->ds_num) == r->values_num); vl.values = (value_t *) calloc (r_area->ds->ds_num, sizeof (value_t)); if (vl.values == NULL) { ERROR ("db query utils: malloc failed."); return (-1); } vl.values_len = r_area->ds->ds_num; for (i = 0; i < r->values_num; i++) { char *value_str = r_area->values_buffer[i]; if (0 != parse_value (value_str, &vl.values[i], r_area->ds->ds[i].type)) { ERROR ("db query utils: udb_result_submit: Parsing `%s' as %s failed.", value_str, DS_TYPE_TO_STRING (r_area->ds->ds[i].type)); errno = EINVAL; return (-1); } } if (q_area->interval > 0) vl.interval = q_area->interval; sstrncpy (vl.host, q_area->host, sizeof (vl.host)); sstrncpy (vl.plugin, q_area->plugin, sizeof (vl.plugin)); sstrncpy (vl.plugin_instance, q_area->db_name, sizeof (vl.plugin_instance)); sstrncpy (vl.type, r->type, sizeof (vl.type)); /* Set vl.type_instance {{{ */ if (r->instances_num <= 0) { if (r->instance_prefix == NULL) vl.type_instance[0] = 0; else sstrncpy (vl.type_instance, r->instance_prefix, sizeof (vl.type_instance)); } else /* if ((r->instances_num > 0) */ { if (r->instance_prefix == NULL) { strjoin (vl.type_instance, sizeof (vl.type_instance), r_area->instances_buffer, r->instances_num, "-"); } else { char tmp[DATA_MAX_NAME_LEN]; strjoin (tmp, sizeof (tmp), r_area->instances_buffer, r->instances_num, "-"); tmp[sizeof (tmp) - 1] = 0; snprintf (vl.type_instance, sizeof (vl.type_instance), "%s-%s", r->instance_prefix, tmp); } } vl.type_instance[sizeof (vl.type_instance) - 1] = 0; /* }}} */ plugin_dispatch_values (&vl); sfree (vl.values); return (0); } /* }}} void udb_result_submit */ static void udb_result_finish_result (udb_result_t const *r, /* {{{ */ udb_result_preparation_area_t *prep_area) { if ((r == NULL) || (prep_area == NULL)) return; prep_area->ds = NULL; sfree (prep_area->instances_pos); sfree (prep_area->values_pos); sfree (prep_area->instances_buffer); sfree (prep_area->values_buffer); } /* }}} void udb_result_finish_result */ static int udb_result_handle_result (udb_result_t *r, /* {{{ */ udb_query_preparation_area_t *q_area, udb_result_preparation_area_t *r_area, udb_query_t const *q, char **column_values) { size_t i; assert (r && q_area && r_area); for (i = 0; i < r->instances_num; i++) r_area->instances_buffer[i] = column_values[r_area->instances_pos[i]]; for (i = 0; i < r->values_num; i++) r_area->values_buffer[i] = column_values[r_area->values_pos[i]]; return udb_result_submit (r, r_area, q, q_area); } /* }}} int udb_result_handle_result */ static int udb_result_prepare_result (udb_result_t const *r, /* {{{ */ udb_result_preparation_area_t *prep_area, char **column_names, size_t column_num) { size_t i; if ((r == NULL) || (prep_area == NULL)) return (-EINVAL); #define BAIL_OUT(status) \ prep_area->ds = NULL; \ sfree (prep_area->instances_pos); \ sfree (prep_area->values_pos); \ sfree (prep_area->instances_buffer); \ sfree (prep_area->values_buffer); \ return (status) /* Make sure previous preparations are cleaned up. */ udb_result_finish_result (r, prep_area); prep_area->instances_pos = NULL; prep_area->values_pos = NULL; /* Read `ds' and check number of values {{{ */ prep_area->ds = plugin_get_ds (r->type); if (prep_area->ds == NULL) { ERROR ("db query utils: udb_result_prepare_result: Type `%s' is not " "known by the daemon. See types.db(5) for details.", r->type); BAIL_OUT (-1); } if (((size_t) prep_area->ds->ds_num) != r->values_num) { ERROR ("db query utils: udb_result_prepare_result: The type `%s' " "requires exactly %i value%s, but the configuration specifies %zu.", r->type, prep_area->ds->ds_num, (prep_area->ds->ds_num == 1) ? "" : "s", r->values_num); BAIL_OUT (-1); } /* }}} */ /* Allocate r->instances_pos, r->values_pos, r->instances_buffer, and * r->values_buffer {{{ */ if (r->instances_num > 0) { prep_area->instances_pos = (size_t *) calloc (r->instances_num, sizeof (size_t)); if (prep_area->instances_pos == NULL) { ERROR ("db query utils: udb_result_prepare_result: malloc failed."); BAIL_OUT (-ENOMEM); } prep_area->instances_buffer = (char **) calloc (r->instances_num, sizeof (char *)); if (prep_area->instances_buffer == NULL) { ERROR ("db query utils: udb_result_prepare_result: malloc failed."); BAIL_OUT (-ENOMEM); } } /* if (r->instances_num > 0) */ prep_area->values_pos = (size_t *) calloc (r->values_num, sizeof (size_t)); if (prep_area->values_pos == NULL) { ERROR ("db query utils: udb_result_prepare_result: malloc failed."); BAIL_OUT (-ENOMEM); } prep_area->values_buffer = (char **) calloc (r->values_num, sizeof (char *)); if (prep_area->values_buffer == NULL) { ERROR ("db query utils: udb_result_prepare_result: malloc failed."); BAIL_OUT (-ENOMEM); } /* }}} */ /* Determine the position of the instance columns {{{ */ for (i = 0; i < r->instances_num; i++) { size_t j; for (j = 0; j < column_num; j++) { if (strcasecmp (r->instances[i], column_names[j]) == 0) { prep_area->instances_pos[i] = j; break; } } if (j >= column_num) { ERROR ("db query utils: udb_result_prepare_result: " "Column `%s' could not be found.", r->instances[i]); BAIL_OUT (-ENOENT); } } /* }}} for (i = 0; i < r->instances_num; i++) */ /* Determine the position of the value columns {{{ */ for (i = 0; i < r->values_num; i++) { size_t j; for (j = 0; j < column_num; j++) { if (strcasecmp (r->values[i], column_names[j]) == 0) { prep_area->values_pos[i] = j; break; } } if (j >= column_num) { ERROR ("db query utils: udb_result_prepare_result: " "Column `%s' could not be found.", r->values[i]); BAIL_OUT (-ENOENT); } } /* }}} for (i = 0; i < r->values_num; i++) */ #undef BAIL_OUT return (0); } /* }}} int udb_result_prepare_result */ static void udb_result_free (udb_result_t *r) /* {{{ */ { size_t i; if (r == NULL) return; sfree (r->type); for (i = 0; i < r->instances_num; i++) sfree (r->instances[i]); sfree (r->instances); for (i = 0; i < r->values_num; i++) sfree (r->values[i]); sfree (r->values); udb_result_free (r->next); sfree (r); } /* }}} void udb_result_free */ static int udb_result_create (const char *query_name, /* {{{ */ udb_result_t **r_head, oconfig_item_t *ci) { udb_result_t *r; int status; int i; if (ci->values_num != 0) { WARNING ("db query utils: The `Result' block doesn't accept " "any arguments. Ignoring %i argument%s.", ci->values_num, (ci->values_num == 1) ? "" : "s"); } r = (udb_result_t *) malloc (sizeof (*r)); if (r == NULL) { ERROR ("db query utils: malloc failed."); return (-1); } memset (r, 0, sizeof (*r)); r->type = NULL; r->instance_prefix = NULL; r->instances = NULL; r->values = NULL; r->next = NULL; /* Fill the `udb_result_t' structure.. */ status = 0; for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("Type", child->key) == 0) status = udb_config_set_string (&r->type, child); else if (strcasecmp ("InstancePrefix", child->key) == 0) status = udb_config_set_string (&r->instance_prefix, child); else if (strcasecmp ("InstancesFrom", child->key) == 0) status = udb_config_add_string (&r->instances, &r->instances_num, child); else if (strcasecmp ("ValuesFrom", child->key) == 0) status = udb_config_add_string (&r->values, &r->values_num, child); else { WARNING ("db query utils: Query `%s': Option `%s' not allowed here.", query_name, child->key); status = -1; } if (status != 0) break; } /* Check that all necessary options have been given. */ while (status == 0) { if (r->type == NULL) { WARNING ("db query utils: `Type' not given for " "result in query `%s'", query_name); status = -1; } if (r->values == NULL) { WARNING ("db query utils: `ValuesFrom' not given for " "result in query `%s'", query_name); status = -1; } break; } /* while (status == 0) */ if (status != 0) { udb_result_free (r); return (-1); } /* If all went well, add this result to the list of results. */ if (*r_head == NULL) { *r_head = r; } else { udb_result_t *last; last = *r_head; while (last->next != NULL) last = last->next; last->next = r; } return (0); } /* }}} int udb_result_create */ /* * Query private functions */ void udb_query_free_one (udb_query_t *q) /* {{{ */ { if (q == NULL) return; sfree (q->name); sfree (q->statement); udb_result_free (q->results); sfree (q); } /* }}} void udb_query_free_one */ /* * Query public functions */ int udb_query_create (udb_query_t ***ret_query_list, /* {{{ */ size_t *ret_query_list_len, oconfig_item_t *ci, udb_query_create_callback_t cb) { udb_query_t **query_list; size_t query_list_len; udb_query_t *q; int status; int i; if ((ret_query_list == NULL) || (ret_query_list_len == NULL)) return (-EINVAL); query_list = *ret_query_list; query_list_len = *ret_query_list_len; if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { WARNING ("db query utils: The `Query' block " "needs exactly one string argument."); return (-1); } q = (udb_query_t *) malloc (sizeof (*q)); if (q == NULL) { ERROR ("db query utils: malloc failed."); return (-1); } memset (q, 0, sizeof (*q)); q->min_version = 0; q->max_version = UINT_MAX; status = udb_config_set_string (&q->name, ci); if (status != 0) { sfree (q); return (status); } /* Fill the `udb_query_t' structure.. */ for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("Statement", child->key) == 0) status = udb_config_set_string (&q->statement, child); else if (strcasecmp ("Result", child->key) == 0) status = udb_result_create (q->name, &q->results, child); else if (strcasecmp ("MinVersion", child->key) == 0) status = udb_config_set_uint (&q->min_version, child); else if (strcasecmp ("MaxVersion", child->key) == 0) status = udb_config_set_uint (&q->max_version, child); /* Call custom callbacks */ else if (cb != NULL) { status = (*cb) (q, child); if (status != 0) { WARNING ("db query utils: The configuration callback failed " "to handle `%s'.", child->key); } } else { WARNING ("db query utils: Query `%s': Option `%s' not allowed here.", q->name, child->key); status = -1; } if (status != 0) break; } /* Check that all necessary options have been given. */ if (status == 0) { if (q->statement == NULL) { WARNING ("db query utils: Query `%s': No `Statement' given.", q->name); status = -1; } if (q->results == NULL) { WARNING ("db query utils: Query `%s': No (valid) `Result' block given.", q->name); status = -1; } } /* if (status == 0) */ /* If all went well, add this query to the list of queries within the * database structure. */ if (status == 0) { udb_query_t **temp; temp = (udb_query_t **) realloc (query_list, sizeof (*query_list) * (query_list_len + 1)); if (temp == NULL) { ERROR ("db query utils: realloc failed"); status = -1; } else { query_list = temp; query_list[query_list_len] = q; query_list_len++; } } if (status != 0) { udb_query_free_one (q); return (-1); } *ret_query_list = query_list; *ret_query_list_len = query_list_len; return (0); } /* }}} int udb_query_create */ void udb_query_free (udb_query_t **query_list, size_t query_list_len) /* {{{ */ { size_t i; if (query_list == NULL) return; for (i = 0; i < query_list_len; i++) udb_query_free_one (query_list[i]); sfree (query_list); } /* }}} void udb_query_free */ int udb_query_pick_from_list_by_name (const char *name, /* {{{ */ udb_query_t **src_list, size_t src_list_len, udb_query_t ***dst_list, size_t *dst_list_len) { size_t i; int num_added; if ((name == NULL) || (src_list == NULL) || (dst_list == NULL) || (dst_list_len == NULL)) { ERROR ("db query utils: udb_query_pick_from_list_by_name: " "Invalid argument."); return (-EINVAL); } num_added = 0; for (i = 0; i < src_list_len; i++) { udb_query_t **tmp_list; size_t tmp_list_len; if (strcasecmp (name, src_list[i]->name) != 0) continue; tmp_list_len = *dst_list_len; tmp_list = (udb_query_t **) realloc (*dst_list, (tmp_list_len + 1) * sizeof (udb_query_t *)); if (tmp_list == NULL) { ERROR ("db query utils: realloc failed."); return (-ENOMEM); } tmp_list[tmp_list_len] = src_list[i]; tmp_list_len++; *dst_list = tmp_list; *dst_list_len = tmp_list_len; num_added++; } /* for (i = 0; i < src_list_len; i++) */ if (num_added <= 0) { ERROR ("db query utils: Cannot find query `%s'. Make sure the " "block is above the database definition!", name); return (-ENOENT); } else { DEBUG ("db query utils: Added %i versions of query `%s'.", num_added, name); } return (0); } /* }}} int udb_query_pick_from_list_by_name */ int udb_query_pick_from_list (oconfig_item_t *ci, /* {{{ */ udb_query_t **src_list, size_t src_list_len, udb_query_t ***dst_list, size_t *dst_list_len) { const char *name; if ((ci == NULL) || (src_list == NULL) || (dst_list == NULL) || (dst_list_len == NULL)) { ERROR ("db query utils: udb_query_pick_from_list: " "Invalid argument."); return (-EINVAL); } if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { ERROR ("db query utils: The `%s' config option " "needs exactly one string argument.", ci->key); return (-1); } name = ci->values[0].value.string; return (udb_query_pick_from_list_by_name (name, src_list, src_list_len, dst_list, dst_list_len)); } /* }}} int udb_query_pick_from_list */ const char *udb_query_get_name (udb_query_t *q) /* {{{ */ { if (q == NULL) return (NULL); return (q->name); } /* }}} const char *udb_query_get_name */ const char *udb_query_get_statement (udb_query_t *q) /* {{{ */ { if (q == NULL) return (NULL); return (q->statement); } /* }}} const char *udb_query_get_statement */ void udb_query_set_user_data (udb_query_t *q, void *user_data) /* {{{ */ { if (q == NULL) return; q->user_data = user_data; } /* }}} void udb_query_set_user_data */ void *udb_query_get_user_data (udb_query_t *q) /* {{{ */ { if (q == NULL) return (NULL); return (q->user_data); } /* }}} void *udb_query_get_user_data */ int udb_query_check_version (udb_query_t *q, unsigned int version) /* {{{ */ { if (q == NULL) return (-EINVAL); if ((version < q->min_version) || (version > q->max_version)) return (0); return (1); } /* }}} int udb_query_check_version */ void udb_query_finish_result (udb_query_t const *q, /* {{{ */ udb_query_preparation_area_t *prep_area) { udb_result_preparation_area_t *r_area; udb_result_t *r; if ((q == NULL) || (prep_area == NULL)) return; prep_area->column_num = 0; sfree (prep_area->host); sfree (prep_area->plugin); sfree (prep_area->db_name); prep_area->interval = 0; for (r = q->results, r_area = prep_area->result_prep_areas; r != NULL; r = r->next, r_area = r_area->next) { /* this may happen during error conditions of the caller */ if (r_area == NULL) break; udb_result_finish_result (r, r_area); } } /* }}} void udb_query_finish_result */ int udb_query_handle_result (udb_query_t const *q, /* {{{ */ udb_query_preparation_area_t *prep_area, char **column_values) { udb_result_preparation_area_t *r_area; udb_result_t *r; int success; int status; if ((q == NULL) || (prep_area == NULL)) return (-EINVAL); if ((prep_area->column_num < 1) || (prep_area->host == NULL) || (prep_area->plugin == NULL) || (prep_area->db_name == NULL)) { ERROR ("db query utils: Query `%s': Query is not prepared; " "can't handle result.", q->name); return (-EINVAL); } #if defined(COLLECT_DEBUG) && COLLECT_DEBUG /* {{{ */ do { size_t i; for (i = 0; i < prep_area->column_num; i++) { DEBUG ("db query utils: udb_query_handle_result (%s, %s): " "column[%zu] = %s;", prep_area->db_name, q->name, i, column_values[i]); } } while (0); #endif /* }}} */ success = 0; for (r = q->results, r_area = prep_area->result_prep_areas; r != NULL; r = r->next, r_area = r_area->next) { status = udb_result_handle_result (r, prep_area, r_area, q, column_values); if (status == 0) success++; } if (success == 0) { ERROR ("db query utils: udb_query_handle_result (%s, %s): " "All results failed.", prep_area->db_name, q->name); return (-1); } return (0); } /* }}} int udb_query_handle_result */ int udb_query_prepare_result (udb_query_t const *q, /* {{{ */ udb_query_preparation_area_t *prep_area, const char *host, const char *plugin, const char *db_name, char **column_names, size_t column_num, cdtime_t interval) { udb_result_preparation_area_t *r_area; udb_result_t *r; int status; if ((q == NULL) || (prep_area == NULL)) return (-EINVAL); udb_query_finish_result (q, prep_area); prep_area->column_num = column_num; prep_area->host = strdup (host); prep_area->plugin = strdup (plugin); prep_area->db_name = strdup (db_name); prep_area->interval = interval; if ((prep_area->host == NULL) || (prep_area->plugin == NULL) || (prep_area->db_name == NULL)) { ERROR ("db query utils: Query `%s': Prepare failed: Out of memory.", q->name); udb_query_finish_result (q, prep_area); return (-ENOMEM); } #if defined(COLLECT_DEBUG) && COLLECT_DEBUG do { size_t i; for (i = 0; i < column_num; i++) { DEBUG ("db query utils: udb_query_prepare_result: " "query = %s; column[%zu] = %s;", q->name, i, column_names[i]); } } while (0); #endif for (r = q->results, r_area = prep_area->result_prep_areas; r != NULL; r = r->next, r_area = r_area->next) { if (! r_area) { ERROR ("db query utils: Query `%s': Invalid number of result " "preparation areas.", q->name); udb_query_finish_result (q, prep_area); return (-EINVAL); } status = udb_result_prepare_result (r, r_area, column_names, column_num); if (status != 0) { udb_query_finish_result (q, prep_area); return (status); } } return (0); } /* }}} int udb_query_prepare_result */ udb_query_preparation_area_t * udb_query_allocate_preparation_area (udb_query_t *q) /* {{{ */ { udb_query_preparation_area_t *q_area; udb_result_preparation_area_t **next_r_area; udb_result_t *r; q_area = (udb_query_preparation_area_t *)malloc (sizeof (*q_area)); if (q_area == NULL) return NULL; memset (q_area, 0, sizeof (*q_area)); next_r_area = &q_area->result_prep_areas; for (r = q->results; r != NULL; r = r->next) { udb_result_preparation_area_t *r_area; r_area = (udb_result_preparation_area_t *)malloc (sizeof (*r_area)); if (r_area == NULL) { for (r_area = q_area->result_prep_areas; r_area != NULL; r_area = r_area->next) { free (r_area); } free (q_area); return NULL; } memset (r_area, 0, sizeof (*r_area)); *next_r_area = r_area; next_r_area = &r_area->next; } return (q_area); } /* }}} udb_query_preparation_area_t *udb_query_allocate_preparation_area */ void udb_query_delete_preparation_area (udb_query_preparation_area_t *q_area) /* {{{ */ { udb_result_preparation_area_t *r_area; if (q_area == NULL) return; r_area = q_area->result_prep_areas; while (r_area != NULL) { udb_result_preparation_area_t *area = r_area; r_area = r_area->next; sfree (area->instances_pos); sfree (area->values_pos); sfree (area->instances_buffer); sfree (area->values_buffer); free (area); } sfree (q_area->host); sfree (q_area->plugin); sfree (q_area->db_name); free (q_area); } /* }}} void udb_query_delete_preparation_area */ /* vim: set sw=2 sts=2 et fdm=marker : */ collectd-5.4.0/src/PaxHeaders.11991/match_empty_counter.c0000644037772200116100000000013212204120331021347 xustar000000000000000030 mtime=1376821465.077973503 30 atime=1376821477.218167931 30 ctime=1376821741.966400036 collectd-5.4.0/src/match_empty_counter.c0000644037772200116100000000523412204120331020117 0ustar00octoeng00000000000000/** * collectd - src/match_empty_counter.c * Copyright (C) 2009 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: * Florian Forster **/ #include "collectd.h" #include "common.h" #include "utils_cache.h" #include "filter_chain.h" /* * private data types */ struct mec_match_s; typedef struct mec_match_s mec_match_t; struct mec_match_s { int dummy; }; /* * internal helper functions */ static int mec_create (const oconfig_item_t *ci, void **user_data) /* {{{ */ { mec_match_t *m; m = (mec_match_t *) malloc (sizeof (*m)); if (m == NULL) { ERROR ("mec_create: malloc failed."); return (-ENOMEM); } memset (m, 0, sizeof (*m)); if (ci->children_num != 0) { ERROR ("empty_counter match: This match does not take any additional " "configuration."); } *user_data = m; return (0); } /* }}} int mec_create */ static int mec_destroy (void **user_data) /* {{{ */ { if (user_data != NULL) { sfree (*user_data); } return (0); } /* }}} int mec_destroy */ static int mec_match (const data_set_t __attribute__((unused)) *ds, /* {{{ */ const value_list_t *vl, notification_meta_t __attribute__((unused)) **meta, void **user_data) { int num_counters; int num_empty; int i; if ((user_data == NULL) || (*user_data == NULL)) return (-1); num_counters = 0; num_empty = 0; for (i = 0; i < ds->ds_num; i++) { if (ds->ds[i].type != DS_TYPE_COUNTER) continue; num_counters++; if (vl->values[i].counter == 0) num_empty++; } if (num_counters == 0) return (FC_MATCH_NO_MATCH); else if (num_counters == num_empty) return (FC_MATCH_MATCHES); else return (FC_MATCH_NO_MATCH); } /* }}} int mec_match */ void module_register (void) { match_proc_t mproc; memset (&mproc, 0, sizeof (mproc)); mproc.create = mec_create; mproc.destroy = mec_destroy; mproc.match = mec_match; fc_register_match ("empty_counter", mproc); } /* module_register */ /* vim: set sw=2 sts=2 tw=78 et fdm=marker : */ collectd-5.4.0/src/PaxHeaders.11991/uuid.c0000644037772200116100000000013212204120331016244 xustar000000000000000030 mtime=1376821465.089973696 30 atime=1376821477.230168122 30 ctime=1376821741.966400036 collectd-5.4.0/src/uuid.c0000644037772200116100000001342212204120331015012 0ustar00octoeng00000000000000/** * collectd - src/uuid.c * Copyright (C) 2007 Red Hat Inc. * * 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: * Dan Berrange * Richard W.M. Jones * * Derived from UUID detection code by Dan Berrange * http://hg.et.redhat.com/virt/daemons/spectre--devel?f=f6e3a1b06433;file=lib/uuid.c **/ #include "collectd.h" #include "common.h" #include "configfile.h" #include "plugin.h" #if HAVE_LIBHAL #include #endif #define UUID_RAW_LENGTH 16 #define UUID_PRINTABLE_COMPACT_LENGTH (UUID_RAW_LENGTH * 2) #define UUID_PRINTABLE_NORMAL_LENGTH (UUID_PRINTABLE_COMPACT_LENGTH + 4) static char *uuidfile = NULL; static const char *config_keys[] = { "UUIDFile" }; static int looks_like_a_uuid (const char *uuid) { int len; if (!uuid) return 0; len = strlen (uuid); if (len < UUID_PRINTABLE_COMPACT_LENGTH) return 0; while (*uuid) { if (!isxdigit ((int)*uuid) && *uuid != '-') return 0; uuid++; } return 1; } static char * uuid_parse_dmidecode(FILE *file) { char line[1024]; while (fgets (line, sizeof (line), file) != NULL) { char *fields[4]; int fields_num; strstripnewline (line); /* Look for a line reading: * UUID: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX */ fields_num = strsplit (line, fields, STATIC_ARRAY_SIZE (fields)); if (fields_num != 2) continue; if (strcmp("UUID:", fields[0]) != 0) continue; if (!looks_like_a_uuid (fields[1])) continue; return strdup (fields[1]); } return NULL; } static char * uuid_get_from_dmidecode(void) { FILE *dmidecode = popen("dmidecode 2>/dev/null", "r"); char *uuid; if (!dmidecode) { return NULL; } uuid = uuid_parse_dmidecode(dmidecode); pclose(dmidecode); return uuid; } #if HAVE_LIBHAL #define UUID_PATH "/org/freedesktop/Hal/devices/computer" #define UUID_PROPERTY "smbios.system.uuid" static char * uuid_get_from_hal(void) { LibHalContext *ctx; DBusError error; DBusConnection *con; dbus_error_init(&error); if (!(con = dbus_bus_get(DBUS_BUS_SYSTEM, &error)) ) { goto bailout_nobus; } ctx = libhal_ctx_new(); libhal_ctx_set_dbus_connection(ctx, con); if (!libhal_ctx_init(ctx, &error)) { goto bailout; } if (!libhal_device_property_exists(ctx, UUID_PATH, UUID_PROPERTY, &error)) { goto bailout; } char *uuid = libhal_device_get_property_string(ctx, UUID_PATH, UUID_PROPERTY, &error); if (looks_like_a_uuid (uuid)) { return uuid; } bailout: { DBusError ctxerror; dbus_error_init(&ctxerror); if (!(libhal_ctx_shutdown(ctx, &ctxerror))) { dbus_error_free(&ctxerror); } } libhal_ctx_free(ctx); //dbus_connection_unref(con); bailout_nobus: if (dbus_error_is_set(&error)) { /*printf("Error %s\n", error.name);*/ dbus_error_free(&error); } return NULL; } #endif static char * uuid_get_from_file(const char *path) { FILE *file; char uuid[UUID_PRINTABLE_NORMAL_LENGTH + 1] = ""; file = fopen (path, "r"); if (file == NULL) return NULL; if (!fgets(uuid, sizeof(uuid), file)) { fclose(file); return NULL; } fclose(file); strstripnewline (uuid); return strdup (uuid); } static char * uuid_get_local(void) { char *uuid; /* Check /etc/uuid / UUIDFile before any other method. */ if ((uuid = uuid_get_from_file(uuidfile ? uuidfile : "/etc/uuid")) != NULL){ return uuid; } #if HAVE_LIBHAL if ((uuid = uuid_get_from_hal()) != NULL) { return uuid; } #endif if ((uuid = uuid_get_from_dmidecode()) != NULL) { return uuid; } if ((uuid = uuid_get_from_file("/sys/hypervisor/uuid")) != NULL) { return uuid; } return NULL; } static int uuid_config (const char *key, const char *value) { if (strcasecmp (key, "UUIDFile") == 0) { char *tmp = strdup (value); if (tmp == NULL) return -1; sfree (uuidfile); uuidfile = tmp; } else { return 1; } return 0; } static int uuid_init (void) { char *uuid = uuid_get_local (); if (uuid) { sstrncpy (hostname_g, uuid, DATA_MAX_NAME_LEN); sfree (uuid); return 0; } WARNING ("uuid: could not read UUID using any known method"); return 0; } void module_register (void) { plugin_register_config ("uuid", uuid_config, config_keys, STATIC_ARRAY_SIZE (config_keys)); plugin_register_init ("uuid", uuid_init); } /* * vim: set tabstop=4: * vim: set shiftwidth=4: * vim: set expandtab: */ /* * Local variables: * indent-tabs-mode: nil * c-indent-level: 4 * c-basic-offset: 4 * tab-width: 4 * End: */ collectd-5.4.0/src/PaxHeaders.11991/collectd-nagios.pod0000644037772200116100000000013012204120331020703 xustar000000000000000030 mtime=1376821465.061973248 30 atime=1376821477.206167738 28 ctime=1376821741.9704001 collectd-5.4.0/src/collectd-nagios.pod0000644037772200116100000000750312204120331017456 0ustar00octoeng00000000000000=encoding UTF-8 =head1 NAME collectd-nagios - Nagios plugin for querying collectd =head1 SYNOPSIS collectd-nagios B<-s> I B<-n> I B<-H> I I<[options]> =head1 DESCRIPTION This small program is the glue between collectd and nagios. collectd collects various performance statistics which it provides via the C, see L. This program is called by Nagios, connects to the UNIX socket and reads the values from collectd. It then returns B, B or B depending on the values and the ranges provided by Nagios. =head1 ARGUMENTS AND OPTIONS The following arguments and options are required and understood by collectd-nagios. The order of the arguments generally doesn't matter, as long as no argument is passed more than once. =over 4 =item B<-s> I Path of the UNIX socket opened by collectd's C. =item B<-n> I The value to read from collectd. The argument is in the form C. =item B<-H> I Hostname to query the values for. =item B<-d> I Each I may be made of multiple "data sources". With this option you can select one or more data sources. To select multiple data sources simply specify this option again. If multiple data sources are examined they are handled according to the consolidation function given with the B<-g> option. =item B<-g> BI<|>BI<|>B When multiple data sources are selected from a value spec, they can be handled differently depending on this option. The values of the following meaning: =over 4 =item B No consolidation if done and the warning and critical regions are applied to each value independently. =item B The warning and critical ranges are applied to the average of all values. =item B The warning and critical ranges are applied to the sum of all values. =item B The warning and critical ranges are applied to the ratio (in percent) of the first value and the sum of all values. A warning is returned if the first value is not defined or if all values sum up to zero. =back =item B<-c> I =item B<-w> I Set the critical (B<-c>) and warning (B<-w>) ranges. These options mostly follow the normal syntax of Nagios plugins. The general format is "IB<:>I". If a value is smaller than I or bigger than I, a I or I status is returned, otherwise the status is I. The tilde sign (B<~>) can be used to explicitly specify infinity. If B<~> is used as a I value, negative infinity is used. In case of I, it is interpreted as positive infinity. If the first character of the I is the atEsign (B<@>), the meaning of the range will be inverted. I.Ee. all values I the range will yield a I or I status, while all values I the range will result in a I status. I (and the colon) may be omitted, I is then assumed to be zero. If I (but not the trailing colon) is omitted, I is assumed to be positive infinity. =item B<-m> If this option is given, "Not a Number" (NaN) is treated as I. By default, the I consolidation reports NaNs as I. Other consolidations simply ignore NaN values. =back =head1 RETURN VALUE As usual for Nagios plugins, this program writes a short, one line status message to STDOUT and signals success or failure with it's return value. It exits with a return value of B<0> for I, B<1> for I and B<2> for I. If the values are not available or some other error occurred, it returns B<3> for I. =head1 SEE ALSO L, L, L, L =head1 AUTHOR Florian Forster EoctoEatEverplant.orgE =cut collectd-5.4.0/src/PaxHeaders.11991/write_redis.c0000644037772200116100000000013012204120331017614 xustar000000000000000030 mtime=1376821465.093973759 30 atime=1376821477.230168122 28 ctime=1376821741.9704001 collectd-5.4.0/src/write_redis.c0000644037772200116100000001471612204120331016373 0ustar00octoeng00000000000000/** * collectd - src/write_redis.c * Copyright (C) 2010 Florian Forster * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Authors: * Florian Forster **/ #include "collectd.h" #include "plugin.h" #include "common.h" #include "configfile.h" #include #include struct wr_node_s { char name[DATA_MAX_NAME_LEN]; char *host; int port; int timeout; REDIS conn; pthread_mutex_t lock; }; typedef struct wr_node_s wr_node_t; /* * Functions */ static int wr_write (const data_set_t *ds, /* {{{ */ const value_list_t *vl, user_data_t *ud) { wr_node_t *node = ud->data; char ident[512]; char key[512]; char value[512]; size_t value_size; char *value_ptr; int status; int i; status = FORMAT_VL (ident, sizeof (ident), vl); if (status != 0) return (status); ssnprintf (key, sizeof (key), "collectd/%s", ident); memset (value, 0, sizeof (value)); value_size = sizeof (value); value_ptr = &value[0]; #define APPEND(...) do { \ status = snprintf (value_ptr, value_size, __VA_ARGS__); \ if (((size_t) status) > value_size) \ { \ value_ptr += value_size; \ value_size = 0; \ } \ else \ { \ value_ptr += status; \ value_size -= status; \ } \ } while (0) APPEND ("%lu", (unsigned long) vl->time); for (i = 0; i < ds->ds_num; i++) { if (ds->ds[i].type == DS_TYPE_COUNTER) APPEND ("%llu", vl->values[i].counter); else if (ds->ds[i].type == DS_TYPE_GAUGE) APPEND ("%g", vl->values[i].gauge); else if (ds->ds[i].type == DS_TYPE_DERIVE) APPEND ("%"PRIi64, vl->values[i].derive); else if (ds->ds[i].type == DS_TYPE_ABSOLUTE) APPEND ("%"PRIu64, vl->values[i].absolute); else assert (23 == 42); } #undef APPEND pthread_mutex_lock (&node->lock); if (node->conn == NULL) { node->conn = credis_connect (node->host, node->port, node->timeout); if (node->conn == NULL) { ERROR ("write_redis plugin: Connecting to host \"%s\" (port %i) failed.", (node->host != NULL) ? node->host : "localhost", (node->port != 0) ? node->port : 6379); pthread_mutex_unlock (&node->lock); return (-1); } } /* "credis_zadd" doesn't handle a NULL pointer gracefully, so I'd rather * have a meaningful assertion message than a normal segmentation fault. */ assert (node->conn != NULL); status = credis_zadd (node->conn, key, (double) vl->time, value); credis_sadd (node->conn, "collectd/values", ident); pthread_mutex_unlock (&node->lock); return (0); } /* }}} int wr_write */ static void wr_config_free (void *ptr) /* {{{ */ { wr_node_t *node = ptr; if (node == NULL) return; if (node->conn != NULL) { credis_close (node->conn); node->conn = NULL; } sfree (node->host); sfree (node); } /* }}} void wr_config_free */ static int wr_config_node (oconfig_item_t *ci) /* {{{ */ { wr_node_t *node; int status; int i; node = malloc (sizeof (*node)); if (node == NULL) return (ENOMEM); memset (node, 0, sizeof (*node)); node->host = NULL; node->port = 0; node->timeout = 1000; node->conn = NULL; pthread_mutex_init (&node->lock, /* attr = */ NULL); status = cf_util_get_string_buffer (ci, node->name, sizeof (node->name)); if (status != 0) { sfree (node); return (status); } for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("Host", child->key) == 0) status = cf_util_get_string (child, &node->host); else if (strcasecmp ("Port", child->key) == 0) { status = cf_util_get_port_number (child); if (status > 0) { node->port = status; status = 0; } } else if (strcasecmp ("Timeout", child->key) == 0) status = cf_util_get_int (child, &node->timeout); else WARNING ("write_redis plugin: Ignoring unknown config option \"%s\".", child->key); if (status != 0) break; } /* for (i = 0; i < ci->children_num; i++) */ if (status == 0) { char cb_name[DATA_MAX_NAME_LEN]; user_data_t ud; ssnprintf (cb_name, sizeof (cb_name), "write_redis/%s", node->name); ud.data = node; ud.free_func = wr_config_free; status = plugin_register_write (cb_name, wr_write, &ud); } if (status != 0) wr_config_free (node); return (status); } /* }}} int wr_config_node */ static int wr_config (oconfig_item_t *ci) /* {{{ */ { int i; for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("Node", child->key) == 0) wr_config_node (child); else WARNING ("write_redis plugin: Ignoring unknown " "configuration option \"%s\" at top level.", child->key); } return (0); } /* }}} int wr_config */ void module_register (void) { plugin_register_complex_config ("write_redis", wr_config); } /* vim: set sw=2 sts=2 tw=78 et fdm=marker : */ collectd-5.4.0/src/PaxHeaders.11991/utils_dns.c0000644037772200116100000000013012204120331017300 xustar000000000000000030 mtime=1376821465.089973696 30 atime=1376821477.230168122 28 ctime=1376821741.9704001 collectd-5.4.0/src/utils_dns.c0000644037772200116100000006504312204120331016056 0ustar00octoeng00000000000000/* * collectd - src/utils_dns.c * Modifications Copyright (C) 2006 Florian octo Forster * Copyright (C) 2002 The Measurement Factory, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of The Measurement Factory nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Authors: * The Measurement Factory, Inc. * Florian octo Forster */ #define _BSD_SOURCE #include "collectd.h" #include "plugin.h" #include "common.h" #if HAVE_SYS_SOCKET_H # include #endif #if HAVE_NET_IF_ARP_H # include #endif #if HAVE_NET_IF_H # include #endif #if HAVE_NET_PPP_DEFS_H # include #endif #if HAVE_NET_IF_PPP_H # include #endif #if HAVE_NETINET_IN_SYSTM_H # include #endif #if HAVE_NETINET_IN_H # include #endif #if HAVE_NETINET_IP6_H # include #endif #if HAVE_NETINET_IP_COMPAT_H # include #endif #if HAVE_NETINET_IF_ETHER_H # include #endif #if HAVE_NETINET_IP_H # include #endif #ifdef HAVE_NETINET_IP_VAR_H # include #endif #if HAVE_NETINET_UDP_H # include #endif #if HAVE_ARPA_INET_H # include #endif #if HAVE_ARPA_NAMESER_H # include #endif #if HAVE_ARPA_NAMESER_COMPAT_H # include #endif #if HAVE_NETDB_H # include #endif #if HAVE_PCAP_H # include #endif #define PCAP_SNAPLEN 1460 #ifndef ETHER_HDR_LEN #define ETHER_ADDR_LEN 6 #define ETHER_TYPE_LEN 2 #define ETHER_HDR_LEN (ETHER_ADDR_LEN * 2 + ETHER_TYPE_LEN) #endif #ifndef ETHERTYPE_8021Q # define ETHERTYPE_8021Q 0x8100 #endif #ifndef ETHERTYPE_IPV6 # define ETHERTYPE_IPV6 0x86DD #endif #ifndef PPP_ADDRESS_VAL # define PPP_ADDRESS_VAL 0xff /* The address byte value */ #endif #ifndef PPP_CONTROL_VAL # define PPP_CONTROL_VAL 0x03 /* The control byte value */ #endif #if HAVE_STRUCT_UDPHDR_UH_DPORT && HAVE_STRUCT_UDPHDR_UH_SPORT # define UDP_DEST uh_dport # define UDP_SRC uh_sport #elif HAVE_STRUCT_UDPHDR_DEST && HAVE_STRUCT_UDPHDR_SOURCE # define UDP_DEST dest # define UDP_SRC source #else # error "`struct udphdr' is unusable." #endif #include "utils_dns.h" /* * Type definitions */ struct ip_list_s { struct in6_addr addr; void *data; struct ip_list_s *next; }; typedef struct ip_list_s ip_list_t; typedef int (printer)(const char *, ...); /* * flags/features for non-interactive mode */ #ifndef T_A6 #define T_A6 38 #endif #ifndef T_SRV #define T_SRV 33 #endif /* * Global variables */ int qtype_counts[T_MAX]; int opcode_counts[OP_MAX]; int qclass_counts[C_MAX]; #if HAVE_PCAP_H static pcap_t *pcap_obj = NULL; #endif static ip_list_t *IgnoreList = NULL; #if HAVE_PCAP_H static void (*Callback) (const rfc1035_header_t *) = NULL; static int query_count_intvl = 0; static int query_count_total = 0; # ifdef __OpenBSD__ static struct bpf_timeval last_ts; # else static struct timeval last_ts; # endif /* __OpenBSD__ */ #endif /* HAVE_PCAP_H */ static int cmp_in6_addr (const struct in6_addr *a, const struct in6_addr *b) { int i; assert (sizeof (struct in6_addr) == 16); for (i = 0; i < 16; i++) if (a->s6_addr[i] != b->s6_addr[i]) break; if (i >= 16) return (0); return (a->s6_addr[i] > b->s6_addr[i] ? 1 : -1); } /* int cmp_addrinfo */ static inline int ignore_list_match (const struct in6_addr *addr) { ip_list_t *ptr; for (ptr = IgnoreList; ptr != NULL; ptr = ptr->next) if (cmp_in6_addr (addr, &ptr->addr) == 0) return (1); return (0); } /* int ignore_list_match */ static void ignore_list_add (const struct in6_addr *addr) { ip_list_t *new; if (ignore_list_match (addr) != 0) return; new = malloc (sizeof (ip_list_t)); if (new == NULL) { perror ("malloc"); return; } memcpy (&new->addr, addr, sizeof (struct in6_addr)); new->next = IgnoreList; IgnoreList = new; } /* void ignore_list_add */ void ignore_list_add_name (const char *name) { struct addrinfo *ai_list; struct addrinfo *ai_ptr; struct in6_addr addr; int status; status = getaddrinfo (name, NULL, NULL, &ai_list); if (status != 0) return; for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) { if (ai_ptr->ai_family == AF_INET) { memset (&addr, '\0', sizeof (addr)); addr.s6_addr[10] = 0xFF; addr.s6_addr[11] = 0xFF; memcpy (addr.s6_addr + 12, &((struct sockaddr_in *) ai_ptr->ai_addr)->sin_addr, 4); ignore_list_add (&addr); } else { ignore_list_add (&((struct sockaddr_in6 *) ai_ptr->ai_addr)->sin6_addr); } } /* for */ freeaddrinfo (ai_list); } #if HAVE_PCAP_H static void in6_addr_from_buffer (struct in6_addr *ia, const void *buf, size_t buf_len, int family) { memset (ia, 0, sizeof (struct in6_addr)); if ((AF_INET == family) && (sizeof (uint32_t) == buf_len)) { ia->s6_addr[10] = 0xFF; ia->s6_addr[11] = 0xFF; memcpy (ia->s6_addr + 12, buf, buf_len); } else if ((AF_INET6 == family) && (sizeof (struct in6_addr) == buf_len)) { memcpy (ia, buf, buf_len); } } /* void in6_addr_from_buffer */ void dnstop_set_pcap_obj (pcap_t *po) { pcap_obj = po; } void dnstop_set_callback (void (*cb) (const rfc1035_header_t *)) { Callback = cb; } #define RFC1035_MAXLABELSZ 63 static int rfc1035NameUnpack(const char *buf, size_t sz, off_t * off, char *name, size_t ns ) { off_t no = 0; unsigned char c; size_t len; static int loop_detect = 0; if (loop_detect > 2) return 4; /* compression loop */ if (ns <= 0) return 4; /* probably compression loop */ do { if ((*off) >= sz) break; c = *(buf + (*off)); if (c > 191) { /* blasted compression */ int rc; unsigned short s; off_t ptr; memcpy(&s, buf + (*off), sizeof(s)); s = ntohs(s); (*off) += sizeof(s); /* Sanity check */ if ((*off) >= sz) return 1; /* message too short */ ptr = s & 0x3FFF; /* Make sure the pointer is inside this message */ if (ptr >= sz) return 2; /* bad compression ptr */ if (ptr < DNS_MSG_HDR_SZ) return 2; /* bad compression ptr */ loop_detect++; rc = rfc1035NameUnpack(buf, sz, &ptr, name + no, ns - no); loop_detect--; return rc; } else if (c > RFC1035_MAXLABELSZ) { /* * "(The 10 and 01 combinations are reserved for future use.)" */ return 3; /* reserved label/compression flags */ break; } else { (*off)++; len = (size_t) c; if (len == 0) break; if (len > (ns - 1)) len = ns - 1; if ((*off) + len > sz) return 4; /* message is too short */ if (no + len + 1 > ns) return 5; /* qname would overflow name buffer */ memcpy(name + no, buf + (*off), len); (*off) += len; no += len; *(name + (no++)) = '.'; } } while (c > 0); if (no > 0) *(name + no - 1) = '\0'; /* make sure we didn't allow someone to overflow the name buffer */ assert(no <= ns); return 0; } static int handle_dns(const char *buf, int len) { rfc1035_header_t qh; uint16_t us; off_t offset; char *t; int status; /* The DNS header is 12 bytes long */ if (len < DNS_MSG_HDR_SZ) return 0; memcpy(&us, buf + 0, 2); qh.id = ntohs(us); memcpy(&us, buf + 2, 2); us = ntohs(us); qh.qr = (us >> 15) & 0x01; qh.opcode = (us >> 11) & 0x0F; qh.aa = (us >> 10) & 0x01; qh.tc = (us >> 9) & 0x01; qh.rd = (us >> 8) & 0x01; qh.ra = (us >> 7) & 0x01; qh.z = (us >> 6) & 0x01; qh.ad = (us >> 5) & 0x01; qh.cd = (us >> 4) & 0x01; qh.rcode = us & 0x0F; memcpy(&us, buf + 4, 2); qh.qdcount = ntohs(us); memcpy(&us, buf + 6, 2); qh.ancount = ntohs(us); memcpy(&us, buf + 8, 2); qh.nscount = ntohs(us); memcpy(&us, buf + 10, 2); qh.arcount = ntohs(us); offset = DNS_MSG_HDR_SZ; memset(qh.qname, '\0', MAX_QNAME_SZ); status = rfc1035NameUnpack(buf, len, &offset, qh.qname, MAX_QNAME_SZ); if (status != 0) { INFO ("utils_dns: handle_dns: rfc1035NameUnpack failed " "with status %i.", status); return 0; } if ('\0' == qh.qname[0]) sstrncpy (qh.qname, ".", sizeof (qh.qname)); while ((t = strchr(qh.qname, '\n'))) *t = ' '; while ((t = strchr(qh.qname, '\r'))) *t = ' '; for (t = qh.qname; *t; t++) *t = tolower((int) *t); memcpy(&us, buf + offset, 2); qh.qtype = ntohs(us); memcpy(&us, buf + offset + 2, 2); qh.qclass = ntohs(us); qh.length = (uint16_t) len; /* gather stats */ qtype_counts[qh.qtype]++; qclass_counts[qh.qclass]++; opcode_counts[qh.opcode]++; if (Callback != NULL) Callback (&qh); return 1; } static int handle_udp(const struct udphdr *udp, int len) { char buf[PCAP_SNAPLEN]; if ((ntohs (udp->UDP_DEST) != 53) && (ntohs (udp->UDP_SRC) != 53)) return 0; memcpy(buf, udp + 1, len - sizeof(*udp)); if (0 == handle_dns(buf, len - sizeof(*udp))) return 0; return 1; } #if HAVE_NETINET_IP6_H static int handle_ipv6 (struct ip6_hdr *ipv6, int len) { char buf[PCAP_SNAPLEN]; unsigned int offset; int nexthdr; struct in6_addr c_src_addr; uint16_t payload_len; if (0 > len) return (0); offset = sizeof (struct ip6_hdr); nexthdr = ipv6->ip6_nxt; c_src_addr = ipv6->ip6_src; payload_len = ntohs (ipv6->ip6_plen); if (ignore_list_match (&c_src_addr)) return (0); /* Parse extension headers. This only handles the standard headers, as * defined in RFC 2460, correctly. Fragments are discarded. */ while ((IPPROTO_ROUTING == nexthdr) /* routing header */ || (IPPROTO_HOPOPTS == nexthdr) /* Hop-by-Hop options. */ || (IPPROTO_FRAGMENT == nexthdr) /* fragmentation header. */ || (IPPROTO_DSTOPTS == nexthdr) /* destination options. */ || (IPPROTO_AH == nexthdr) /* destination options. */ || (IPPROTO_ESP == nexthdr)) /* encapsulating security payload. */ { struct ip6_ext ext_hdr; uint16_t ext_hdr_len; /* Catch broken packets */ if ((offset + sizeof (struct ip6_ext)) > (unsigned int)len) return (0); /* Cannot handle fragments. */ if (IPPROTO_FRAGMENT == nexthdr) return (0); memcpy (&ext_hdr, (char *) ipv6 + offset, sizeof (struct ip6_ext)); nexthdr = ext_hdr.ip6e_nxt; ext_hdr_len = (8 * (ntohs (ext_hdr.ip6e_len) + 1)); /* This header is longer than the packets payload.. WTF? */ if (ext_hdr_len > payload_len) return (0); offset += ext_hdr_len; payload_len -= ext_hdr_len; } /* while */ /* Catch broken and empty packets */ if (((offset + payload_len) > (unsigned int)len) || (payload_len == 0) || (payload_len > PCAP_SNAPLEN)) return (0); if (IPPROTO_UDP != nexthdr) return (0); memcpy (buf, (char *) ipv6 + offset, payload_len); if (handle_udp ((struct udphdr *) buf, payload_len) == 0) return (0); return (1); /* Success */ } /* int handle_ipv6 */ /* #endif HAVE_NETINET_IP6_H */ #else /* if !HAVE_NETINET_IP6_H */ static int handle_ipv6 (__attribute__((unused)) void *pkg, __attribute__((unused)) int len) { return (0); } #endif /* !HAVE_NETINET_IP6_H */ static int handle_ip(const struct ip *ip, int len) { char buf[PCAP_SNAPLEN]; int offset = ip->ip_hl << 2; struct in6_addr c_src_addr; struct in6_addr c_dst_addr; if (ip->ip_v == 6) return (handle_ipv6 ((void *) ip, len)); in6_addr_from_buffer (&c_src_addr, &ip->ip_src.s_addr, sizeof (ip->ip_src.s_addr), AF_INET); in6_addr_from_buffer (&c_dst_addr, &ip->ip_dst.s_addr, sizeof (ip->ip_dst.s_addr), AF_INET); if (ignore_list_match (&c_src_addr)) return (0); if (IPPROTO_UDP != ip->ip_p) return 0; memcpy(buf, (void *) ip + offset, len - offset); if (0 == handle_udp((struct udphdr *) buf, len - offset)) return 0; return 1; } #if HAVE_NET_IF_PPP_H static int handle_ppp(const u_char * pkt, int len) { char buf[PCAP_SNAPLEN]; unsigned short us; unsigned short proto; if (len < 2) return 0; if (*pkt == PPP_ADDRESS_VAL && *(pkt + 1) == PPP_CONTROL_VAL) { pkt += 2; /* ACFC not used */ len -= 2; } if (len < 2) return 0; if (*pkt % 2) { proto = *pkt; /* PFC is used */ pkt++; len--; } else { memcpy(&us, pkt, sizeof(us)); proto = ntohs(us); pkt += 2; len -= 2; } if (ETHERTYPE_IP != proto && PPP_IP != proto) return 0; memcpy(buf, pkt, len); return handle_ip((struct ip *) buf, len); } #endif /* HAVE_NET_IF_PPP_H */ static int handle_null(const u_char * pkt, int len) { unsigned int family; memcpy(&family, pkt, sizeof(family)); if (AF_INET != family) return 0; return handle_ip((struct ip *) (pkt + 4), len - 4); } #ifdef DLT_LOOP static int handle_loop(const u_char * pkt, int len) { unsigned int family; memcpy(&family, pkt, sizeof(family)); if (AF_INET != ntohl(family)) return 0; return handle_ip((struct ip *) (pkt + 4), len - 4); } #endif #ifdef DLT_RAW static int handle_raw(const u_char * pkt, int len) { return handle_ip((struct ip *) pkt, len); } #endif static int handle_ether(const u_char * pkt, int len) { char buf[PCAP_SNAPLEN]; struct ether_header *e = (void *) pkt; unsigned short etype = ntohs(e->ether_type); if (len < ETHER_HDR_LEN) return 0; pkt += ETHER_HDR_LEN; len -= ETHER_HDR_LEN; if (ETHERTYPE_8021Q == etype) { etype = ntohs(*(unsigned short *) (pkt + 2)); pkt += 4; len -= 4; } if ((ETHERTYPE_IP != etype) && (ETHERTYPE_IPV6 != etype)) return 0; memcpy(buf, pkt, len); if (ETHERTYPE_IPV6 == etype) return (handle_ipv6 ((void *) buf, len)); else return handle_ip((struct ip *) buf, len); } #ifdef DLT_LINUX_SLL static int handle_linux_sll (const u_char *pkt, int len) { struct sll_header { uint16_t pkt_type; uint16_t dev_type; uint16_t addr_len; uint8_t addr[8]; uint16_t proto_type; } *hdr; uint16_t etype; if ((0 > len) || ((unsigned int)len < sizeof (struct sll_header))) return (0); hdr = (struct sll_header *) pkt; pkt = (u_char *) (hdr + 1); len -= sizeof (struct sll_header); etype = ntohs (hdr->proto_type); if ((ETHERTYPE_IP != etype) && (ETHERTYPE_IPV6 != etype)) return 0; if (ETHERTYPE_IPV6 == etype) return (handle_ipv6 ((void *) pkt, len)); else return handle_ip((struct ip *) pkt, len); } #endif /* DLT_LINUX_SLL */ /* public function */ void handle_pcap(u_char *udata, const struct pcap_pkthdr *hdr, const u_char *pkt) { int status; if (hdr->caplen < ETHER_HDR_LEN) return; switch (pcap_datalink (pcap_obj)) { case DLT_EN10MB: status = handle_ether (pkt, hdr->caplen); break; #if HAVE_NET_IF_PPP_H case DLT_PPP: status = handle_ppp (pkt, hdr->caplen); break; #endif #ifdef DLT_LOOP case DLT_LOOP: status = handle_loop (pkt, hdr->caplen); break; #endif #ifdef DLT_RAW case DLT_RAW: status = handle_raw (pkt, hdr->caplen); break; #endif #ifdef DLT_LINUX_SLL case DLT_LINUX_SLL: status = handle_linux_sll (pkt, hdr->caplen); break; #endif case DLT_NULL: status = handle_null (pkt, hdr->caplen); break; default: ERROR ("handle_pcap: unsupported data link type %d", pcap_datalink(pcap_obj)); status = 0; break; } /* switch (pcap_datalink(pcap_obj)) */ if (0 == status) return; query_count_intvl++; query_count_total++; last_ts = hdr->ts; } #endif /* HAVE_PCAP_H */ const char *qtype_str(int t) { static char buf[32]; switch (t) { #if (defined (__NAMESER)) && (__NAMESER >= 19991001) case ns_t_a: return ("A"); case ns_t_ns: return ("NS"); case ns_t_md: return ("MD"); case ns_t_mf: return ("MF"); case ns_t_cname: return ("CNAME"); case ns_t_soa: return ("SOA"); case ns_t_mb: return ("MB"); case ns_t_mg: return ("MG"); case ns_t_mr: return ("MR"); case ns_t_null: return ("NULL"); case ns_t_wks: return ("WKS"); case ns_t_ptr: return ("PTR"); case ns_t_hinfo: return ("HINFO"); case ns_t_minfo: return ("MINFO"); case ns_t_mx: return ("MX"); case ns_t_txt: return ("TXT"); case ns_t_rp: return ("RP"); case ns_t_afsdb: return ("AFSDB"); case ns_t_x25: return ("X25"); case ns_t_isdn: return ("ISDN"); case ns_t_rt: return ("RT"); case ns_t_nsap: return ("NSAP"); case ns_t_nsap_ptr: return ("NSAP-PTR"); case ns_t_sig: return ("SIG"); case ns_t_key: return ("KEY"); case ns_t_px: return ("PX"); case ns_t_gpos: return ("GPOS"); case ns_t_aaaa: return ("AAAA"); case ns_t_loc: return ("LOC"); case ns_t_nxt: return ("NXT"); case ns_t_eid: return ("EID"); case ns_t_nimloc: return ("NIMLOC"); case ns_t_srv: return ("SRV"); case ns_t_atma: return ("ATMA"); case ns_t_naptr: return ("NAPTR"); case ns_t_kx: return ("KX"); case ns_t_cert: return ("CERT"); case ns_t_a6: return ("A6"); case ns_t_dname: return ("DNAME"); case ns_t_sink: return ("SINK"); case ns_t_opt: return ("OPT"); # if __NAMESER >= 19991006 case ns_t_tsig: return ("TSIG"); # endif case ns_t_ixfr: return ("IXFR"); case ns_t_axfr: return ("AXFR"); case ns_t_mailb: return ("MAILB"); case ns_t_maila: return ("MAILA"); case ns_t_any: return ("ANY"); case ns_t_zxfr: return ("ZXFR"); /* #endif __NAMESER >= 19991006 */ #elif (defined (__BIND)) && (__BIND >= 19950621) case T_A: return ("A"); /* 1 ... */ case T_NS: return ("NS"); case T_MD: return ("MD"); case T_MF: return ("MF"); case T_CNAME: return ("CNAME"); case T_SOA: return ("SOA"); case T_MB: return ("MB"); case T_MG: return ("MG"); case T_MR: return ("MR"); case T_NULL: return ("NULL"); case T_WKS: return ("WKS"); case T_PTR: return ("PTR"); case T_HINFO: return ("HINFO"); case T_MINFO: return ("MINFO"); case T_MX: return ("MX"); case T_TXT: return ("TXT"); case T_RP: return ("RP"); case T_AFSDB: return ("AFSDB"); case T_X25: return ("X25"); case T_ISDN: return ("ISDN"); case T_RT: return ("RT"); case T_NSAP: return ("NSAP"); case T_NSAP_PTR: return ("NSAP_PTR"); case T_SIG: return ("SIG"); case T_KEY: return ("KEY"); case T_PX: return ("PX"); case T_GPOS: return ("GPOS"); case T_AAAA: return ("AAAA"); case T_LOC: return ("LOC"); case T_NXT: return ("NXT"); case T_EID: return ("EID"); case T_NIMLOC: return ("NIMLOC"); case T_SRV: return ("SRV"); case T_ATMA: return ("ATMA"); case T_NAPTR: return ("NAPTR"); /* ... 35 */ #if (__BIND >= 19960801) case T_KX: return ("KX"); /* 36 ... */ case T_CERT: return ("CERT"); case T_A6: return ("A6"); case T_DNAME: return ("DNAME"); case T_SINK: return ("SINK"); case T_OPT: return ("OPT"); case T_APL: return ("APL"); case T_DS: return ("DS"); case T_SSHFP: return ("SSHFP"); case T_RRSIG: return ("RRSIG"); case T_NSEC: return ("NSEC"); case T_DNSKEY: return ("DNSKEY"); /* ... 48 */ case T_TKEY: return ("TKEY"); /* 249 */ #endif /* __BIND >= 19960801 */ case T_TSIG: return ("TSIG"); /* 250 ... */ case T_IXFR: return ("IXFR"); case T_AXFR: return ("AXFR"); case T_MAILB: return ("MAILB"); case T_MAILA: return ("MAILA"); case T_ANY: return ("ANY"); /* ... 255 */ #endif /* __BIND >= 19950621 */ default: ssnprintf (buf, sizeof (buf), "#%i", t); return (buf); }; /* switch (t) */ /* NOTREACHED */ return (NULL); } const char *opcode_str (int o) { static char buf[30]; switch (o) { case 0: return "Query"; break; case 1: return "Iquery"; break; case 2: return "Status"; break; case 4: return "Notify"; break; case 5: return "Update"; break; default: ssnprintf(buf, sizeof (buf), "Opcode%d", o); return buf; } /* NOTREACHED */ } const char *rcode_str (int rcode) { static char buf[32]; switch (rcode) { #if (defined (__NAMESER)) && (__NAMESER >= 19991006) case ns_r_noerror: return ("NOERROR"); case ns_r_formerr: return ("FORMERR"); case ns_r_servfail: return ("SERVFAIL"); case ns_r_nxdomain: return ("NXDOMAIN"); case ns_r_notimpl: return ("NOTIMPL"); case ns_r_refused: return ("REFUSED"); case ns_r_yxdomain: return ("YXDOMAIN"); case ns_r_yxrrset: return ("YXRRSET"); case ns_r_nxrrset: return ("NXRRSET"); case ns_r_notauth: return ("NOTAUTH"); case ns_r_notzone: return ("NOTZONE"); case ns_r_max: return ("MAX"); case ns_r_badsig: return ("BADSIG"); case ns_r_badkey: return ("BADKEY"); case ns_r_badtime: return ("BADTIME"); /* #endif __NAMESER >= 19991006 */ #elif (defined (__BIND)) && (__BIND >= 19950621) case NOERROR: return ("NOERROR"); case FORMERR: return ("FORMERR"); case SERVFAIL: return ("SERVFAIL"); case NXDOMAIN: return ("NXDOMAIN"); case NOTIMP: return ("NOTIMP"); case REFUSED: return ("REFUSED"); #if defined (YXDOMAIN) && defined (NXRRSET) case YXDOMAIN: return ("YXDOMAIN"); case YXRRSET: return ("YXRRSET"); case NXRRSET: return ("NXRRSET"); case NOTAUTH: return ("NOTAUTH"); case NOTZONE: return ("NOTZONE"); #endif /* RFC2136 rcodes */ #endif /* __BIND >= 19950621 */ default: ssnprintf (buf, sizeof (buf), "RCode%i", rcode); return (buf); } /* Never reached */ return (NULL); } /* const char *rcode_str (int rcode) */ #if 0 static int main(int argc, char *argv[]) { char errbuf[PCAP_ERRBUF_SIZE]; int x; struct stat sb; int readfile_state = 0; struct bpf_program fp; port53 = htons(53); SubReport = Sources_report; ignore_addr.s_addr = 0; progname = strdup(strrchr(argv[0], '/') ? strchr(argv[0], '/') + 1 : argv[0]); srandom(time(NULL)); ResetCounters(); while ((x = getopt(argc, argv, "ab:f:i:pst")) != -1) { switch (x) { case 'a': anon_flag = 1; break; case 's': sld_flag = 1; break; case 't': nld_flag = 1; break; case 'p': promisc_flag = 0; break; case 'b': bpf_program_str = strdup(optarg); break; case 'i': ignore_addr.s_addr = inet_addr(optarg); break; case 'f': set_filter(optarg); break; default: usage(); break; } } argc -= optind; argv += optind; if (argc < 1) usage(); device = strdup(argv[0]); if (0 == stat(device, &sb)) readfile_state = 1; if (readfile_state) { pcap_obj = pcap_open_offline(device, errbuf); } else { pcap_obj = pcap_open_live(device, PCAP_SNAPLEN, promisc_flag, 1000, errbuf); } if (NULL == pcap_obj) { fprintf(stderr, "pcap_open_*: %s\n", errbuf); exit(1); } if (0 == isatty(1)) { if (0 == readfile_state) { fprintf(stderr, "Non-interactive mode requires savefile argument\n"); exit(1); } interactive = 0; print_func = printf; } memset(&fp, '\0', sizeof(fp)); x = pcap_compile(pcap_obj, &fp, bpf_program_str, 1, 0); if (x < 0) { fprintf(stderr, "pcap_compile failed\n"); exit(1); } x = pcap_setfilter(pcap_obj, &fp); if (x < 0) { fprintf(stderr, "pcap_setfilter failed\n"); exit(1); } /* * non-blocking call added for Mac OS X bugfix. Sent by Max Horn. * ref http://www.tcpdump.org/lists/workers/2002/09/msg00033.html */ x = pcap_setnonblock(pcap_obj, 1, errbuf); if (x < 0) { fprintf(stderr, "pcap_setnonblock failed: %s\n", errbuf); exit(1); } switch (pcap_datalink(pcap_obj)) { case DLT_EN10MB: handle_datalink = handle_ether; break; #if HAVE_NET_IF_PPP_H case DLT_PPP: handle_datalink = handle_ppp; break; #endif #ifdef DLT_LOOP case DLT_LOOP: handle_datalink = handle_loop; break; #endif #ifdef DLT_RAW case DLT_RAW: handle_datalink = handle_raw; break; #endif case DLT_NULL: handle_datalink = handle_null; break; default: fprintf(stderr, "unsupported data link type %d\n", pcap_datalink(pcap_obj)); return 1; break; } if (interactive) { init_curses(); while (0 == Quit) { if (readfile_state < 2) { /* * On some OSes select() might return 0 even when * there are packets to process. Thus, we always * ignore its return value and just call pcap_dispatch() * anyway. */ if (0 == readfile_state) /* interactive */ pcap_select(pcap_obj, 1, 0); x = pcap_dispatch(pcap_obj, 50, handle_pcap, NULL); } if (0 == x && 1 == readfile_state) { /* block on keyboard until user quits */ readfile_state++; nodelay(w, 0); } keyboard(); cron_pre(); report(); cron_post(); } endwin(); /* klin, Thu Nov 28 08:56:51 2002 */ } else { while (pcap_dispatch(pcap_obj, 50, handle_pcap, NULL)) (void) 0; cron_pre(); Sources_report(); print_func("\n"); Destinatioreport(); print_func("\n"); Qtypes_report(); print_func("\n"); Opcodes_report(); print_func("\n"); Tld_report(); print_func("\n"); Sld_report(); print_func("\n"); Nld_report(); print_func("\n"); SldBySource_report(); } pcap_close(pcap_obj); return 0; } /* static int main(int argc, char *argv[]) */ #endif /* * vim:shiftwidth=4:tabstop=8:softtabstop=4 */ collectd-5.4.0/src/PaxHeaders.11991/collectd-java.50000644037772200116100000000013212204120752017737 xustar000000000000000030 mtime=1376821738.542345393 30 atime=1376821738.550345521 30 ctime=1376821741.974400164 collectd-5.4.0/src/collectd-java.50000644037772200116100000006567512204120752016526 0ustar00octoeng00000000000000.\" Automatically generated by Pod::Man 2.25 (Pod::Simple 3.16) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .ie \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .el \{\ . de IX .. .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "COLLECTD-JAVA 5" .TH COLLECTD-JAVA 5 "2013-08-18" "5.4.0" "collectd" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" collectd\-java \- Documentation of collectd's "java plugin" .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 4 \& LoadPlugin "java" \& \& JVMArg "\-verbose:jni" \& JVMArg "\-Djava.class.path=/opt/collectd/lib/collectd/bindings/java" \& \& LoadPlugin "org.collectd.java.Foobar" \& \& # To be parsed by the plugin \& \& .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" The \fIJava\fR plugin embeds a \fIJava Virtual Machine\fR (\s-1JVM\s0) into \fIcollectd\fR and provides a Java interface to part of collectd's \s-1API\s0. This makes it possible to write additions to the daemon in Java. .PP This plugin is similar in nature to, but shares no code with, the \fIPerl\fR plugin by Sebastian Harl, see \fIcollectd\-perl\fR\|(5) for details. .SH "CONFIGURATION" .IX Header "CONFIGURATION" A short outline of this plugin's configuration can be seen in \*(L"\s-1SYNOPSIS\s0\*(R" above. For a complete list of all configuration options and their semantics please read "Plugin \f(CW\*(C`java\*(C'\fR" in \fIcollectd.conf\fR\|(5). .SH "OVERVIEW" .IX Header "OVERVIEW" When writing additions for collectd in Java, the underlying C base is mostly hidden from you. All complex data types are converted to their Java counterparts before they're passed to your functions. These Java classes reside in the \&\fIorg.collectd.api\fR namespace. .PP The \fIJava\fR plugin will create one object of each class configured with the \&\fBLoadPlugin\fR option. The constructor of this class can then register \*(L"callback methods\*(R", i.\ e. methods that will be called by the daemon when appropriate. .PP The available classes are: .IP "\fBorg.collectd.api.Collectd\fR" 4 .IX Item "org.collectd.api.Collectd" All \s-1API\s0 functions exported to Java are implemented as static functions of this class. See \*(L"\s-1EXPORTED\s0 \s-1API\s0 \s-1FUNCTIONS\s0\*(R" below. .IP "\fBorg.collectd.api.OConfigValue\fR" 4 .IX Item "org.collectd.api.OConfigValue" Corresponds to \f(CW\*(C`oconfig_value_t\*(C'\fR, defined in \fIsrc/liboconfig/oconfig.h\fR. .IP "\fBorg.collectd.api.OConfigItem\fR" 4 .IX Item "org.collectd.api.OConfigItem" Corresponds to \f(CW\*(C`oconfig_item_t\*(C'\fR, defined in \fIsrc/liboconfig/oconfig.h\fR. .IP "\fBorg.collectd.api.DataSource\fR" 4 .IX Item "org.collectd.api.DataSource" Corresponds to \f(CW\*(C`data_source_t\*(C'\fR, defined in \fIsrc/plugin.h\fR. .IP "\fBorg.collectd.api.DataSet\fR" 4 .IX Item "org.collectd.api.DataSet" Corresponds to \f(CW\*(C`data_set_t\*(C'\fR, defined in \fIsrc/plugin.h\fR. .IP "\fBorg.collectd.api.ValueList\fR" 4 .IX Item "org.collectd.api.ValueList" Corresponds to \f(CW\*(C`value_list_t\*(C'\fR, defined in \fIsrc/plugin.h\fR. .IP "\fBorg.collectd.api.Notification\fR" 4 .IX Item "org.collectd.api.Notification" Corresponds to \f(CW\*(C`notification_t\*(C'\fR, defined in \fIsrc/plugin.h\fR. .PP In the remainder of this document, we'll use the short form of these names, for example \fBValueList\fR. In order to be able to use these abbreviated names, you need to \fBimport\fR the classes. .SH "EXPORTED API FUNCTIONS" .IX Header "EXPORTED API FUNCTIONS" All collectd \s-1API\s0 functions that are available to Java plugins are implemented as \fIpublic\ static\fR functions of the \fBCollectd\fR class. This makes calling these functions pretty straight forward. For example, to send an error message to the daemon, you'd do something like this: .PP .Vb 1 \& Collectd.logError ("That wasn\*(Aqt chicken!"); .Ve .PP The following are the currently exported functions. .SS "registerConfig" .IX Subsection "registerConfig" Signature: \fIint\fR \fBregisterConfig\fR (\fIString\fR name, \&\fICollectdConfigInterface\fR object); .PP Registers the \fBconfig\fR function of \fIobject\fR with the daemon. .PP Returns zero upon success and non-zero when an error occurred. .PP See \*(L"config callback\*(R" below. .SS "registerInit" .IX Subsection "registerInit" Signature: \fIint\fR \fBregisterInit\fR (\fIString\fR name, \&\fICollectdInitInterface\fR object); .PP Registers the \fBinit\fR function of \fIobject\fR with the daemon. .PP Returns zero upon success and non-zero when an error occurred. .PP See \*(L"init callback\*(R" below. .SS "registerRead" .IX Subsection "registerRead" Signature: \fIint\fR \fBregisterRead\fR (\fIString\fR name, \&\fICollectdReadInterface\fR object) .PP Registers the \fBread\fR function of \fIobject\fR with the daemon. .PP Returns zero upon success and non-zero when an error occurred. .PP See \*(L"read callback\*(R" below. .SS "registerWrite" .IX Subsection "registerWrite" Signature: \fIint\fR \fBregisterWrite\fR (\fIString\fR name, \&\fICollectdWriteInterface\fR object) .PP Registers the \fBwrite\fR function of \fIobject\fR with the daemon. .PP Returns zero upon success and non-zero when an error occurred. .PP See \*(L"write callback\*(R" below. .SS "registerFlush" .IX Subsection "registerFlush" Signature: \fIint\fR \fBregisterFlush\fR (\fIString\fR name, \&\fICollectdFlushInterface\fR object) .PP Registers the \fBflush\fR function of \fIobject\fR with the daemon. .PP Returns zero upon success and non-zero when an error occurred. .PP See \*(L"flush callback\*(R" below. .SS "registerShutdown" .IX Subsection "registerShutdown" Signature: \fIint\fR \fBregisterShutdown\fR (\fIString\fR name, \&\fICollectdShutdownInterface\fR object); .PP Registers the \fBshutdown\fR function of \fIobject\fR with the daemon. .PP Returns zero upon success and non-zero when an error occurred. .PP See \*(L"shutdown callback\*(R" below. .SS "registerLog" .IX Subsection "registerLog" Signature: \fIint\fR \fBregisterLog\fR (\fIString\fR name, \&\fICollectdLogInterface\fR object); .PP Registers the \fBlog\fR function of \fIobject\fR with the daemon. .PP Returns zero upon success and non-zero when an error occurred. .PP See \*(L"log callback\*(R" below. .SS "registerNotification" .IX Subsection "registerNotification" Signature: \fIint\fR \fBregisterNotification\fR (\fIString\fR name, \&\fICollectdNotificationInterface\fR object); .PP Registers the \fBnotification\fR function of \fIobject\fR with the daemon. .PP Returns zero upon success and non-zero when an error occurred. .PP See \*(L"notification callback\*(R" below. .SS "registerMatch" .IX Subsection "registerMatch" Signature: \fIint\fR \fBregisterMatch\fR (\fIString\fR name, \&\fICollectdMatchFactoryInterface\fR object); .PP Registers the \fBcreateMatch\fR function of \fIobject\fR with the daemon. .PP Returns zero upon success and non-zero when an error occurred. .PP See \*(L"match callback\*(R" below. .SS "registerTarget" .IX Subsection "registerTarget" Signature: \fIint\fR \fBregisterTarget\fR (\fIString\fR name, \&\fICollectdTargetFactoryInterface\fR object); .PP Registers the \fBcreateTarget\fR function of \fIobject\fR with the daemon. .PP Returns zero upon success and non-zero when an error occurred. .PP See \*(L"target callback\*(R" below. .SS "dispatchValues" .IX Subsection "dispatchValues" Signature: \fIint\fR \fBdispatchValues\fR (\fIValueList\fR) .PP Passes the values represented by the \fBValueList\fR object to the \&\f(CW\*(C`plugin_dispatch_values\*(C'\fR function of the daemon. The \*(L"data set\*(R" (or list of \&\*(L"data sources\*(R") associated with the object are ignored, because \&\f(CW\*(C`plugin_dispatch_values\*(C'\fR will automatically lookup the required data set. It is therefore absolutely okay to leave this blank. .PP Returns zero upon success or non-zero upon failure. .SS "getDS" .IX Subsection "getDS" Signature: \fIDataSet\fR \fBgetDS\fR (\fIString\fR) .PP Returns the appropriate \fItype\fR or \fBnull\fR if the type is not defined. .SS "logError" .IX Subsection "logError" Signature: \fIvoid\fR \fBlogError\fR (\fIString\fR) .PP Sends a log message with severity \fB\s-1ERROR\s0\fR to the daemon. .SS "logWarning" .IX Subsection "logWarning" Signature: \fIvoid\fR \fBlogWarning\fR (\fIString\fR) .PP Sends a log message with severity \fB\s-1WARNING\s0\fR to the daemon. .SS "logNotice" .IX Subsection "logNotice" Signature: \fIvoid\fR \fBlogNotice\fR (\fIString\fR) .PP Sends a log message with severity \fB\s-1NOTICE\s0\fR to the daemon. .SS "logInfo" .IX Subsection "logInfo" Signature: \fIvoid\fR \fBlogInfo\fR (\fIString\fR) .PP Sends a log message with severity \fB\s-1INFO\s0\fR to the daemon. .SS "logDebug" .IX Subsection "logDebug" Signature: \fIvoid\fR \fBlogDebug\fR (\fIString\fR) .PP Sends a log message with severity \fB\s-1DEBUG\s0\fR to the daemon. .SH "REGISTERING CALLBACKS" .IX Header "REGISTERING CALLBACKS" When starting up, collectd creates an object of each configured class. The constructor of this class should then register \*(L"callbacks\*(R" with the daemon, using the appropriate static functions in \fBCollectd\fR, see \*(L"\s-1EXPORTED\s0 \s-1API\s0 \s-1FUNCTIONS\s0\*(R" above. To register a callback, the object being passed to one of the register functions must implement an appropriate interface, which are all in the \fBorg.collectd.api\fR namespace. .PP A constructor may register any number of these callbacks, even none. An object without callback methods is never actively called by collectd, but may still call the exported \s-1API\s0 functions. One could, for example, start a new thread in the constructor and dispatch (submit to the daemon) values asynchronously, whenever one is available. .PP Each callback method is now explained in more detail: .SS "config callback" .IX Subsection "config callback" Interface: \fBorg.collectd.api.CollectdConfigInterface\fR .PP Signature: \fIint\fR \fBconfig\fR (\fIOConfigItem\fR ci) .PP This method is passed a \fBOConfigItem\fR object, if both, method and configuration, are available. \fBOConfigItem\fR is the root of a tree representing the configuration for this plugin. The root itself is the representation of the \&\fB\fR block, so in next to all cases the children of the root are the first interesting objects. .PP To signal success, this method has to return zero. Anything else will be considered an error condition and the plugin will be disabled entirely. .PP See \*(L"registerConfig\*(R" above. .SS "init callback" .IX Subsection "init callback" Interface: \fBorg.collectd.api.CollectdInitInterface\fR .PP Signature: \fIint\fR \fBinit\fR () .PP This method is called after the configuration has been handled. It is supposed to set up the plugin. e.\ g. start threads, open connections, or check if can do anything useful at all. .PP To signal success, this method has to return zero. Anything else will be considered an error condition and the plugin will be disabled entirely. .PP See \*(L"registerInit\*(R" above. .SS "read callback" .IX Subsection "read callback" Interface: \fBorg.collectd.api.CollectdReadInterface\fR .PP Signature: \fIint\fR \fBread\fR () .PP This method is called periodically and is supposed to gather statistics in whatever fashion. These statistics are represented as a \fBValueList\fR object and sent to the daemon using dispatchValues. .PP To signal success, this method has to return zero. Anything else will be considered an error condition and cause an appropriate message to be logged. Currently, returning non-zero does not have any other effects. In particular, Java \*(L"read\*(R"\-methods are not suspended for increasing intervals like C \&\*(L"read\*(R"\-functions. .PP See \*(L"registerRead\*(R" above. .SS "write callback" .IX Subsection "write callback" Interface: \fBorg.collectd.api.CollectdWriteInterface\fR .PP Signature: \fIint\fR \fBwrite\fR (\fIValueList\fR vl) .PP This method is called whenever a value is dispatched to the daemon. The corresponding C \*(L"write\*(R"\-functions are passed a \f(CW\*(C`data_set_t\*(C'\fR, so they can decide which values are absolute values (gauge) and which are counter values. To get the corresponding \f(CW\*(C`List\*(C'\fR, call the \fBgetDataSource\fR method of the \fBValueList\fR object. .PP To signal success, this method has to return zero. Anything else will be considered an error condition and cause an appropriate message to be logged. .PP See \*(L"registerWrite\*(R" above. .SS "flush callback" .IX Subsection "flush callback" Interface: \fBorg.collectd.api.CollectdFlushInterface\fR .PP Signature: \fIint\fR \fBflush\fR (\fIint\fR timeout, \fIString\fR identifier) .PP This method is called when the daemon received a flush command. This can either be done using the \f(CW\*(C`USR1\*(C'\fR signal (see \fIcollectd\fR\|(1)) or using the \fIunixsock\fR plugin (see \fIcollectd\-unixsock\fR\|(5)). .PP If \fItimeout\fR is greater than zero, only values older than this number of seconds should be flushed. To signal that all values should be flushed regardless of age, this argument is set to a negative number. .PP The \fIidentifier\fR specifies which value should be flushed. If it is not possible to flush one specific value, flush all values. To signal that all values should be flushed, this argument is set to \fInull\fR. .PP To signal success, this method has to return zero. Anything else will be considered an error condition and cause an appropriate message to be logged. .PP See \*(L"registerFlush\*(R" above. .SS "shutdown callback" .IX Subsection "shutdown callback" Interface: \fBorg.collectd.api.CollectdShutdownInterface\fR .PP Signature: \fIint\fR \fBshutdown\fR () .PP This method is called when the daemon is shutting down. You should not rely on the destructor to clean up behind the object but use this function instead. .PP To signal success, this method has to return zero. Anything else will be considered an error condition and cause an appropriate message to be logged. .PP See \*(L"registerShutdown\*(R" above. .SS "log callback" .IX Subsection "log callback" Interface: \fBorg.collectd.api.CollectdLogInterface\fR .PP Signature: \fIvoid\fR \fBlog\fR (\fIint\fR severity, \fIString\fR message) .PP This callback can be used to receive log messages from the daemon. .PP The argument \fIseverity\fR is one of: .IP "\(bu" 4 org.collectd.api.Collectd.LOG_ERR .IP "\(bu" 4 org.collectd.api.Collectd.LOG_WARNING .IP "\(bu" 4 org.collectd.api.Collectd.LOG_NOTICE .IP "\(bu" 4 org.collectd.api.Collectd.LOG_INFO .IP "\(bu" 4 org.collectd.api.Collectd.LOG_DEBUG .PP The function does not return any value. .PP See \*(L"registerLog\*(R" above. .SS "notification callback" .IX Subsection "notification callback" Interface: \fBorg.collectd.api.CollectdNotificationInterface\fR .PP Signature: \fIint\fR \fBnotification\fR (\fINotification\fR n) .PP This callback can be used to receive notifications from the daemon. .PP To signal success, this method has to return zero. Anything else will be considered an error condition and cause an appropriate message to be logged. .PP See \*(L"registerNotification\*(R" above. .SS "match callback" .IX Subsection "match callback" The match (and target, see \*(L"target callback\*(R" below) callbacks work a bit different from the other callbacks above: You don't register a match callback with the daemon directly, but you register a function which, when called, creates an appropriate object. The object creating the \*(L"match\*(R" objects is called \*(L"match factory\*(R". .PP See \*(L"registerMatch\*(R" above. .PP \fIFactory object\fR .IX Subsection "Factory object" .PP Interface: \fBorg.collectd.api.CollectdMatchFactoryInterface\fR .PP Signature: \fICollectdMatchInterface\fR \fBcreateMatch\fR (\fIOConfigItem\fR ci); .PP Called by the daemon to create \*(L"match\*(R" objects. .PP Returns: A new object which implements the \fBCollectdMatchInterface\fR interface. .PP \fIMatch object\fR .IX Subsection "Match object" .PP Interface: \fBorg.collectd.api.CollectdMatchInterface\fR .PP Signature: \fIint\fR \fBmatch\fR (\fIDataSet\fR ds, \fIValueList\fR vl); .PP Called when processing a chain to determine whether or not a \fIValueList\fR matches. How values are matches is up to the implementing class. .PP Has to return one of: .IP "\(bu" 4 \&\fBCollectd.FC_MATCH_NO_MATCH\fR .IP "\(bu" 4 \&\fBCollectd.FC_MATCH_MATCHES\fR .SS "target callback" .IX Subsection "target callback" The target (and match, see \*(L"match callback\*(R" above) callbacks work a bit different from the other callbacks above: You don't register a target callback with the daemon directly, but you register a function which, when called, creates an appropriate object. The object creating the \*(L"target\*(R" objects is called \*(L"target factory\*(R". .PP See \*(L"registerTarget\*(R" above. .PP \fIFactory object\fR .IX Subsection "Factory object" .PP Interface: \fBorg.collectd.api.CollectdTargetFactoryInterface\fR .PP Signature: \fICollectdTargetInterface\fR \fBcreateTarget\fR (\fIOConfigItem\fR ci); .PP Called by the daemon to create \*(L"target\*(R" objects. .PP Returns: A new object which implements the \fBCollectdTargetInterface\fR interface. .PP \fITarget object\fR .IX Subsection "Target object" .PP Interface: \fBorg.collectd.api.CollectdTargetInterface\fR .PP Signature: \fIint\fR \fBinvoke\fR (\fIDataSet\fR ds, \fIValueList\fR vl); .PP Called when processing a chain to perform some action. The action performed is up to the implementing class. .PP Has to return one of: .IP "\(bu" 4 \&\fBCollectd.FC_TARGET_CONTINUE\fR .IP "\(bu" 4 \&\fBCollectd.FC_TARGET_STOP\fR .IP "\(bu" 4 \&\fBCollectd.FC_TARGET_RETURN\fR .SH "EXAMPLE" .IX Header "EXAMPLE" This short example demonstrates how to register a read callback with the daemon: .PP .Vb 2 \& import org.collectd.api.Collectd; \& import org.collectd.api.ValueList; \& \& import org.collectd.api.CollectdReadInterface; \& \& public class Foobar implements CollectdReadInterface \& { \& public Foobar () \& { \& Collectd.registerRead ("Foobar", this); \& } \& \& public int read () \& { \& ValueList vl; \& \& /* Do something... */ \& \& Collectd.dispatchValues (vl); \& } \& } .Ve .SH "PLUGINS" .IX Header "PLUGINS" The following plugins are implemented in \fIJava\fR. Both, the \fBLoadPlugin\fR option and the \fBPlugin\fR block must be inside the \&\fB\fR block (see above). .SS "GenericJMX plugin" .IX Subsection "GenericJMX plugin" The GenericJMX plugin reads \fIManaged Beans\fR (MBeans) from an \fIMBeanServer\fR using \s-1JMX\s0. \s-1JMX\s0 is a generic framework to provide and query various management information. The interface is used by Java processes to provide internal statistics as well as by the \fIJava Virtual Machine\fR (\s-1JVM\s0) to provide information about the memory used, threads and so on. .PP The configuration of the \fIGenericJMX plugin\fR consists of two blocks: \fIMBean\fR blocks that define a mapping of MBean attributes to the XtypesX used by \&\fIcollectd\fR, and \fIConnection\fR blocks which define the parameters needed to connect to an \fIMBeanServer\fR and what data to collect. The configuration of the \&\fI\s-1SNMP\s0 plugin\fR is similar in nature, in case you know it. .PP \fIMBean blocks\fR .IX Subsection "MBean blocks" .PP \&\fIMBean\fR blocks specify what data is retrieved from \fIMBeans\fR and how that data is mapped on the \fIcollectd\fR data types. The block requires one string argument, a name. This name is used in the \fIConnection\fR blocks (see below) to refer to a specific \fIMBean\fR block. Therefore, the names must be unique. .PP The following options are recognized within \fIMBean\fR blocks: .IP "\fBObjectName\fR \fIpattern\fR" 4 .IX Item "ObjectName pattern" Sets the pattern which is used to retrieve \fIMBeans\fR from the \fIMBeanServer\fR. If more than one MBean is returned you should use the \fBInstanceFrom\fR option (see below) to make the identifiers unique. .Sp See also: .IP "\fBInstancePrefix\fR \fIprefix\fR" 4 .IX Item "InstancePrefix prefix" Prefixes the generated \fIplugin instance\fR with \fIprefix\fR. \fI(optional)\fR .IP "\fBInstanceFrom\fR \fIproperty\fR" 4 .IX Item "InstanceFrom property" The \fIobject names\fR used by \s-1JMX\s0 to identify \fIMBeans\fR include so called \&\fIXpropertiesX\fR which are basically key-value-pairs. If the given object name is not unique and multiple MBeans are returned, the values of those properties usually differ. You can use this option to build the \fIplugin instance\fR from the appropriate property values. This option is optional and may be repeated to generate the \fIplugin instance\fR from multiple property values. .IP "\fB\fR blocks" 4 .IX Item " blocks" The \fIvalue\fR blocks map one or more attributes of an \fIMBean\fR to a value list in \fIcollectd\fR. There must be at least one Value block within each \fIMBean\fR block. .RS 4 .IP "\fBType\fR type" 4 .IX Item "Type type" Sets the data set used within \fIcollectd\fR to handle the values of the \fIMBean\fR attribute. .IP "\fBInstancePrefix\fR \fIprefix\fR" 4 .IX Item "InstancePrefix prefix" Works like the option of the same name directly beneath the \fIMBean\fR block, but sets the type instance instead. \fI(optional)\fR .IP "\fBInstanceFrom\fR \fIprefix\fR" 4 .IX Item "InstanceFrom prefix" Works like the option of the same name directly beneath the \fIMBean\fR block, but sets the type instance instead. \fI(optional)\fR .IP "\fBTable\fR \fBtrue\fR|\fBfalse\fR" 4 .IX Item "Table true|false" Set this to true if the returned attribute is a \fIcomposite type\fR. If set to true, the keys within the \fIcomposite type\fR is appended to the \&\fItype instance\fR. .IP "\fBAttribute\fR \fIpath\fR" 4 .IX Item "Attribute path" Sets the name of the attribute from which to read the value. You can access the keys of composite types by using a dot to concatenate the key name to the attribute name. For example: Xattrib0.key42X. If \fBTable\fR is set to \fBtrue\fR \&\fIpath\fR must point to a \fIcomposite type\fR, otherwise it must point to a numeric type. .RE .RS 4 .RE .PP \fIConnection blocks\fR .IX Subsection "Connection blocks" .PP Connection blocks specify \fIhow\fR to connect to an \fIMBeanServer\fR and what data to retrieve. The following configuration options are available: .IP "\fBHost\fR \fIname\fR" 4 .IX Item "Host name" Host name used when dispatching the values to \fIcollectd\fR. The option sets this field only, it is \fInot\fR used to connect to anything and doesn't need to be a real, resolvable name. .IP "\fBServiceURL\fR \fI\s-1URL\s0\fR" 4 .IX Item "ServiceURL URL" Specifies how the \fIMBeanServer\fR can be reached. Any string accepted by the \&\fIJMXServiceURL\fR is valid. .Sp See also: .IP "\fBUser\fR \fIname\fR" 4 .IX Item "User name" Use \fIname\fR to authenticate to the server. If not configured, XmonitorRoleX will be used. .IP "\fBPassword\fR \fIpassword\fR" 4 .IX Item "Password password" Use \fIpassword\fR to authenticate to the server. If not given, unauthenticated access is used. .IP "\fBInstancePrefix\fR \fIprefix\fR" 4 .IX Item "InstancePrefix prefix" Prefixes the generated \fIplugin instance\fR with \fIprefix\fR. If a second \&\fIInstancePrefix\fR is specified in a referenced \fIMBean\fR block, the prefix specified in the \fIConnection\fR block will appear at the beginning of the \&\fIplugin instance\fR, the prefix specified in the \fIMBean\fR block will be appended to it. .IP "\fBCollect\fR \fImbean_block_name\fR" 4 .IX Item "Collect mbean_block_name" Configures which of the \fIMBean\fR blocks to use with this connection. May be repeated to collect multiple \fIMBeans\fR from this server. .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIcollectd\fR\|(1), \&\fIcollectd.conf\fR\|(5), \&\fIcollectd\-perl\fR\|(5), \&\fItypes.db\fR\|(5) .SH "AUTHOR" .IX Header "AUTHOR" Florian Forster collectd-5.4.0/src/PaxHeaders.11991/unixsock.c0000644037772200116100000000013212204120331017141 xustar000000000000000030 mtime=1376821465.085973632 30 atime=1376821477.226168058 30 ctime=1376821741.974400164 collectd-5.4.0/src/unixsock.c0000644037772200116100000002521012204120331015705 0ustar00octoeng00000000000000/** * collectd - src/unixsock.c * Copyright (C) 2007,2008 Florian octo 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 * * Author: * Florian octo Forster **/ #include "collectd.h" #include "common.h" #include "plugin.h" #include "configfile.h" #include "utils_cmd_flush.h" #include "utils_cmd_getval.h" #include "utils_cmd_listval.h" #include "utils_cmd_putval.h" #include "utils_cmd_putnotif.h" /* Folks without pthread will need to disable this plugin. */ #include #include #include #include #include #ifndef UNIX_PATH_MAX # define UNIX_PATH_MAX sizeof (((struct sockaddr_un *)0)->sun_path) #endif #define US_DEFAULT_PATH LOCALSTATEDIR"/run/"PACKAGE_NAME"-unixsock" /* * Private variables */ /* valid configuration file keys */ static const char *config_keys[] = { "SocketFile", "SocketGroup", "SocketPerms", "DeleteSocket" }; static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); static int loop = 0; /* socket configuration */ static int sock_fd = -1; static char *sock_file = NULL; static char *sock_group = NULL; static int sock_perms = S_IRWXU | S_IRWXG; static _Bool delete_socket = 0; static pthread_t listen_thread = (pthread_t) 0; /* * Functions */ static int us_open_socket (void) { struct sockaddr_un sa; int status; sock_fd = socket (PF_UNIX, SOCK_STREAM, 0); if (sock_fd < 0) { char errbuf[1024]; ERROR ("unixsock plugin: socket failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } memset (&sa, '\0', sizeof (sa)); sa.sun_family = AF_UNIX; sstrncpy (sa.sun_path, (sock_file != NULL) ? sock_file : US_DEFAULT_PATH, sizeof (sa.sun_path)); DEBUG ("unixsock plugin: socket path = %s", sa.sun_path); if (delete_socket) { errno = 0; status = unlink (sa.sun_path); if ((status != 0) && (errno != ENOENT)) { char errbuf[1024]; WARNING ("unixsock plugin: Deleting socket file \"%s\" failed: %s", sa.sun_path, sstrerror (errno, errbuf, sizeof (errbuf))); } else if (status == 0) { INFO ("unixsock plugin: Successfully deleted socket file \"%s\".", sa.sun_path); } } status = bind (sock_fd, (struct sockaddr *) &sa, sizeof (sa)); if (status != 0) { char errbuf[1024]; sstrerror (errno, errbuf, sizeof (errbuf)); ERROR ("unixsock plugin: bind failed: %s", errbuf); close (sock_fd); sock_fd = -1; return (-1); } chmod (sa.sun_path, sock_perms); status = listen (sock_fd, 8); if (status != 0) { char errbuf[1024]; ERROR ("unixsock plugin: listen failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); close (sock_fd); sock_fd = -1; return (-1); } do { char *grpname; struct group *g; struct group sg; char grbuf[2048]; grpname = (sock_group != NULL) ? sock_group : COLLECTD_GRP_NAME; g = NULL; status = getgrnam_r (grpname, &sg, grbuf, sizeof (grbuf), &g); if (status != 0) { char errbuf[1024]; WARNING ("unixsock plugin: getgrnam_r (%s) failed: %s", grpname, sstrerror (errno, errbuf, sizeof (errbuf))); break; } if (g == NULL) { WARNING ("unixsock plugin: No such group: `%s'", grpname); break; } if (chown ((sock_file != NULL) ? sock_file : US_DEFAULT_PATH, (uid_t) -1, g->gr_gid) != 0) { char errbuf[1024]; WARNING ("unixsock plugin: chown (%s, -1, %i) failed: %s", (sock_file != NULL) ? sock_file : US_DEFAULT_PATH, (int) g->gr_gid, sstrerror (errno, errbuf, sizeof (errbuf))); } } while (0); return (0); } /* int us_open_socket */ static void *us_handle_client (void *arg) { int fdin; int fdout; FILE *fhin, *fhout; fdin = *((int *) arg); free (arg); arg = NULL; DEBUG ("unixsock plugin: us_handle_client: Reading from fd #%i", fdin); fdout = dup (fdin); if (fdout < 0) { char errbuf[1024]; ERROR ("unixsock plugin: dup failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); close (fdin); pthread_exit ((void *) 1); } fhin = fdopen (fdin, "r"); if (fhin == NULL) { char errbuf[1024]; ERROR ("unixsock plugin: fdopen failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); close (fdin); close (fdout); pthread_exit ((void *) 1); return ((void *) 1); } fhout = fdopen (fdout, "w"); if (fhout == NULL) { char errbuf[1024]; ERROR ("unixsock plugin: fdopen failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); fclose (fhin); /* this closes fdin as well */ close (fdout); pthread_exit ((void *) 1); return ((void *) 1); } /* change output buffer to line buffered mode */ if (setvbuf (fhout, NULL, _IOLBF, 0) != 0) { char errbuf[1024]; ERROR ("unixsock plugin: setvbuf failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); fclose (fhin); fclose (fhout); pthread_exit ((void *) 1); return ((void *) 0); } while (42) { char buffer[1024]; char buffer_copy[1024]; char *fields[128]; int fields_num; int len; errno = 0; if (fgets (buffer, sizeof (buffer), fhin) == NULL) { if ((errno == EINTR) || (errno == EAGAIN)) continue; if (errno != 0) { char errbuf[1024]; WARNING ("unixsock plugin: failed to read from socket #%i: %s", fileno (fhin), sstrerror (errno, errbuf, sizeof (errbuf))); } break; } len = strlen (buffer); while ((len > 0) && ((buffer[len - 1] == '\n') || (buffer[len - 1] == '\r'))) buffer[--len] = '\0'; if (len == 0) continue; sstrncpy (buffer_copy, buffer, sizeof (buffer_copy)); fields_num = strsplit (buffer_copy, fields, sizeof (fields) / sizeof (fields[0])); if (fields_num < 1) { fprintf (fhout, "-1 Internal error\n"); fclose (fhin); fclose (fhout); pthread_exit ((void *) 1); return ((void *) 1); } if (strcasecmp (fields[0], "getval") == 0) { handle_getval (fhout, buffer); } else if (strcasecmp (fields[0], "putval") == 0) { handle_putval (fhout, buffer); } else if (strcasecmp (fields[0], "listval") == 0) { handle_listval (fhout, buffer); } else if (strcasecmp (fields[0], "putnotif") == 0) { handle_putnotif (fhout, buffer); } else if (strcasecmp (fields[0], "flush") == 0) { handle_flush (fhout, buffer); } else { if (fprintf (fhout, "-1 Unknown command: %s\n", fields[0]) < 0) { char errbuf[1024]; WARNING ("unixsock plugin: failed to write to socket #%i: %s", fileno (fhout), sstrerror (errno, errbuf, sizeof (errbuf))); break; } } } /* while (fgets) */ DEBUG ("unixsock plugin: us_handle_client: Exiting.."); fclose (fhin); fclose (fhout); pthread_exit ((void *) 0); return ((void *) 0); } /* void *us_handle_client */ static void *us_server_thread (void __attribute__((unused)) *arg) { int status; int *remote_fd; pthread_t th; pthread_attr_t th_attr; pthread_attr_init (&th_attr); pthread_attr_setdetachstate (&th_attr, PTHREAD_CREATE_DETACHED); if (us_open_socket () != 0) pthread_exit ((void *) 1); while (loop != 0) { DEBUG ("unixsock plugin: Calling accept.."); status = accept (sock_fd, NULL, NULL); if (status < 0) { char errbuf[1024]; if (errno == EINTR) continue; ERROR ("unixsock plugin: accept failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); close (sock_fd); sock_fd = -1; pthread_attr_destroy (&th_attr); pthread_exit ((void *) 1); } remote_fd = (int *) malloc (sizeof (int)); if (remote_fd == NULL) { char errbuf[1024]; WARNING ("unixsock plugin: malloc failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); close (status); continue; } *remote_fd = status; DEBUG ("Spawning child to handle connection on fd #%i", *remote_fd); status = plugin_thread_create (&th, &th_attr, us_handle_client, (void *) remote_fd); if (status != 0) { char errbuf[1024]; WARNING ("unixsock plugin: pthread_create failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); close (*remote_fd); free (remote_fd); continue; } } /* while (loop) */ close (sock_fd); sock_fd = -1; pthread_attr_destroy (&th_attr); status = unlink ((sock_file != NULL) ? sock_file : US_DEFAULT_PATH); if (status != 0) { char errbuf[1024]; NOTICE ("unixsock plugin: unlink (%s) failed: %s", (sock_file != NULL) ? sock_file : US_DEFAULT_PATH, sstrerror (errno, errbuf, sizeof (errbuf))); } return ((void *) 0); } /* void *us_server_thread */ static int us_config (const char *key, const char *val) { if (strcasecmp (key, "SocketFile") == 0) { char *new_sock_file = strdup (val); if (new_sock_file == NULL) return (1); sfree (sock_file); sock_file = new_sock_file; } else if (strcasecmp (key, "SocketGroup") == 0) { char *new_sock_group = strdup (val); if (new_sock_group == NULL) return (1); sfree (sock_group); sock_group = new_sock_group; } else if (strcasecmp (key, "SocketPerms") == 0) { sock_perms = (int) strtol (val, NULL, 8); } else if (strcasecmp (key, "DeleteSocket") == 0) { if (IS_TRUE (val)) delete_socket = 1; else delete_socket = 0; } else { return (-1); } return (0); } /* int us_config */ static int us_init (void) { static int have_init = 0; int status; /* Initialize only once. */ if (have_init != 0) return (0); have_init = 1; loop = 1; status = plugin_thread_create (&listen_thread, NULL, us_server_thread, NULL); if (status != 0) { char errbuf[1024]; ERROR ("unixsock plugin: pthread_create failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } return (0); } /* int us_init */ static int us_shutdown (void) { void *ret; loop = 0; if (listen_thread != (pthread_t) 0) { pthread_kill (listen_thread, SIGTERM); pthread_join (listen_thread, &ret); listen_thread = (pthread_t) 0; } plugin_unregister_init ("unixsock"); plugin_unregister_shutdown ("unixsock"); return (0); } /* int us_shutdown */ void module_register (void) { plugin_register_config ("unixsock", us_config, config_keys, config_keys_num); plugin_register_init ("unixsock", us_init); plugin_register_shutdown ("unixsock", us_shutdown); } /* void module_register (void) */ /* vim: set sw=4 ts=4 sts=4 tw=78 : */ collectd-5.4.0/src/PaxHeaders.11991/users.c0000644037772200116100000000013212204120331016437 xustar000000000000000030 mtime=1376821465.085973632 30 atime=1376821477.226168058 30 ctime=1376821741.974400164 collectd-5.4.0/src/users.c0000644037772200116100000000564712204120331015217 0ustar00octoeng00000000000000/** * collectd - src/users.c * Copyright (C) 2005-2007 Sebastian Harl * Copyright (C) 2005 Niki W. Waibel * Copyright (C) 2005-2007 Florian octo Forster * Copyright (C) 2008 Oleg King * * 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: * Sebastian Harl * Niki W. Waibel * Florian octo Forster * Oleg King **/ #include "collectd.h" #include "common.h" #include "plugin.h" #if HAVE_STATGRAB_H # include #endif /* HAVE_STATGRAB_H */ #if HAVE_UTMPX_H # include /* #endif HAVE_UTMPX_H */ #elif HAVE_UTMP_H # include /* #endif HAVE_UTMP_H */ #else # error "No applicable input method." #endif static void users_submit (gauge_t value) { value_t values[1]; value_list_t vl = VALUE_LIST_INIT; values[0].gauge = value; vl.values = values; vl.values_len = 1; sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "users", sizeof (vl.plugin)); sstrncpy (vl.type, "users", sizeof (vl.plugin)); plugin_dispatch_values (&vl); } /* void users_submit */ static int users_read (void) { #if HAVE_GETUTXENT unsigned int users = 0; struct utmpx *entry = NULL; /* according to the *utent(3) man page none of the functions sets errno in case of an error, so we cannot do any error-checking here */ setutxent(); while (NULL != (entry = getutxent())) { if (USER_PROCESS == entry->ut_type) { ++users; } } endutxent(); users_submit (users); /* #endif HAVE_GETUTXENT */ #elif HAVE_GETUTENT unsigned int users = 0; struct utmp *entry = NULL; /* according to the *utent(3) man page none of the functions sets errno in case of an error, so we cannot do any error-checking here */ setutent(); while (NULL != (entry = getutent())) { if (USER_PROCESS == entry->ut_type) { ++users; } } endutent(); users_submit (users); /* #endif HAVE_GETUTENT */ #elif HAVE_LIBSTATGRAB sg_user_stats *us; us = sg_get_user_stats (); if (us == NULL) return (-1); users_submit ((gauge_t) us->num_entries); /* #endif HAVE_LIBSTATGRAB */ #else # error "No applicable input method." #endif return (0); } /* int users_read */ void module_register (void) { plugin_register_read ("users", users_read); } /* void module_register(void) */ collectd-5.4.0/src/PaxHeaders.11991/utils_vl_lookup_test.c0000644037772200116100000000013212204120331021567 xustar000000000000000030 mtime=1376821465.089973696 30 atime=1376821477.230168122 30 ctime=1376821741.978400227 collectd-5.4.0/src/utils_vl_lookup_test.c0000644037772200116100000002007412204120331020336 0ustar00octoeng00000000000000/** * collectd - src/utils_vl_lookup_test.c * Copyright (C) 2012 Florian Forster * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Authors: * Florian Forster **/ #include "collectd.h" #include "utils_vl_lookup.h" static _Bool expect_new_obj = 0; static _Bool have_new_obj = 0; static identifier_t last_class_ident; static identifier_t last_obj_ident; static data_source_t dsrc_test = { "value", DS_TYPE_DERIVE, 0.0, NAN }; static data_set_t const ds_test = { "test", 1, &dsrc_test }; static data_source_t dsrc_unknown = { "value", DS_TYPE_DERIVE, 0.0, NAN }; static data_set_t const ds_unknown = { "unknown", 1, &dsrc_unknown }; static int lookup_obj_callback (data_set_t const *ds, value_list_t const *vl, void *user_class, void *user_obj) { identifier_t *class = user_class; identifier_t *obj = user_obj; assert (expect_new_obj == have_new_obj); memcpy (&last_class_ident, class, sizeof (last_class_ident)); memcpy (&last_obj_ident, obj, sizeof (last_obj_ident)); if (strcmp (obj->plugin_instance, "failure") == 0) return (-1); return (0); } static void *lookup_class_callback (data_set_t const *ds, value_list_t const *vl, void *user_class) { identifier_t *class = user_class; identifier_t *obj; assert (expect_new_obj); memcpy (&last_class_ident, class, sizeof (last_class_ident)); obj = malloc (sizeof (*obj)); strncpy (obj->host, vl->host, sizeof (obj->host)); strncpy (obj->plugin, vl->plugin, sizeof (obj->plugin)); strncpy (obj->plugin_instance, vl->plugin_instance, sizeof (obj->plugin_instance)); strncpy (obj->type, vl->type, sizeof (obj->type)); strncpy (obj->type_instance, vl->type_instance, sizeof (obj->type_instance)); have_new_obj = 1; return ((void *) obj); } static void checked_lookup_add (lookup_t *obj, /* {{{ */ char const *host, char const *plugin, char const *plugin_instance, char const *type, char const *type_instance, unsigned int group_by) { identifier_t ident; void *user_class; int status; memset (&ident, 0, sizeof (ident)); strncpy (ident.host, host, sizeof (ident.host)); strncpy (ident.plugin, plugin, sizeof (ident.plugin)); strncpy (ident.plugin_instance, plugin_instance, sizeof (ident.plugin_instance)); strncpy (ident.type, type, sizeof (ident.type)); strncpy (ident.type_instance, type_instance, sizeof (ident.type_instance)); user_class = malloc (sizeof (ident)); memmove (user_class, &ident, sizeof (ident)); status = lookup_add (obj, &ident, group_by, user_class); assert (status == 0); } /* }}} void test_add */ static int checked_lookup_search (lookup_t *obj, char const *host, char const *plugin, char const *plugin_instance, char const *type, char const *type_instance, _Bool expect_new) { int status; value_list_t vl = VALUE_LIST_STATIC; data_set_t const *ds = &ds_unknown; strncpy (vl.host, host, sizeof (vl.host)); strncpy (vl.plugin, plugin, sizeof (vl.plugin)); strncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance)); strncpy (vl.type, type, sizeof (vl.type)); strncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); if (strcmp (vl.type, "test") == 0) ds = &ds_test; expect_new_obj = expect_new; have_new_obj = 0; status = lookup_search (obj, ds, &vl); return (status); } static lookup_t *checked_lookup_create (void) { lookup_t *obj = lookup_create ( lookup_class_callback, lookup_obj_callback, (void *) free, (void *) free); assert (obj != NULL); return (obj); } static void testcase0 (void) { lookup_t *obj = checked_lookup_create (); checked_lookup_add (obj, "/.*/", "test", "", "test", "/.*/", LU_GROUP_BY_HOST); checked_lookup_search (obj, "host0", "test", "", "test", "0", /* expect new = */ 1); checked_lookup_search (obj, "host0", "test", "", "test", "1", /* expect new = */ 0); checked_lookup_search (obj, "host1", "test", "", "test", "0", /* expect new = */ 1); checked_lookup_search (obj, "host1", "test", "", "test", "1", /* expect new = */ 0); lookup_destroy (obj); } static void testcase1 (void) { lookup_t *obj = checked_lookup_create (); checked_lookup_add (obj, "/.*/", "/.*/", "/.*/", "test", "/.*/", LU_GROUP_BY_HOST); checked_lookup_search (obj, "host0", "plugin0", "", "test", "0", /* expect new = */ 1); checked_lookup_search (obj, "host0", "plugin0", "", "test", "1", /* expect new = */ 0); checked_lookup_search (obj, "host0", "plugin1", "", "test", "0", /* expect new = */ 0); checked_lookup_search (obj, "host0", "plugin1", "", "test", "1", /* expect new = */ 0); checked_lookup_search (obj, "host1", "plugin0", "", "test", "0", /* expect new = */ 1); checked_lookup_search (obj, "host1", "plugin0", "", "test", "1", /* expect new = */ 0); checked_lookup_search (obj, "host1", "plugin1", "", "test", "0", /* expect new = */ 0); checked_lookup_search (obj, "host1", "plugin1", "", "test", "1", /* expect new = */ 0); lookup_destroy (obj); } static void testcase2 (void) { lookup_t *obj = checked_lookup_create (); int status; checked_lookup_add (obj, "/.*/", "plugin0", "", "test", "/.*/", LU_GROUP_BY_HOST); checked_lookup_add (obj, "/.*/", "/.*/", "", "test", "ti0", LU_GROUP_BY_HOST); status = checked_lookup_search (obj, "host0", "plugin1", "", "test", "", /* expect new = */ 0); assert (status == 0); status = checked_lookup_search (obj, "host0", "plugin0", "", "test", "", /* expect new = */ 1); assert (status == 1); status = checked_lookup_search (obj, "host0", "plugin1", "", "test", "ti0", /* expect new = */ 1); assert (status == 1); status = checked_lookup_search (obj, "host0", "plugin0", "", "test", "ti0", /* expect new = */ 0); assert (status == 2); lookup_destroy (obj); } static void testcase3 (void) { lookup_t *obj = checked_lookup_create (); checked_lookup_add (obj, "/^db[0-9]\\./", "cpu", "/.*/", "cpu", "/.*/", LU_GROUP_BY_TYPE_INSTANCE); checked_lookup_search (obj, "db0.example.com", "cpu", "0", "cpu", "user", /* expect new = */ 1); checked_lookup_search (obj, "db0.example.com", "cpu", "0", "cpu", "idle", /* expect new = */ 1); checked_lookup_search (obj, "db0.example.com", "cpu", "1", "cpu", "user", /* expect new = */ 0); checked_lookup_search (obj, "db0.example.com", "cpu", "1", "cpu", "idle", /* expect new = */ 0); checked_lookup_search (obj, "app0.example.com", "cpu", "0", "cpu", "user", /* expect new = */ 0); checked_lookup_search (obj, "app0.example.com", "cpu", "0", "cpu", "idle", /* expect new = */ 0); checked_lookup_search (obj, "db1.example.com", "cpu", "0", "cpu", "user", /* expect new = */ 0); checked_lookup_search (obj, "db1.example.com", "cpu", "0", "cpu", "idle", /* expect new = */ 0); checked_lookup_search (obj, "db1.example.com", "cpu", "0", "cpu", "system", /* expect new = */ 1); lookup_destroy (obj); } int main (int argc, char **argv) /* {{{ */ { testcase0 (); testcase1 (); testcase2 (); testcase3 (); return (EXIT_SUCCESS); } /* }}} int main */ collectd-5.4.0/src/PaxHeaders.11991/collectd-threshold.50000644037772200116100000000013212204120753021013 xustar000000000000000030 mtime=1376821739.546361416 30 atime=1376821739.558361607 30 ctime=1376821741.978400227 collectd-5.4.0/src/collectd-threshold.50000644037772200116100000003032012204120753017555 0ustar00octoeng00000000000000.\" Automatically generated by Pod::Man 2.25 (Pod::Simple 3.16) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .ie \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .el \{\ . de IX .. .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "COLLECTD-THRESHOLD 5" .TH COLLECTD-THRESHOLD 5 "2013-08-18" "5.4.0" "collectd" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" collectd\-threshold \- Documentation of collectd's Threshold plugin .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 11 \& LoadPlugin "threshold" \& \& \& WarningMin 0.00 \& WarningMax 1000.00 \& FailureMin 0.00 \& FailureMax 1200.00 \& Invert false \& Instance "bar" \& \& .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" Starting with version \f(CW4.3.0\fR \fIcollectd\fR has support for \fBmonitoring\fR. By that we mean that the values are not only stored or sent somewhere, but that they are judged and, if a problem is recognized, acted upon. The only action the \fIThreshold plugin\fR takes itself is to generate and dispatch a \&\fInotification\fR. Other plugins can register to receive notifications and perform appropriate further actions. .PP Since systems and what you expect them to do differ a lot, you can configure \&\fIthresholds\fR for your values freely. This gives you a lot of flexibility but also a lot of responsibility. .PP Every time a value is out of range, a notification is dispatched. This means that the idle percentage of your \s-1CPU\s0 needs to be less then the configured threshold only once for a notification to be generated. There's no such thing as a moving average or similar \- at least not now. .PP Also, all values that match a threshold are considered to be relevant or \&\*(L"interesting\*(R". As a consequence collectd will issue a notification if they are not received for \fBTimeout\fR iterations. The \fBTimeout\fR configuration option is explained in section \*(L"\s-1GLOBAL\s0 \s-1OPTIONS\s0\*(R" in \fIcollectd.conf\fR\|(5). If, for example, \&\fBTimeout\fR is set to \*(L"2\*(R" (the default) and some hosts sends it's \s-1CPU\s0 statistics to the server every 60 seconds, a notification will be dispatched after about 120 seconds. It may take a little longer because the timeout is checked only once each \fBInterval\fR on the server. .PP When a value comes within range again or is received after it was missing, an \&\*(L"OKAY-notification\*(R" is dispatched. .SH "CONFIGURATION" .IX Header "CONFIGURATION" Here is a configuration example to get you started. Read below for more information. .PP .Vb 10 \& LoadPlugin "threshold" \& \& \& WarningMin 0.00 \& WarningMax 1000.00 \& FailureMin 0.00 \& FailureMax 1200.00 \& Invert false \& Instance "bar" \& \& \& \& Instance "eth0" \& \& FailureMax 10000000 \& DataSource "rx" \& \& \& \& \& \& Instance "idle" \& FailureMin 10 \& \& \& \& \& Instance "cached" \& WarningMin 100000000 \& \& \& \& \& DataSource "midterm" \& FailureMax 4 \& Hits 3 \& Hysteresis 3 \& \& \& .Ve .PP There are basically two types of configuration statements: The \f(CW\*(C`Host\*(C'\fR, \&\f(CW\*(C`Plugin\*(C'\fR, and \f(CW\*(C`Type\*(C'\fR blocks select the value for which a threshold should be configured. The \f(CW\*(C`Plugin\*(C'\fR and \f(CW\*(C`Type\*(C'\fR blocks may be specified further using the \&\f(CW\*(C`Instance\*(C'\fR option. You can combine the block by nesting the blocks, though they must be nested in the above order, i.e. \f(CW\*(C`Host\*(C'\fR may contain either \&\f(CW\*(C`Plugin\*(C'\fR and \f(CW\*(C`Type\*(C'\fR blocks, \f(CW\*(C`Plugin\*(C'\fR may only contain \f(CW\*(C`Type\*(C'\fR blocks and \&\f(CW\*(C`Type\*(C'\fR may not contain other blocks. If multiple blocks apply to the same value the most specific block is used. .PP The other statements specify the threshold to configure. They \fBmust\fR be included in a \f(CW\*(C`Type\*(C'\fR block. Currently the following statements are recognized: .IP "\fBFailureMax\fR \fIValue\fR" 4 .IX Item "FailureMax Value" .PD 0 .IP "\fBWarningMax\fR \fIValue\fR" 4 .IX Item "WarningMax Value" .PD Sets the upper bound of acceptable values. If unset defaults to positive infinity. If a value is greater than \fBFailureMax\fR a \fB\s-1FAILURE\s0\fR notification will be created. If the value is greater than \fBWarningMax\fR but less than (or equal to) \fBFailureMax\fR a \fB\s-1WARNING\s0\fR notification will be created. .IP "\fBFailureMin\fR \fIValue\fR" 4 .IX Item "FailureMin Value" .PD 0 .IP "\fBWarningMin\fR \fIValue\fR" 4 .IX Item "WarningMin Value" .PD Sets the lower bound of acceptable values. If unset defaults to negative infinity. If a value is less than \fBFailureMin\fR a \fB\s-1FAILURE\s0\fR notification will be created. If the value is less than \fBWarningMin\fR but greater than (or equal to) \fBFailureMin\fR a \fB\s-1WARNING\s0\fR notification will be created. .IP "\fBDataSource\fR \fIDSName\fR" 4 .IX Item "DataSource DSName" Some data sets have more than one \*(L"data source\*(R". Interesting examples are the \&\f(CW\*(C`if_octets\*(C'\fR data set, which has received (\f(CW\*(C`rx\*(C'\fR) and sent (\f(CW\*(C`tx\*(C'\fR) bytes and the \f(CW\*(C`disk_ops\*(C'\fR data set, which holds \f(CW\*(C`read\*(C'\fR and \f(CW\*(C`write\*(C'\fR operations. The system load data set, \f(CW\*(C`load\*(C'\fR, even has three data sources: \f(CW\*(C`shortterm\*(C'\fR, \&\f(CW\*(C`midterm\*(C'\fR, and \f(CW\*(C`longterm\*(C'\fR. .Sp Normally, all data sources are checked against a configured threshold. If this is undesirable, or if you want to specify different limits for each data source, you can use the \fBDataSource\fR option to have a threshold apply only to one data source. .IP "\fBInvert\fR \fBtrue\fR|\fBfalse\fR" 4 .IX Item "Invert true|false" If set to \fBtrue\fR the range of acceptable values is inverted, i.e. values between \fBFailureMin\fR and \fBFailureMax\fR (\fBWarningMin\fR and \fBWarningMax\fR) are not okay. Defaults to \fBfalse\fR. .IP "\fBPersist\fR \fBtrue\fR|\fBfalse\fR" 4 .IX Item "Persist true|false" Sets how often notifications are generated. If set to \fBtrue\fR one notification will be generated for each value that is out of the acceptable range. If set to \&\fBfalse\fR (the default) then a notification is only generated if a value is out of range but the previous value was okay. .Sp This applies to missing values, too: If set to \fBtrue\fR a notification about a missing value is generated once every \fBInterval\fR seconds. If set to \fBfalse\fR only one such notification is generated until the value appears again. .IP "\fBPersistOK\fR \fBtrue\fR|\fBfalse\fR" 4 .IX Item "PersistOK true|false" Sets how \s-1OKAY\s0 notifications act. If set to \fBtrue\fR one notification will be generated for each value that is in the acceptable range. If set to \fBfalse\fR (the default) then a notification is only generated if a value is in range but the previous value was not. .IP "\fBPercentage\fR \fBtrue\fR|\fBfalse\fR" 4 .IX Item "Percentage true|false" If set to \fBtrue\fR, the minimum and maximum values given are interpreted as percentage value, relative to the other data sources. This is helpful for example for the \*(L"df\*(R" type, where you may want to issue a warning when less than 5\ % of the total space is available. Defaults to \fBfalse\fR. .IP "\fBHits\fR \fIValue\fR" 4 .IX Item "Hits Value" Sets the number of occurrences which the threshold must be raised before to dispatch any notification or, in other words, the number of \fBInterval\fRs that the threshold must be match before dispatch any notification. .IP "\fBHysteresis\fR \fIValue\fR" 4 .IX Item "Hysteresis Value" Sets the hysteresis value for threshold. The hysteresis is a method to prevent flapping between states, until a new received value for a previously matched threshold down below the threshold condition (\fBWarningMax\fR, \fBFailureMin\fR or everything else) minus the hysteresis value, the failure (respectively warning) state will be keep. .IP "\fBInteresting\fR \fBtrue\fR|\fBfalse\fR" 4 .IX Item "Interesting true|false" If set to \fBtrue\fR (the default), a notification with severity \f(CW\*(C`FAILURE\*(C'\fR will be created when a matching value list is no longer updated and purged from the internal cache. When this happens depends on the \fIinterval\fR of the value list and the global \fBTimeout\fR setting. See the \fBInterval\fR and \fBTimeout\fR settings in \fIcollectd.conf\fR\|(5) for details. If set to \fBfalse\fR, this event will be ignored. .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIcollectd\fR\|(1), \&\fIcollectd.conf\fR\|(5) .SH "AUTHOR" .IX Header "AUTHOR" Florian Forster collectd-5.4.0/src/PaxHeaders.11991/collectd-tg.c0000644037772200116100000000013212204120331017477 xustar000000000000000030 mtime=1376821465.065973312 30 atime=1376821477.210167802 30 ctime=1376821741.978400227 collectd-5.4.0/src/collectd-tg.c0000644037772200116100000002447712204120331016261 0ustar00octoeng00000000000000/** * collectd-td - collectd traffic generator * Copyright (C) 2010-2012 Florian octo 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: * Florian Forster **/ #if HAVE_CONFIG_H # include "config.h" #endif #ifndef _ISOC99_SOURCE # define _ISOC99_SOURCE #endif #ifndef _POSIX_C_SOURCE # define _POSIX_C_SOURCE 200809L #endif #ifndef _XOPEN_SOURCE # define _XOPEN_SOURCE 700 #endif #if !__GNUC__ # define __attribute__(x) /**/ #endif #include #include #include #include #include #include #include #include "utils_heap.h" #include "libcollectdclient/collectd/client.h" #include "libcollectdclient/collectd/network.h" #include "libcollectdclient/collectd/network_buffer.h" #define DEF_NUM_HOSTS 1000 #define DEF_NUM_PLUGINS 20 #define DEF_NUM_VALUES 100000 #define DEF_INTERVAL 10.0 static int conf_num_hosts = DEF_NUM_HOSTS; static int conf_num_plugins = DEF_NUM_PLUGINS; static int conf_num_values = DEF_NUM_VALUES; static double conf_interval = DEF_INTERVAL; static const char *conf_destination = NET_DEFAULT_V6_ADDR; static const char *conf_service = NET_DEFAULT_PORT; static lcc_network_t *net; static c_heap_t *values_heap = NULL; static struct sigaction sigint_action; static struct sigaction sigterm_action; static _Bool loop = 1; __attribute__((noreturn)) static void exit_usage (int exit_status) /* {{{ */ { fprintf ((exit_status == EXIT_FAILURE) ? stderr : stdout, "collectd-tg -- collectd traffic generator\n" "\n" " Usage: collectd-ng [OPTION]\n" "\n" " Valid options:\n" " -n Number of value lists. (Default: %i)\n" " -H Number of hosts to emulate. (Default: %i)\n" " -p Number of plugins to emulate. (Default: %i)\n" " -i Interval of each value in seconds. (Default: %.3f)\n" " -d Destination address of the network packets.\n" " (Default: %s)\n" " -D Destination port of the network packets.\n" " (Default: %s)\n" " -h Print usage information (this output).\n" "\n" "Copyright (C) 2010-2012 Florian Forster\n" "Licensed under the GNU General Public License, version 2 (GPLv2)\n", DEF_NUM_VALUES, DEF_NUM_HOSTS, DEF_NUM_PLUGINS, DEF_INTERVAL, NET_DEFAULT_V6_ADDR, NET_DEFAULT_PORT); exit (exit_status); } /* }}} void exit_usage */ static void signal_handler (int signal) /* {{{ */ { loop = 0; } /* }}} void signal_handler */ static int compare_time (const void *v0, const void *v1) /* {{{ */ { const lcc_value_list_t *vl0 = v0; const lcc_value_list_t *vl1 = v1; if (vl0->time < vl1->time) return (-1); else if (vl0->time > vl1->time) return (1); else return (0); } /* }}} int compare_time */ static int get_boundet_random (int min, int max) /* {{{ */ { int range; if (min >= max) return (-1); if (min == (max - 1)) return (min); range = max - min; return (min + ((int) (((double) range) * ((double) random ()) / (((double) RAND_MAX) + 1.0)))); } /* }}} int get_boundet_random */ static lcc_value_list_t *create_value_list (void) /* {{{ */ { lcc_value_list_t *vl; int host_num; vl = malloc (sizeof (*vl)); if (vl == NULL) { fprintf (stderr, "malloc failed.\n"); return (NULL); } memset (vl, 0, sizeof (*vl)); vl->values = calloc (/* nmemb = */ 1, sizeof (*vl->values)); if (vl->values == NULL) { fprintf (stderr, "calloc failed.\n"); free (vl); return (NULL); } vl->values_types = calloc (/* nmemb = */ 1, sizeof (*vl->values_types)); if (vl->values_types == NULL) { fprintf (stderr, "calloc failed.\n"); free (vl->values); free (vl); return (NULL); } vl->values_len = 1; host_num = get_boundet_random (0, conf_num_hosts); vl->interval = conf_interval; vl->time = 1.0 + time (NULL) + (host_num % (1 + (int) vl->interval)); if (get_boundet_random (0, 2) == 0) vl->values_types[0] = LCC_TYPE_GAUGE; else vl->values_types[0] = LCC_TYPE_DERIVE; snprintf (vl->identifier.host, sizeof (vl->identifier.host), "host%04i", host_num); snprintf (vl->identifier.plugin, sizeof (vl->identifier.plugin), "plugin%03i", get_boundet_random (0, conf_num_plugins)); strncpy (vl->identifier.type, (vl->values_types[0] == LCC_TYPE_GAUGE) ? "gauge" : "derive", sizeof (vl->identifier.type)); snprintf (vl->identifier.type_instance, sizeof (vl->identifier.type_instance), "ti%li", random ()); return (vl); } /* }}} int create_value_list */ static void destroy_value_list (lcc_value_list_t *vl) /* {{{ */ { if (vl == NULL) return; free (vl->values); free (vl->values_types); free (vl); } /* }}} void destroy_value_list */ static int send_value (lcc_value_list_t *vl) /* {{{ */ { int status; if (vl->values_types[0] == LCC_TYPE_GAUGE) vl->values[0].gauge = 100.0 * ((gauge_t) random ()) / (((gauge_t) RAND_MAX) + 1.0); else vl->values[0].derive += get_boundet_random (0, 100); status = lcc_network_values_send (net, vl); if (status != 0) fprintf (stderr, "lcc_network_values_send failed with status %i.\n", status); vl->time += vl->interval; return (0); } /* }}} int send_value */ static int get_integer_opt (const char *str, int *ret_value) /* {{{ */ { char *endptr; int tmp; errno = 0; endptr = NULL; tmp = (int) strtol (str, &endptr, /* base = */ 0); if (errno != 0) { fprintf (stderr, "Unable to parse option as a number: \"%s\": %s\n", str, strerror (errno)); exit (EXIT_FAILURE); } else if (endptr == str) { fprintf (stderr, "Unable to parse option as a number: \"%s\"\n", str); exit (EXIT_FAILURE); } else if (*endptr != 0) { fprintf (stderr, "Garbage after end of value: \"%s\"\n", str); exit (EXIT_FAILURE); } *ret_value = tmp; return (0); } /* }}} int get_integer_opt */ static int get_double_opt (const char *str, double *ret_value) /* {{{ */ { char *endptr; double tmp; errno = 0; endptr = NULL; tmp = strtod (str, &endptr); if (errno != 0) { fprintf (stderr, "Unable to parse option as a number: \"%s\": %s\n", str, strerror (errno)); exit (EXIT_FAILURE); } else if (endptr == str) { fprintf (stderr, "Unable to parse option as a number: \"%s\"\n", str); exit (EXIT_FAILURE); } else if (*endptr != 0) { fprintf (stderr, "Garbage after end of value: \"%s\"\n", str); exit (EXIT_FAILURE); } *ret_value = tmp; return (0); } /* }}} int get_double_opt */ static int read_options (int argc, char **argv) /* {{{ */ { int opt; while ((opt = getopt (argc, argv, "n:H:p:i:d:D:h")) != -1) { switch (opt) { case 'n': get_integer_opt (optarg, &conf_num_values); break; case 'H': get_integer_opt (optarg, &conf_num_hosts); break; case 'p': get_integer_opt (optarg, &conf_num_plugins); break; case 'i': get_double_opt (optarg, &conf_interval); break; case 'd': conf_destination = optarg; break; case 'D': conf_service = optarg; break; case 'h': exit_usage (EXIT_SUCCESS); default: exit_usage (EXIT_FAILURE); } /* switch (opt) */ } /* while (getopt) */ return (0); } /* }}} int read_options */ int main (int argc, char **argv) /* {{{ */ { int i; time_t last_time; int values_sent = 0; read_options (argc, argv); sigint_action.sa_handler = signal_handler; sigaction (SIGINT, &sigint_action, /* old = */ NULL); sigterm_action.sa_handler = signal_handler; sigaction (SIGTERM, &sigterm_action, /* old = */ NULL); values_heap = c_heap_create (compare_time); if (values_heap == NULL) { fprintf (stderr, "c_heap_create failed.\n"); exit (EXIT_FAILURE); } net = lcc_network_create (); if (net == NULL) { fprintf (stderr, "lcc_network_create failed.\n"); exit (EXIT_FAILURE); } else { lcc_server_t *srv; srv = lcc_server_create (net, conf_destination, conf_service); if (srv == NULL) { fprintf (stderr, "lcc_server_create failed.\n"); exit (EXIT_FAILURE); } lcc_server_set_ttl (srv, 42); #if 0 lcc_server_set_security_level (srv, ENCRYPT, "admin", "password1"); #endif } fprintf (stdout, "Creating %i values ... ", conf_num_values); fflush (stdout); for (i = 0; i < conf_num_values; i++) { lcc_value_list_t *vl; vl = create_value_list (); if (vl == NULL) { fprintf (stderr, "create_value_list failed.\n"); exit (EXIT_FAILURE); } c_heap_insert (values_heap, vl); } fprintf (stdout, "done\n"); last_time = 0; while (loop) { lcc_value_list_t *vl = c_heap_get_root (values_heap); if (vl == NULL) break; if (vl->time != last_time) { printf ("%i values have been sent.\n", values_sent); /* Check if we need to sleep */ time_t now = time (NULL); while (now < vl->time) { /* 1 / 100 second */ struct timespec ts = { 0, 10000000 }; nanosleep (&ts, /* remaining = */ NULL); now = time (NULL); if (!loop) break; } last_time = vl->time; } send_value (vl); values_sent++; c_heap_insert (values_heap, vl); } fprintf (stdout, "Shutting down.\n"); fflush (stdout); while (42) { lcc_value_list_t *vl = c_heap_get_root (values_heap); if (vl == NULL) break; destroy_value_list (vl); } c_heap_destroy (values_heap); lcc_network_destroy (net); exit (EXIT_SUCCESS); return (0); } /* }}} int main */ /* vim: set sw=2 sts=2 et fdm=marker : */ collectd-5.4.0/src/PaxHeaders.11991/curl_xml.c0000644037772200116100000000013112204120331017122 xustar000000000000000030 mtime=1376821465.069973376 30 atime=1376821477.214167866 29 ctime=1376821741.98240029 collectd-5.4.0/src/curl_xml.c0000644037772200116100000006503312204120331015676 0ustar00octoeng00000000000000/** * collectd - src/curl_xml.c * Copyright (C) 2009,2010 Amit Gupta * * 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: * Amit Gupta **/ #include "collectd.h" #include "common.h" #include "plugin.h" #include "configfile.h" #include "utils_llist.h" #include #include #include #include #include #define CX_DEFAULT_HOST "localhost" /* * Private data structures */ struct cx_values_s /* {{{ */ { char path[DATA_MAX_NAME_LEN]; size_t path_len; }; typedef struct cx_values_s cx_values_t; /* }}} */ struct cx_xpath_s /* {{{ */ { char *path; char *type; cx_values_t *values; int values_len; char *instance_prefix; char *instance; int is_table; unsigned long magic; }; typedef struct cx_xpath_s cx_xpath_t; /* }}} */ struct cx_namespace_s /* {{{ */ { char *prefix; char *url; }; typedef struct cx_namespace_s cx_namespace_t; /* }}} */ struct cx_s /* {{{ */ { char *instance; char *host; char *url; char *user; char *pass; char *credentials; _Bool verify_peer; _Bool verify_host; char *cacert; char *post_body; struct curl_slist *headers; cx_namespace_t *namespaces; size_t namespaces_num; CURL *curl; char curl_errbuf[CURL_ERROR_SIZE]; char *buffer; size_t buffer_size; size_t buffer_fill; llist_t *list; /* list of xpath blocks */ }; typedef struct cx_s cx_t; /* }}} */ /* * Private functions */ static size_t cx_curl_callback (void *buf, /* {{{ */ size_t size, size_t nmemb, void *user_data) { size_t len = size * nmemb; cx_t *db; db = user_data; if (db == NULL) { ERROR ("curl_xml plugin: cx_curl_callback: " "user_data pointer is NULL."); return (0); } if (len <= 0) return (len); if ((db->buffer_fill + len) >= db->buffer_size) { char *temp; temp = (char *) realloc (db->buffer, db->buffer_fill + len + 1); if (temp == NULL) { ERROR ("curl_xml plugin: realloc failed."); return (0); } db->buffer = temp; db->buffer_size = db->buffer_fill + len + 1; } memcpy (db->buffer + db->buffer_fill, (char *) buf, len); db->buffer_fill += len; db->buffer[db->buffer_fill] = 0; return (len); } /* }}} size_t cx_curl_callback */ static void cx_xpath_free (cx_xpath_t *xpath) /* {{{ */ { if (xpath == NULL) return; sfree (xpath->path); sfree (xpath->type); sfree (xpath->instance_prefix); sfree (xpath->instance); sfree (xpath->values); sfree (xpath); } /* }}} void cx_xpath_free */ static void cx_list_free (llist_t *list) /* {{{ */ { llentry_t *le; le = llist_head (list); while (le != NULL) { llentry_t *le_next; le_next = le->next; sfree (le->key); cx_xpath_free (le->value); le = le_next; } llist_destroy (list); list = NULL; } /* }}} void cx_list_free */ static void cx_free (void *arg) /* {{{ */ { cx_t *db; size_t i; DEBUG ("curl_xml plugin: cx_free (arg = %p);", arg); db = (cx_t *) arg; if (db == NULL) return; if (db->curl != NULL) curl_easy_cleanup (db->curl); db->curl = NULL; if (db->list != NULL) cx_list_free (db->list); sfree (db->buffer); sfree (db->instance); sfree (db->host); sfree (db->url); sfree (db->user); sfree (db->pass); sfree (db->credentials); sfree (db->cacert); sfree (db->post_body); curl_slist_free_all (db->headers); for (i = 0; i < db->namespaces_num; i++) { sfree (db->namespaces[i].prefix); sfree (db->namespaces[i].url); } sfree (db->namespaces); sfree (db); } /* }}} void cx_free */ static int cx_config_append_string (const char *name, struct curl_slist **dest, /* {{{ */ oconfig_item_t *ci) { if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { WARNING ("curl_xml plugin: `%s' needs exactly one string argument.", name); return (-1); } *dest = curl_slist_append(*dest, ci->values[0].value.string); if (*dest == NULL) return (-1); return (0); } /* }}} int cx_config_append_string */ static int cx_check_type (const data_set_t *ds, cx_xpath_t *xpath) /* {{{ */ { if (!ds) { WARNING ("curl_xml plugin: DataSet `%s' not defined.", xpath->type); return (-1); } if (ds->ds_num != xpath->values_len) { WARNING ("curl_xml plugin: DataSet `%s' requires %i values, but config talks about %i", xpath->type, ds->ds_num, xpath->values_len); return (-1); } return (0); } /* }}} cx_check_type */ static xmlXPathObjectPtr cx_evaluate_xpath (xmlXPathContextPtr xpath_ctx, /* {{{ */ xmlChar *expr) { xmlXPathObjectPtr xpath_obj; /* XXX: When to free this? */ xpath_obj = xmlXPathEvalExpression(BAD_CAST expr, xpath_ctx); if (xpath_obj == NULL) { WARNING ("curl_xml plugin: " "Error unable to evaluate xpath expression \"%s\". Skipping...", expr); return NULL; } return xpath_obj; } /* }}} cx_evaluate_xpath */ static int cx_if_not_text_node (xmlNodePtr node) /* {{{ */ { if (node->type == XML_TEXT_NODE || node->type == XML_ATTRIBUTE_NODE || node->type == XML_ELEMENT_NODE) return (0); WARNING ("curl_xml plugin: " "Node \"%s\" doesn't seem to be a text node. Skipping...", node->name); return -1; } /* }}} cx_if_not_text_node */ static int cx_handle_single_value_xpath (xmlXPathContextPtr xpath_ctx, /* {{{ */ cx_xpath_t *xpath, const data_set_t *ds, value_list_t *vl, int index) { xmlXPathObjectPtr values_node_obj; xmlNodeSetPtr values_node; int tmp_size; char *node_value; values_node_obj = cx_evaluate_xpath (xpath_ctx, BAD_CAST xpath->values[index].path); if (values_node_obj == NULL) return (-1); /* Error already logged. */ values_node = values_node_obj->nodesetval; tmp_size = (values_node) ? values_node->nodeNr : 0; if (tmp_size == 0) { WARNING ("curl_xml plugin: " "relative xpath expression \"%s\" doesn't match any of the nodes. " "Skipping...", xpath->values[index].path); xmlXPathFreeObject (values_node_obj); return (-1); } if (tmp_size > 1) { WARNING ("curl_xml plugin: " "relative xpath expression \"%s\" is expected to return " "only one node. Skipping...", xpath->values[index].path); xmlXPathFreeObject (values_node_obj); return (-1); } /* ignoring the element if other than textnode/attribute*/ if (cx_if_not_text_node(values_node->nodeTab[0])) { WARNING ("curl_xml plugin: " "relative xpath expression \"%s\" is expected to return " "only text/attribute node which is not the case. Skipping...", xpath->values[index].path); xmlXPathFreeObject (values_node_obj); return (-1); } node_value = (char *) xmlNodeGetContent(values_node->nodeTab[0]); switch (ds->ds[index].type) { case DS_TYPE_COUNTER: vl->values[index].counter = (counter_t) strtoull (node_value, /* endptr = */ NULL, /* base = */ 0); break; case DS_TYPE_DERIVE: vl->values[index].derive = (derive_t) strtoll (node_value, /* endptr = */ NULL, /* base = */ 0); break; case DS_TYPE_ABSOLUTE: vl->values[index].absolute = (absolute_t) strtoull (node_value, /* endptr = */ NULL, /* base = */ 0); break; case DS_TYPE_GAUGE: vl->values[index].gauge = (gauge_t) strtod (node_value, /* endptr = */ NULL); } /* free up object */ xmlXPathFreeObject (values_node_obj); /* We have reached here which means that * we have got something to work */ return (0); } /* }}} int cx_handle_single_value_xpath */ static int cx_handle_all_value_xpaths (xmlXPathContextPtr xpath_ctx, /* {{{ */ cx_xpath_t *xpath, const data_set_t *ds, value_list_t *vl) { value_t values[xpath->values_len]; int status; int i; assert (xpath->values_len > 0); assert (xpath->values_len == vl->values_len); assert (xpath->values_len == ds->ds_num); vl->values = values; for (i = 0; i < xpath->values_len; i++) { status = cx_handle_single_value_xpath (xpath_ctx, xpath, ds, vl, i); if (status != 0) return (-1); /* An error has been printed. */ } /* for (i = 0; i < xpath->values_len; i++) */ plugin_dispatch_values (vl); vl->values = NULL; return (0); } /* }}} int cx_handle_all_value_xpaths */ static int cx_handle_instance_xpath (xmlXPathContextPtr xpath_ctx, /* {{{ */ cx_xpath_t *xpath, value_list_t *vl, _Bool is_table) { xmlXPathObjectPtr instance_node_obj = NULL; xmlNodeSetPtr instance_node = NULL; memset (vl->type_instance, 0, sizeof (vl->type_instance)); /* If the base xpath returns more than one block, the result is assumed to be * a table. The `Instance' option is not optional in this case. Check for the * condition and inform the user. */ if (is_table && (vl->type_instance == NULL)) { WARNING ("curl_xml plugin: " "Base-XPath %s is a table (more than one result was returned), " "but no instance-XPath has been defined.", xpath->path); return (-1); } /* instance has to be an xpath expression */ if (xpath->instance != NULL) { int tmp_size; instance_node_obj = cx_evaluate_xpath (xpath_ctx, BAD_CAST xpath->instance); if (instance_node_obj == NULL) return (-1); /* error is logged already */ instance_node = instance_node_obj->nodesetval; tmp_size = (instance_node) ? instance_node->nodeNr : 0; if (tmp_size <= 0) { WARNING ("curl_xml plugin: " "relative xpath expression for 'InstanceFrom' \"%s\" doesn't match " "any of the nodes. Skipping the node.", xpath->instance); xmlXPathFreeObject (instance_node_obj); return (-1); } if (tmp_size > 1) { WARNING ("curl_xml plugin: " "relative xpath expression for 'InstanceFrom' \"%s\" is expected " "to return only one text node. Skipping the node.", xpath->instance); xmlXPathFreeObject (instance_node_obj); return (-1); } /* ignoring the element if other than textnode/attribute */ if (cx_if_not_text_node(instance_node->nodeTab[0])) { WARNING ("curl_xml plugin: " "relative xpath expression \"%s\" is expected to return only text node " "which is not the case. Skipping the node.", xpath->instance); xmlXPathFreeObject (instance_node_obj); return (-1); } } /* if (xpath->instance != NULL) */ if (xpath->instance_prefix != NULL) { if (instance_node != NULL) ssnprintf (vl->type_instance, sizeof (vl->type_instance),"%s%s", xpath->instance_prefix, (char *) xmlNodeGetContent(instance_node->nodeTab[0])); else sstrncpy (vl->type_instance, xpath->instance_prefix, sizeof (vl->type_instance)); } else { /* If instance_prefix and instance_node are NULL, then * don't set the type_instance */ if (instance_node != NULL) sstrncpy (vl->type_instance, (char *) xmlNodeGetContent(instance_node->nodeTab[0]), sizeof (vl->type_instance)); } /* Free `instance_node_obj' this late, because `instance_node' points to * somewhere inside this structure. */ xmlXPathFreeObject (instance_node_obj); return (0); } /* }}} int cx_handle_instance_xpath */ static int cx_handle_base_xpath (char const *plugin_instance, /* {{{ */ char const *host, xmlXPathContextPtr xpath_ctx, const data_set_t *ds, char *base_xpath, cx_xpath_t *xpath) { int total_nodes; int i; xmlXPathObjectPtr base_node_obj = NULL; xmlNodeSetPtr base_nodes = NULL; value_list_t vl = VALUE_LIST_INIT; base_node_obj = cx_evaluate_xpath (xpath_ctx, BAD_CAST base_xpath); if (base_node_obj == NULL) return -1; /* error is logged already */ base_nodes = base_node_obj->nodesetval; total_nodes = (base_nodes) ? base_nodes->nodeNr : 0; if (total_nodes == 0) { ERROR ("curl_xml plugin: " "xpath expression \"%s\" doesn't match any of the nodes. " "Skipping the xpath block...", base_xpath); xmlXPathFreeObject (base_node_obj); return -1; } /* If base_xpath returned multiple results, then */ /* Instance in the xpath block is required */ if (total_nodes > 1 && xpath->instance == NULL) { ERROR ("curl_xml plugin: " "InstanceFrom is must in xpath block since the base xpath expression \"%s\" " "returned multiple results. Skipping the xpath block...", base_xpath); return -1; } /* set the values for the value_list */ vl.values_len = ds->ds_num; sstrncpy (vl.type, xpath->type, sizeof (vl.type)); sstrncpy (vl.plugin, "curl_xml", sizeof (vl.plugin)); sstrncpy (vl.host, (host != NULL) ? host : hostname_g, sizeof (vl.host)); if (plugin_instance != NULL) sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance)); for (i = 0; i < total_nodes; i++) { int status; xpath_ctx->node = base_nodes->nodeTab[i]; status = cx_handle_instance_xpath (xpath_ctx, xpath, &vl, /* is_table = */ (total_nodes > 1)); if (status != 0) continue; /* An error has already been reported. */ status = cx_handle_all_value_xpaths (xpath_ctx, xpath, ds, &vl); if (status != 0) continue; /* An error has been logged. */ } /* for (i = 0; i < total_nodes; i++) */ /* free up the allocated memory */ xmlXPathFreeObject (base_node_obj); return (0); } /* }}} cx_handle_base_xpath */ static int cx_handle_parsed_xml(xmlDocPtr doc, /* {{{ */ xmlXPathContextPtr xpath_ctx, cx_t *db) { llentry_t *le; const data_set_t *ds; cx_xpath_t *xpath; int status=-1; le = llist_head (db->list); while (le != NULL) { /* get the ds */ xpath = (cx_xpath_t *) le->value; ds = plugin_get_ds (xpath->type); if ( (cx_check_type(ds, xpath) == 0) && (cx_handle_base_xpath(db->instance, db->host, xpath_ctx, ds, le->key, xpath) == 0) ) status = 0; /* we got atleast one success */ le = le->next; } /* while (le != NULL) */ return status; } /* }}} cx_handle_parsed_xml */ static int cx_parse_stats_xml(xmlChar* xml, cx_t *db) /* {{{ */ { int status; xmlDocPtr doc; xmlXPathContextPtr xpath_ctx; size_t i; /* Load the XML */ doc = xmlParseDoc(xml); if (doc == NULL) { ERROR ("curl_xml plugin: Failed to parse the xml document - %s", xml); return (-1); } xpath_ctx = xmlXPathNewContext(doc); if(xpath_ctx == NULL) { ERROR ("curl_xml plugin: Failed to create the xml context"); xmlFreeDoc(doc); return (-1); } for (i = 0; i < db->namespaces_num; i++) { cx_namespace_t const *ns = db->namespaces + i; status = xmlXPathRegisterNs (xpath_ctx, BAD_CAST ns->prefix, BAD_CAST ns->url); if (status != 0) { ERROR ("curl_xml plugin: " "unable to register NS with prefix=\"%s\" and href=\"%s\"\n", ns->prefix, ns->url); xmlXPathFreeContext(xpath_ctx); xmlFreeDoc (doc); return (status); } } status = cx_handle_parsed_xml (doc, xpath_ctx, db); /* Cleanup */ xmlXPathFreeContext(xpath_ctx); xmlFreeDoc(doc); return status; } /* }}} cx_parse_stats_xml */ static int cx_curl_perform (cx_t *db, CURL *curl) /* {{{ */ { int status; long rc; char *ptr; char *url; db->buffer_fill = 0; status = curl_easy_perform (curl); if (status != CURLE_OK) { ERROR ("curl_xml plugin: curl_easy_perform failed with status %i: %s (%s)", status, db->curl_errbuf, url); return (-1); } curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &url); curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &rc); /* The response code is zero if a non-HTTP transport was used. */ if ((rc != 0) && (rc != 200)) { ERROR ("curl_xml plugin: curl_easy_perform failed with response code %ld (%s)", rc, url); return (-1); } ptr = db->buffer; status = cx_parse_stats_xml(BAD_CAST ptr, db); db->buffer_fill = 0; return status; } /* }}} int cx_curl_perform */ static int cx_read (user_data_t *ud) /* {{{ */ { cx_t *db; if ((ud == NULL) || (ud->data == NULL)) { ERROR ("curl_xml plugin: cx_read: Invalid user data."); return (-1); } db = (cx_t *) ud->data; return cx_curl_perform (db, db->curl); } /* }}} int cx_read */ /* Configuration handling functions {{{ */ static int cx_config_add_values (const char *name, cx_xpath_t *xpath, /* {{{ */ oconfig_item_t *ci) { int i; if (ci->values_num < 1) { WARNING ("curl_xml plugin: `ValuesFrom' needs at least one argument."); return (-1); } for (i = 0; i < ci->values_num; i++) if (ci->values[i].type != OCONFIG_TYPE_STRING) { WARNING ("curl_xml plugin: `ValuesFrom' needs only string argument."); return (-1); } sfree (xpath->values); xpath->values_len = 0; xpath->values = (cx_values_t *) malloc (sizeof (cx_values_t) * ci->values_num); if (xpath->values == NULL) return (-1); xpath->values_len = ci->values_num; /* populate cx_values_t structure */ for (i = 0; i < ci->values_num; i++) { xpath->values[i].path_len = sizeof (ci->values[i].value.string); sstrncpy (xpath->values[i].path, ci->values[i].value.string, sizeof (xpath->values[i].path)); } return (0); } /* }}} cx_config_add_values */ static int cx_config_add_xpath (cx_t *db, /* {{{ */ oconfig_item_t *ci) { cx_xpath_t *xpath; int status; int i; xpath = (cx_xpath_t *) malloc (sizeof (*xpath)); if (xpath == NULL) { ERROR ("curl_xml plugin: malloc failed."); return (-1); } memset (xpath, 0, sizeof (*xpath)); status = cf_util_get_string (ci, &xpath->path); if (status != 0) { sfree (xpath); return (status); } /* error out if xpath->path is an empty string */ if (*xpath->path == 0) { ERROR ("curl_xml plugin: invalid xpath. " "xpath value can't be an empty string"); return (-1); } status = 0; for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("Type", child->key) == 0) status = cf_util_get_string (child, &xpath->type); else if (strcasecmp ("InstancePrefix", child->key) == 0) status = cf_util_get_string (child, &xpath->instance_prefix); else if (strcasecmp ("InstanceFrom", child->key) == 0) status = cf_util_get_string (child, &xpath->instance); else if (strcasecmp ("ValuesFrom", child->key) == 0) status = cx_config_add_values ("ValuesFrom", xpath, child); else { WARNING ("curl_xml plugin: Option `%s' not allowed here.", child->key); status = -1; } if (status != 0) break; } /* for (i = 0; i < ci->children_num; i++) */ if (status == 0 && xpath->type == NULL) { WARNING ("curl_xml plugin: `Type' missing in `xpath' block."); status = -1; } if (status == 0) { char *name; llentry_t *le; if (db->list == NULL) { db->list = llist_create(); if (db->list == NULL) { ERROR ("curl_xml plugin: list creation failed."); return (-1); } } name = strdup(xpath->path); if (name == NULL) { ERROR ("curl_xml plugin: strdup failed."); return (-1); } le = llentry_create (name, xpath); if (le == NULL) { ERROR ("curl_xml plugin: llentry_create failed."); return (-1); } llist_append (db->list, le); } return (status); } /* }}} int cx_config_add_xpath */ static int cx_config_add_namespace (cx_t *db, /* {{{ */ oconfig_item_t *ci) { cx_namespace_t *ns; if ((ci->values_num != 2) || (ci->values[0].type != OCONFIG_TYPE_STRING) || (ci->values[1].type != OCONFIG_TYPE_STRING)) { WARNING ("curl_xml plugin: The `Namespace' option " "needs exactly two string arguments."); return (EINVAL); } ns = realloc (db->namespaces, sizeof (*db->namespaces) * (db->namespaces_num + 1)); if (ns == NULL) { ERROR ("curl_xml plugin: realloc failed."); return (ENOMEM); } db->namespaces = ns; ns = db->namespaces + db->namespaces_num; memset (ns, 0, sizeof (*ns)); ns->prefix = strdup (ci->values[0].value.string); ns->url = strdup (ci->values[1].value.string); if ((ns->prefix == NULL) || (ns->url == NULL)) { sfree (ns->prefix); sfree (ns->url); ERROR ("curl_xml plugin: strdup failed."); return (ENOMEM); } db->namespaces_num++; return (0); } /* }}} int cx_config_add_namespace */ /* Initialize db->curl */ static int cx_init_curl (cx_t *db) /* {{{ */ { db->curl = curl_easy_init (); if (db->curl == NULL) { ERROR ("curl_xml plugin: curl_easy_init failed."); return (-1); } curl_easy_setopt (db->curl, CURLOPT_NOSIGNAL, 1L); curl_easy_setopt (db->curl, CURLOPT_WRITEFUNCTION, cx_curl_callback); curl_easy_setopt (db->curl, CURLOPT_WRITEDATA, db); curl_easy_setopt (db->curl, CURLOPT_USERAGENT, PACKAGE_NAME"/"PACKAGE_VERSION); curl_easy_setopt (db->curl, CURLOPT_ERRORBUFFER, db->curl_errbuf); curl_easy_setopt (db->curl, CURLOPT_URL, db->url); if (db->user != NULL) { size_t credentials_size; credentials_size = strlen (db->user) + 2; if (db->pass != NULL) credentials_size += strlen (db->pass); db->credentials = (char *) malloc (credentials_size); if (db->credentials == NULL) { ERROR ("curl_xml plugin: malloc failed."); return (-1); } ssnprintf (db->credentials, credentials_size, "%s:%s", db->user, (db->pass == NULL) ? "" : db->pass); curl_easy_setopt (db->curl, CURLOPT_USERPWD, db->credentials); } curl_easy_setopt (db->curl, CURLOPT_SSL_VERIFYPEER, db->verify_peer ? 1L : 0L); curl_easy_setopt (db->curl, CURLOPT_SSL_VERIFYHOST, db->verify_host ? 2L : 0L); if (db->cacert != NULL) curl_easy_setopt (db->curl, CURLOPT_CAINFO, db->cacert); if (db->headers != NULL) curl_easy_setopt (db->curl, CURLOPT_HTTPHEADER, db->headers); if (db->post_body != NULL) curl_easy_setopt (db->curl, CURLOPT_POSTFIELDS, db->post_body); return (0); } /* }}} int cx_init_curl */ static int cx_config_add_url (oconfig_item_t *ci) /* {{{ */ { cx_t *db; int status = 0; int i; if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { WARNING ("curl_xml plugin: The `URL' block " "needs exactly one string argument."); return (-1); } db = (cx_t *) malloc (sizeof (*db)); if (db == NULL) { ERROR ("curl_xml plugin: malloc failed."); return (-1); } memset (db, 0, sizeof (*db)); if (strcasecmp ("URL", ci->key) == 0) { status = cf_util_get_string (ci, &db->url); if (status != 0) { sfree (db); return (status); } } else { ERROR ("curl_xml plugin: cx_config: " "Invalid key: %s", ci->key); return (-1); } /* Fill the `cx_t' structure.. */ for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("Instance", child->key) == 0) status = cf_util_get_string (child, &db->instance); else if (strcasecmp ("Host", child->key) == 0) status = cf_util_get_string (child, &db->host); else if (strcasecmp ("User", child->key) == 0) status = cf_util_get_string (child, &db->user); else if (strcasecmp ("Password", child->key) == 0) status = cf_util_get_string (child, &db->pass); else if (strcasecmp ("VerifyPeer", child->key) == 0) status = cf_util_get_boolean (child, &db->verify_peer); else if (strcasecmp ("VerifyHost", child->key) == 0) status = cf_util_get_boolean (child, &db->verify_host); else if (strcasecmp ("CACert", child->key) == 0) status = cf_util_get_string (child, &db->cacert); else if (strcasecmp ("xpath", child->key) == 0) status = cx_config_add_xpath (db, child); else if (strcasecmp ("Header", child->key) == 0) status = cx_config_append_string ("Header", &db->headers, child); else if (strcasecmp ("Post", child->key) == 0) status = cf_util_get_string (child, &db->post_body); else if (strcasecmp ("Namespace", child->key) == 0) status = cx_config_add_namespace (db, child); else { WARNING ("curl_xml plugin: Option `%s' not allowed here.", child->key); status = -1; } if (status != 0) break; } if (status == 0) { if (db->list == NULL) { WARNING ("curl_xml plugin: No (valid) `Key' block " "within `URL' block `%s'.", db->url); status = -1; } if (status == 0) status = cx_init_curl (db); } /* If all went well, register this database for reading */ if (status == 0) { user_data_t ud; char *cb_name; if (db->instance == NULL) db->instance = strdup("default"); DEBUG ("curl_xml plugin: Registering new read callback: %s", db->instance); memset (&ud, 0, sizeof (ud)); ud.data = (void *) db; ud.free_func = cx_free; cb_name = ssnprintf_alloc ("curl_xml-%s-%s", db->instance, db->url); plugin_register_complex_read (/* group = */ "curl_xml", cb_name, cx_read, /* interval = */ NULL, &ud); sfree (cb_name); } else { cx_free (db); return (-1); } return (0); } /* }}} int cx_config_add_url */ /* }}} End of configuration handling functions */ static int cx_config (oconfig_item_t *ci) /* {{{ */ { int success; int errors; int status; int i; success = 0; errors = 0; for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("URL", child->key) == 0) { status = cx_config_add_url (child); if (status == 0) success++; else errors++; } else { WARNING ("curl_xml plugin: Option `%s' not allowed here.", child->key); errors++; } } if ((success == 0) && (errors > 0)) { ERROR ("curl_xml plugin: All statements failed."); return (-1); } return (0); } /* }}} int cx_config */ void module_register (void) { plugin_register_complex_config ("curl_xml", cx_config); } /* void module_register */ /* vim: set sw=2 sts=2 et fdm=marker : */ collectd-5.4.0/src/PaxHeaders.11991/utils_tail_match.c0000644037772200116100000000013112204120331020622 xustar000000000000000030 mtime=1376821465.089973696 30 atime=1376821477.230168122 29 ctime=1376821741.98240029 collectd-5.4.0/src/utils_tail_match.c0000644037772200116100000001477112204120331017401 0ustar00octoeng00000000000000/* * collectd - src/utils_tail_match.c * Copyright (C) 2007-2008 C-Ware, Inc. * Copyright (C) 2008 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 * * Author: * Luke Heberling * Florian Forster * * Description: * Encapsulates useful code to plugins which must parse a log file. */ #include "collectd.h" #include "common.h" #include "plugin.h" #include "utils_match.h" #include "utils_tail.h" #include "utils_tail_match.h" struct cu_tail_match_simple_s { char plugin[DATA_MAX_NAME_LEN]; char plugin_instance[DATA_MAX_NAME_LEN]; char type[DATA_MAX_NAME_LEN]; char type_instance[DATA_MAX_NAME_LEN]; }; typedef struct cu_tail_match_simple_s cu_tail_match_simple_t; struct cu_tail_match_match_s { cu_match_t *match; void *user_data; int (*submit) (cu_match_t *match, void *user_data); void (*free) (void *user_data); }; typedef struct cu_tail_match_match_s cu_tail_match_match_t; struct cu_tail_match_s { int flags; cu_tail_t *tail; cu_tail_match_match_t *matches; size_t matches_num; }; /* * Private functions */ static int simple_submit_match (cu_match_t *match, void *user_data) { cu_tail_match_simple_t *data = (cu_tail_match_simple_t *) user_data; cu_match_value_t *match_value; value_list_t vl = VALUE_LIST_INIT; value_t values[1]; match_value = (cu_match_value_t *) match_get_user_data (match); if (match_value == NULL) return (-1); if ((match_value->ds_type & UTILS_MATCH_DS_TYPE_GAUGE) && (match_value->values_num == 0)) values[0].gauge = NAN; else values[0] = match_value->value; vl.values = values; vl.values_len = 1; sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, data->plugin, sizeof (vl.plugin)); sstrncpy (vl.plugin_instance, data->plugin_instance, sizeof (vl.plugin_instance)); sstrncpy (vl.type, data->type, sizeof (vl.type)); sstrncpy (vl.type_instance, data->type_instance, sizeof (vl.type_instance)); plugin_dispatch_values (&vl); if (match_value->ds_type & UTILS_MATCH_DS_TYPE_GAUGE) { match_value->value.gauge = NAN; match_value->values_num = 0; } return (0); } /* int simple_submit_match */ static int tail_callback (void *data, char *buf, int __attribute__((unused)) buflen) { cu_tail_match_t *obj = (cu_tail_match_t *) data; size_t i; for (i = 0; i < obj->matches_num; i++) match_apply (obj->matches[i].match, buf); return (0); } /* int tail_callback */ /* * Public functions */ cu_tail_match_t *tail_match_create (const char *filename) { cu_tail_match_t *obj; obj = (cu_tail_match_t *) malloc (sizeof (cu_tail_match_t)); if (obj == NULL) return (NULL); memset (obj, '\0', sizeof (cu_tail_match_t)); obj->tail = cu_tail_create (filename); if (obj->tail == NULL) { sfree (obj); return (NULL); } return (obj); } /* cu_tail_match_t *tail_match_create */ void tail_match_destroy (cu_tail_match_t *obj) { size_t i; if (obj == NULL) return; if (obj->tail != NULL) { cu_tail_destroy (obj->tail); obj->tail = NULL; } for (i = 0; i < obj->matches_num; i++) { cu_tail_match_match_t *match = obj->matches + i; if (match->match != NULL) { match_destroy (match->match); match->match = NULL; } if ((match->user_data != NULL) && (match->free != NULL)) (*match->free) (match->user_data); match->user_data = NULL; } sfree (obj->matches); sfree (obj); } /* void tail_match_destroy */ int tail_match_add_match (cu_tail_match_t *obj, cu_match_t *match, int (*submit_match) (cu_match_t *match, void *user_data), void *user_data, void (*free_user_data) (void *user_data)) { cu_tail_match_match_t *temp; temp = (cu_tail_match_match_t *) realloc (obj->matches, sizeof (cu_tail_match_match_t) * (obj->matches_num + 1)); if (temp == NULL) return (-1); obj->matches = temp; obj->matches_num++; temp = obj->matches + (obj->matches_num - 1); temp->match = match; temp->user_data = user_data; temp->submit = submit_match; temp->free = free_user_data; return (0); } /* int tail_match_add_match */ int tail_match_add_match_simple (cu_tail_match_t *obj, const char *regex, const char *excluderegex, int ds_type, const char *plugin, const char *plugin_instance, const char *type, const char *type_instance) { cu_match_t *match; cu_tail_match_simple_t *user_data; int status; match = match_create_simple (regex, excluderegex, ds_type); if (match == NULL) return (-1); user_data = (cu_tail_match_simple_t *) malloc (sizeof (cu_tail_match_simple_t)); if (user_data == NULL) { match_destroy (match); return (-1); } memset (user_data, '\0', sizeof (cu_tail_match_simple_t)); sstrncpy (user_data->plugin, plugin, sizeof (user_data->plugin)); if (plugin_instance != NULL) sstrncpy (user_data->plugin_instance, plugin_instance, sizeof (user_data->plugin_instance)); sstrncpy (user_data->type, type, sizeof (user_data->type)); if (type_instance != NULL) sstrncpy (user_data->type_instance, type_instance, sizeof (user_data->type_instance)); status = tail_match_add_match (obj, match, simple_submit_match, user_data, free); if (status != 0) { match_destroy (match); sfree (user_data); } return (status); } /* int tail_match_add_match_simple */ int tail_match_read (cu_tail_match_t *obj) { char buffer[4096]; int status; size_t i; status = cu_tail_read (obj->tail, buffer, sizeof (buffer), tail_callback, (void *) obj); if (status != 0) { ERROR ("tail_match: cu_tail_read failed."); return (status); } for (i = 0; i < obj->matches_num; i++) { cu_tail_match_match_t *lt_match = obj->matches + i; if (lt_match->submit == NULL) continue; (*lt_match->submit) (lt_match->match, lt_match->user_data); } return (0); } /* int tail_match_read */ /* vim: set sw=2 sts=2 ts=8 : */ collectd-5.4.0/src/PaxHeaders.11991/apple_sensors.c0000644037772200116100000000013112204120331020152 xustar000000000000000030 mtime=1376821465.061973248 30 atime=1376821477.206167738 29 ctime=1376821741.98240029 collectd-5.4.0/src/apple_sensors.c0000644037772200116100000001352612204120331016726 0ustar00octoeng00000000000000/** * collectd - src/apple_sensors.c * Copyright (C) 2006,2007 Florian octo 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: * Florian octo Forster **/ #include "collectd.h" #include "common.h" #include "plugin.h" #if HAVE_CTYPE_H # include #endif #if HAVE_MACH_MACH_TYPES_H # include #endif #if HAVE_MACH_MACH_INIT_H # include #endif #if HAVE_MACH_MACH_ERROR_H # include #endif #if HAVE_MACH_MACH_PORT_H # include #endif #if HAVE_COREFOUNDATION_COREFOUNDATION_H # include #endif #if HAVE_IOKIT_IOKITLIB_H # include #endif #if HAVE_IOKIT_IOTYPES_H # include #endif static mach_port_t io_master_port = MACH_PORT_NULL; static int as_init (void) { kern_return_t status; if (io_master_port != MACH_PORT_NULL) { mach_port_deallocate (mach_task_self (), io_master_port); io_master_port = MACH_PORT_NULL; } status = IOMasterPort (MACH_PORT_NULL, &io_master_port); if (status != kIOReturnSuccess) { ERROR ("IOMasterPort failed: %s", mach_error_string (status)); io_master_port = MACH_PORT_NULL; return (-1); } return (0); } static void as_submit (const char *type, const char *type_instance, double val) { value_t values[1]; value_list_t vl = VALUE_LIST_INIT; DEBUG ("type = %s; type_instance = %s; val = %f;", type, type_instance, val); values[0].gauge = val; vl.values = values; vl.values_len = 1; sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "apple_sensors", sizeof (vl.plugin)); sstrncpy (vl.plugin_instance, "", sizeof (vl.plugin_instance)); sstrncpy (vl.type, type, sizeof (vl.type)); sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); plugin_dispatch_values (&vl); } static int as_read (void) { kern_return_t status; io_iterator_t iterator; io_object_t io_obj; CFMutableDictionaryRef prop_dict; CFTypeRef property; char type[128]; char inst[128]; int value_int; double value_double; int i; if (!io_master_port || (io_master_port == MACH_PORT_NULL)) return (-1); status = IOServiceGetMatchingServices (io_master_port, IOServiceNameMatching("IOHWSensor"), &iterator); if (status != kIOReturnSuccess) { ERROR ("IOServiceGetMatchingServices failed: %s", mach_error_string (status)); return (-1); } while ((io_obj = IOIteratorNext (iterator))) { prop_dict = NULL; status = IORegistryEntryCreateCFProperties (io_obj, &prop_dict, kCFAllocatorDefault, kNilOptions); if (status != kIOReturnSuccess) { DEBUG ("IORegistryEntryCreateCFProperties failed: %s", mach_error_string (status)); continue; } /* Copy the sensor type. */ property = NULL; if (!CFDictionaryGetValueIfPresent (prop_dict, CFSTR ("type"), &property)) continue; if (CFGetTypeID (property) != CFStringGetTypeID ()) continue; if (!CFStringGetCString (property, type, sizeof (type), kCFStringEncodingASCII)) continue; type[sizeof (type) - 1] = '\0'; /* Copy the sensor location. This will be used as `instance'. */ property = NULL; if (!CFDictionaryGetValueIfPresent (prop_dict, CFSTR ("location"), &property)) continue; if (CFGetTypeID (property) != CFStringGetTypeID ()) continue; if (!CFStringGetCString (property, inst, sizeof (inst), kCFStringEncodingASCII)) continue; inst[sizeof (inst) - 1] = '\0'; for (i = 0; i < 128; i++) { if (inst[i] == '\0') break; else if (isalnum (inst[i])) inst[i] = (char) tolower (inst[i]); else inst[i] = '_'; } /* Get the actual value. Some computation, based on the `type' * is neccessary. */ property = NULL; if (!CFDictionaryGetValueIfPresent (prop_dict, CFSTR ("current-value"), &property)) continue; if (CFGetTypeID (property) != CFNumberGetTypeID ()) continue; if (!CFNumberGetValue (property, kCFNumberIntType, &value_int)) continue; /* Found e.g. in the 1.5GHz PowerBooks */ if (strcmp (type, "temperature") == 0) { value_double = ((double) value_int) / 65536.0; sstrncpy (type, "temperature", sizeof (type)); } else if (strcmp (type, "temp") == 0) { value_double = ((double) value_int) / 10.0; sstrncpy (type, "temperature", sizeof (type)); } else if (strcmp (type, "fanspeed") == 0) { value_double = ((double) value_int) / 65536.0; sstrncpy (type, "fanspeed", sizeof (type)); } else if (strcmp (type, "voltage") == 0) { /* Leave this to the battery plugin. */ continue; } else if (strcmp (type, "adc") == 0) { value_double = ((double) value_int) / 10.0; sstrncpy (type, "fanspeed", sizeof (type)); } else { DEBUG ("apple_sensors: Read unknown sensor type: %s", type); value_double = (double) value_int; } as_submit (type, inst, value_double); CFRelease (prop_dict); IOObjectRelease (io_obj); } /* while (iterator) */ IOObjectRelease (iterator); return (0); } /* int as_read */ void module_register (void) { plugin_register_init ("apple_sensors", as_init); plugin_register_read ("apple_sensors", as_read); } /* void module_register */ collectd-5.4.0/src/PaxHeaders.11991/utils_subst.h0000644037772200116100000000013212204120331017663 xustar000000000000000030 mtime=1376821465.089973696 30 atime=1376821477.230168122 30 ctime=1376821741.986400354 collectd-5.4.0/src/utils_subst.h0000644037772200116100000000630612204120331016434 0ustar00octoeng00000000000000/** * collectd - src/utils_subst.h * Copyright (C) 2008 Sebastian Harl * * 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: * Sebastian "tokkee" Harl **/ /* * This module provides functions for string substitution. */ #ifndef UTILS_SUBST_H #define UTILS_SUBST_H 1 #include /* * subst: * * Replace a substring of a string with the specified replacement text. The * resulting string is stored in the buffer pointed to by 'buf' of length * 'buflen'. Upon success, the buffer will always be null-terminated. The * result may be truncated if the buffer is too small. * * The substring to be replaces is identified by the two offsets 'off1' and * 'off2' where 'off1' specifies the offset to the beginning of the substring * and 'off2' specifies the offset to the first byte after the substring. * * The minimum buffer size to store the complete return value (including the * terminating '\0' character) thus has to be: * off1 + strlen(replacement) + strlen(string) - off2 + 1 * * Example: * * 01234567890 * string = "foo_____bar" * ^ ^ * | | * off1 off2 * * off1 = 3 * off2 = 8 * * replacement = " - " * * -> "foo - bar" * * The function returns 'buf' on success, NULL else. */ char *subst (char *buf, size_t buflen, const char *string, int off1, int off2, const char *replacement); /* * asubst: * * This function is very similar to subst(). It differs in that it * automatically allocates the memory required for the return value which the * user then has to free himself. * * Returns the newly allocated result string on success, NULL else. */ char *asubst (const char *string, int off1, int off2, const char *replacement); /* * subst_string: * * Works like `subst', but instead of specifying start and end offsets you * specify `needle', the string that is to be replaced. If `needle' is found * in `string' (using strstr(3)), the offset is calculated and `subst' is * called with the determined parameters. * * If the substring is not found, no error will be indicated and * `subst_string' works mostly like `strncpy'. * * If the substring appears multiple times, all appearances will be replaced. * If the substring has been found `buflen' times, an endless loop is assumed * and the loop is broken. A warning is printed and the function returns * success. */ char *subst_string (char *buf, size_t buflen, const char *string, const char *needle, const char *replacement); #endif /* UTILS_SUBST_H */ /* vim: set sw=4 ts=4 tw=78 noexpandtab : */ collectd-5.4.0/src/PaxHeaders.11991/xmms.c0000644037772200116100000000013212204120331016262 xustar000000000000000030 mtime=1376821465.093973759 30 atime=1376821477.230168122 30 ctime=1376821741.986400354 collectd-5.4.0/src/xmms.c0000644037772200116100000000345712204120331015037 0ustar00octoeng00000000000000/** * collectd - src/xmms.c * Copyright (C) 2007 Florian octo 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: * Florian octo Forster **/ #include "collectd.h" #include "plugin.h" #include "common.h" #include static gint xmms_session; static void cxmms_submit (const char *type, gauge_t value) { value_t values[1]; value_list_t vl = VALUE_LIST_INIT; values[0].gauge = value; vl.values = values; vl.values_len = 1; sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "xmms", sizeof (vl.plugin)); sstrncpy (vl.type, type, sizeof (vl.type)); plugin_dispatch_values (&vl); } /* void cxmms_submit */ int cxmms_read (void) { gint rate; gint freq; gint nch; if (!xmms_remote_is_running (xmms_session)) return (0); xmms_remote_get_info (xmms_session, &rate, &freq, &nch); if ((freq == 0) || (nch == 0)) return (-1); cxmms_submit ("bitrate", rate); cxmms_submit ("frequency", freq); return (0); } /* int read */ void module_register (void) { plugin_register_read ("xmms", cxmms_read); } /* void module_register */ /* * vim: shiftwidth=2:softtabstop=2:textwidth=78 */ collectd-5.4.0/src/PaxHeaders.11991/dbi.c0000644037772200116100000000013212204120331016034 xustar000000000000000030 mtime=1376821465.069973376 30 atime=1376821477.214167866 30 ctime=1376821741.990400418 collectd-5.4.0/src/dbi.c0000644037772200116100000005430012204120331014602 0ustar00octoeng00000000000000/** * collectd - src/dbi.c * Copyright (C) 2008-2013 Florian octo 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: * Florian octo Forster **/ #include "collectd.h" #include "common.h" #include "plugin.h" #include "configfile.h" #include "utils_db_query.h" #include /* * Data types */ struct cdbi_driver_option_s /* {{{ */ { char *key; union { char *string; int numeric; } value; _Bool is_numeric; }; typedef struct cdbi_driver_option_s cdbi_driver_option_t; /* }}} */ struct cdbi_database_s /* {{{ */ { char *name; char *select_db; char *driver; char *host; cdbi_driver_option_t *driver_options; size_t driver_options_num; udb_query_preparation_area_t **q_prep_areas; udb_query_t **queries; size_t queries_num; dbi_conn connection; }; typedef struct cdbi_database_s cdbi_database_t; /* }}} */ /* * Global variables */ static udb_query_t **queries = NULL; static size_t queries_num = 0; static cdbi_database_t **databases = NULL; static size_t databases_num = 0; /* * Functions */ static const char *cdbi_strerror (dbi_conn conn, /* {{{ */ char *buffer, size_t buffer_size) { const char *msg; int status; if (conn == NULL) { sstrncpy (buffer, "connection is NULL", buffer_size); return (buffer); } msg = NULL; status = dbi_conn_error (conn, &msg); if ((status >= 0) && (msg != NULL)) ssnprintf (buffer, buffer_size, "%s (status %i)", msg, status); else ssnprintf (buffer, buffer_size, "dbi_conn_error failed with status %i", status); return (buffer); } /* }}} const char *cdbi_conn_error */ static int cdbi_result_get_field (dbi_result res, /* {{{ */ unsigned int index, char *buffer, size_t buffer_size) { unsigned short src_type; src_type = dbi_result_get_field_type_idx (res, index); if (src_type == DBI_TYPE_ERROR) { ERROR ("dbi plugin: cdbi_result_get: " "dbi_result_get_field_type_idx failed."); return (-1); } if (src_type == DBI_TYPE_INTEGER) { long long value; value = dbi_result_get_longlong_idx (res, index); ssnprintf (buffer, buffer_size, "%lli", value); } else if (src_type == DBI_TYPE_DECIMAL) { double value; value = dbi_result_get_double_idx (res, index); ssnprintf (buffer, buffer_size, "%63.15g", value); } else if (src_type == DBI_TYPE_STRING) { const char *value; value = dbi_result_get_string_idx (res, index); if (value == NULL) sstrncpy (buffer, "", buffer_size); else if (strcmp ("ERROR", value) == 0) return (-1); else sstrncpy (buffer, value, buffer_size); } /* DBI_TYPE_BINARY */ /* DBI_TYPE_DATETIME */ else { const char *field_name; field_name = dbi_result_get_field_name (res, index); if (field_name == NULL) field_name = ""; ERROR ("dbi plugin: Column `%s': Don't know how to handle " "source type %hu.", field_name, src_type); return (-1); } return (0); } /* }}} int cdbi_result_get_field */ static void cdbi_database_free (cdbi_database_t *db) /* {{{ */ { size_t i; if (db == NULL) return; sfree (db->name); sfree (db->driver); for (i = 0; i < db->driver_options_num; i++) { sfree (db->driver_options[i].key); if (!db->driver_options[i].is_numeric) sfree (db->driver_options[i].value.string); } sfree (db->driver_options); if (db->q_prep_areas) for (i = 0; i < db->queries_num; ++i) udb_query_delete_preparation_area (db->q_prep_areas[i]); free (db->q_prep_areas); sfree (db); } /* }}} void cdbi_database_free */ /* Configuration handling functions {{{ * * * * Statement "SELECT name, value FROM table" * * Type "gauge" * InstancesFrom "name" * ValuesFrom "value" * * ... * * * * Driver "mysql" * DriverOption "hostname" "localhost" * ... * Query "plugin_instance0" * * */ static int cdbi_config_add_database_driver_option (cdbi_database_t *db, /* {{{ */ oconfig_item_t *ci) { cdbi_driver_option_t *option; if ((ci->values_num != 2) || (ci->values[0].type != OCONFIG_TYPE_STRING) || ((ci->values[1].type != OCONFIG_TYPE_STRING) && (ci->values[1].type != OCONFIG_TYPE_NUMBER))) { WARNING ("dbi plugin: The `DriverOption' config option " "needs exactly two arguments."); return (-1); } option = (cdbi_driver_option_t *) realloc (db->driver_options, sizeof (*option) * (db->driver_options_num + 1)); if (option == NULL) { ERROR ("dbi plugin: realloc failed"); return (-1); } db->driver_options = option; option = db->driver_options + db->driver_options_num; memset (option, 0, sizeof (*option)); option->key = strdup (ci->values[0].value.string); if (option->key == NULL) { ERROR ("dbi plugin: strdup failed."); return (-1); } if (ci->values[1].type == OCONFIG_TYPE_STRING) { option->value.string = strdup (ci->values[1].value.string); if (option->value.string == NULL) { ERROR ("dbi plugin: strdup failed."); sfree (option->key); return (-1); } } else { assert (ci->values[1].type == OCONFIG_TYPE_NUMBER); option->value.numeric = (int) (ci->values[1].value.number + .5); option->is_numeric = 1; } db->driver_options_num++; return (0); } /* }}} int cdbi_config_add_database_driver_option */ static int cdbi_config_add_database (oconfig_item_t *ci) /* {{{ */ { cdbi_database_t *db; int status; int i; if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { WARNING ("dbi plugin: The `Database' block " "needs exactly one string argument."); return (-1); } db = (cdbi_database_t *) malloc (sizeof (*db)); if (db == NULL) { ERROR ("dbi plugin: malloc failed."); return (-1); } memset (db, 0, sizeof (*db)); status = cf_util_get_string (ci, &db->name); if (status != 0) { sfree (db); return (status); } /* Fill the `cdbi_database_t' structure.. */ for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("Driver", child->key) == 0) status = cf_util_get_string (child, &db->driver); else if (strcasecmp ("DriverOption", child->key) == 0) status = cdbi_config_add_database_driver_option (db, child); else if (strcasecmp ("SelectDB", child->key) == 0) status = cf_util_get_string (child, &db->select_db); else if (strcasecmp ("Query", child->key) == 0) status = udb_query_pick_from_list (child, queries, queries_num, &db->queries, &db->queries_num); else if (strcasecmp ("Host", child->key) == 0) status = cf_util_get_string (child, &db->host); else { WARNING ("dbi plugin: Option `%s' not allowed here.", child->key); status = -1; } if (status != 0) break; } /* Check that all necessary options have been given. */ while (status == 0) { if (db->driver == NULL) { WARNING ("dbi plugin: `Driver' not given for database `%s'", db->name); status = -1; } if (db->driver_options_num == 0) { WARNING ("dbi plugin: No `DriverOption' given for database `%s'. " "This will likely not work.", db->name); } break; } /* while (status == 0) */ while ((status == 0) && (db->queries_num > 0)) { db->q_prep_areas = (udb_query_preparation_area_t **) calloc ( db->queries_num, sizeof (*db->q_prep_areas)); if (db->q_prep_areas == NULL) { WARNING ("dbi plugin: malloc failed"); status = -1; break; } for (i = 0; i < db->queries_num; ++i) { db->q_prep_areas[i] = udb_query_allocate_preparation_area (db->queries[i]); if (db->q_prep_areas[i] == NULL) { WARNING ("dbi plugin: udb_query_allocate_preparation_area failed"); status = -1; break; } } break; } /* If all went well, add this database to the global list of databases. */ if (status == 0) { cdbi_database_t **temp; temp = (cdbi_database_t **) realloc (databases, sizeof (*databases) * (databases_num + 1)); if (temp == NULL) { ERROR ("dbi plugin: realloc failed"); status = -1; } else { databases = temp; databases[databases_num] = db; databases_num++; } } if (status != 0) { cdbi_database_free (db); return (-1); } return (0); } /* }}} int cdbi_config_add_database */ static int cdbi_config (oconfig_item_t *ci) /* {{{ */ { int i; for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("Query", child->key) == 0) udb_query_create (&queries, &queries_num, child, /* callback = */ NULL); else if (strcasecmp ("Database", child->key) == 0) cdbi_config_add_database (child); else { WARNING ("snmp plugin: Ignoring unknown config option `%s'.", child->key); } } /* for (ci->children) */ return (0); } /* }}} int cdbi_config */ /* }}} End of configuration handling functions */ static int cdbi_init (void) /* {{{ */ { static int did_init = 0; int status; if (did_init != 0) return (0); if (queries_num == 0) { ERROR ("dbi plugin: No blocks have been found. Without them, " "this plugin can't do anything useful, so we will returns an error."); return (-1); } if (databases_num == 0) { ERROR ("dbi plugin: No blocks have been found. Without them, " "this plugin can't do anything useful, so we will returns an error."); return (-1); } status = dbi_initialize (NULL); if (status < 0) { ERROR ("dbi plugin: cdbi_init: dbi_initialize failed with status %i.", status); return (-1); } else if (status == 0) { ERROR ("dbi plugin: `dbi_initialize' could not load any drivers. Please " "install at least one `DBD' or check your installation."); return (-1); } DEBUG ("dbi plugin: cdbi_init: dbi_initialize reports %i driver%s.", status, (status == 1) ? "" : "s"); return (0); } /* }}} int cdbi_init */ static int cdbi_read_database_query (cdbi_database_t *db, /* {{{ */ udb_query_t *q, udb_query_preparation_area_t *prep_area) { const char *statement; dbi_result res; size_t column_num; char **column_names; char **column_values; int status; size_t i; /* Macro that cleans up dynamically allocated memory and returns the * specified status. */ #define BAIL_OUT(status) \ if (column_names != NULL) { sfree (column_names[0]); sfree (column_names); } \ if (column_values != NULL) { sfree (column_values[0]); sfree (column_values); } \ if (res != NULL) { dbi_result_free (res); res = NULL; } \ return (status) column_names = NULL; column_values = NULL; res = NULL; statement = udb_query_get_statement (q); assert (statement != NULL); res = dbi_conn_query (db->connection, statement); if (res == NULL) { char errbuf[1024]; ERROR ("dbi plugin: cdbi_read_database_query (%s, %s): " "dbi_conn_query failed: %s", db->name, udb_query_get_name (q), cdbi_strerror (db->connection, errbuf, sizeof (errbuf))); BAIL_OUT (-1); } else /* Get the number of columns */ { unsigned int db_status; db_status = dbi_result_get_numfields (res); if (db_status == DBI_FIELD_ERROR) { char errbuf[1024]; ERROR ("dbi plugin: cdbi_read_database_query (%s, %s): " "dbi_result_get_numfields failed: %s", db->name, udb_query_get_name (q), cdbi_strerror (db->connection, errbuf, sizeof (errbuf))); BAIL_OUT (-1); } column_num = (size_t) db_status; DEBUG ("cdbi_read_database_query (%s, %s): There are %zu columns.", db->name, udb_query_get_name (q), column_num); } /* Allocate `column_names' and `column_values'. {{{ */ column_names = (char **) calloc (column_num, sizeof (char *)); if (column_names == NULL) { ERROR ("dbi plugin: malloc failed."); BAIL_OUT (-1); } column_names[0] = (char *) calloc (column_num, DATA_MAX_NAME_LEN * sizeof (char)); if (column_names[0] == NULL) { ERROR ("dbi plugin: malloc failed."); BAIL_OUT (-1); } for (i = 1; i < column_num; i++) column_names[i] = column_names[i - 1] + DATA_MAX_NAME_LEN; column_values = (char **) calloc (column_num, sizeof (char *)); if (column_values == NULL) { ERROR ("dbi plugin: malloc failed."); BAIL_OUT (-1); } column_values[0] = (char *) calloc (column_num, DATA_MAX_NAME_LEN * sizeof (char)); if (column_values[0] == NULL) { ERROR ("dbi plugin: malloc failed."); BAIL_OUT (-1); } for (i = 1; i < column_num; i++) column_values[i] = column_values[i - 1] + DATA_MAX_NAME_LEN; /* }}} */ /* Copy the field names to `column_names' */ for (i = 0; i < column_num; i++) /* {{{ */ { const char *column_name; column_name = dbi_result_get_field_name (res, (unsigned int) (i + 1)); if (column_name == NULL) { ERROR ("dbi plugin: cdbi_read_database_query (%s, %s): " "Cannot retrieve name of field %zu.", db->name, udb_query_get_name (q), i + 1); BAIL_OUT (-1); } sstrncpy (column_names[i], column_name, DATA_MAX_NAME_LEN); } /* }}} for (i = 0; i < column_num; i++) */ udb_query_prepare_result (q, prep_area, (db->host ? db->host : hostname_g), /* plugin = */ "dbi", db->name, column_names, column_num, /* interval = */ 0); /* 0 = error; 1 = success; */ status = dbi_result_first_row (res); /* {{{ */ if (status != 1) { char errbuf[1024]; ERROR ("dbi plugin: cdbi_read_database_query (%s, %s): " "dbi_result_first_row failed: %s. Maybe the statement didn't " "return any rows?", db->name, udb_query_get_name (q), cdbi_strerror (db->connection, errbuf, sizeof (errbuf))); udb_query_finish_result (q, prep_area); BAIL_OUT (-1); } /* }}} */ /* Iterate over all rows and call `udb_query_handle_result' with each list of * values. */ while (42) /* {{{ */ { status = 0; /* Copy the value of the columns to `column_values' */ for (i = 0; i < column_num; i++) /* {{{ */ { status = cdbi_result_get_field (res, (unsigned int) (i + 1), column_values[i], DATA_MAX_NAME_LEN); if (status != 0) { ERROR ("dbi plugin: cdbi_read_database_query (%s, %s): " "cdbi_result_get_field (%zu) failed.", db->name, udb_query_get_name (q), i + 1); status = -1; break; } } /* }}} for (i = 0; i < column_num; i++) */ /* If all values were copied successfully, call `udb_query_handle_result' * to dispatch the row to the daemon. */ if (status == 0) /* {{{ */ { status = udb_query_handle_result (q, prep_area, column_values); if (status != 0) { ERROR ("dbi plugin: cdbi_read_database_query (%s, %s): " "udb_query_handle_result failed.", db->name, udb_query_get_name (q)); } } /* }}} */ /* Get the next row from the database. */ status = dbi_result_next_row (res); /* {{{ */ if (status != 1) { if (dbi_conn_error (db->connection, NULL) != 0) { char errbuf[1024]; WARNING ("dbi plugin: cdbi_read_database_query (%s, %s): " "dbi_result_next_row failed: %s.", db->name, udb_query_get_name (q), cdbi_strerror (db->connection, errbuf, sizeof (errbuf))); } break; } /* }}} */ } /* }}} while (42) */ /* Tell the db query interface that we're done with this query. */ udb_query_finish_result (q, prep_area); /* Clean up and return `status = 0' (success) */ BAIL_OUT (0); #undef BAIL_OUT } /* }}} int cdbi_read_database_query */ static int cdbi_connect_database (cdbi_database_t *db) /* {{{ */ { dbi_driver driver; dbi_conn connection; size_t i; int status; if (db->connection != NULL) { status = dbi_conn_ping (db->connection); if (status != 0) /* connection is alive */ return (0); dbi_conn_close (db->connection); db->connection = NULL; } driver = dbi_driver_open (db->driver); if (driver == NULL) { ERROR ("dbi plugin: cdbi_connect_database: dbi_driver_open (%s) failed.", db->driver); INFO ("dbi plugin: Maybe the driver isn't installed? " "Known drivers are:"); for (driver = dbi_driver_list (NULL); driver != NULL; driver = dbi_driver_list (driver)) { INFO ("dbi plugin: * %s", dbi_driver_get_name (driver)); } return (-1); } connection = dbi_conn_open (driver); if (connection == NULL) { ERROR ("dbi plugin: cdbi_connect_database: dbi_conn_open (%s) failed.", db->driver); return (-1); } /* Set all the driver options. Because this is a very very very generic * interface, the error handling is kind of long. If an invalid option is * encountered, it will get a list of options understood by the driver and * report that as `INFO'. This way, users hopefully don't have too much * trouble finding out how to configure the plugin correctly.. */ for (i = 0; i < db->driver_options_num; i++) { if (db->driver_options[i].is_numeric) { status = dbi_conn_set_option_numeric (connection, db->driver_options[i].key, db->driver_options[i].value.numeric); if (status != 0) { char errbuf[1024]; ERROR ("dbi plugin: cdbi_connect_database (%s): " "dbi_conn_set_option_numeric (\"%s\", %i) failed: %s.", db->name, db->driver_options[i].key, db->driver_options[i].value.numeric, cdbi_strerror (connection, errbuf, sizeof (errbuf))); } } else { status = dbi_conn_set_option (connection, db->driver_options[i].key, db->driver_options[i].value.string); if (status != 0) { char errbuf[1024]; ERROR ("dbi plugin: cdbi_connect_database (%s): " "dbi_conn_set_option (\"%s\", \"%s\") failed: %s.", db->name, db->driver_options[i].key, db->driver_options[i].value.string, cdbi_strerror (connection, errbuf, sizeof (errbuf))); } } if (status != 0) { char const *opt; INFO ("dbi plugin: This is a list of all options understood " "by the `%s' driver:", db->driver); for (opt = dbi_conn_get_option_list (connection, NULL); opt != NULL; opt = dbi_conn_get_option_list (connection, opt)) { INFO ("dbi plugin: * %s", opt); } dbi_conn_close (connection); return (-1); } } /* for (i = 0; i < db->driver_options_num; i++) */ status = dbi_conn_connect (connection); if (status != 0) { char errbuf[1024]; ERROR ("dbi plugin: cdbi_connect_database (%s): " "dbi_conn_connect failed: %s", db->name, cdbi_strerror (connection, errbuf, sizeof (errbuf))); dbi_conn_close (connection); return (-1); } if (db->select_db != NULL) { status = dbi_conn_select_db (connection, db->select_db); if (status != 0) { char errbuf[1024]; WARNING ("dbi plugin: cdbi_connect_database (%s): " "dbi_conn_select_db (%s) failed: %s. Check the `SelectDB' option.", db->name, db->select_db, cdbi_strerror (connection, errbuf, sizeof (errbuf))); dbi_conn_close (connection); return (-1); } } db->connection = connection; return (0); } /* }}} int cdbi_connect_database */ static int cdbi_read_database (cdbi_database_t *db) /* {{{ */ { size_t i; int success; int status; unsigned int db_version; status = cdbi_connect_database (db); if (status != 0) return (status); assert (db->connection != NULL); db_version = dbi_conn_get_engine_version (db->connection); /* TODO: Complain if `db_version == 0' */ success = 0; for (i = 0; i < db->queries_num; i++) { /* Check if we know the database's version and if so, if this query applies * to that version. */ if ((db_version != 0) && (udb_query_check_version (db->queries[i], db_version) == 0)) continue; status = cdbi_read_database_query (db, db->queries[i], db->q_prep_areas[i]); if (status == 0) success++; } if (success == 0) { ERROR ("dbi plugin: All queries failed for database `%s'.", db->name); return (-1); } return (0); } /* }}} int cdbi_read_database */ static int cdbi_read (void) /* {{{ */ { size_t i; int success = 0; int status; for (i = 0; i < databases_num; i++) { status = cdbi_read_database (databases[i]); if (status == 0) success++; } if (success == 0) { ERROR ("dbi plugin: No database could be read. Will return an error so " "the plugin will be delayed."); return (-1); } return (0); } /* }}} int cdbi_read */ static int cdbi_shutdown (void) /* {{{ */ { size_t i; for (i = 0; i < databases_num; i++) { if (databases[i]->connection != NULL) { dbi_conn_close (databases[i]->connection); databases[i]->connection = NULL; } cdbi_database_free (databases[i]); } sfree (databases); databases_num = 0; udb_query_free (queries, queries_num); queries = NULL; queries_num = 0; return (0); } /* }}} int cdbi_shutdown */ void module_register (void) /* {{{ */ { plugin_register_complex_config ("dbi", cdbi_config); plugin_register_init ("dbi", cdbi_init); plugin_register_read ("dbi", cdbi_read); plugin_register_shutdown ("dbi", cdbi_shutdown); } /* }}} void module_register */ /* * vim: shiftwidth=2 softtabstop=2 et fdm=marker */ collectd-5.4.0/src/PaxHeaders.11991/mysql.c0000644037772200116100000000013212204120331016443 xustar000000000000000030 mtime=1376821465.077973503 30 atime=1376821477.222167995 30 ctime=1376821741.990400418 collectd-5.4.0/src/mysql.c0000644037772200116100000004332512204120331015216 0ustar00octoeng00000000000000/** * collectd - src/mysql.c * Copyright (C) 2006-2010 Florian octo Forster * Copyright (C) 2008 Mirko Buffoni * Copyright (C) 2009 Doug MacEachern * Copyright (C) 2009 Sebastian tokkee Harl * Copyright (C) 2009 Rodolphe Quiédeville * * 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: * Florian octo Forster * Mirko Buffoni * Doug MacEachern * Sebastian tokkee Harl * Rodolphe Quiédeville **/ #include "collectd.h" #include "common.h" #include "plugin.h" #include "configfile.h" #ifdef HAVE_MYSQL_H #include #elif defined(HAVE_MYSQL_MYSQL_H) #include #endif /* TODO: Understand `Select_*' and possibly do that stuff as well.. */ struct mysql_database_s /* {{{ */ { char *instance; char *host; char *user; char *pass; char *database; char *socket; int port; _Bool master_stats; _Bool slave_stats; _Bool slave_notif; _Bool slave_io_running; _Bool slave_sql_running; MYSQL *con; _Bool is_connected; }; typedef struct mysql_database_s mysql_database_t; /* }}} */ static int mysql_read (user_data_t *ud); static void mysql_database_free (void *arg) /* {{{ */ { mysql_database_t *db; DEBUG ("mysql plugin: mysql_database_free (arg = %p);", arg); db = (mysql_database_t *) arg; if (db == NULL) return; if (db->con != NULL) mysql_close (db->con); sfree (db->host); sfree (db->user); sfree (db->pass); sfree (db->socket); sfree (db->instance); sfree (db->database); sfree (db); } /* }}} void mysql_database_free */ /* Configuration handling functions {{{ * * * * Host "localhost" * Port 22000 * ... * * */ static int mysql_config_database (oconfig_item_t *ci) /* {{{ */ { mysql_database_t *db; int status = 0; int i; if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { WARNING ("mysql plugin: The `Database' block " "needs exactly one string argument."); return (-1); } db = (mysql_database_t *) malloc (sizeof (*db)); if (db == NULL) { ERROR ("mysql plugin: malloc failed."); return (-1); } memset (db, 0, sizeof (*db)); /* initialize all the pointers */ db->host = NULL; db->user = NULL; db->pass = NULL; db->database = NULL; db->socket = NULL; db->con = NULL; /* trigger a notification, if it's not running */ db->slave_io_running = 1; db->slave_sql_running = 1; status = cf_util_get_string (ci, &db->instance); if (status != 0) { sfree (db); return (status); } assert (db->instance != NULL); /* Fill the `mysql_database_t' structure.. */ for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("Host", child->key) == 0) status = cf_util_get_string (child, &db->host); else if (strcasecmp ("User", child->key) == 0) status = cf_util_get_string (child, &db->user); else if (strcasecmp ("Password", child->key) == 0) status = cf_util_get_string (child, &db->pass); else if (strcasecmp ("Port", child->key) == 0) { status = cf_util_get_port_number (child); if (status > 0) { db->port = status; status = 0; } } else if (strcasecmp ("Socket", child->key) == 0) status = cf_util_get_string (child, &db->socket); else if (strcasecmp ("Database", child->key) == 0) status = cf_util_get_string (child, &db->database); else if (strcasecmp ("MasterStats", child->key) == 0) status = cf_util_get_boolean (child, &db->master_stats); else if (strcasecmp ("SlaveStats", child->key) == 0) status = cf_util_get_boolean (child, &db->slave_stats); else if (strcasecmp ("SlaveNotifications", child->key) == 0) status = cf_util_get_boolean (child, &db->slave_notif); else { WARNING ("mysql plugin: Option `%s' not allowed here.", child->key); status = -1; } if (status != 0) break; } /* If all went well, register this database for reading */ if (status == 0) { user_data_t ud; char cb_name[DATA_MAX_NAME_LEN]; DEBUG ("mysql plugin: Registering new read callback: %s", (db->database != NULL) ? db->database : ""); memset (&ud, 0, sizeof (ud)); ud.data = (void *) db; ud.free_func = mysql_database_free; if (db->instance != NULL) ssnprintf (cb_name, sizeof (cb_name), "mysql-%s", db->instance); else sstrncpy (cb_name, "mysql", sizeof (cb_name)); plugin_register_complex_read (/* group = */ NULL, cb_name, mysql_read, /* interval = */ NULL, &ud); } else { mysql_database_free (db); return (-1); } return (0); } /* }}} int mysql_config_database */ static int mysql_config (oconfig_item_t *ci) /* {{{ */ { int i; if (ci == NULL) return (EINVAL); /* Fill the `mysql_database_t' structure.. */ for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("Database", child->key) == 0) mysql_config_database (child); else WARNING ("mysql plugin: Option \"%s\" not allowed here.", child->key); } return (0); } /* }}} int mysql_config */ /* }}} End of configuration handling functions */ static MYSQL *getconnection (mysql_database_t *db) { if (db->is_connected) { int status; status = mysql_ping (db->con); if (status == 0) return (db->con); WARNING ("mysql plugin: Lost connection to instance \"%s\": %s", db->instance, mysql_error (db->con)); } db->is_connected = 0; if (db->con == NULL) { db->con = mysql_init (NULL); if (db->con == NULL) { ERROR ("mysql plugin: mysql_init failed: %s", mysql_error (db->con)); return (NULL); } } if (mysql_real_connect (db->con, db->host, db->user, db->pass, db->database, db->port, db->socket, 0) == NULL) { ERROR ("mysql plugin: Failed to connect to database %s " "at server %s: %s", (db->database != NULL) ? db->database : "", (db->host != NULL) ? db->host : "localhost", mysql_error (db->con)); return (NULL); } INFO ("mysql plugin: Successfully connected to database %s " "at server %s (server version: %s, protocol version: %d)", (db->database != NULL) ? db->database : "", mysql_get_host_info (db->con), mysql_get_server_info (db->con), mysql_get_proto_info (db->con)); db->is_connected = 1; return (db->con); } /* static MYSQL *getconnection (mysql_database_t *db) */ static void set_host (mysql_database_t *db, char *buf, size_t buflen) { if ((db->host == NULL) || (strcmp ("", db->host) == 0) || (strcmp ("localhost", db->host) == 0)) sstrncpy (buf, hostname_g, buflen); else sstrncpy (buf, db->host, buflen); } /* void set_host */ static void submit (const char *type, const char *type_instance, value_t *values, size_t values_len, mysql_database_t *db) { value_list_t vl = VALUE_LIST_INIT; vl.values = values; vl.values_len = values_len; set_host (db, vl.host, sizeof (vl.host)); sstrncpy (vl.plugin, "mysql", sizeof (vl.plugin)); /* Assured by "mysql_config_database" */ assert (db->instance != NULL); sstrncpy (vl.plugin_instance, db->instance, sizeof (vl.plugin_instance)); sstrncpy (vl.type, type, sizeof (vl.type)); if (type_instance != NULL) sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); plugin_dispatch_values (&vl); } /* submit */ static void counter_submit (const char *type, const char *type_instance, derive_t value, mysql_database_t *db) { value_t values[1]; values[0].derive = value; submit (type, type_instance, values, STATIC_ARRAY_SIZE (values), db); } /* void counter_submit */ static void gauge_submit (const char *type, const char *type_instance, gauge_t value, mysql_database_t *db) { value_t values[1]; values[0].gauge = value; submit (type, type_instance, values, STATIC_ARRAY_SIZE (values), db); } /* void gauge_submit */ static void derive_submit (const char *type, const char *type_instance, derive_t value, mysql_database_t *db) { value_t values[1]; values[0].derive = value; submit (type, type_instance, values, STATIC_ARRAY_SIZE (values), db); } /* void derive_submit */ static void traffic_submit (derive_t rx, derive_t tx, mysql_database_t *db) { value_t values[2]; values[0].derive = rx; values[1].derive = tx; submit ("mysql_octets", NULL, values, STATIC_ARRAY_SIZE (values), db); } /* void traffic_submit */ static MYSQL_RES *exec_query (MYSQL *con, const char *query) { MYSQL_RES *res; int query_len = strlen (query); if (mysql_real_query (con, query, query_len)) { ERROR ("mysql plugin: Failed to execute query: %s", mysql_error (con)); INFO ("mysql plugin: SQL query was: %s", query); return (NULL); } res = mysql_store_result (con); if (res == NULL) { ERROR ("mysql plugin: Failed to store query result: %s", mysql_error (con)); INFO ("mysql plugin: SQL query was: %s", query); return (NULL); } return (res); } /* exec_query */ static int mysql_read_master_stats (mysql_database_t *db, MYSQL *con) { MYSQL_RES *res; MYSQL_ROW row; char *query; int field_num; unsigned long long position; query = "SHOW MASTER STATUS"; res = exec_query (con, query); if (res == NULL) return (-1); row = mysql_fetch_row (res); if (row == NULL) { ERROR ("mysql plugin: Failed to get master statistics: " "`%s' did not return any rows.", query); mysql_free_result (res); return (-1); } field_num = mysql_num_fields (res); if (field_num < 2) { ERROR ("mysql plugin: Failed to get master statistics: " "`%s' returned less than two columns.", query); mysql_free_result (res); return (-1); } position = atoll (row[1]); counter_submit ("mysql_log_position", "master-bin", position, db); row = mysql_fetch_row (res); if (row != NULL) WARNING ("mysql plugin: `%s' returned more than one row - " "ignoring further results.", query); mysql_free_result (res); return (0); } /* mysql_read_master_stats */ static int mysql_read_slave_stats (mysql_database_t *db, MYSQL *con) { MYSQL_RES *res; MYSQL_ROW row; char *query; int field_num; /* WTF? libmysqlclient does not seem to provide any means to * translate a column name to a column index ... :-/ */ const int READ_MASTER_LOG_POS_IDX = 6; const int SLAVE_IO_RUNNING_IDX = 10; const int SLAVE_SQL_RUNNING_IDX = 11; const int EXEC_MASTER_LOG_POS_IDX = 21; const int SECONDS_BEHIND_MASTER_IDX = 32; query = "SHOW SLAVE STATUS"; res = exec_query (con, query); if (res == NULL) return (-1); row = mysql_fetch_row (res); if (row == NULL) { ERROR ("mysql plugin: Failed to get slave statistics: " "`%s' did not return any rows.", query); mysql_free_result (res); return (-1); } field_num = mysql_num_fields (res); if (field_num < 33) { ERROR ("mysql plugin: Failed to get slave statistics: " "`%s' returned less than 33 columns.", query); mysql_free_result (res); return (-1); } if (db->slave_stats) { unsigned long long counter; double gauge; counter = atoll (row[READ_MASTER_LOG_POS_IDX]); counter_submit ("mysql_log_position", "slave-read", counter, db); counter = atoll (row[EXEC_MASTER_LOG_POS_IDX]); counter_submit ("mysql_log_position", "slave-exec", counter, db); if (row[SECONDS_BEHIND_MASTER_IDX] != NULL) { gauge = atof (row[SECONDS_BEHIND_MASTER_IDX]); gauge_submit ("time_offset", NULL, gauge, db); } } if (db->slave_notif) { notification_t n = { 0, cdtime (), "", "", "mysql", "", "time_offset", "", NULL }; char *io, *sql; io = row[SLAVE_IO_RUNNING_IDX]; sql = row[SLAVE_SQL_RUNNING_IDX]; set_host (db, n.host, sizeof (n.host)); /* Assured by "mysql_config_database" */ assert (db->instance != NULL); sstrncpy (n.plugin_instance, db->instance, sizeof (n.plugin_instance)); if (((io == NULL) || (strcasecmp (io, "yes") != 0)) && (db->slave_io_running)) { n.severity = NOTIF_WARNING; ssnprintf (n.message, sizeof (n.message), "slave I/O thread not started or not connected to master"); plugin_dispatch_notification (&n); db->slave_io_running = 0; } else if (((io != NULL) && (strcasecmp (io, "yes") == 0)) && (! db->slave_io_running)) { n.severity = NOTIF_OKAY; ssnprintf (n.message, sizeof (n.message), "slave I/O thread started and connected to master"); plugin_dispatch_notification (&n); db->slave_io_running = 1; } if (((sql == NULL) || (strcasecmp (sql, "yes") != 0)) && (db->slave_sql_running)) { n.severity = NOTIF_WARNING; ssnprintf (n.message, sizeof (n.message), "slave SQL thread not started"); plugin_dispatch_notification (&n); db->slave_sql_running = 0; } else if (((sql != NULL) && (strcasecmp (sql, "yes") == 0)) && (! db->slave_sql_running)) { n.severity = NOTIF_OKAY; ssnprintf (n.message, sizeof (n.message), "slave SQL thread started"); plugin_dispatch_notification (&n); db->slave_sql_running = 1; } } row = mysql_fetch_row (res); if (row != NULL) WARNING ("mysql plugin: `%s' returned more than one row - " "ignoring further results.", query); mysql_free_result (res); return (0); } /* mysql_read_slave_stats */ static int mysql_read (user_data_t *ud) { mysql_database_t *db; MYSQL *con; MYSQL_RES *res; MYSQL_ROW row; char *query; derive_t qcache_hits = 0; derive_t qcache_inserts = 0; derive_t qcache_not_cached = 0; derive_t qcache_lowmem_prunes = 0; gauge_t qcache_queries_in_cache = NAN; gauge_t threads_running = NAN; gauge_t threads_connected = NAN; gauge_t threads_cached = NAN; derive_t threads_created = 0; unsigned long long traffic_incoming = 0ULL; unsigned long long traffic_outgoing = 0ULL; if ((ud == NULL) || (ud->data == NULL)) { ERROR ("mysql plugin: mysql_database_read: Invalid user data."); return (-1); } db = (mysql_database_t *) ud->data; /* An error message will have been printed in this case */ if ((con = getconnection (db)) == NULL) return (-1); query = "SHOW STATUS"; if (mysql_get_server_version (con) >= 50002) query = "SHOW GLOBAL STATUS"; res = exec_query (con, query); if (res == NULL) return (-1); while ((row = mysql_fetch_row (res))) { char *key; unsigned long long val; key = row[0]; val = atoll (row[1]); if (strncmp (key, "Com_", strlen ("Com_")) == 0) { if (val == 0ULL) continue; /* Ignore `prepared statements' */ if (strncmp (key, "Com_stmt_", strlen ("Com_stmt_")) != 0) counter_submit ("mysql_commands", key + strlen ("Com_"), val, db); } else if (strncmp (key, "Handler_", strlen ("Handler_")) == 0) { if (val == 0ULL) continue; counter_submit ("mysql_handler", key + strlen ("Handler_"), val, db); } else if (strncmp (key, "Qcache_", strlen ("Qcache_")) == 0) { if (strcmp (key, "Qcache_hits") == 0) qcache_hits = (derive_t) val; else if (strcmp (key, "Qcache_inserts") == 0) qcache_inserts = (derive_t) val; else if (strcmp (key, "Qcache_not_cached") == 0) qcache_not_cached = (derive_t) val; else if (strcmp (key, "Qcache_lowmem_prunes") == 0) qcache_lowmem_prunes = (derive_t) val; else if (strcmp (key, "Qcache_queries_in_cache") == 0) qcache_queries_in_cache = (gauge_t) val; } else if (strncmp (key, "Bytes_", strlen ("Bytes_")) == 0) { if (strcmp (key, "Bytes_received") == 0) traffic_incoming += val; else if (strcmp (key, "Bytes_sent") == 0) traffic_outgoing += val; } else if (strncmp (key, "Threads_", strlen ("Threads_")) == 0) { if (strcmp (key, "Threads_running") == 0) threads_running = (gauge_t) val; else if (strcmp (key, "Threads_connected") == 0) threads_connected = (gauge_t) val; else if (strcmp (key, "Threads_cached") == 0) threads_cached = (gauge_t) val; else if (strcmp (key, "Threads_created") == 0) threads_created = (derive_t) val; } else if (strncmp (key, "Table_locks_", strlen ("Table_locks_")) == 0) { counter_submit ("mysql_locks", key + strlen ("Table_locks_"), val, db); } } mysql_free_result (res); res = NULL; if ((qcache_hits != 0) || (qcache_inserts != 0) || (qcache_not_cached != 0) || (qcache_lowmem_prunes != 0)) { derive_submit ("cache_result", "qcache-hits", qcache_hits, db); derive_submit ("cache_result", "qcache-inserts", qcache_inserts, db); derive_submit ("cache_result", "qcache-not_cached", qcache_not_cached, db); derive_submit ("cache_result", "qcache-prunes", qcache_lowmem_prunes, db); gauge_submit ("cache_size", "qcache", qcache_queries_in_cache, db); } if (threads_created != 0) { gauge_submit ("threads", "running", threads_running, db); gauge_submit ("threads", "connected", threads_connected, db); gauge_submit ("threads", "cached", threads_cached, db); derive_submit ("total_threads", "created", threads_created, db); } traffic_submit (traffic_incoming, traffic_outgoing, db); if (db->master_stats) mysql_read_master_stats (db, con); if ((db->slave_stats) || (db->slave_notif)) mysql_read_slave_stats (db, con); return (0); } /* int mysql_read */ void module_register (void) { plugin_register_complex_config ("mysql", mysql_config); } /* void module_register */ collectd-5.4.0/src/PaxHeaders.11991/apache.c0000644037772200116100000000013212204120331016517 xustar000000000000000030 mtime=1376821465.061973248 30 atime=1376821477.206167738 30 ctime=1376821741.994400482 collectd-5.4.0/src/apache.c0000644037772200116100000004232612204120331015272 0ustar00octoeng00000000000000/** * collectd - src/apache.c * Copyright (C) 2006-2010 Florian octo Forster * Copyright (C) 2007 Florent EppO Monbillard * Copyright (C) 2009 Amit Gupta * * 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: * Florian octo Forster * Florent EppO Monbillard * - connections/lighttpd extension * Amit Gupta **/ #include "collectd.h" #include "common.h" #include "plugin.h" #include "configfile.h" #include enum server_enum { APACHE = 0, LIGHTTPD }; struct apache_s { int server_type; char *name; char *host; char *url; char *user; char *pass; int verify_peer; int verify_host; char *cacert; char *server; /* user specific server type */ char *apache_buffer; char apache_curl_error[CURL_ERROR_SIZE]; size_t apache_buffer_size; size_t apache_buffer_fill; CURL *curl; }; /* apache_s */ typedef struct apache_s apache_t; /* TODO: Remove this prototype */ static int apache_read_host (user_data_t *user_data); static void apache_free (apache_t *st) { if (st == NULL) return; sfree (st->name); sfree (st->host); sfree (st->url); sfree (st->user); sfree (st->pass); sfree (st->cacert); sfree (st->server); sfree (st->apache_buffer); if (st->curl) { curl_easy_cleanup(st->curl); st->curl = NULL; } } /* apache_free */ static size_t apache_curl_callback (void *buf, size_t size, size_t nmemb, void *user_data) { size_t len = size * nmemb; apache_t *st; st = user_data; if (st == NULL) { ERROR ("apache plugin: apache_curl_callback: " "user_data pointer is NULL."); return (0); } if (len <= 0) return (len); if ((st->apache_buffer_fill + len) >= st->apache_buffer_size) { char *temp; temp = (char *) realloc (st->apache_buffer, st->apache_buffer_fill + len + 1); if (temp == NULL) { ERROR ("apache plugin: realloc failed."); return (0); } st->apache_buffer = temp; st->apache_buffer_size = st->apache_buffer_fill + len + 1; } memcpy (st->apache_buffer + st->apache_buffer_fill, (char *) buf, len); st->apache_buffer_fill += len; st->apache_buffer[st->apache_buffer_fill] = 0; return (len); } /* int apache_curl_callback */ static size_t apache_header_callback (void *buf, size_t size, size_t nmemb, void *user_data) { size_t len = size * nmemb; apache_t *st; st = user_data; if (st == NULL) { ERROR ("apache plugin: apache_header_callback: " "user_data pointer is NULL."); return (0); } if (len <= 0) return (len); /* look for the Server header */ if (strncasecmp (buf, "Server: ", strlen ("Server: ")) != 0) return (len); if (strstr (buf, "Apache") != NULL) st->server_type = APACHE; else if (strstr (buf, "lighttpd") != NULL) st->server_type = LIGHTTPD; else if (strstr (buf, "IBM_HTTP_Server") != NULL) st->server_type = APACHE; else { const char *hdr = buf; hdr += strlen ("Server: "); NOTICE ("apache plugin: Unknown server software: %s", hdr); } return (len); } /* apache_header_callback */ /* Configuration handling functiions * * * URL ... * * URL ... * */ static int config_set_string (char **ret_string, /* {{{ */ oconfig_item_t *ci) { char *string; if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { WARNING ("apache plugin: The `%s' config option " "needs exactly one string argument.", ci->key); return (-1); } string = strdup (ci->values[0].value.string); if (string == NULL) { ERROR ("apache plugin: strdup failed."); return (-1); } if (*ret_string != NULL) free (*ret_string); *ret_string = string; return (0); } /* }}} int config_set_string */ static int config_set_boolean (int *ret_boolean, /* {{{ */ oconfig_item_t *ci) { if ((ci->values_num != 1) || ((ci->values[0].type != OCONFIG_TYPE_BOOLEAN) && (ci->values[0].type != OCONFIG_TYPE_STRING))) { WARNING ("apache plugin: The `%s' config option " "needs exactly one boolean argument.", ci->key); return (-1); } if (ci->values[0].type == OCONFIG_TYPE_BOOLEAN) { if (ci->values[0].value.boolean) *ret_boolean = 1; else *ret_boolean = 0; } else /* if (ci->values[0].type != OCONFIG_TYPE_STRING) */ { char *string = ci->values[0].value.string; if (IS_TRUE (string)) *ret_boolean = 1; else if (IS_FALSE (string)) *ret_boolean = 0; else { ERROR ("apache plugin: Cannot parse string " "as boolean value: %s", string); return (-1); } } return (0); } /* }}} int config_set_boolean */ static int config_add (oconfig_item_t *ci) { apache_t *st; int i; int status; if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { WARNING ("apache plugin: The `%s' config option " "needs exactly one string argument.", ci->key); return (-1); } st = (apache_t *) malloc (sizeof (*st)); if (st == NULL) { ERROR ("apache plugin: malloc failed."); return (-1); } memset (st, 0, sizeof (*st)); status = config_set_string (&st->name, ci); if (status != 0) { sfree (st); return (status); } assert (st->name != NULL); for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("URL", child->key) == 0) status = config_set_string (&st->url, child); else if (strcasecmp ("Host", child->key) == 0) status = config_set_string (&st->host, child); else if (strcasecmp ("User", child->key) == 0) status = config_set_string (&st->user, child); else if (strcasecmp ("Password", child->key) == 0) status = config_set_string (&st->pass, child); else if (strcasecmp ("VerifyPeer", child->key) == 0) status = config_set_boolean (&st->verify_peer, child); else if (strcasecmp ("VerifyHost", child->key) == 0) status = config_set_boolean (&st->verify_host, child); else if (strcasecmp ("CACert", child->key) == 0) status = config_set_string (&st->cacert, child); else if (strcasecmp ("Server", child->key) == 0) status = config_set_string (&st->server, child); else { WARNING ("apache plugin: Option `%s' not allowed here.", child->key); status = -1; } if (status != 0) break; } /* Check if struct is complete.. */ if ((status == 0) && (st->url == NULL)) { ERROR ("apache plugin: Instance `%s': " "No URL has been configured.", st->name); status = -1; } if (status == 0) { user_data_t ud; char callback_name[3*DATA_MAX_NAME_LEN]; memset (&ud, 0, sizeof (ud)); ud.data = st; ud.free_func = (void *) apache_free; memset (callback_name, 0, sizeof (callback_name)); ssnprintf (callback_name, sizeof (callback_name), "apache/%s/%s", (st->host != NULL) ? st->host : hostname_g, (st->name != NULL) ? st->name : "default"), status = plugin_register_complex_read (/* group = */ NULL, /* name = */ callback_name, /* callback = */ apache_read_host, /* interval = */ NULL, /* user_data = */ &ud); } if (status != 0) { apache_free(st); return (-1); } return (0); } /* int config_add */ static int config (oconfig_item_t *ci) { int status = 0; int i; for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("Instance", child->key) == 0) config_add (child); else WARNING ("apache plugin: The configuration option " "\"%s\" is not allowed here. Did you " "forget to add an block " "around the configuration?", child->key); } /* for (ci->children) */ return (status); } /* int config */ /* initialize curl for each host */ static int init_host (apache_t *st) /* {{{ */ { static char credentials[1024]; assert (st->url != NULL); /* (Assured by `config_add') */ if (st->curl != NULL) { curl_easy_cleanup (st->curl); st->curl = NULL; } if ((st->curl = curl_easy_init ()) == NULL) { ERROR ("apache plugin: init_host: `curl_easy_init' failed."); return (-1); } curl_easy_setopt (st->curl, CURLOPT_NOSIGNAL, 1L); curl_easy_setopt (st->curl, CURLOPT_WRITEFUNCTION, apache_curl_callback); curl_easy_setopt (st->curl, CURLOPT_WRITEDATA, st); /* not set as yet if the user specified string doesn't match apache or * lighttpd, then ignore it. Headers will be parsed to find out the * server type */ st->server_type = -1; if (st->server != NULL) { if (strcasecmp(st->server, "apache") == 0) st->server_type = APACHE; else if (strcasecmp(st->server, "lighttpd") == 0) st->server_type = LIGHTTPD; else if (strcasecmp(st->server, "ibm_http_server") == 0) st->server_type = APACHE; else WARNING ("apache plugin: Unknown `Server' setting: %s", st->server); } /* if not found register a header callback to determine the server_type */ if (st->server_type == -1) { curl_easy_setopt (st->curl, CURLOPT_HEADERFUNCTION, apache_header_callback); curl_easy_setopt (st->curl, CURLOPT_WRITEHEADER, st); } curl_easy_setopt (st->curl, CURLOPT_USERAGENT, PACKAGE_NAME"/"PACKAGE_VERSION); curl_easy_setopt (st->curl, CURLOPT_ERRORBUFFER, st->apache_curl_error); if (st->user != NULL) { int status; status = ssnprintf (credentials, sizeof (credentials), "%s:%s", st->user, (st->pass == NULL) ? "" : st->pass); if ((status < 0) || ((size_t) status >= sizeof (credentials))) { ERROR ("apache plugin: init_host: Returning an error " "because the credentials have been " "truncated."); curl_easy_cleanup (st->curl); st->curl = NULL; return (-1); } curl_easy_setopt (st->curl, CURLOPT_USERPWD, credentials); } curl_easy_setopt (st->curl, CURLOPT_URL, st->url); curl_easy_setopt (st->curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt (st->curl, CURLOPT_MAXREDIRS, 50L); if (st->verify_peer != 0) { curl_easy_setopt (st->curl, CURLOPT_SSL_VERIFYPEER, 1L); } else { curl_easy_setopt (st->curl, CURLOPT_SSL_VERIFYPEER, 0L); } if (st->verify_host != 0) { curl_easy_setopt (st->curl, CURLOPT_SSL_VERIFYHOST, 2L); } else { curl_easy_setopt (st->curl, CURLOPT_SSL_VERIFYHOST, 0L); } if (st->cacert != NULL) { curl_easy_setopt (st->curl, CURLOPT_CAINFO, st->cacert); } return (0); } /* }}} int init_host */ static void submit_value (const char *type, const char *type_instance, value_t value, apache_t *st) { value_list_t vl = VALUE_LIST_INIT; vl.values = &value; vl.values_len = 1; sstrncpy (vl.host, (st->host != NULL) ? st->host : hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "apache", sizeof (vl.plugin)); if (st->name != NULL) sstrncpy (vl.plugin_instance, st->name, sizeof (vl.plugin_instance)); sstrncpy (vl.type, type, sizeof (vl.type)); if (type_instance != NULL) sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); plugin_dispatch_values (&vl); } /* void submit_value */ static void submit_derive (const char *type, const char *type_instance, derive_t c, apache_t *st) { value_t v; v.derive = c; submit_value (type, type_instance, v, st); } /* void submit_derive */ static void submit_gauge (const char *type, const char *type_instance, gauge_t g, apache_t *st) { value_t v; v.gauge = g; submit_value (type, type_instance, v, st); } /* void submit_gauge */ static void submit_scoreboard (char *buf, apache_t *st) { /* * Scoreboard Key: * "_" Waiting for Connection, "S" Starting up, * "R" Reading Request for apache and read-POST for lighttpd, * "W" Sending Reply, "K" Keepalive (read), "D" DNS Lookup, * "C" Closing connection, "L" Logging, "G" Gracefully finishing, * "I" Idle cleanup of worker, "." Open slot with no current process * Lighttpd specific legends - * "E" hard error, "." connect, "h" handle-request, * "q" request-start, "Q" request-end, "s" response-start * "S" response-end, "r" read */ long long open = 0LL; long long waiting = 0LL; long long starting = 0LL; long long reading = 0LL; long long sending = 0LL; long long keepalive = 0LL; long long dnslookup = 0LL; long long closing = 0LL; long long logging = 0LL; long long finishing = 0LL; long long idle_cleanup = 0LL; /* lighttpd specific */ long long hard_error = 0LL; long long lighttpd_read = 0LL; long long handle_request = 0LL; long long request_start = 0LL; long long request_end = 0LL; long long response_start = 0LL; long long response_end = 0LL; int i; for (i = 0; buf[i] != '\0'; i++) { if (buf[i] == '.') open++; else if (buf[i] == '_') waiting++; else if (buf[i] == 'S') starting++; else if (buf[i] == 'R') reading++; else if (buf[i] == 'W') sending++; else if (buf[i] == 'K') keepalive++; else if (buf[i] == 'D') dnslookup++; else if (buf[i] == 'C') closing++; else if (buf[i] == 'L') logging++; else if (buf[i] == 'G') finishing++; else if (buf[i] == 'I') idle_cleanup++; else if (buf[i] == 'r') lighttpd_read++; else if (buf[i] == 'h') handle_request++; else if (buf[i] == 'E') hard_error++; else if (buf[i] == 'q') request_start++; else if (buf[i] == 'Q') request_end++; else if (buf[i] == 's') response_start++; else if (buf[i] == 'S') response_end++; } if (st->server_type == APACHE) { submit_gauge ("apache_scoreboard", "open" , open, st); submit_gauge ("apache_scoreboard", "waiting" , waiting, st); submit_gauge ("apache_scoreboard", "starting" , starting, st); submit_gauge ("apache_scoreboard", "reading" , reading, st); submit_gauge ("apache_scoreboard", "sending" , sending, st); submit_gauge ("apache_scoreboard", "keepalive", keepalive, st); submit_gauge ("apache_scoreboard", "dnslookup", dnslookup, st); submit_gauge ("apache_scoreboard", "closing" , closing, st); submit_gauge ("apache_scoreboard", "logging" , logging, st); submit_gauge ("apache_scoreboard", "finishing", finishing, st); submit_gauge ("apache_scoreboard", "idle_cleanup", idle_cleanup, st); } else { submit_gauge ("apache_scoreboard", "connect" , open, st); submit_gauge ("apache_scoreboard", "close" , closing, st); submit_gauge ("apache_scoreboard", "hard_error" , hard_error, st); submit_gauge ("apache_scoreboard", "read" , lighttpd_read, st); submit_gauge ("apache_scoreboard", "read_post" , reading, st); submit_gauge ("apache_scoreboard", "write" , sending, st); submit_gauge ("apache_scoreboard", "handle_request", handle_request, st); submit_gauge ("apache_scoreboard", "request_start" , request_start, st); submit_gauge ("apache_scoreboard", "request_end" , request_end, st); submit_gauge ("apache_scoreboard", "response_start", response_start, st); submit_gauge ("apache_scoreboard", "response_end" , response_end, st); } } static int apache_read_host (user_data_t *user_data) /* {{{ */ { int i; char *ptr; char *saveptr; char *lines[16]; int lines_num = 0; char *fields[4]; int fields_num; apache_t *st; st = user_data->data; assert (st->url != NULL); /* (Assured by `config_add') */ if (st->curl == NULL) { int status; status = init_host (st); if (status != 0) return (-1); } assert (st->curl != NULL); st->apache_buffer_fill = 0; if (curl_easy_perform (st->curl) != CURLE_OK) { ERROR ("apache: curl_easy_perform failed: %s", st->apache_curl_error); return (-1); } /* fallback - server_type to apache if not set at this time */ if (st->server_type == -1) { WARNING ("apache plugin: Unable to determine server software " "automatically. Will assume Apache."); st->server_type = APACHE; } ptr = st->apache_buffer; saveptr = NULL; while ((lines[lines_num] = strtok_r (ptr, "\n\r", &saveptr)) != NULL) { ptr = NULL; lines_num++; if (lines_num >= 16) break; } for (i = 0; i < lines_num; i++) { fields_num = strsplit (lines[i], fields, 4); if (fields_num == 3) { if ((strcmp (fields[0], "Total") == 0) && (strcmp (fields[1], "Accesses:") == 0)) submit_derive ("apache_requests", "", atoll (fields[2]), st); else if ((strcmp (fields[0], "Total") == 0) && (strcmp (fields[1], "kBytes:") == 0)) submit_derive ("apache_bytes", "", 1024LL * atoll (fields[2]), st); } else if (fields_num == 2) { if (strcmp (fields[0], "Scoreboard:") == 0) submit_scoreboard (fields[1], st); else if ((strcmp (fields[0], "BusyServers:") == 0) /* Apache 1.* */ || (strcmp (fields[0], "BusyWorkers:") == 0) /* Apache 2.* */) submit_gauge ("apache_connections", NULL, atol (fields[1]), st); else if ((strcmp (fields[0], "IdleServers:") == 0) /* Apache 1.x */ || (strcmp (fields[0], "IdleWorkers:") == 0) /* Apache 2.x */) submit_gauge ("apache_idle_workers", NULL, atol (fields[1]), st); } } st->apache_buffer_fill = 0; return (0); } /* }}} int apache_read_host */ void module_register (void) { plugin_register_complex_config ("apache", config); } /* void module_register */ /* vim: set sw=8 noet fdm=marker : */ collectd-5.4.0/src/PaxHeaders.11991/df.c0000644037772200116100000000013212204120331015667 xustar000000000000000030 mtime=1376821465.069973376 30 atime=1376821477.214167866 30 ctime=1376821741.994400482 collectd-5.4.0/src/df.c0000644037772200116100000002244212204120331014437 0ustar00octoeng00000000000000/** * collectd - src/df.c * Copyright (C) 2005-2009 Florian octo Forster * Copyright (C) 2009 Paul Sadauskas * * 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: * Florian octo Forster * Paul Sadauskas **/ #include "collectd.h" #include "common.h" #include "plugin.h" #include "configfile.h" #include "utils_mount.h" #include "utils_ignorelist.h" #if HAVE_STATVFS # if HAVE_SYS_STATVFS_H # include # endif # define STATANYFS statvfs # define STATANYFS_STR "statvfs" # define BLOCKSIZE(s) ((s).f_frsize ? (s).f_frsize : (s).f_bsize) #elif HAVE_STATFS # if HAVE_SYS_STATFS_H # include # endif # define STATANYFS statfs # define STATANYFS_STR "statfs" # define BLOCKSIZE(s) (s).f_bsize #else # error "No applicable input method." #endif static const char *config_keys[] = { "Device", "MountPoint", "FSType", "IgnoreSelected", "ReportByDevice", "ReportReserved", "ReportInodes", "ValuesAbsolute", "ValuesPercentage" }; static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); static ignorelist_t *il_device = NULL; static ignorelist_t *il_mountpoint = NULL; static ignorelist_t *il_fstype = NULL; static _Bool by_device = 0; static _Bool report_inodes = 0; static _Bool values_absolute = 1; static _Bool values_percentage = 0; static int df_init (void) { if (il_device == NULL) il_device = ignorelist_create (1); if (il_mountpoint == NULL) il_mountpoint = ignorelist_create (1); if (il_fstype == NULL) il_fstype = ignorelist_create (1); return (0); } static int df_config (const char *key, const char *value) { df_init (); if (strcasecmp (key, "Device") == 0) { if (ignorelist_add (il_device, value)) return (1); return (0); } else if (strcasecmp (key, "MountPoint") == 0) { if (ignorelist_add (il_mountpoint, value)) return (1); return (0); } else if (strcasecmp (key, "FSType") == 0) { if (ignorelist_add (il_fstype, value)) return (1); return (0); } else if (strcasecmp (key, "IgnoreSelected") == 0) { if (IS_TRUE (value)) { ignorelist_set_invert (il_device, 0); ignorelist_set_invert (il_mountpoint, 0); ignorelist_set_invert (il_fstype, 0); } else { ignorelist_set_invert (il_device, 1); ignorelist_set_invert (il_mountpoint, 1); ignorelist_set_invert (il_fstype, 1); } return (0); } else if (strcasecmp (key, "ReportByDevice") == 0) { if (IS_TRUE (value)) by_device = 1; return (0); } else if (strcasecmp (key, "ReportInodes") == 0) { if (IS_TRUE (value)) report_inodes = 1; else report_inodes = 0; return (0); } else if (strcasecmp (key, "ValuesAbsolute") == 0) { if (IS_TRUE (value)) values_absolute = 1; else values_absolute = 0; return (0); } else if (strcasecmp (key, "ValuesPercentage") == 0) { if (IS_TRUE (value)) values_percentage = 1; else values_percentage = 0; return (0); } return (-1); } __attribute__ ((nonnull(2))) static void df_submit_one (char *plugin_instance, const char *type, const char *type_instance, gauge_t value) { value_t values[1]; value_list_t vl = VALUE_LIST_INIT; values[0].gauge = value; vl.values = values; vl.values_len = 1; sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "df", sizeof (vl.plugin)); if (plugin_instance != NULL) sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance)); sstrncpy (vl.type, type, sizeof (vl.type)); if (type_instance != NULL) sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); plugin_dispatch_values (&vl); } /* void df_submit_one */ static int df_read (void) { #if HAVE_STATVFS struct statvfs statbuf; #elif HAVE_STATFS struct statfs statbuf; #endif /* struct STATANYFS statbuf; */ cu_mount_t *mnt_list; cu_mount_t *mnt_ptr; mnt_list = NULL; if (cu_mount_getlist (&mnt_list) == NULL) { ERROR ("df plugin: cu_mount_getlist failed."); return (-1); } for (mnt_ptr = mnt_list; mnt_ptr != NULL; mnt_ptr = mnt_ptr->next) { unsigned long long blocksize; char disk_name[256]; uint64_t blk_free; uint64_t blk_reserved; uint64_t blk_used; if (ignorelist_match (il_device, (mnt_ptr->spec_device != NULL) ? mnt_ptr->spec_device : mnt_ptr->device)) continue; if (ignorelist_match (il_mountpoint, mnt_ptr->dir)) continue; if (ignorelist_match (il_fstype, mnt_ptr->type)) continue; if (STATANYFS (mnt_ptr->dir, &statbuf) < 0) { char errbuf[1024]; ERROR (STATANYFS_STR"(%s) failed: %s", mnt_ptr->dir, sstrerror (errno, errbuf, sizeof (errbuf))); continue; } if (!statbuf.f_blocks) continue; if (by_device) { /* eg, /dev/hda1 -- strip off the "/dev/" */ if (strncmp (mnt_ptr->spec_device, "/dev/", strlen ("/dev/")) == 0) sstrncpy (disk_name, mnt_ptr->spec_device + strlen ("/dev/"), sizeof (disk_name)); else sstrncpy (disk_name, mnt_ptr->spec_device, sizeof (disk_name)); if (strlen(disk_name) < 1) { DEBUG("df: no device name for mountpoint %s, skipping", mnt_ptr->dir); continue; } } else { if (strcmp (mnt_ptr->dir, "/") == 0) { if (strcmp (mnt_ptr->type, "rootfs") == 0) continue; sstrncpy (disk_name, "root", sizeof (disk_name)); } else { int i, len; sstrncpy (disk_name, mnt_ptr->dir + 1, sizeof (disk_name)); len = strlen (disk_name); for (i = 0; i < len; i++) if (disk_name[i] == '/') disk_name[i] = '-'; } } blocksize = BLOCKSIZE(statbuf); /* * Sanity-check for the values in the struct */ /* Check for negative "available" byes. For example UFS can * report negative free space for user. Notice. blk_reserved * will start to diminish after this. */ #if HAVE_STATVFS /* Cast and temporary variable are needed to avoid * compiler warnings. * ((struct statvfs).f_bavail is unsigned (POSIX)) */ int64_t signed_bavail = (int64_t) statbuf.f_bavail; if (signed_bavail < 0) statbuf.f_bavail = 0; #elif HAVE_STATFS if (statbuf.f_bavail < 0) statbuf.f_bavail = 0; #endif /* Make sure that f_blocks >= f_bfree >= f_bavail */ if (statbuf.f_bfree < statbuf.f_bavail) statbuf.f_bfree = statbuf.f_bavail; if (statbuf.f_blocks < statbuf.f_bfree) statbuf.f_blocks = statbuf.f_bfree; blk_free = (uint64_t) statbuf.f_bavail; blk_reserved = (uint64_t) (statbuf.f_bfree - statbuf.f_bavail); blk_used = (uint64_t) (statbuf.f_blocks - statbuf.f_bfree); if (values_absolute) { df_submit_one (disk_name, "df_complex", "free", (gauge_t) (blk_free * blocksize)); df_submit_one (disk_name, "df_complex", "reserved", (gauge_t) (blk_reserved * blocksize)); df_submit_one (disk_name, "df_complex", "used", (gauge_t) (blk_used * blocksize)); } if (values_percentage) { if (statbuf.f_blocks > 0) { df_submit_one (disk_name, "percent_bytes", "free", (gauge_t) ((float_t)(blk_free) / statbuf.f_blocks * 100)); df_submit_one (disk_name, "percent_bytes", "reserved", (gauge_t) ((float_t)(blk_reserved) / statbuf.f_blocks * 100)); df_submit_one (disk_name, "percent_bytes", "used", (gauge_t) ((float_t)(blk_used) / statbuf.f_blocks * 100)); } else return (-1); } /* inode handling */ if (report_inodes) { uint64_t inode_free; uint64_t inode_reserved; uint64_t inode_used; /* Sanity-check for the values in the struct */ if (statbuf.f_ffree < statbuf.f_favail) statbuf.f_ffree = statbuf.f_favail; if (statbuf.f_files < statbuf.f_ffree) statbuf.f_files = statbuf.f_ffree; inode_free = (uint64_t) statbuf.f_favail; inode_reserved = (uint64_t) (statbuf.f_ffree - statbuf.f_favail); inode_used = (uint64_t) (statbuf.f_files - statbuf.f_ffree); if (values_percentage) { if (statbuf.f_files > 0) { df_submit_one (disk_name, "percent_inodes", "free", (gauge_t) ((float_t)(inode_free) / statbuf.f_files * 100)); df_submit_one (disk_name, "percent_inodes", "reserved", (gauge_t) ((float_t)(inode_reserved) / statbuf.f_files * 100)); df_submit_one (disk_name, "percent_inodes", "used", (gauge_t) ((float_t)(inode_used) / statbuf.f_files * 100)); } else return (-1); } if (values_absolute) { df_submit_one (disk_name, "df_inodes", "free", (gauge_t) inode_free); df_submit_one (disk_name, "df_inodes", "reserved", (gauge_t) inode_reserved); df_submit_one (disk_name, "df_inodes", "used", (gauge_t) inode_used); } } } cu_mount_freelist (mnt_list); return (0); } /* int df_read */ void module_register (void) { plugin_register_config ("df", df_config, config_keys, config_keys_num); plugin_register_init ("df", df_init); plugin_register_read ("df", df_read); } /* void module_register */ collectd-5.4.0/src/PaxHeaders.11991/configfile.h0000644037772200116100000000013212204120331017410 xustar000000000000000030 mtime=1376821465.069973376 30 atime=1376821477.214167866 30 ctime=1376821741.994400482 collectd-5.4.0/src/configfile.h0000644037772200116100000001262612204120331016163 0ustar00octoeng00000000000000#ifndef CONFIGFILE_H #define CONFIGFILE_H /** * collectd - src/configfile.h * Copyright (C) 2005-2011 Florian octo 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; either version 2 of the License, or (at your * option) any later version. * * 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: * Florian octo Forster **/ #include "collectd.h" #include "utils_time.h" #include "liboconfig/oconfig.h" /* * DESCRIPTION * Remove a registered plugin from the internal data structures. * * PARAMETERS * `type' Name of the plugin (must be the same as passed to * `plugin_register' */ void cf_unregister (const char *type); void cf_unregister_complex (const char *type); /* * DESCRIPTION * `cf_register' is called by plugins that wish to receive config keys. The * plugin will then receive all keys it registered for if they're found in a * `' section. * * PARAMETERS * `type' Name of the plugin (must be the same as passed to * `plugin_register' * `callback' Pointer to the callback function. The callback must return zero * upon success, a value smaller than zero if it doesn't know how * to handle the `key' passed to it (the first argument) or a * value greater than zero if it knows how to handle the key but * failed. * `keys' Array of key values this plugin wished to receive. The last * element must be a NULL-pointer. * `keys_num' Number of elements in the array (not counting the last NULL- * pointer. * * NOTES * `cf_unregister' will be called for `type' to make sure only one record * exists for each `type' at any time. This means that `cf_register' may be * called multiple times, but only the last call will have an effect. */ void cf_register (const char *type, int (*callback) (const char *, const char *), const char **keys, int keys_num); int cf_register_complex (const char *type, int (*callback) (oconfig_item_t *)); /* * DESCRIPTION * `cf_read' reads the config file `filename' and dispatches the read * information to functions/variables. Most important: Is calls `plugin_load' * to load specific plugins, depending on the current mode of operation. * * PARAMETERS * `filename' An additional filename to look for. This function calls * `lc_process' which already searches many standard locations.. * If set to NULL will use the `CONFIGFILE' define. * * RETURN VALUE * Returns zero upon success and non-zero otherwise. A error-message will have * been printed in this case. */ int cf_read (char *filename); int global_option_set (const char *option, const char *value); const char *global_option_get (const char *option); long global_option_get_long (const char *option, long default_value); long global_option_get_long_in_range (const char *option, long default_value, long min, long max); cdtime_t cf_get_default_interval (void); /* Assures the config option is a string, duplicates it and returns the copy in * "ret_string". If necessary "*ret_string" is freed first. Returns zero upon * success. */ int cf_util_get_string (const oconfig_item_t *ci, char **ret_string); /* Assures the config option is a string and copies it to the provided buffer. * Assures null-termination. */ int cf_util_get_string_buffer (const oconfig_item_t *ci, char *buffer, size_t buffer_size); /* Assures the config option is a number and returns it as an int. */ int cf_util_get_int (const oconfig_item_t *ci, int *ret_value); /* Assures the config option is a number and returns it as a double. */ int cf_util_get_double (const oconfig_item_t *ci, double *ret_value); /* Assures the config option is a boolean and assignes it to `ret_bool'. * Otherwise, `ret_bool' is not changed and non-zero is returned. */ int cf_util_get_boolean (const oconfig_item_t *ci, _Bool *ret_bool); /* Assures the config option is a boolean and set or unset the given flag in * `ret_value' as appropriate. Returns non-zero on error. */ int cf_util_get_flag (const oconfig_item_t *ci, unsigned int *ret_value, unsigned int flag); /* Assures that the config option is a string or a number if the correct range * of 1-65535. The string is then converted to a port number using * `service_name_to_port_number' and returned. * Returns the port number in the range [1-65535] or less than zero upon * failure. */ int cf_util_get_port_number (const oconfig_item_t *ci); /* Assures that the config option is either a service name (a string) or a port * number (an integer in the appropriate range) and returns a newly allocated * string. If ret_string points to a non-NULL pointer, it is freed before * assigning a new value. */ int cf_util_get_service (const oconfig_item_t *ci, char **ret_string); int cf_util_get_cdtime (const oconfig_item_t *ci, cdtime_t *ret_value); #endif /* defined(CONFIGFILE_H) */ collectd-5.4.0/src/PaxHeaders.11991/tokyotyrant.c0000644037772200116100000000013212204120331017705 xustar000000000000000030 mtime=1376821465.085973632 30 atime=1376821477.226168058 30 ctime=1376821741.998400545 collectd-5.4.0/src/tokyotyrant.c0000644037772200116100000000706412204120331016460 0ustar00octoeng00000000000000/** * collectd - src/tokyotyrant.c * Copyright (C) 2009 Paul Sadauskas * * 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: * Paul Sadauskas **/ #include "collectd.h" #include "plugin.h" #include "common.h" #include "utils_cache.h" #include "utils_parse_option.h" #include #define DEFAULT_HOST "127.0.0.1" #define DEFAULT_PORT 1978 static const char *config_keys[] = { "Host", "Port" }; static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); static char *config_host = NULL; static char *config_port = NULL; static TCRDB *rdb = NULL; static int tt_config (const char *key, const char *value) { if (strcasecmp ("Host", key) == 0) { char *temp; temp = strdup (value); if (temp == NULL) { ERROR("tokyotyrant plugin: Host strdup failed."); return (1); } sfree (config_host); config_host = temp; } else if (strcasecmp ("Port", key) == 0) { char *temp; temp = strdup (value); if (temp == NULL) { ERROR("tokyotyrant plugin: Port strdup failed."); return (1); } sfree (config_port); config_port = temp; } else { ERROR ("tokyotyrant plugin: error: unrecognized configuration key %s", key); return (-1); } return (0); } static void printerr() { int ecode = tcrdbecode(rdb); ERROR ("tokyotyrant plugin: error: %d, %s", ecode, tcrdberrmsg(ecode)); } static void tt_submit (gauge_t val, const char* type) { value_t values[1]; value_list_t vl = VALUE_LIST_INIT; values[0].gauge = val; vl.values = values; vl.values_len = STATIC_ARRAY_SIZE (values); sstrncpy (vl.host, config_host, sizeof (vl.host)); sstrncpy (vl.plugin, "tokyotyrant", sizeof (vl.plugin)); sstrncpy (vl.plugin_instance, config_port, sizeof (vl.plugin_instance)); sstrncpy (vl.type, type, sizeof (vl.type)); plugin_dispatch_values (&vl); } static void tt_open_db (void) { char* host = NULL; int port = DEFAULT_PORT; if (rdb != NULL) return; host = ((config_host != NULL) ? config_host : DEFAULT_HOST); if (config_port != NULL) { port = service_name_to_port_number (config_port); if (port <= 0) return; } rdb = tcrdbnew (); if (rdb == NULL) return; else if (!tcrdbopen(rdb, host, port)) { printerr (); tcrdbdel (rdb); rdb = NULL; } } /* void tt_open_db */ static int tt_read (void) { gauge_t rnum, size; tt_open_db (); if (rdb == NULL) return (-1); rnum = tcrdbrnum(rdb); tt_submit (rnum, "records"); size = tcrdbsize(rdb); tt_submit (size, "file_size"); return (0); } static int tt_shutdown(void) { sfree(config_host); sfree(config_port); if (rdb != NULL) { if (!tcrdbclose(rdb)) { printerr (); tcrdbdel (rdb); return (1); } tcrdbdel (rdb); rdb = NULL; } return(0); } void module_register (void) { plugin_register_config("tokyotyrant", tt_config, config_keys, config_keys_num); plugin_register_read("tokyotyrant", tt_read); plugin_register_shutdown("tokyotyrant", tt_shutdown); } /* vim: set sw=8 ts=8 tw=78 : */ collectd-5.4.0/src/PaxHeaders.11991/network.h0000644037772200116100000000013212204120331016774 xustar000000000000000030 mtime=1376821465.081973567 30 atime=1376821477.222167995 30 ctime=1376821741.998400545 collectd-5.4.0/src/network.h0000644037772200116100000000463612204120331015551 0ustar00octoeng00000000000000/** * collectd - src/network.h * Copyright (C) 2005-2008 Florian octo 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: * Florian octo Forster **/ #ifndef NETWORK_H #define NETWORK_H /* * From RFC2365: Administratively Scoped IP Multicast * * The IPv4 Organization Local Scope -- 239.192.0.0/14 * * 239.192.0.0/14 is defined to be the IPv4 Organization Local Scope, and is * the space from which an organization should allocate sub-ranges when * defining scopes for private use. * * Port 25826 is not assigned as of 2005-09-12 */ /* * From RFC2373: IP Version 6 Addressing Architecture * * 2.7 Multicast Addresses * * | 8 | 4 | 4 | 80 bits | 32 bits | * +--------+----+----+---------------------------+-----------------+ * |11111111|flgs|scop| reserved must be zero | group ID | * +--------+----+----+---------------------------+-----------------+ * * flgs = 1 => non-permanently-assigned ("transient") multicast address. * scop = 8 => organization-local scope * * group = efc0:4a42 = 239.192.74.66 */ #define NET_DEFAULT_V4_ADDR "239.192.74.66" #define NET_DEFAULT_V6_ADDR "ff18::efc0:4a42" #define NET_DEFAULT_PORT "25826" #define TYPE_HOST 0x0000 #define TYPE_TIME 0x0001 #define TYPE_TIME_HR 0x0008 #define TYPE_PLUGIN 0x0002 #define TYPE_PLUGIN_INSTANCE 0x0003 #define TYPE_TYPE 0x0004 #define TYPE_TYPE_INSTANCE 0x0005 #define TYPE_VALUES 0x0006 #define TYPE_INTERVAL 0x0007 #define TYPE_INTERVAL_HR 0x0009 /* Types to transmit notifications */ #define TYPE_MESSAGE 0x0100 #define TYPE_SEVERITY 0x0101 #define TYPE_SIGN_SHA256 0x0200 #define TYPE_ENCR_AES256 0x0210 #endif /* NETWORK_H */ collectd-5.4.0/src/PaxHeaders.11991/syslog.c0000644037772200116100000000013212204120331016616 xustar000000000000000030 mtime=1376821465.085973632 30 atime=1376821477.226168058 30 ctime=1376821741.998400545 collectd-5.4.0/src/syslog.c0000644037772200116100000000712312204120331015365 0ustar00octoeng00000000000000/** * collectd - src/syslog.c * Copyright (C) 2007 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; either version 2 of the License, or (at your * option) any later version. * * 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: * Florian Forster **/ #include "collectd.h" #include "common.h" #include "plugin.h" #if HAVE_SYSLOG_H # include #endif #if COLLECT_DEBUG static int log_level = LOG_DEBUG; #else static int log_level = LOG_INFO; #endif /* COLLECT_DEBUG */ static int notif_severity = 0; static const char *config_keys[] = { "LogLevel", "NotifyLevel", }; static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); static int sl_config (const char *key, const char *value) { if (strcasecmp (key, "LogLevel") == 0) { log_level = parse_log_severity (value); if (log_level < 0) return (1); } else if (strcasecmp (key, "NotifyLevel") == 0) { notif_severity = parse_notif_severity (value); if (notif_severity < 0) return (1); } return (0); } /* int sl_config */ static void sl_log (int severity, const char *msg, user_data_t __attribute__((unused)) *user_data) { if (severity > log_level) return; syslog (severity, "%s", msg); } /* void sl_log */ static int sl_shutdown (void) { closelog (); return (0); } static int sl_notification (const notification_t *n, user_data_t __attribute__((unused)) *user_data) { char buf[1024] = ""; size_t offset = 0; int log_severity; char *severity_string; int status; if (n->severity > notif_severity) return (0); switch (n->severity) { case NOTIF_FAILURE: severity_string = "FAILURE"; log_severity = LOG_ERR; break; case NOTIF_WARNING: severity_string = "WARNING"; log_severity = LOG_WARNING; break; case NOTIF_OKAY: severity_string = "OKAY"; log_severity = LOG_NOTICE; break; default: severity_string = "UNKNOWN"; log_severity = LOG_ERR; } #define BUFFER_ADD(...) do { \ status = ssnprintf (&buf[offset], sizeof (buf) - offset, \ __VA_ARGS__); \ if (status < 1) \ return (-1); \ else if (((size_t) status) >= (sizeof (buf) - offset)) \ return (-ENOMEM); \ else \ offset += ((size_t) status); \ } while (0) #define BUFFER_ADD_FIELD(field) do { \ if (n->field[0]) \ BUFFER_ADD (", " #field " = %s", n->field); \ } while (0) BUFFER_ADD ("Notification: severity = %s", severity_string); BUFFER_ADD_FIELD (host); BUFFER_ADD_FIELD (plugin); BUFFER_ADD_FIELD (plugin_instance); BUFFER_ADD_FIELD (type); BUFFER_ADD_FIELD (type_instance); BUFFER_ADD_FIELD (message); #undef BUFFER_ADD_FIELD #undef BUFFER_ADD buf[sizeof (buf) - 1] = '\0'; sl_log (log_severity, buf, NULL); return (0); } /* int sl_notification */ void module_register (void) { openlog ("collectd", LOG_CONS | LOG_PID, LOG_DAEMON); plugin_register_config ("syslog", sl_config, config_keys, config_keys_num); plugin_register_log ("syslog", sl_log, /* user_data = */ NULL); plugin_register_notification ("syslog", sl_notification, NULL); plugin_register_shutdown ("syslog", sl_shutdown); } /* void module_register(void) */ collectd-5.4.0/src/PaxHeaders.11991/collectd-python.pod0000644037772200116100000000013212204120331020746 xustar000000000000000030 mtime=1376821465.065973312 30 atime=1376821477.206167738 30 ctime=1376821741.998400545 collectd-5.4.0/src/collectd-python.pod0000644037772200116100000006012312204120331017514 0ustar00octoeng00000000000000# Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. =encoding UTF-8 =head1 NAME collectd-python - Documentation of collectd's C =head1 SYNOPSIS Globals true # ... ModulePath "/path/to/your/python/modules" LogTraces true Interactive false Import "spam" spam "wonderful" "lovely" =head1 DESCRIPTION The C embeds a Python-interpreter into collectd and provides an interface to collectd's plugin system. This makes it possible to write plugins for collectd in Python. This is a lot more efficient than executing a Python-script every time you want to read a value with the C (see L) and provides a lot more functionality, too. The minimum required Python version is I<2.3>. =head1 CONFIGURATION =over 4 =item B I Loads the Python plugin I. Unlike most other LoadPlugin lines, this one should be a block containing the line "Globals true". This will cause collectd to export the name of all objects in the Python interpreter for all plugins to see. If you don't do this or your platform does not support it, the embedded interpreter will start anyway but you won't be able to load certain Python modules, e.g. "time". =item B I The default encoding for Unicode objects you pass to collectd. If you omit this option it will default to B on I and B on I. This is hardcoded in Python and will ignore everything else, including your locale. =item B I Appends I to B. You won't be able to import any scripts you wrote unless they are located in one of the directories in this list. Please note that it only has effect on plugins loaded after this option. You can use multiple B lines to add more than one directory. =item B I If a Python script throws an exception it will be logged by collectd with the name of the exception and the message. If you set this option to true it will also log the full stacktrace just like the default output of an interactive Python interpreter. This should probably be set to false most of the time but is very useful for development and debugging of new modules. =item B I This option will cause the module to launch an interactive Python interpreter that reads from and writes to the terminal. Note that collectd will terminate right after starting up if you try to run it as a daemon while this option is enabled so make sure to start collectd with the B<-f> option. The B module is I imported into the interpreter's globals. You have to do it manually. Be sure to read the help text of the module, it can be used as a reference guide during coding. This interactive session will behave slightly differently from a daemonized collectd script as well as from a normal Python interpreter: =over 4 =item B<1.> collectd will try to import the B module to give you a decent way of entering your commands. The daemonized collectd won't do that. =item B<2.> collectd will block I. Pressing I will usually cause collectd to shut down. This would be problematic in an interactive session, therefore this signal will be blocked. You can still use it to interrupt syscalls like sleep and pause but it won't generate a I exception either. To quit collectd send I (press I at the beginning of a new line). =item B<3.> collectd handles I. This means that Python won't be able to determine the return code of spawned processes with system(), popen() and subprocess. This will result in Python not using external programs like less to display help texts. You can override this behavior with the B environment variable, e.g. I before starting collectd. Depending on your version of Python this might or might not result in an B exception which can be ignored. If you really need to spawn new processes from Python you can register an init callback and reset the action for SIGCHLD to the default behavior. Please note that this I break the exec plugin. Do not even load the exec plugin if you intend to do this! There is an example script located in B to do this. If you import this from I SIGCHLD will be handled normally and spawning processes from Python will work as intended. =back =item EB IE block This block may be used to pass on configuration settings to a Python module. The configuration is converted into an instance of the B class which is passed to the registered configuration callback. See below for details about the B class and how to register callbacks. The I identifies the callback. =back =head1 STRINGS There are a lot of places where strings are sent from collectd to Python and from Python to collectd. How exactly this works depends on whether byte or unicode strings or Python2 or Python3 are used. Python2 has I, which is just bytes, and I. Python3 has I, which is a unicode object, and I. When passing strings from Python to collectd all of these object are supported in all places, however I should be used if possible. These strings must not contain a NUL byte. Ignoring this will result in a I exception. If a byte string was used it will be used as is by collectd. If a unicode object was used it will be encoded using the default encoding (see above). If this is not possible Python will raise a I exception. When passing strings from collectd to Python the behavior depends on the Python version used. Python2 will always receive a I object. Python3 will usually receive a I object as well, however the original string will be decoded to unicode using the default encoding. If this fails because the string is not a valid sequence for this encoding a I object will be returned instead. =head1 WRITING YOUR OWN PLUGINS Writing your own plugins is quite simple. collectd manages plugins by means of B which call the appropriate B registered by the plugins. Any plugin basically consists of the implementation of these callback functions and initializing code which registers the functions with collectd. See the section "EXAMPLES" below for a really basic example. The following types of B are known to collectd (all of them are optional): =over 4 =item configuration functions These are called during configuration if an appropriate B block has been encountered. It is called once for each B block which matches the name of the callback as provided with the B method - see below. Python thread support has not been initialized at this point so do not use any threading functions here! =item init functions These are called once after loading the module and before any calls to the read and write functions. It should be used to initialize the internal state of the plugin (e.Eg. open sockets, ...). This is the earliest point where you may use threads. =item read functions These are used to collect the actual data. It is called once per interval (see the B configuration option of collectd). Usually it will call B to dispatch the values to collectd which will pass them on to all registered B. If this function throws any kind of exception the plugin will be skipped for an increasing amount of time until it returns normally again. =item write functions These are used to write the dispatched values. It is called once for every value that was dispatched by any plugin. =item flush functions These are used to flush internal caches of plugins. It is usually triggered by the user only. Any plugin which caches data before writing it to disk should provide this kind of callback function. =item log functions These are used to pass messages of plugins or the daemon itself to the user. =item notification function These are used to act upon notifications. In general, a notification is a status message that may be associated with a data instance. Usually, a notification is generated by the daemon if a configured threshold has been exceeded (see the section "THRESHOLD CONFIGURATION" in L for more details), but any plugin may dispatch notifications as well. =item shutdown functions These are called once before the daemon shuts down. It should be used to clean up the plugin (e.g. close sockets, ...). =back Any function (except log functions) may throw an exception in case of errors. The exception will be passed on to the user using collectd's logging mechanism. If a log callback throws an exception it will be printed to standard error instead. See the documentation of the various B methods in the section "FUNCTIONS" below for the number and types of arguments passed to each B. This section also explains how to register B with collectd. To enable a module, copy it to a place where Python can find it (i.Ee. a directory listed in B) just as any other Python plugin and add an appropriate B option to the configuration file. After restarting collectd you're done. =head1 CLASSES The following complex types are used to pass values between the Python plugin and collectd: =head2 Signed The Signed class is just a long. It has all its methods and behaves exactly like any other long object. It is used to indicate if an integer was or should be stored as a signed or unsigned integer object. class Signed(long) This is a long by another name. Use it in meta data dicts to choose the way it is stored in the meta data. =head2 Unsigned The Unsigned class is just a long. It has all its methods and behaves exactly like any other long object. It is used to indicate if an integer was or should be stored as a signed or unsigned integer object. class Unsigned(long) This is a long by another name. Use it in meta data dicts to choose the way it is stored in the meta data. =head2 Config The Config class is an object which keeps the information provided in the configuration file. The sequence of children keeps one entry for each configuration option. Each such entry is another Config instance, which may nest further if nested blocks are used. class Config(object) This represents a piece of collectd's config file. It is passed to scripts with config callbacks (see B) and is of little use if created somewhere else. It has no methods beyond the bare minimum and only exists for its data members. Data descriptors defined here: =over 4 =item parent This represents the parent of this node. On the root node of the config tree it will be None. =item key This is the keyword of this item, i.e. the first word of any given line in the config file. It will always be a string. =item values This is a tuple (which might be empty) of all value, i.e. words following the keyword in any given line in the config file. Every item in this tuple will be either a string, a float or a boolean, depending on the contents of the configuration file. =item children This is a tuple of child nodes. For most nodes this will be empty. If this node represents a block instead of a single line of the config file it will contain all nodes in this block. =back =head2 PluginData This should not be used directly but it is the base class for both Values and Notification. It is used to identify the source of a value or notification. class PluginData(object) This is an internal class that is the base for Values and Notification. It is pretty useless by itself and was therefore not exported to the collectd module. Data descriptors defined here: =over 4 =item host The hostname of the host this value was read from. For dispatching this can be set to an empty string which means the local hostname as defined in collectd.conf. =item plugin The name of the plugin that read the data. Setting this member to an empty string will insert "python" upon dispatching. =item plugin_instance Plugin instance string. May be empty. =item time This is the Unix timestamp of the time this value was read. For dispatching values this can be set to zero which means "now". This means the time the value is actually dispatched, not the time it was set to 0. =item type The type of this value. This type has to be defined in your I. Attempting to set it to any other value will raise a I exception. Assigning a type is mandatory, calling dispatch without doing so will raise a I exception. =item type_instance Type instance string. May be empty. =back =head2 Values A Value is an object which features a sequence of values. It is based on the I type and uses its members to identify the values. class Values(PluginData) A Values object used for dispatching values to collectd and receiving values from write callbacks. Method resolution order: =over 4 =item Values =item PluginData =item object =back Methods defined here: =over 4 =item B([type][, values][, plugin_instance][, type_instance][, plugin][, host][, time][, interval]) -> None. Dispatch this instance to the collectd process. The object has members for each of the possible arguments for this method. For a detailed explanation of these parameters see the member of the same same. If you do not submit a parameter the value saved in its member will be submitted. If you do provide a parameter it will be used instead, without altering the member. =item B([destination][, type][, values][, plugin_instance][, type_instance][, plugin][, host][, time][, interval]) -> None. Write this instance to a single plugin or all plugins if "destination" is omitted. This will bypass the main collectd process and all filtering and caching. Other than that it works similar to "dispatch". In most cases "dispatch" should be used instead of "write". =back Data descriptors defined here: =over 4 =item interval The interval is the timespan in seconds between two submits for the same data source. This value has to be a positive integer, so you can't submit more than one value per second. If this member is set to a non-positive value, the default value as specified in the config file will be used (default: 10). If you submit values more often than the specified interval, the average will be used. If you submit less values, your graphs will have gaps. =item values These are the actual values that get dispatched to collectd. It has to be a sequence (a tuple or list) of numbers. The size of the sequence and the type of its content depend on the type member your I file. For more information on this read the L manual page. If the sequence does not have the correct size upon dispatch a I exception will be raised. If the content of the sequence is not a number, a I exception will be raised. =item meta These are the meta data for this Value object. It has to be a dictionary of numbers, strings or bools. All keys must be strings. I and objects will be dispatched as signed integers unless they are between 2**63 and 2**64-1, which will result in a unsigned integer. You can force one of these storage classes by using the classes B and B. A meta object received by a write callback will always contain B or B objects. =back =head2 Notification A notification is an object defining the severity and message of the status message as well as an identification of a data instance by means of the members of I on which it is based. class Notification(PluginData) The Notification class is a wrapper around the collectd notification. It can be used to notify other plugins about bad stuff happening. It works similar to Values but has a severity and a message instead of interval and time. Notifications can be dispatched at any time and can be received with register_notification. Method resolution order: =over 4 =item Notification =item PluginData =item object =back Methods defined here: =over 4 =item B([type][, values][, plugin_instance][, type_instance][, plugin][, host][, time][, interval]) -> None. Dispatch a value list. Dispatch this instance to the collectd process. The object has members for each of the possible arguments for this method. For a detailed explanation of these parameters see the member of the same same. If you do not submit a parameter the value saved in its member will be submitted. If you do provide a parameter it will be used instead, without altering the member. =back Data descriptors defined here: =over 4 =item message Some kind of description of what's going on and why this Notification was generated. =item severity The severity of this notification. Assign or compare to I, I or I. =back =head1 FUNCTIONS The following functions provide the C-interface to Python-modules. =over 4 =item B(I[, I][, I]) -> identifier There are eight different register functions to get callback for eight different events. With one exception all of them are called as shown above. =over 4 =item I is a callable object that will be called every time the event is triggered. =item I is an optional object that will be passed back to the callback function every time it is called. If you omit this parameter no object is passed back to your callback, not even None. =item I is an optional identifier for this callback. The default name is B.I. I is taken from the B<__module__> attribute of your callback function. Every callback needs a unique identifier, so if you want to register the same callback multiple times in the same module you need to specify a name here. Otherwise it's safe to ignore this parameter. =item I is the full identifier assigned to this callback. =back These functions are called in the various stages of the daemon (see the section L<"WRITING YOUR OWN PLUGINS"> above) and are passed the following arguments: =over 4 =item register_config The only argument passed is a I object. See above for the layout of this data type. Note that you cannot receive the whole config files this way, only B blocks inside the Python configuration block. Additionally you will only receive blocks where your callback identifier matches BI. =item register_init The callback will be called without arguments. =item register_read(callback[, interval][, data][, name]) -> identifier This function takes an additional parameter: I. It specifies the time between calls to the callback function. The callback will be called without arguments. =item register_shutdown The callback will be called without arguments. =item register_write The callback function will be called with one argument passed, which will be a I object. For the layout of I see above. If this callback function throws an exception the next call will be delayed by an increasing interval. =item register_flush Like B is important for this callback because it determines what flush requests the plugin will receive. The arguments passed are I and I. I indicates that only data older than I seconds is to be flushed. I specifies which values are to be flushed. =item register_log The arguments are I and I. The severity is an integer and small for important messages and high for less important messages. The least important level is B, the most important level is B. In between there are (from least to most important): B, B, and B. I is simply a string B a newline at the end. If this callback throws an exception it will B be logged. It will just be printed to B which usually means silently ignored. =item register_notification The only argument passed is a I object. See above for the layout of this data type. =back =item B(I) -> None Removes a callback or data-set from collectd's internal list of callback functions. Every I function has an I function. I is either the string that was returned by the register function or a callback function. The identifier will be constructed in the same way as for the register functions. =item B(I][, I]) -> None Flush one or all plugins. I and the specified I are passed on to the registered flush-callbacks. If omitted, the timeout defaults to C<-1>. The identifier defaults to None. If the B argument has been specified, only named plugin will be flushed. =item B, B, B, B, B(I) Log a message with the specified severity. =back =head1 EXAMPLES Any Python module will start similar to: import collectd A very simple read function might look like: def read(data=None): vl = collectd.Values(type='gauge') vl.plugin='python.spam' vl.dispatch(values=[random.random() * 100]) A very simple write function might look like: def write(vl, data=None): for i in vl.values: print "%s (%s): %f" % (vl.plugin, vl.type, i) To register those functions with collectd: collectd.register_read(read); collectd.register_write(write); See the section L<"CLASSES"> above for a complete documentation of the data types used by the read, write and match functions. =head1 NOTES =over 4 =item Please feel free to send in new plugins to collectd's mailing list at EcollectdEatEverplant.orgE for review and, possibly, inclusion in the main distribution. In the latter case, we will take care of keeping the plugin up to date and adapting it to new versions of collectd. Before submitting your plugin, please take a look at L. =back =head1 CAVEATS =over 4 =item collectd is heavily multi-threaded. Each collectd thread accessing the Python plugin will be mapped to a Python interpreter thread. Any such thread will be created and destroyed transparently and on-the-fly. Hence, any plugin has to be thread-safe if it provides several entry points from collectd (i.Ee. if it registers more than one callback or if a registered callback may be called more than once in parallel). =item The Python thread module is initialized just before calling the init callbacks. This means you must not use Python's threading module prior to this point. This includes all config and possibly other callback as well. =item The python plugin exports the internal API of collectd which is considered unstable and subject to change at any time. We try hard to not break backwards compatibility in the Python API during the life cycle of one major release. However, this cannot be guaranteed at all times. Watch out for warnings dispatched by the python plugin after upgrades. =back =head1 KNOWN BUGS =over 4 =item Not all aspects of the collectd API are accessible from Python. This includes but is not limited to filters and data sets. =back =head1 SEE ALSO L, L, L, L, L, L, =head1 AUTHOR The C has been written by Sven Trenkel EcollectdEatEsemidefinite.deE. This manpage has been written by Sven Trenkel EcollectdEatEsemidefinite.deE. It is based on the L manual page by Florian Forster EoctoEatEverplant.orgE and Sebastian Harl EshEatEtokkee.orgE. =cut collectd-5.4.0/src/PaxHeaders.11991/plugin.c0000644037772200116100000000013212204120331016574 xustar000000000000000030 mtime=1376821465.081973567 30 atime=1376821477.222167995 30 ctime=1376821742.002400609 collectd-5.4.0/src/plugin.c0000644037772200116100000015747312204120331015361 0ustar00octoeng00000000000000/** * collectd - src/plugin.c * Copyright (C) 2005-2013 Florian octo 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: * Florian octo Forster * Sebastian Harl **/ #include "collectd.h" #include "common.h" #include "plugin.h" #include "configfile.h" #include "filter_chain.h" #include "utils_avltree.h" #include "utils_cache.h" #include "utils_complain.h" #include "utils_llist.h" #include "utils_heap.h" #include "utils_time.h" #include "utils_random.h" #if HAVE_PTHREAD_H # include #endif #include /* * Private structures */ struct callback_func_s { void *cf_callback; user_data_t cf_udata; plugin_ctx_t cf_ctx; }; typedef struct callback_func_s callback_func_t; #define RF_SIMPLE 0 #define RF_COMPLEX 1 #define RF_REMOVE 65535 struct read_func_s { /* `read_func_t' "inherits" from `callback_func_t'. * The `rf_super' member MUST be the first one in this structure! */ #define rf_callback rf_super.cf_callback #define rf_udata rf_super.cf_udata #define rf_ctx rf_super.cf_ctx callback_func_t rf_super; char rf_group[DATA_MAX_NAME_LEN]; char *rf_name; int rf_type; cdtime_t rf_interval; cdtime_t rf_effective_interval; cdtime_t rf_next_read; }; typedef struct read_func_s read_func_t; struct write_queue_s; typedef struct write_queue_s write_queue_t; struct write_queue_s { value_list_t *vl; plugin_ctx_t ctx; write_queue_t *next; }; /* * Private variables */ static c_avl_tree_t *plugins_loaded = NULL; static llist_t *list_init; static llist_t *list_write; static llist_t *list_flush; static llist_t *list_missing; static llist_t *list_shutdown; static llist_t *list_log; static llist_t *list_notification; static fc_chain_t *pre_cache_chain = NULL; static fc_chain_t *post_cache_chain = NULL; static c_avl_tree_t *data_sets; static char *plugindir = NULL; static c_heap_t *read_heap = NULL; static llist_t *read_list; static int read_loop = 1; static pthread_mutex_t read_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t read_cond = PTHREAD_COND_INITIALIZER; static pthread_t *read_threads = NULL; static int read_threads_num = 0; static write_queue_t *write_queue_head; static write_queue_t *write_queue_tail; static long write_queue_length = 0; static _Bool write_loop = 1; static pthread_mutex_t write_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t write_cond = PTHREAD_COND_INITIALIZER; static pthread_t *write_threads = NULL; static size_t write_threads_num = 0; static pthread_key_t plugin_ctx_key; static _Bool plugin_ctx_key_initialized = 0; static long write_limit_high = 0; static long write_limit_low = 0; /* * Static functions */ static int plugin_dispatch_values_internal (value_list_t *vl); static const char *plugin_get_dir (void) { if (plugindir == NULL) return (PLUGINDIR); else return (plugindir); } static void destroy_callback (callback_func_t *cf) /* {{{ */ { if (cf == NULL) return; if ((cf->cf_udata.data != NULL) && (cf->cf_udata.free_func != NULL)) { cf->cf_udata.free_func (cf->cf_udata.data); cf->cf_udata.data = NULL; cf->cf_udata.free_func = NULL; } sfree (cf); } /* }}} void destroy_callback */ static void destroy_all_callbacks (llist_t **list) /* {{{ */ { llentry_t *le; if (*list == NULL) return; le = llist_head (*list); while (le != NULL) { llentry_t *le_next; le_next = le->next; sfree (le->key); destroy_callback (le->value); le->value = NULL; le = le_next; } llist_destroy (*list); *list = NULL; } /* }}} void destroy_all_callbacks */ static void destroy_read_heap (void) /* {{{ */ { if (read_heap == NULL) return; while (42) { callback_func_t *cf; cf = c_heap_get_root (read_heap); if (cf == NULL) break; destroy_callback (cf); } c_heap_destroy (read_heap); read_heap = NULL; } /* }}} void destroy_read_heap */ static int register_callback (llist_t **list, /* {{{ */ const char *name, callback_func_t *cf) { llentry_t *le; char *key; if (*list == NULL) { *list = llist_create (); if (*list == NULL) { ERROR ("plugin: register_callback: " "llist_create failed."); destroy_callback (cf); return (-1); } } key = strdup (name); if (key == NULL) { ERROR ("plugin: register_callback: strdup failed."); destroy_callback (cf); return (-1); } le = llist_search (*list, name); if (le == NULL) { le = llentry_create (key, cf); if (le == NULL) { ERROR ("plugin: register_callback: " "llentry_create failed."); free (key); destroy_callback (cf); return (-1); } llist_append (*list, le); } else { callback_func_t *old_cf; old_cf = le->value; le->value = cf; WARNING ("plugin: register_callback: " "a callback named `%s' already exists - " "overwriting the old entry!", name); destroy_callback (old_cf); sfree (key); } return (0); } /* }}} int register_callback */ static int create_register_callback (llist_t **list, /* {{{ */ const char *name, void *callback, user_data_t *ud) { callback_func_t *cf; cf = (callback_func_t *) malloc (sizeof (*cf)); if (cf == NULL) { ERROR ("plugin: create_register_callback: malloc failed."); return (-1); } memset (cf, 0, sizeof (*cf)); cf->cf_callback = callback; if (ud == NULL) { cf->cf_udata.data = NULL; cf->cf_udata.free_func = NULL; } else { cf->cf_udata = *ud; } cf->cf_ctx = plugin_get_ctx (); return (register_callback (list, name, cf)); } /* }}} int create_register_callback */ static int plugin_unregister (llist_t *list, const char *name) /* {{{ */ { llentry_t *e; if (list == NULL) return (-1); e = llist_search (list, name); if (e == NULL) return (-1); llist_remove (list, e); sfree (e->key); destroy_callback (e->value); llentry_destroy (e); return (0); } /* }}} int plugin_unregister */ /* * (Try to) load the shared object `file'. Won't complain if it isn't a shared * object, but it will bitch about a shared object not having a * ``module_register'' symbol.. */ static int plugin_load_file (char *file, uint32_t flags) { lt_dlhandle dlh; void (*reg_handle) (void); lt_dlinit (); lt_dlerror (); /* clear errors */ #if LIBTOOL_VERSION == 2 if (flags & PLUGIN_FLAGS_GLOBAL) { lt_dladvise advise; lt_dladvise_init(&advise); lt_dladvise_global(&advise); dlh = lt_dlopenadvise(file, advise); lt_dladvise_destroy(&advise); } else { dlh = lt_dlopen (file); } #else /* if LIBTOOL_VERSION == 1 */ if (flags & PLUGIN_FLAGS_GLOBAL) WARNING ("plugin_load_file: The global flag is not supported, " "libtool 2 is required for this."); dlh = lt_dlopen (file); #endif if (dlh == NULL) { char errbuf[1024] = ""; ssnprintf (errbuf, sizeof (errbuf), "lt_dlopen (\"%s\") failed: %s. " "The most common cause for this problem are " "missing dependencies. Use ldd(1) to check " "the dependencies of the plugin " "/ shared object.", file, lt_dlerror ()); ERROR ("%s", errbuf); /* Make sure this is printed to STDERR in any case, but also * make sure it's printed only once. */ if (list_log != NULL) fprintf (stderr, "ERROR: %s\n", errbuf); return (1); } if ((reg_handle = (void (*) (void)) lt_dlsym (dlh, "module_register")) == NULL) { WARNING ("Couldn't find symbol \"module_register\" in \"%s\": %s\n", file, lt_dlerror ()); lt_dlclose (dlh); return (-1); } (*reg_handle) (); return (0); } static void *plugin_read_thread (void __attribute__((unused)) *args) { while (read_loop != 0) { read_func_t *rf; plugin_ctx_t old_ctx; cdtime_t now; int status; int rf_type; int rc; /* Get the read function that needs to be read next. * We don't need to hold "read_lock" for the heap, but we need * to call c_heap_get_root() and pthread_cond_wait() in the * same protected block. */ pthread_mutex_lock (&read_lock); rf = c_heap_get_root (read_heap); if (rf == NULL) { pthread_cond_wait (&read_cond, &read_lock); pthread_mutex_unlock (&read_lock); continue; } pthread_mutex_unlock (&read_lock); if (rf->rf_interval == 0) { /* this should not happen, because the interval is set * for each plugin when loading it * XXX: issue a warning? */ rf->rf_interval = plugin_get_interval (); rf->rf_effective_interval = rf->rf_interval; rf->rf_next_read = cdtime (); } /* sleep until this entry is due, * using pthread_cond_timedwait */ pthread_mutex_lock (&read_lock); /* In pthread_cond_timedwait, spurious wakeups are possible * (and really happen, at least on NetBSD with > 1 CPU), thus * we need to re-evaluate the condition every time * pthread_cond_timedwait returns. */ rc = 0; while ((read_loop != 0) && (cdtime () < rf->rf_next_read) && rc == 0) { struct timespec ts = { 0 }; CDTIME_T_TO_TIMESPEC (rf->rf_next_read, &ts); rc = pthread_cond_timedwait (&read_cond, &read_lock, &ts); } /* Must hold `read_lock' when accessing `rf->rf_type'. */ rf_type = rf->rf_type; pthread_mutex_unlock (&read_lock); /* Check if we're supposed to stop.. This may have interrupted * the sleep, too. */ if (read_loop == 0) { /* Insert `rf' again, so it can be free'd correctly */ c_heap_insert (read_heap, rf); break; } /* The entry has been marked for deletion. The linked list * entry has already been removed by `plugin_unregister_read'. * All we have to do here is free the `read_func_t' and * continue. */ if (rf_type == RF_REMOVE) { DEBUG ("plugin_read_thread: Destroying the `%s' " "callback.", rf->rf_name); sfree (rf->rf_name); destroy_callback ((callback_func_t *) rf); rf = NULL; continue; } DEBUG ("plugin_read_thread: Handling `%s'.", rf->rf_name); old_ctx = plugin_set_ctx (rf->rf_ctx); if (rf_type == RF_SIMPLE) { int (*callback) (void); callback = rf->rf_callback; status = (*callback) (); } else { plugin_read_cb callback; assert (rf_type == RF_COMPLEX); callback = rf->rf_callback; status = (*callback) (&rf->rf_udata); } plugin_set_ctx (old_ctx); /* If the function signals failure, we will increase the * intervals in which it will be called. */ if (status != 0) { rf->rf_effective_interval *= 2; if (rf->rf_effective_interval > TIME_T_TO_CDTIME_T (86400)) rf->rf_effective_interval = TIME_T_TO_CDTIME_T (86400); NOTICE ("read-function of plugin `%s' failed. " "Will suspend it for %.3f seconds.", rf->rf_name, CDTIME_T_TO_DOUBLE (rf->rf_effective_interval)); } else { /* Success: Restore the interval, if it was changed. */ rf->rf_effective_interval = rf->rf_interval; } /* update the ``next read due'' field */ now = cdtime (); DEBUG ("plugin_read_thread: Effective interval of the " "%s plugin is %.3f seconds.", rf->rf_name, CDTIME_T_TO_DOUBLE (rf->rf_effective_interval)); /* Calculate the next (absolute) time at which this function * should be called. */ rf->rf_next_read += rf->rf_effective_interval; /* Check, if `rf_next_read' is in the past. */ if (rf->rf_next_read < now) { /* `rf_next_read' is in the past. Insert `now' * so this value doesn't trail off into the * past too much. */ rf->rf_next_read = now; } DEBUG ("plugin_read_thread: Next read of the %s plugin at %.3f.", rf->rf_name, CDTIME_T_TO_DOUBLE (rf->rf_next_read)); /* Re-insert this read function into the heap again. */ c_heap_insert (read_heap, rf); } /* while (read_loop) */ pthread_exit (NULL); return ((void *) 0); } /* void *plugin_read_thread */ static void start_read_threads (int num) { int i; if (read_threads != NULL) return; read_threads = (pthread_t *) calloc (num, sizeof (pthread_t)); if (read_threads == NULL) { ERROR ("plugin: start_read_threads: calloc failed."); return; } read_threads_num = 0; for (i = 0; i < num; i++) { if (pthread_create (read_threads + read_threads_num, NULL, plugin_read_thread, NULL) == 0) { read_threads_num++; } else { ERROR ("plugin: start_read_threads: pthread_create failed."); return; } } /* for (i) */ } /* void start_read_threads */ static void stop_read_threads (void) { int i; if (read_threads == NULL) return; INFO ("collectd: Stopping %i read threads.", read_threads_num); pthread_mutex_lock (&read_lock); read_loop = 0; DEBUG ("plugin: stop_read_threads: Signalling `read_cond'"); pthread_cond_broadcast (&read_cond); pthread_mutex_unlock (&read_lock); for (i = 0; i < read_threads_num; i++) { if (pthread_join (read_threads[i], NULL) != 0) { ERROR ("plugin: stop_read_threads: pthread_join failed."); } read_threads[i] = (pthread_t) 0; } sfree (read_threads); read_threads_num = 0; } /* void stop_read_threads */ static void plugin_value_list_free (value_list_t *vl) /* {{{ */ { if (vl == NULL) return; meta_data_destroy (vl->meta); sfree (vl->values); sfree (vl); } /* }}} void plugin_value_list_free */ static value_list_t *plugin_value_list_clone (value_list_t const *vl_orig) /* {{{ */ { value_list_t *vl; if (vl_orig == NULL) return (NULL); vl = malloc (sizeof (*vl)); if (vl == NULL) return (NULL); memcpy (vl, vl_orig, sizeof (*vl)); vl->values = calloc (vl_orig->values_len, sizeof (*vl->values)); if (vl->values == NULL) { plugin_value_list_free (vl); return (NULL); } memcpy (vl->values, vl_orig->values, vl_orig->values_len * sizeof (*vl->values)); vl->meta = meta_data_clone (vl->meta); if ((vl_orig->meta != NULL) && (vl->meta == NULL)) { plugin_value_list_free (vl); return (NULL); } if (vl->time == 0) vl->time = cdtime (); /* Fill in the interval from the thread context, if it is zero. */ if (vl->interval == 0) { plugin_ctx_t ctx = plugin_get_ctx (); if (ctx.interval != 0) vl->interval = ctx.interval; else { char name[6 * DATA_MAX_NAME_LEN]; FORMAT_VL (name, sizeof (name), vl); ERROR ("plugin_value_list_clone: Unable to determine " "interval from context for " "value list \"%s\". " "This indicates a broken plugin. " "Please report this problem to the " "collectd mailing list or at " ".", name); vl->interval = cf_get_default_interval (); } } return (vl); } /* }}} value_list_t *plugin_value_list_clone */ static int plugin_write_enqueue (value_list_t const *vl) /* {{{ */ { write_queue_t *q; q = malloc (sizeof (*q)); if (q == NULL) return (ENOMEM); q->next = NULL; q->vl = plugin_value_list_clone (vl); if (q->vl == NULL) { sfree (q); return (ENOMEM); } /* Store context of caller (read plugin); otherwise, it would not be * available to the write plugins when actually dispatching the * value-list later on. */ q->ctx = plugin_get_ctx (); pthread_mutex_lock (&write_lock); if (write_queue_tail == NULL) { write_queue_head = q; write_queue_tail = q; write_queue_length = 1; } else { write_queue_tail->next = q; write_queue_tail = q; write_queue_length += 1; } pthread_cond_signal (&write_cond); pthread_mutex_unlock (&write_lock); return (0); } /* }}} int plugin_write_enqueue */ static value_list_t *plugin_write_dequeue (void) /* {{{ */ { write_queue_t *q; value_list_t *vl; pthread_mutex_lock (&write_lock); while (write_loop && (write_queue_head == NULL)) pthread_cond_wait (&write_cond, &write_lock); if (write_queue_head == NULL) { pthread_mutex_unlock (&write_lock); return (NULL); } q = write_queue_head; write_queue_head = q->next; write_queue_length -= 1; if (write_queue_head == NULL) { write_queue_tail = NULL; assert(0 == write_queue_length); } pthread_mutex_unlock (&write_lock); (void) plugin_set_ctx (q->ctx); vl = q->vl; sfree (q); return (vl); } /* }}} value_list_t *plugin_write_dequeue */ static void *plugin_write_thread (void __attribute__((unused)) *args) /* {{{ */ { while (write_loop) { value_list_t *vl = plugin_write_dequeue (); if (vl == NULL) continue; plugin_dispatch_values_internal (vl); plugin_value_list_free (vl); } pthread_exit (NULL); return ((void *) 0); } /* }}} void *plugin_write_thread */ static void start_write_threads (size_t num) /* {{{ */ { size_t i; if (write_threads != NULL) return; write_threads = (pthread_t *) calloc (num, sizeof (pthread_t)); if (write_threads == NULL) { ERROR ("plugin: start_write_threads: calloc failed."); return; } write_threads_num = 0; for (i = 0; i < num; i++) { int status; status = pthread_create (write_threads + write_threads_num, /* attr = */ NULL, plugin_write_thread, /* arg = */ NULL); if (status != 0) { char errbuf[1024]; ERROR ("plugin: start_write_threads: pthread_create failed " "with status %i (%s).", status, sstrerror (status, errbuf, sizeof (errbuf))); return; } write_threads_num++; } /* for (i) */ } /* }}} void start_write_threads */ static void stop_write_threads (void) /* {{{ */ { write_queue_t *q; int i; if (write_threads == NULL) return; INFO ("collectd: Stopping %zu write threads.", write_threads_num); pthread_mutex_lock (&write_lock); write_loop = 0; DEBUG ("plugin: stop_write_threads: Signalling `write_cond'"); pthread_cond_broadcast (&write_cond); pthread_mutex_unlock (&write_lock); for (i = 0; i < write_threads_num; i++) { if (pthread_join (write_threads[i], NULL) != 0) { ERROR ("plugin: stop_write_threads: pthread_join failed."); } write_threads[i] = (pthread_t) 0; } sfree (write_threads); write_threads_num = 0; pthread_mutex_lock (&write_lock); i = 0; for (q = write_queue_head; q != NULL; ) { write_queue_t *q1 = q; plugin_value_list_free (q->vl); q = q->next; sfree (q1); i++; } write_queue_head = NULL; write_queue_tail = NULL; write_queue_length = 0; pthread_mutex_unlock (&write_lock); if (i > 0) { WARNING ("plugin: %i value list%s left after shutting down " "the write threads.", i, (i == 1) ? " was" : "s were"); } } /* }}} void stop_write_threads */ /* * Public functions */ void plugin_set_dir (const char *dir) { if (plugindir != NULL) free (plugindir); if (dir == NULL) plugindir = NULL; else if ((plugindir = strdup (dir)) == NULL) { char errbuf[1024]; ERROR ("strdup failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); } } static _Bool plugin_is_loaded (char const *name) { int status; if (plugins_loaded == NULL) plugins_loaded = c_avl_create ((void *) strcasecmp); assert (plugins_loaded != NULL); status = c_avl_get (plugins_loaded, name, /* ret_value = */ NULL); return (status == 0); } static int plugin_mark_loaded (char const *name) { char *name_copy; int status; name_copy = strdup (name); if (name_copy == NULL) return (ENOMEM); status = c_avl_insert (plugins_loaded, /* key = */ name_copy, /* value = */ NULL); return (status); } static void plugin_free_loaded () { void *key; void *value; if (plugins_loaded == NULL) return; while (c_avl_pick (plugins_loaded, &key, &value) == 0) { sfree (key); assert (value == NULL); } c_avl_destroy (plugins_loaded); plugins_loaded = NULL; } #define BUFSIZE 512 int plugin_load (char const *plugin_name, uint32_t flags) { DIR *dh; const char *dir; char filename[BUFSIZE] = ""; char typename[BUFSIZE]; int typename_len; int ret; struct stat statbuf; struct dirent *de; int status; if (plugin_name == NULL) return (EINVAL); /* Check if plugin is already loaded and don't do anything in this * case. */ if (plugin_is_loaded (plugin_name)) return (0); dir = plugin_get_dir (); ret = 1; /* * XXX: Magic at work: * * Some of the language bindings, for example the Python and Perl * plugins, need to be able to export symbols to the scripts they run. * For this to happen, the "Globals" flag needs to be set. * Unfortunately, this technical detail is hard to explain to the * average user and she shouldn't have to worry about this, ideally. * So in order to save everyone's sanity use a different default for a * handful of special plugins. --octo */ if ((strcasecmp ("perl", plugin_name) == 0) || (strcasecmp ("python", plugin_name) == 0)) flags |= PLUGIN_FLAGS_GLOBAL; /* `cpu' should not match `cpufreq'. To solve this we add `.so' to the * type when matching the filename */ status = ssnprintf (typename, sizeof (typename), "%s.so", plugin_name); if ((status < 0) || ((size_t) status >= sizeof (typename))) { WARNING ("plugin_load: Filename too long: \"%s.so\"", plugin_name); return (-1); } typename_len = strlen (typename); if ((dh = opendir (dir)) == NULL) { char errbuf[1024]; ERROR ("plugin_load: opendir (%s) failed: %s", dir, sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } while ((de = readdir (dh)) != NULL) { if (strncasecmp (de->d_name, typename, typename_len)) continue; status = ssnprintf (filename, sizeof (filename), "%s/%s", dir, de->d_name); if ((status < 0) || ((size_t) status >= sizeof (filename))) { WARNING ("plugin_load: Filename too long: \"%s/%s\"", dir, de->d_name); continue; } if (lstat (filename, &statbuf) == -1) { char errbuf[1024]; WARNING ("plugin_load: stat (\"%s\") failed: %s", filename, sstrerror (errno, errbuf, sizeof (errbuf))); continue; } else if (!S_ISREG (statbuf.st_mode)) { /* don't follow symlinks */ WARNING ("plugin_load: %s is not a regular file.", filename); continue; } status = plugin_load_file (filename, flags); if (status == 0) { /* success */ plugin_mark_loaded (plugin_name); ret = 0; break; } else { ERROR ("plugin_load: Load plugin \"%s\" failed with " "status %i.", plugin_name, status); } } closedir (dh); if (filename[0] == 0) ERROR ("plugin_load: Could not find plugin \"%s\" in %s", plugin_name, dir); return (ret); } /* * The `register_*' functions follow */ int plugin_register_config (const char *name, int (*callback) (const char *key, const char *val), const char **keys, int keys_num) { cf_register (name, callback, keys, keys_num); return (0); } /* int plugin_register_config */ int plugin_register_complex_config (const char *type, int (*callback) (oconfig_item_t *)) { return (cf_register_complex (type, callback)); } /* int plugin_register_complex_config */ int plugin_register_init (const char *name, int (*callback) (void)) { return (create_register_callback (&list_init, name, (void *) callback, /* user_data = */ NULL)); } /* plugin_register_init */ static int plugin_compare_read_func (const void *arg0, const void *arg1) { const read_func_t *rf0; const read_func_t *rf1; rf0 = arg0; rf1 = arg1; if (rf0->rf_next_read < rf1->rf_next_read) return (-1); else if (rf0->rf_next_read > rf1->rf_next_read) return (1); else return (0); } /* int plugin_compare_read_func */ /* Add a read function to both, the heap and a linked list. The linked list if * used to look-up read functions, especially for the remove function. The heap * is used to determine which plugin to read next. */ static int plugin_insert_read (read_func_t *rf) { int status; llentry_t *le; rf->rf_next_read = cdtime (); rf->rf_effective_interval = rf->rf_interval; pthread_mutex_lock (&read_lock); if (read_list == NULL) { read_list = llist_create (); if (read_list == NULL) { pthread_mutex_unlock (&read_lock); ERROR ("plugin_insert_read: read_list failed."); return (-1); } } if (read_heap == NULL) { read_heap = c_heap_create (plugin_compare_read_func); if (read_heap == NULL) { pthread_mutex_unlock (&read_lock); ERROR ("plugin_insert_read: c_heap_create failed."); return (-1); } } le = llist_search (read_list, rf->rf_name); if (le != NULL) { pthread_mutex_unlock (&read_lock); WARNING ("The read function \"%s\" is already registered. " "Check for duplicate \"LoadPlugin\" lines " "in your configuration!", rf->rf_name); return (EINVAL); } le = llentry_create (rf->rf_name, rf); if (le == NULL) { pthread_mutex_unlock (&read_lock); ERROR ("plugin_insert_read: llentry_create failed."); return (-1); } status = c_heap_insert (read_heap, rf); if (status != 0) { pthread_mutex_unlock (&read_lock); ERROR ("plugin_insert_read: c_heap_insert failed."); llentry_destroy (le); return (-1); } /* This does not fail. */ llist_append (read_list, le); /* Wake up all the read threads. */ pthread_cond_broadcast (&read_cond); pthread_mutex_unlock (&read_lock); return (0); } /* int plugin_insert_read */ int plugin_register_read (const char *name, int (*callback) (void)) { read_func_t *rf; int status; rf = malloc (sizeof (*rf)); if (rf == NULL) { ERROR ("plugin_register_read: malloc failed."); return (ENOMEM); } memset (rf, 0, sizeof (read_func_t)); rf->rf_callback = (void *) callback; rf->rf_udata.data = NULL; rf->rf_udata.free_func = NULL; rf->rf_ctx = plugin_get_ctx (); rf->rf_group[0] = '\0'; rf->rf_name = strdup (name); rf->rf_type = RF_SIMPLE; rf->rf_interval = plugin_get_interval (); status = plugin_insert_read (rf); if (status != 0) sfree (rf); return (status); } /* int plugin_register_read */ int plugin_register_complex_read (const char *group, const char *name, plugin_read_cb callback, const struct timespec *interval, user_data_t *user_data) { read_func_t *rf; int status; rf = malloc (sizeof (*rf)); if (rf == NULL) { ERROR ("plugin_register_complex_read: malloc failed."); return (ENOMEM); } memset (rf, 0, sizeof (read_func_t)); rf->rf_callback = (void *) callback; if (group != NULL) sstrncpy (rf->rf_group, group, sizeof (rf->rf_group)); else rf->rf_group[0] = '\0'; rf->rf_name = strdup (name); rf->rf_type = RF_COMPLEX; if (interval != NULL) rf->rf_interval = TIMESPEC_TO_CDTIME_T (interval); else rf->rf_interval = plugin_get_interval (); /* Set user data */ if (user_data == NULL) { rf->rf_udata.data = NULL; rf->rf_udata.free_func = NULL; } else { rf->rf_udata = *user_data; } rf->rf_ctx = plugin_get_ctx (); status = plugin_insert_read (rf); if (status != 0) sfree (rf); return (status); } /* int plugin_register_complex_read */ int plugin_register_write (const char *name, plugin_write_cb callback, user_data_t *ud) { return (create_register_callback (&list_write, name, (void *) callback, ud)); } /* int plugin_register_write */ int plugin_register_flush (const char *name, plugin_flush_cb callback, user_data_t *ud) { return (create_register_callback (&list_flush, name, (void *) callback, ud)); } /* int plugin_register_flush */ int plugin_register_missing (const char *name, plugin_missing_cb callback, user_data_t *ud) { return (create_register_callback (&list_missing, name, (void *) callback, ud)); } /* int plugin_register_missing */ int plugin_register_shutdown (const char *name, int (*callback) (void)) { return (create_register_callback (&list_shutdown, name, (void *) callback, /* user_data = */ NULL)); } /* int plugin_register_shutdown */ static void plugin_free_data_sets (void) { void *key; void *value; if (data_sets == NULL) return; while (c_avl_pick (data_sets, &key, &value) == 0) { data_set_t *ds = value; /* key is a pointer to ds->type */ sfree (ds->ds); sfree (ds); } c_avl_destroy (data_sets); data_sets = NULL; } /* void plugin_free_data_sets */ int plugin_register_data_set (const data_set_t *ds) { data_set_t *ds_copy; int i; if ((data_sets != NULL) && (c_avl_get (data_sets, ds->type, NULL) == 0)) { NOTICE ("Replacing DS `%s' with another version.", ds->type); plugin_unregister_data_set (ds->type); } else if (data_sets == NULL) { data_sets = c_avl_create ((int (*) (const void *, const void *)) strcmp); if (data_sets == NULL) return (-1); } ds_copy = (data_set_t *) malloc (sizeof (data_set_t)); if (ds_copy == NULL) return (-1); memcpy(ds_copy, ds, sizeof (data_set_t)); ds_copy->ds = (data_source_t *) malloc (sizeof (data_source_t) * ds->ds_num); if (ds_copy->ds == NULL) { free (ds_copy); return (-1); } for (i = 0; i < ds->ds_num; i++) memcpy (ds_copy->ds + i, ds->ds + i, sizeof (data_source_t)); return (c_avl_insert (data_sets, (void *) ds_copy->type, (void *) ds_copy)); } /* int plugin_register_data_set */ int plugin_register_log (const char *name, plugin_log_cb callback, user_data_t *ud) { return (create_register_callback (&list_log, name, (void *) callback, ud)); } /* int plugin_register_log */ int plugin_register_notification (const char *name, plugin_notification_cb callback, user_data_t *ud) { return (create_register_callback (&list_notification, name, (void *) callback, ud)); } /* int plugin_register_log */ int plugin_unregister_config (const char *name) { cf_unregister (name); return (0); } /* int plugin_unregister_config */ int plugin_unregister_complex_config (const char *name) { cf_unregister_complex (name); return (0); } /* int plugin_unregister_complex_config */ int plugin_unregister_init (const char *name) { return (plugin_unregister (list_init, name)); } int plugin_unregister_read (const char *name) /* {{{ */ { llentry_t *le; read_func_t *rf; if (name == NULL) return (-ENOENT); pthread_mutex_lock (&read_lock); if (read_list == NULL) { pthread_mutex_unlock (&read_lock); return (-ENOENT); } le = llist_search (read_list, name); if (le == NULL) { pthread_mutex_unlock (&read_lock); WARNING ("plugin_unregister_read: No such read function: %s", name); return (-ENOENT); } llist_remove (read_list, le); rf = le->value; assert (rf != NULL); rf->rf_type = RF_REMOVE; pthread_mutex_unlock (&read_lock); llentry_destroy (le); DEBUG ("plugin_unregister_read: Marked `%s' for removal.", name); return (0); } /* }}} int plugin_unregister_read */ static int compare_read_func_group (llentry_t *e, void *ud) /* {{{ */ { read_func_t *rf = e->value; char *group = ud; return strcmp (rf->rf_group, (const char *)group); } /* }}} int compare_read_func_group */ int plugin_unregister_read_group (const char *group) /* {{{ */ { llentry_t *le; read_func_t *rf; int found = 0; if (group == NULL) return (-ENOENT); pthread_mutex_lock (&read_lock); if (read_list == NULL) { pthread_mutex_unlock (&read_lock); return (-ENOENT); } while (42) { le = llist_search_custom (read_list, compare_read_func_group, (void *)group); if (le == NULL) break; ++found; llist_remove (read_list, le); rf = le->value; assert (rf != NULL); rf->rf_type = RF_REMOVE; llentry_destroy (le); DEBUG ("plugin_unregister_read_group: " "Marked `%s' (group `%s') for removal.", rf->rf_name, group); } pthread_mutex_unlock (&read_lock); if (found == 0) { WARNING ("plugin_unregister_read_group: No such " "group of read function: %s", group); return (-ENOENT); } return (0); } /* }}} int plugin_unregister_read_group */ int plugin_unregister_write (const char *name) { return (plugin_unregister (list_write, name)); } int plugin_unregister_flush (const char *name) { return (plugin_unregister (list_flush, name)); } int plugin_unregister_missing (const char *name) { return (plugin_unregister (list_missing, name)); } int plugin_unregister_shutdown (const char *name) { return (plugin_unregister (list_shutdown, name)); } int plugin_unregister_data_set (const char *name) { data_set_t *ds; if (data_sets == NULL) return (-1); if (c_avl_remove (data_sets, name, NULL, (void *) &ds) != 0) return (-1); sfree (ds->ds); sfree (ds); return (0); } /* int plugin_unregister_data_set */ int plugin_unregister_log (const char *name) { return (plugin_unregister (list_log, name)); } int plugin_unregister_notification (const char *name) { return (plugin_unregister (list_notification, name)); } void plugin_init_all (void) { char const *chain_name; long write_threads_num; llentry_t *le; int status; /* Init the value cache */ uc_init (); chain_name = global_option_get ("PreCacheChain"); pre_cache_chain = fc_chain_get_by_name (chain_name); chain_name = global_option_get ("PostCacheChain"); post_cache_chain = fc_chain_get_by_name (chain_name); write_limit_high = global_option_get_long ("WriteQueueLimitHigh", /* default = */ 0); if (write_limit_high < 0) { ERROR ("WriteQueueLimitHigh must be positive or zero."); write_limit_high = 0; } write_limit_low = global_option_get_long ("WriteQueueLimitLow", /* default = */ write_limit_high / 2); if (write_limit_low < 0) { ERROR ("WriteQueueLimitLow must be positive or zero."); write_limit_low = write_limit_high / 2; } else if (write_limit_low > write_limit_high) { ERROR ("WriteQueueLimitLow must not be larger than " "WriteQueueLimitHigh."); write_limit_low = write_limit_high; } write_threads_num = global_option_get_long ("WriteThreads", /* default = */ 5); if (write_threads_num < 1) { ERROR ("WriteThreads must be positive."); write_threads_num = 5; } start_write_threads ((size_t) write_threads_num); if ((list_init == NULL) && (read_heap == NULL)) return; /* Calling all init callbacks before checking if read callbacks * are available allows the init callbacks to register the read * callback. */ le = llist_head (list_init); while (le != NULL) { callback_func_t *cf; plugin_init_cb callback; plugin_ctx_t old_ctx; cf = le->value; old_ctx = plugin_set_ctx (cf->cf_ctx); callback = cf->cf_callback; status = (*callback) (); plugin_set_ctx (old_ctx); if (status != 0) { ERROR ("Initialization of plugin `%s' " "failed with status %i. " "Plugin will be unloaded.", le->key, status); /* Plugins that register read callbacks from the init * callback should take care of appropriate error * handling themselves. */ /* FIXME: Unload _all_ functions */ plugin_unregister_read (le->key); } le = le->next; } /* Start read-threads */ if (read_heap != NULL) { const char *rt; int num; rt = global_option_get ("ReadThreads"); num = atoi (rt); if (num != -1) start_read_threads ((num > 0) ? num : 5); } } /* void plugin_init_all */ /* TODO: Rename this function. */ void plugin_read_all (void) { uc_check_timeout (); return; } /* void plugin_read_all */ /* Read function called when the `-T' command line argument is given. */ int plugin_read_all_once (void) { int status; int return_status = 0; if (read_heap == NULL) { NOTICE ("No read-functions are registered."); return (0); } while (42) { read_func_t *rf; plugin_ctx_t old_ctx; rf = c_heap_get_root (read_heap); if (rf == NULL) break; old_ctx = plugin_set_ctx (rf->rf_ctx); if (rf->rf_type == RF_SIMPLE) { int (*callback) (void); callback = rf->rf_callback; status = (*callback) (); } else { plugin_read_cb callback; callback = rf->rf_callback; status = (*callback) (&rf->rf_udata); } plugin_set_ctx (old_ctx); if (status != 0) { NOTICE ("read-function of plugin `%s' failed.", rf->rf_name); return_status = -1; } destroy_callback ((void *) rf); } return (return_status); } /* int plugin_read_all_once */ int plugin_write (const char *plugin, /* {{{ */ const data_set_t *ds, const value_list_t *vl) { llentry_t *le; int status; if (vl == NULL) return (EINVAL); if (list_write == NULL) return (ENOENT); if (ds == NULL) { ds = plugin_get_ds (vl->type); if (ds == NULL) { ERROR ("plugin_write: Unable to lookup type `%s'.", vl->type); return (ENOENT); } } if (plugin == NULL) { int success = 0; int failure = 0; le = llist_head (list_write); while (le != NULL) { callback_func_t *cf = le->value; plugin_write_cb callback; /* do not switch plugin context; rather keep the context (interval) * information of the calling read plugin */ DEBUG ("plugin: plugin_write: Writing values via %s.", le->key); callback = cf->cf_callback; status = (*callback) (ds, vl, &cf->cf_udata); if (status != 0) failure++; else success++; le = le->next; } if ((success == 0) && (failure != 0)) status = -1; else status = 0; } else /* plugin != NULL */ { callback_func_t *cf; plugin_write_cb callback; le = llist_head (list_write); while (le != NULL) { if (strcasecmp (plugin, le->key) == 0) break; le = le->next; } if (le == NULL) return (ENOENT); cf = le->value; /* do not switch plugin context; rather keep the context (interval) * information of the calling read plugin */ DEBUG ("plugin: plugin_write: Writing values via %s.", le->key); callback = cf->cf_callback; status = (*callback) (ds, vl, &cf->cf_udata); } return (status); } /* }}} int plugin_write */ int plugin_flush (const char *plugin, cdtime_t timeout, const char *identifier) { llentry_t *le; if (list_flush == NULL) return (0); le = llist_head (list_flush); while (le != NULL) { callback_func_t *cf; plugin_flush_cb callback; plugin_ctx_t old_ctx; if ((plugin != NULL) && (strcmp (plugin, le->key) != 0)) { le = le->next; continue; } cf = le->value; old_ctx = plugin_set_ctx (cf->cf_ctx); callback = cf->cf_callback; (*callback) (timeout, identifier, &cf->cf_udata); plugin_set_ctx (old_ctx); le = le->next; } return (0); } /* int plugin_flush */ void plugin_shutdown_all (void) { llentry_t *le; stop_read_threads (); destroy_all_callbacks (&list_init); pthread_mutex_lock (&read_lock); llist_destroy (read_list); read_list = NULL; pthread_mutex_unlock (&read_lock); destroy_read_heap (); plugin_flush (/* plugin = */ NULL, /* timeout = */ 0, /* identifier = */ NULL); le = NULL; if (list_shutdown != NULL) le = llist_head (list_shutdown); while (le != NULL) { callback_func_t *cf; plugin_shutdown_cb callback; plugin_ctx_t old_ctx; cf = le->value; old_ctx = plugin_set_ctx (cf->cf_ctx); callback = cf->cf_callback; /* Advance the pointer before calling the callback allows * shutdown functions to unregister themselves. If done the * other way around the memory `le' points to will be freed * after callback returns. */ le = le->next; (*callback) (); plugin_set_ctx (old_ctx); } stop_write_threads (); /* Write plugins which use the `user_data' pointer usually need the * same data available to the flush callback. If this is the case, set * the free_function to NULL when registering the flush callback and to * the real free function when registering the write callback. This way * the data isn't freed twice. */ destroy_all_callbacks (&list_flush); destroy_all_callbacks (&list_missing); destroy_all_callbacks (&list_write); destroy_all_callbacks (&list_notification); destroy_all_callbacks (&list_shutdown); destroy_all_callbacks (&list_log); plugin_free_loaded (); plugin_free_data_sets (); } /* void plugin_shutdown_all */ int plugin_dispatch_missing (const value_list_t *vl) /* {{{ */ { llentry_t *le; if (list_missing == NULL) return (0); le = llist_head (list_missing); while (le != NULL) { callback_func_t *cf; plugin_missing_cb callback; plugin_ctx_t old_ctx; int status; cf = le->value; old_ctx = plugin_set_ctx (cf->cf_ctx); callback = cf->cf_callback; status = (*callback) (vl, &cf->cf_udata); plugin_set_ctx (old_ctx); if (status != 0) { if (status < 0) { ERROR ("plugin_dispatch_missing: Callback function \"%s\" " "failed with status %i.", le->key, status); return (status); } else { return (0); } } le = le->next; } return (0); } /* int }}} plugin_dispatch_missing */ static int plugin_dispatch_values_internal (value_list_t *vl) { int status; static c_complain_t no_write_complaint = C_COMPLAIN_INIT_STATIC; value_t *saved_values; int saved_values_len; data_set_t *ds; int free_meta_data = 0; if ((vl == NULL) || (vl->type[0] == 0) || (vl->values == NULL) || (vl->values_len < 1)) { ERROR ("plugin_dispatch_values: Invalid value list " "from plugin %s.", vl->plugin); return (-1); } /* Free meta data only if the calling function didn't specify any. In * this case matches and targets may add some and the calling function * may not expect (and therefore free) that data. */ if (vl->meta == NULL) free_meta_data = 1; if (list_write == NULL) c_complain_once (LOG_WARNING, &no_write_complaint, "plugin_dispatch_values: No write callback has been " "registered. Please load at least one output plugin, " "if you want the collected data to be stored."); if (data_sets == NULL) { ERROR ("plugin_dispatch_values: No data sets registered. " "Could the types database be read? Check " "your `TypesDB' setting!"); return (-1); } if (c_avl_get (data_sets, vl->type, (void *) &ds) != 0) { char ident[6 * DATA_MAX_NAME_LEN]; FORMAT_VL (ident, sizeof (ident), vl); INFO ("plugin_dispatch_values: Dataset not found: %s " "(from \"%s\"), check your types.db!", vl->type, ident); return (-1); } /* Assured by plugin_value_list_clone(). The time is determined at * _enqueue_ time. */ assert (vl->time != 0); assert (vl->interval != 0); DEBUG ("plugin_dispatch_values: time = %.3f; interval = %.3f; " "host = %s; " "plugin = %s; plugin_instance = %s; " "type = %s; type_instance = %s;", CDTIME_T_TO_DOUBLE (vl->time), CDTIME_T_TO_DOUBLE (vl->interval), vl->host, vl->plugin, vl->plugin_instance, vl->type, vl->type_instance); #if COLLECT_DEBUG assert (0 == strcmp (ds->type, vl->type)); #else if (0 != strcmp (ds->type, vl->type)) WARNING ("plugin_dispatch_values: (ds->type = %s) != (vl->type = %s)", ds->type, vl->type); #endif #if COLLECT_DEBUG assert (ds->ds_num == vl->values_len); #else if (ds->ds_num != vl->values_len) { ERROR ("plugin_dispatch_values: ds->type = %s: " "(ds->ds_num = %i) != " "(vl->values_len = %i)", ds->type, ds->ds_num, vl->values_len); return (-1); } #endif escape_slashes (vl->host, sizeof (vl->host)); escape_slashes (vl->plugin, sizeof (vl->plugin)); escape_slashes (vl->plugin_instance, sizeof (vl->plugin_instance)); escape_slashes (vl->type, sizeof (vl->type)); escape_slashes (vl->type_instance, sizeof (vl->type_instance)); /* Copy the values. This way, we can assure `targets' that they get * dynamically allocated values, which they can free and replace if * they like. */ if ((pre_cache_chain != NULL) || (post_cache_chain != NULL)) { saved_values = vl->values; saved_values_len = vl->values_len; vl->values = (value_t *) calloc (vl->values_len, sizeof (*vl->values)); if (vl->values == NULL) { ERROR ("plugin_dispatch_values: calloc failed."); vl->values = saved_values; return (-1); } memcpy (vl->values, saved_values, vl->values_len * sizeof (*vl->values)); } else /* if ((pre == NULL) && (post == NULL)) */ { saved_values = NULL; saved_values_len = 0; } if (pre_cache_chain != NULL) { status = fc_process_chain (ds, vl, pre_cache_chain); if (status < 0) { WARNING ("plugin_dispatch_values: Running the " "pre-cache chain failed with " "status %i (%#x).", status, status); } else if (status == FC_TARGET_STOP) { /* Restore the state of the value_list so that plugins * don't get confused.. */ if (saved_values != NULL) { free (vl->values); vl->values = saved_values; vl->values_len = saved_values_len; } return (0); } } /* Update the value cache */ uc_update (ds, vl); if (post_cache_chain != NULL) { status = fc_process_chain (ds, vl, post_cache_chain); if (status < 0) { WARNING ("plugin_dispatch_values: Running the " "post-cache chain failed with " "status %i (%#x).", status, status); } } else fc_default_action (ds, vl); /* Restore the state of the value_list so that plugins don't get * confused.. */ if (saved_values != NULL) { free (vl->values); vl->values = saved_values; vl->values_len = saved_values_len; } if ((free_meta_data != 0) && (vl->meta != NULL)) { meta_data_destroy (vl->meta); vl->meta = NULL; } return (0); } /* int plugin_dispatch_values_internal */ static double get_drop_probability (void) /* {{{ */ { long pos; long size; long wql; pthread_mutex_lock (&write_lock); wql = write_queue_length; pthread_mutex_unlock (&write_lock); if (wql < write_limit_low) return (0.0); if (wql >= write_limit_high) return (1.0); pos = 1 + wql - write_limit_low; size = 1 + write_limit_high - write_limit_low; return (((double) pos) / ((double) size)); } /* }}} double get_drop_probability */ static _Bool check_drop_value (void) /* {{{ */ { static cdtime_t last_message_time = 0; static pthread_mutex_t last_message_lock = PTHREAD_MUTEX_INITIALIZER; double p; double q; int status; if (write_limit_high == 0) return (0); p = get_drop_probability (); if (p == 0.0) return (0); status = pthread_mutex_trylock (&last_message_lock); if (status == 0) { cdtime_t now; now = cdtime (); if ((now - last_message_time) > TIME_T_TO_CDTIME_T (1)) { last_message_time = now; ERROR ("plugin_dispatch_values: Low water mark " "reached. Dropping %.0f%% of metrics.", 100.0 * p); } pthread_mutex_unlock (&last_message_lock); } if (p == 1.0) return (1); q = cdrand_d (); if (q > p) return (1); else return (0); } /* }}} _Bool check_drop_value */ int plugin_dispatch_values (value_list_t const *vl) { int status; if (check_drop_value ()) return (0); status = plugin_write_enqueue (vl); if (status != 0) { char errbuf[1024]; ERROR ("plugin_dispatch_values: plugin_write_enqueue failed " "with status %i (%s).", status, sstrerror (status, errbuf, sizeof (errbuf))); return (status); } return (0); } int plugin_dispatch_notification (const notification_t *notif) { llentry_t *le; /* Possible TODO: Add flap detection here */ DEBUG ("plugin_dispatch_notification: severity = %i; message = %s; " "time = %.3f; host = %s;", notif->severity, notif->message, CDTIME_T_TO_DOUBLE (notif->time), notif->host); /* Nobody cares for notifications */ if (list_notification == NULL) return (-1); le = llist_head (list_notification); while (le != NULL) { callback_func_t *cf; plugin_notification_cb callback; int status; /* do not switch plugin context; rather keep the context * (interval) information of the calling plugin */ cf = le->value; callback = cf->cf_callback; status = (*callback) (notif, &cf->cf_udata); if (status != 0) { WARNING ("plugin_dispatch_notification: Notification " "callback %s returned %i.", le->key, status); } le = le->next; } return (0); } /* int plugin_dispatch_notification */ void plugin_log (int level, const char *format, ...) { char msg[1024]; va_list ap; llentry_t *le; #if !COLLECT_DEBUG if (level >= LOG_DEBUG) return; #endif va_start (ap, format); vsnprintf (msg, sizeof (msg), format, ap); msg[sizeof (msg) - 1] = '\0'; va_end (ap); if (list_log == NULL) { fprintf (stderr, "%s\n", msg); return; } le = llist_head (list_log); while (le != NULL) { callback_func_t *cf; plugin_log_cb callback; cf = le->value; callback = cf->cf_callback; /* do not switch plugin context; rather keep the context * (interval) information of the calling plugin */ (*callback) (level, msg, &cf->cf_udata); le = le->next; } } /* void plugin_log */ int parse_log_severity (const char *severity) { int log_level = -1; if ((0 == strcasecmp (severity, "emerg")) || (0 == strcasecmp (severity, "alert")) || (0 == strcasecmp (severity, "crit")) || (0 == strcasecmp (severity, "err"))) log_level = LOG_ERR; else if (0 == strcasecmp (severity, "warning")) log_level = LOG_WARNING; else if (0 == strcasecmp (severity, "notice")) log_level = LOG_NOTICE; else if (0 == strcasecmp (severity, "info")) log_level = LOG_INFO; #if COLLECT_DEBUG else if (0 == strcasecmp (severity, "debug")) log_level = LOG_DEBUG; #endif /* COLLECT_DEBUG */ return (log_level); } /* int parse_log_severity */ int parse_notif_severity (const char *severity) { int notif_severity = -1; if (strcasecmp (severity, "FAILURE") == 0) notif_severity = NOTIF_FAILURE; else if (strcmp (severity, "OKAY") == 0) notif_severity = NOTIF_OKAY; else if ((strcmp (severity, "WARNING") == 0) || (strcmp (severity, "WARN") == 0)) notif_severity = NOTIF_WARNING; return (notif_severity); } /* int parse_notif_severity */ const data_set_t *plugin_get_ds (const char *name) { data_set_t *ds; if (data_sets == NULL) { ERROR ("plugin_get_ds: No data sets are defined yet."); return (NULL); } if (c_avl_get (data_sets, name, (void *) &ds) != 0) { DEBUG ("No such dataset registered: %s", name); return (NULL); } return (ds); } /* data_set_t *plugin_get_ds */ static int plugin_notification_meta_add (notification_t *n, const char *name, enum notification_meta_type_e type, const void *value) { notification_meta_t *meta; notification_meta_t *tail; if ((n == NULL) || (name == NULL) || (value == NULL)) { ERROR ("plugin_notification_meta_add: A pointer is NULL!"); return (-1); } meta = (notification_meta_t *) malloc (sizeof (notification_meta_t)); if (meta == NULL) { ERROR ("plugin_notification_meta_add: malloc failed."); return (-1); } memset (meta, 0, sizeof (notification_meta_t)); sstrncpy (meta->name, name, sizeof (meta->name)); meta->type = type; switch (type) { case NM_TYPE_STRING: { meta->nm_value.nm_string = strdup ((const char *) value); if (meta->nm_value.nm_string == NULL) { ERROR ("plugin_notification_meta_add: strdup failed."); sfree (meta); return (-1); } break; } case NM_TYPE_SIGNED_INT: { meta->nm_value.nm_signed_int = *((int64_t *) value); break; } case NM_TYPE_UNSIGNED_INT: { meta->nm_value.nm_unsigned_int = *((uint64_t *) value); break; } case NM_TYPE_DOUBLE: { meta->nm_value.nm_double = *((double *) value); break; } case NM_TYPE_BOOLEAN: { meta->nm_value.nm_boolean = *((_Bool *) value); break; } default: { ERROR ("plugin_notification_meta_add: Unknown type: %i", type); sfree (meta); return (-1); } } /* switch (type) */ meta->next = NULL; tail = n->meta; while ((tail != NULL) && (tail->next != NULL)) tail = tail->next; if (tail == NULL) n->meta = meta; else tail->next = meta; return (0); } /* int plugin_notification_meta_add */ int plugin_notification_meta_add_string (notification_t *n, const char *name, const char *value) { return (plugin_notification_meta_add (n, name, NM_TYPE_STRING, value)); } int plugin_notification_meta_add_signed_int (notification_t *n, const char *name, int64_t value) { return (plugin_notification_meta_add (n, name, NM_TYPE_SIGNED_INT, &value)); } int plugin_notification_meta_add_unsigned_int (notification_t *n, const char *name, uint64_t value) { return (plugin_notification_meta_add (n, name, NM_TYPE_UNSIGNED_INT, &value)); } int plugin_notification_meta_add_double (notification_t *n, const char *name, double value) { return (plugin_notification_meta_add (n, name, NM_TYPE_DOUBLE, &value)); } int plugin_notification_meta_add_boolean (notification_t *n, const char *name, _Bool value) { return (plugin_notification_meta_add (n, name, NM_TYPE_BOOLEAN, &value)); } int plugin_notification_meta_copy (notification_t *dst, const notification_t *src) { notification_meta_t *meta; assert (dst != NULL); assert (src != NULL); assert (dst != src); assert ((src->meta == NULL) || (src->meta != dst->meta)); for (meta = src->meta; meta != NULL; meta = meta->next) { if (meta->type == NM_TYPE_STRING) plugin_notification_meta_add_string (dst, meta->name, meta->nm_value.nm_string); else if (meta->type == NM_TYPE_SIGNED_INT) plugin_notification_meta_add_signed_int (dst, meta->name, meta->nm_value.nm_signed_int); else if (meta->type == NM_TYPE_UNSIGNED_INT) plugin_notification_meta_add_unsigned_int (dst, meta->name, meta->nm_value.nm_unsigned_int); else if (meta->type == NM_TYPE_DOUBLE) plugin_notification_meta_add_double (dst, meta->name, meta->nm_value.nm_double); else if (meta->type == NM_TYPE_BOOLEAN) plugin_notification_meta_add_boolean (dst, meta->name, meta->nm_value.nm_boolean); } return (0); } /* int plugin_notification_meta_copy */ int plugin_notification_meta_free (notification_meta_t *n) { notification_meta_t *this; notification_meta_t *next; if (n == NULL) { ERROR ("plugin_notification_meta_free: n == NULL!"); return (-1); } this = n; while (this != NULL) { next = this->next; if (this->type == NM_TYPE_STRING) { free ((char *)this->nm_value.nm_string); this->nm_value.nm_string = NULL; } sfree (this); this = next; } return (0); } /* int plugin_notification_meta_free */ static void plugin_ctx_destructor (void *ctx) { sfree (ctx); } /* void plugin_ctx_destructor */ static plugin_ctx_t ctx_init = { /* interval = */ 0 }; static plugin_ctx_t *plugin_ctx_create (void) { plugin_ctx_t *ctx; ctx = malloc (sizeof (*ctx)); if (ctx == NULL) { char errbuf[1024]; ERROR ("Failed to allocate plugin context: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return NULL; } *ctx = ctx_init; assert (plugin_ctx_key_initialized); pthread_setspecific (plugin_ctx_key, ctx); DEBUG("Created new plugin context."); return (ctx); } /* int plugin_ctx_create */ void plugin_init_ctx (void) { pthread_key_create (&plugin_ctx_key, plugin_ctx_destructor); plugin_ctx_key_initialized = 1; } /* void plugin_init_ctx */ plugin_ctx_t plugin_get_ctx (void) { plugin_ctx_t *ctx; assert (plugin_ctx_key_initialized); ctx = pthread_getspecific (plugin_ctx_key); if (ctx == NULL) { ctx = plugin_ctx_create (); /* this must no happen -- exit() instead? */ if (ctx == NULL) return ctx_init; } return (*ctx); } /* plugin_ctx_t plugin_get_ctx */ plugin_ctx_t plugin_set_ctx (plugin_ctx_t ctx) { plugin_ctx_t *c; plugin_ctx_t old; assert (plugin_ctx_key_initialized); c = pthread_getspecific (plugin_ctx_key); if (c == NULL) { c = plugin_ctx_create (); /* this must no happen -- exit() instead? */ if (c == NULL) return ctx_init; } old = *c; *c = ctx; return (old); } /* void plugin_set_ctx */ cdtime_t plugin_get_interval (void) { cdtime_t interval; interval = plugin_get_ctx().interval; if (interval > 0) return interval; return cf_get_default_interval (); } /* cdtime_t plugin_get_interval */ typedef struct { plugin_ctx_t ctx; void *(*start_routine) (void *); void *arg; } plugin_thread_t; static void *plugin_thread_start (void *arg) { plugin_thread_t *plugin_thread = arg; void *(*start_routine) (void *) = plugin_thread->start_routine; void *plugin_arg = plugin_thread->arg; plugin_set_ctx (plugin_thread->ctx); free (plugin_thread); return start_routine (plugin_arg); } /* void *plugin_thread_start */ int plugin_thread_create (pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg) { plugin_thread_t *plugin_thread; plugin_thread = malloc (sizeof (*plugin_thread)); if (plugin_thread == NULL) return -1; plugin_thread->ctx = plugin_get_ctx (); plugin_thread->start_routine = start_routine; plugin_thread->arg = arg; return pthread_create (thread, attr, plugin_thread_start, plugin_thread); } /* int plugin_thread_create */ /* vim: set sw=8 ts=8 noet fdm=marker : */ collectd-5.4.0/src/PaxHeaders.11991/liboconfig0000644037772200116100000000013212204120755017202 xustar000000000000000030 mtime=1376821741.710395949 30 atime=1376821742.006400674 30 ctime=1376821742.002400609 collectd-5.4.0/src/liboconfig/0000755037772200116100000000000012204120755016023 5ustar00octoeng00000000000000collectd-5.4.0/src/liboconfig/PaxHeaders.11991/scanner.l0000644037772200116100000000013212204120331021053 xustar000000000000000030 mtime=1376821465.073973439 30 atime=1376821477.218167931 30 ctime=1376821742.006400674 collectd-5.4.0/src/liboconfig/scanner.l0000644037772200116100000000677512204120331017636 0ustar00octoeng00000000000000/** * oconfig - src/scanner.l * Copyright (C) 2007 Florian octo Forster * Copyright (C) 2008 Sebastian tokkee Harl * * 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 */ %{ #include #include "oconfig.h" #include "aux_types.h" #include "parser.h" /* multiline string buffer */ static char *ml_buffer = NULL; static int ml_pos = 0; static int ml_len = 0; #define ml_free (ml_len - ml_pos) static void ml_append (char *); #ifdef yyterminate # undef yyterminate #endif #define yyterminate() \ do { free (ml_buffer); ml_buffer = NULL; ml_pos = 0; ml_len = 0; \ return YY_NULL; } while (0) %} %option yylineno %option noyywrap %x ML WHITE_SPACE [\ \t\b] NON_WHITE_SPACE [^\ \t\b] EOL (\r\n|\n) QUOTED_STRING ([^\\"]+|\\.)* UNQUOTED_STRING [0-9A-Za-z_]+ HEX_NUMBER 0[xX][0-9a-fA-F]+ OCT_NUMBER 0[0-7]+ DEC_NUMBER [\+\-]?[0-9]+ FLOAT_NUMBER [\+\-]?[0-9]*\.[0-9]+([eE][\+\-][0-9]+)? NUMBER ({FLOAT_NUMBER}|{HEX_NUMBER}|{OCT_NUMBER}|{DEC_NUMBER}) BOOL_TRUE (true|yes|on) BOOL_FALSE (false|no|off) COMMENT #.* PORT (6(5(5(3[0-5]|[0-2][0-9])|[0-4][0-9][0-9])|[0-4][0-9][0-9][0-9])|[1-5][0-9][0-9][0-9][0-9]|[1-9][0-9]?[0-9]?[0-9]?) IP_BYTE (2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]) IPV4_ADDR {IP_BYTE}\.{IP_BYTE}\.{IP_BYTE}\.{IP_BYTE}(:{PORT})? %% {WHITE_SPACE} | {COMMENT} {/* ignore */} \\{EOL} {/* continue line */} {EOL} {return (EOL);} "/" {return (SLASH);} "<" {return (OPENBRAC);} ">" {return (CLOSEBRAC);} {BOOL_TRUE} {yylval.boolean = 1; return (BTRUE);} {BOOL_FALSE} {yylval.boolean = 0; return (BFALSE);} {IPV4_ADDR} {yylval.string = yytext; return (UNQUOTED_STRING);} {NUMBER} {yylval.number = strtod (yytext, NULL); return (NUMBER);} \"{QUOTED_STRING}\" {yylval.string = yytext; return (QUOTED_STRING);} {UNQUOTED_STRING} {yylval.string = yytext; return (UNQUOTED_STRING);} \"{QUOTED_STRING}\\{EOL} { int len = strlen (yytext); ml_pos = 0; /* remove "\\" */ if ('\r' == yytext[len - 2]) len -= 3; else len -= 2; yytext[len] = '\0'; ml_append (yytext); BEGIN (ML); } ^{WHITE_SPACE}+ {/* remove leading white-space */} {NON_WHITE_SPACE}{QUOTED_STRING}\\{EOL} { int len = strlen (yytext); /* remove "\\" */ if ('\r' == yytext[len - 2]) len -= 3; else len -= 2; yytext[len] = '\0'; ml_append(yytext); } {NON_WHITE_SPACE}{QUOTED_STRING}\" { ml_append(yytext); yylval.string = ml_buffer; BEGIN (INITIAL); return (QUOTED_STRING); } %% static void ml_append (char *string) { int len = strlen (string); int s; if (ml_free <= len) { ml_len += len - ml_free + 1; ml_buffer = (char *)realloc (ml_buffer, ml_len); if (NULL == ml_buffer) YY_FATAL_ERROR ("out of dynamic memory in ml_append"); } s = snprintf (ml_buffer + ml_pos, ml_free, "%s", string); if ((0 > s) || (ml_free <= s)) YY_FATAL_ERROR ("failed to write to multiline buffer"); ml_pos += s; return; } /* ml_append */ collectd-5.4.0/src/liboconfig/PaxHeaders.11991/oconfig.h0000644037772200116100000000013212204120331021042 xustar000000000000000030 mtime=1376821465.073973439 30 atime=1376821477.218167931 30 ctime=1376821742.006400674 collectd-5.4.0/src/liboconfig/oconfig.h0000644037772200116100000000324112204120331017606 0ustar00octoeng00000000000000#ifndef OCONFIG_H #define OCONFIG_H 1 #include /** * oconfig - src/oconfig.h * Copyright (C) 2006-2009 Florian octo 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 */ /* * Types */ #define OCONFIG_TYPE_STRING 0 #define OCONFIG_TYPE_NUMBER 1 #define OCONFIG_TYPE_BOOLEAN 2 struct oconfig_value_s { union { char *string; double number; int boolean; } value; int type; }; typedef struct oconfig_value_s oconfig_value_t; struct oconfig_item_s; typedef struct oconfig_item_s oconfig_item_t; struct oconfig_item_s { char *key; oconfig_value_t *values; int values_num; oconfig_item_t *parent; oconfig_item_t *children; int children_num; }; /* * Functions */ oconfig_item_t *oconfig_parse_fh (FILE *fh); oconfig_item_t *oconfig_parse_file (const char *file); oconfig_item_t *oconfig_clone (const oconfig_item_t *ci); void oconfig_free (oconfig_item_t *ci); /* * vim: shiftwidth=2:tabstop=8:softtabstop=2 */ #endif /* OCONFIG_H */ collectd-5.4.0/src/liboconfig/PaxHeaders.11991/ChangeLog0000644037772200116100000000013212204120331021017 xustar000000000000000030 mtime=1376821465.073973439 30 atime=1376821477.218167931 30 ctime=1376821742.010400738 collectd-5.4.0/src/liboconfig/ChangeLog0000644037772200116100000000015712204120331017566 0ustar00octoeng000000000000002007-02-15, Version 0.1.1 * src/parser.y: Fixes a memory leak. 2007-02-11, Version 0.1.0 * Initial release. collectd-5.4.0/src/liboconfig/PaxHeaders.11991/Makefile.am0000644037772200116100000000013212204120331021301 xustar000000000000000030 mtime=1376821465.073973439 30 atime=1376821477.218167931 30 ctime=1376821742.010400738 collectd-5.4.0/src/liboconfig/Makefile.am0000644037772200116100000000043612204120331020050 0ustar00octoeng00000000000000AUTOMAKE_OPTIONS = foreign no-dependencies BUILT_SOURCES = parser.h #CLEANFILES = parser.[ch] scanner.c AM_YFLAGS = -d noinst_LTLIBRARIES = liboconfig.la liboconfig_la_LDFLAGS = -version-info 0:0:0 $(LEXLIB) liboconfig_la_SOURCES = oconfig.c oconfig.h aux_types.h scanner.l parser.y collectd-5.4.0/src/liboconfig/PaxHeaders.11991/aux_types.h0000644037772200116100000000013212204120331021437 xustar000000000000000030 mtime=1376821465.073973439 30 atime=1376821477.218167931 30 ctime=1376821742.010400738 collectd-5.4.0/src/liboconfig/aux_types.h0000644037772200116100000000053112204120331020202 0ustar00octoeng00000000000000#ifndef AUX_TYPES_H #define AUX_TYPES_H 1 struct statement_list_s { oconfig_item_t *statement; int statement_num; }; typedef struct statement_list_s statement_list_t; struct argument_list_s { oconfig_value_t *argument; int argument_num; }; typedef struct argument_list_s argument_list_t; #endif /* AUX_TYPES_H */ collectd-5.4.0/src/liboconfig/PaxHeaders.11991/parser.h0000644037772200116100000000013212204120755020724 xustar000000000000000030 mtime=1376821741.594394098 30 atime=1376821741.594394098 30 ctime=1376821742.014400802 collectd-5.4.0/src/liboconfig/parser.h0000644037772200116100000000505212204120755017472 0ustar00octoeng00000000000000/* A Bison parser, made by GNU Bison 2.5. */ /* Bison interface for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. 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, either version 3 of the License, or (at your option) any later version. 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, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { NUMBER = 258, BTRUE = 259, BFALSE = 260, QUOTED_STRING = 261, UNQUOTED_STRING = 262, SLASH = 263, OPENBRAC = 264, CLOSEBRAC = 265, EOL = 266 }; #endif /* Tokens. */ #define NUMBER 258 #define BTRUE 259 #define BFALSE 260 #define QUOTED_STRING 261 #define UNQUOTED_STRING 262 #define SLASH 263 #define OPENBRAC 264 #define CLOSEBRAC 265 #define EOL 266 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE { /* Line 2068 of yacc.c */ #line 38 "parser.y" double number; int boolean; char *string; oconfig_value_t cv; oconfig_item_t ci; argument_list_t al; statement_list_t sl; /* Line 2068 of yacc.c */ #line 84 "parser.h" } YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 #endif extern YYSTYPE yylval; collectd-5.4.0/src/liboconfig/PaxHeaders.11991/parser.c0000644037772200116100000000013212204120755020717 xustar000000000000000030 mtime=1376821741.582393908 30 atime=1376821741.578393844 30 ctime=1376821742.014400802 collectd-5.4.0/src/liboconfig/parser.c0000644037772200116100000014745512204120755017503 0ustar00octoeng00000000000000/* A Bison parser, made by GNU Bison 2.5. */ /* Bison implementation for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. 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, either version 3 of the License, or (at your option) any later version. 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, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ #define YYBISON_VERSION "2.5" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 0 /* Push parsers. */ #define YYPUSH 0 /* Pull parsers. */ #define YYPULL 1 /* Using locations. */ #define YYLSP_NEEDED 0 /* Copy the first part of user declarations. */ /* Line 268 of yacc.c */ #line 19 "parser.y" #include #include #include "oconfig.h" #include "aux_types.h" static char *unquote (const char *orig); static int yyerror (const char *s); /* Lexer variables */ extern int yylineno; extern char *yytext; extern oconfig_item_t *ci_root; extern char *c_file; /* Line 268 of yacc.c */ #line 89 "parser.c" /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 1 #endif /* Enabling the token table. */ #ifndef YYTOKEN_TABLE # define YYTOKEN_TABLE 0 #endif /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { NUMBER = 258, BTRUE = 259, BFALSE = 260, QUOTED_STRING = 261, UNQUOTED_STRING = 262, SLASH = 263, OPENBRAC = 264, CLOSEBRAC = 265, EOL = 266 }; #endif /* Tokens. */ #define NUMBER 258 #define BTRUE 259 #define BFALSE 260 #define QUOTED_STRING 261 #define UNQUOTED_STRING 262 #define SLASH 263 #define OPENBRAC 264 #define CLOSEBRAC 265 #define EOL 266 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE { /* Line 293 of yacc.c */ #line 38 "parser.y" double number; int boolean; char *string; oconfig_value_t cv; oconfig_item_t ci; argument_list_t al; statement_list_t sl; /* Line 293 of yacc.c */ #line 159 "parser.c" } YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 #endif /* Copy the second part of user declarations. */ /* Line 343 of yacc.c */ #line 171 "parser.c" #ifdef short # undef short #endif #ifdef YYTYPE_UINT8 typedef YYTYPE_UINT8 yytype_uint8; #else typedef unsigned char yytype_uint8; #endif #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; #elif (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) typedef signed char yytype_int8; #else typedef short int yytype_int8; #endif #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else typedef unsigned short int yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else typedef short int yytype_int16; #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned int # endif #endif #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ # define YY_(msgid) dgettext ("bison-runtime", msgid) # endif # endif # ifndef YY_ # define YY_(msgid) msgid # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(e) ((void) (e)) #else # define YYUSE(e) /* empty */ #endif /* Identity function, used to suppress warnings about constant conditions. */ #ifndef lint # define YYID(n) (n) #else #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int YYID (int yyi) #else static int YYID (yyi) int yyi; #endif { return yyi; } #endif #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include /* INFRINGES ON USER NAME SPACE */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's `empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined EXIT_SUCCESS \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include /* INFRINGES ON USER NAME SPACE */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yytype_int16 yyss_alloc; YYSTYPE yyvs_alloc; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) # define YYCOPY_NEEDED 1 /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ YYSIZE_T yynewbytes; \ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ Stack = &yyptr->Stack_alloc; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (YYID (0)) #endif #if defined YYCOPY_NEEDED && YYCOPY_NEEDED /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(To, From, Count) \ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) # else # define YYCOPY(To, From, Count) \ do \ { \ YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (To)[yyi] = (From)[yyi]; \ } \ while (YYID (0)) # endif # endif #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ #define YYFINAL 24 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 46 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 12 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 12 /* YYNRULES -- Number of rules. */ #define YYNRULES 23 /* YYNRULES -- Number of states. */ #define YYNSTATES 37 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 266 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; #if YYDEBUG /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in YYRHS. */ static const yytype_uint8 yyprhs[] = { 0, 0, 3, 5, 7, 9, 11, 13, 15, 18, 20, 22, 26, 31, 37, 43, 47, 50, 52, 54, 56, 59, 61, 63 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { 23, 0, -1, 6, -1, 7, -1, 3, -1, 4, -1, 5, -1, 13, -1, 15, 14, -1, 14, -1, 7, -1, 16, 15, 11, -1, 9, 16, 10, 11, -1, 9, 16, 15, 10, 11, -1, 9, 8, 16, 10, 11, -1, 18, 22, 19, -1, 18, 19, -1, 17, -1, 20, -1, 11, -1, 22, 21, -1, 21, -1, 22, -1, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { 0, 73, 73, 74, 78, 79, 80, 81, 85, 92, 101, 105, 115, 121, 131, 138, 151, 167, 168, 169, 173, 183, 200, 208 }; #endif #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "NUMBER", "BTRUE", "BFALSE", "QUOTED_STRING", "UNQUOTED_STRING", "SLASH", "OPENBRAC", "CLOSEBRAC", "EOL", "$accept", "string", "argument", "argument_list", "identifier", "option", "block_begin", "block_end", "block", "statement", "statement_list", "entire_file", 0 }; #endif # ifdef YYPRINT /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to token YYLEX-NUM. */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { 0, 12, 13, 13, 14, 14, 14, 14, 15, 15, 16, 17, 18, 18, 19, 20, 20, 21, 21, 21, 22, 22, 23, 23 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 3, 4, 5, 5, 3, 2, 1, 1, 1, 2, 1, 1, 0 }; /* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. Performed when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ static const yytype_uint8 yydefact[] = { 23, 10, 0, 19, 0, 17, 0, 18, 21, 22, 0, 0, 4, 5, 6, 2, 3, 7, 9, 0, 0, 16, 0, 20, 1, 0, 0, 11, 8, 0, 15, 12, 0, 0, 13, 0, 14 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { -1, 17, 18, 19, 4, 5, 6, 21, 7, 8, 9, 10 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ #define YYPACT_NINF -12 static const yytype_int8 yypact[] = { 0, -12, 9, -12, 33, -12, 34, -12, -12, 0, 17, 16, -12, -12, -12, -12, -12, -12, -12, -1, 5, -12, 34, -12, -12, 13, 25, -12, -12, 9, -12, -12, 14, 23, -12, 31, -12 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { -12, -12, -11, 35, -2, -12, -12, 12, -12, -8, 38, -12 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If YYTABLE_NINF, syntax error. */ #define YYTABLE_NINF -1 static const yytype_uint8 yytable[] = { 11, 23, 12, 13, 14, 15, 16, 1, 28, 2, 27, 3, 1, 29, 23, 28, 1, 24, 11, 12, 13, 14, 15, 16, 31, 34, 25, 33, 12, 13, 14, 15, 16, 35, 30, 32, 12, 13, 14, 15, 16, 1, 36, 20, 22, 3, 26 }; #define yypact_value_is_default(yystate) \ ((yystate) == (-12)) #define yytable_value_is_error(yytable_value) \ YYID (0) static const yytype_uint8 yycheck[] = { 2, 9, 3, 4, 5, 6, 7, 7, 19, 9, 11, 11, 7, 8, 22, 26, 7, 0, 20, 3, 4, 5, 6, 7, 11, 11, 10, 29, 3, 4, 5, 6, 7, 10, 22, 10, 3, 4, 5, 6, 7, 7, 11, 9, 6, 11, 11 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 7, 9, 11, 16, 17, 18, 20, 21, 22, 23, 16, 3, 4, 5, 6, 7, 13, 14, 15, 9, 19, 22, 21, 0, 10, 15, 11, 14, 8, 19, 11, 10, 16, 11, 10, 11 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. However, YYFAIL appears to be in use. Nevertheless, it is formally deprecated in Bison 2.4.2's NEWS entry, where a plan to phase it out is discussed. */ #define YYFAIL goto yyerrlab #if defined YYFAIL /* This is here to suppress warnings from the GCC cpp's -Wunused-macros. Normally we don't worry about that warning, but some users do, and we want to make it easy for users to remove YYFAIL uses, which will produce warnings from Bison 2.5. */ #endif #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ { \ yychar = (Token); \ yylval = (Value); \ YYPOPSTACK (1); \ goto yybackup; \ } \ else \ { \ yyerror (YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (YYID (0)) #define YYTERROR 1 #define YYERRCODE 256 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. If N is 0, then set CURRENT to the empty location which ends the previous symbol: RHS[0] (always defined). */ #define YYRHSLOC(Rhs, K) ((Rhs)[K]) #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ do \ if (YYID (N)) \ { \ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ } \ else \ { \ (Current).first_line = (Current).last_line = \ YYRHSLOC (Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC (Rhs, 0).last_column; \ } \ while (YYID (0)) #endif /* This macro is provided for backward compatibility. */ #ifndef YY_LOCATION_PRINT # define YY_LOCATION_PRINT(File, Loc) ((void) 0) #endif /* YYLEX -- calling `yylex' with the right arguments. */ #ifdef YYLEX_PARAM # define YYLEX yylex (YYLEX_PARAM) #else # define YYLEX yylex () #endif /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (YYID (0)) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Type, Value); \ YYFPRINTF (stderr, "\n"); \ } \ } while (YYID (0)) /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) #else static void yy_symbol_value_print (yyoutput, yytype, yyvaluep) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; #endif { if (!yyvaluep) return; # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # else YYUSE (yyoutput); # endif switch (yytype) { default: break; } } /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) #else static void yy_symbol_print (yyoutput, yytype, yyvaluep) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; #endif { if (yytype < YYNTOKENS) YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); else YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); yy_symbol_value_print (yyoutput, yytype, yyvaluep); YYFPRINTF (yyoutput, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) #else static void yy_stack_print (yybottom, yytop) yytype_int16 *yybottom; yytype_int16 *yytop; #endif { YYFPRINTF (stderr, "Stack now"); for (; yybottom <= yytop; yybottom++) { int yybot = *yybottom; YYFPRINTF (stderr, " %d", yybot); } YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (YYID (0)) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_reduce_print (YYSTYPE *yyvsp, int yyrule) #else static void yy_reduce_print (yyvsp, yyrule) YYSTYPE *yyvsp; int yyrule; #endif { int yynrhs = yyr2[yyrule]; int yyi; unsigned long int yylno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) ); YYFPRINTF (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyvsp, Rule); \ } while (YYID (0)) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen strlen # else /* Return the length of YYSTR. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static YYSIZE_T yystrlen (const char *yystr) #else static YYSIZE_T yystrlen (yystr) const char *yystr; #endif { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif # endif # ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static char * yystpcpy (char *yydest, const char *yysrc) #else static char * yystpcpy (yydest, yysrc) char *yydest; const char *yysrc; #endif { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif # ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYSIZE_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYSIZE_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; /* Fall through. */ default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (! yyres) return yystrlen (yystr); return yystpcpy (yyres, yystr) - yyres; } # endif /* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message about the unexpected token YYTOKEN for the state stack whose top is YYSSP. Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is not large enough to hold the message. In that case, also set *YYMSG_ALLOC to the required number of bytes. Return 2 if the required number of bytes is too large to store. */ static int yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, yytype_int16 *yyssp, int yytoken) { YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]); YYSIZE_T yysize = yysize0; YYSIZE_T yysize1; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; /* Internationalized format string. */ const char *yyformat = 0; /* Arguments of yyformat. */ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; /* Number of reported tokens (one for the "unexpected", one per "expected"). */ int yycount = 0; /* There are many possibilities here to consider: - Assume YYFAIL is not used. It's too flawed to consider. See for details. YYERROR is fine as it does not invoke this function. - If this state is a consistent state with a default action, then the only way this function was invoked is if the default action is an error action. In that case, don't check for expected tokens because there are none. - The only way there can be no lookahead present (in yychar) is if this state is a consistent state with a default action. Thus, detecting the absence of a lookahead is sufficient to determine that there is no unexpected or expected token to report. In that case, just report a simple "syntax error". - Don't assume there isn't a lookahead just because this state is a consistent state with a default action. There might have been a previous inconsistent state, consistent state with a non-default action, or user semantic action that manipulated yychar. - Of course, the expected token list depends on states to have correct lookahead information, and it depends on the parser not to perform extra reductions after fetching a lookahead from the scanner and before detecting a syntax error. Thus, state merging (from LALR or IELR) and default reductions corrupt the expected token list. However, the list is correct for canonical LR with one exception: it will still contain any token that will not be accepted due to an error action in a later state. */ if (yytoken != YYEMPTY) { int yyn = yypact[*yyssp]; yyarg[yycount++] = yytname[yytoken]; if (!yypact_value_is_default (yyn)) { /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. In other words, skip the first -YYN actions for this state because they are default actions. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yyx; for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR && !yytable_value_is_error (yytable[yyx + yyn])) { if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { yycount = 1; yysize = yysize0; break; } yyarg[yycount++] = yytname[yyx]; yysize1 = yysize + yytnamerr (0, yytname[yyx]); if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) return 2; yysize = yysize1; } } } switch (yycount) { # define YYCASE_(N, S) \ case N: \ yyformat = S; \ break YYCASE_(0, YY_("syntax error")); YYCASE_(1, YY_("syntax error, unexpected %s")); YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); # undef YYCASE_ } yysize1 = yysize + yystrlen (yyformat); if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) return 2; yysize = yysize1; if (*yymsg_alloc < yysize) { *yymsg_alloc = 2 * yysize; if (! (yysize <= *yymsg_alloc && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; return 1; } /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ { char *yyp = *yymsg; int yyi = 0; while ((*yyp = *yyformat) != '\0') if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yyarg[yyi++]); yyformat += 2; } else { yyp++; yyformat++; } } return 0; } #endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) #else static void yydestruct (yymsg, yytype, yyvaluep) const char *yymsg; int yytype; YYSTYPE *yyvaluep; #endif { YYUSE (yyvaluep); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); switch (yytype) { default: break; } } /* Prevent warnings from -Wmissing-prototypes. */ #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); #else int yyparse (); #endif #else /* ! YYPARSE_PARAM */ #if defined __STDC__ || defined __cplusplus int yyparse (void); #else int yyparse (); #endif #endif /* ! YYPARSE_PARAM */ /* The lookahead symbol. */ int yychar; /* The semantic value of the lookahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; /*----------. | yyparse. | `----------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (void *YYPARSE_PARAM) #else int yyparse (YYPARSE_PARAM) void *YYPARSE_PARAM; #endif #else /* ! YYPARSE_PARAM */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (void) #else int yyparse () #endif #endif { int yystate; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* The stacks and their tools: `yyss': related to states. `yyvs': related to semantic values. Refer to the stacks thru separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yytype_int16 yyssa[YYINITDEPTH]; yytype_int16 *yyss; yytype_int16 *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs; YYSTYPE *yyvsp; YYSIZE_T yystacksize; int yyn; int yyresult; /* Lookahead token as an internal (translated) token number. */ int yytoken; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; yytoken = 0; yyss = yyssa; yyvs = yyvsa; yystacksize = YYINITDEPTH; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ yyssp = yyss; yyvsp = yyvs; goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE goto yyexhaustedlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yytype_int16 *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); if (yystate == YYFINAL) YYACCEPT; goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a lookahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yypact_value_is_default (yyn)) goto yydefault; /* Not known => get a lookahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = YYLEX; } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yytable_value_is_error (yyn)) goto yyerrlab; yyn = -yyn; goto yyreduce; } /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); /* Discard the shifted token. */ yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: `$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 2: /* Line 1806 of yacc.c */ #line 73 "parser.y" {(yyval.string) = unquote ((yyvsp[(1) - (1)].string));} break; case 3: /* Line 1806 of yacc.c */ #line 74 "parser.y" {(yyval.string) = strdup ((yyvsp[(1) - (1)].string));} break; case 4: /* Line 1806 of yacc.c */ #line 78 "parser.y" {(yyval.cv).value.number = (yyvsp[(1) - (1)].number); (yyval.cv).type = OCONFIG_TYPE_NUMBER;} break; case 5: /* Line 1806 of yacc.c */ #line 79 "parser.y" {(yyval.cv).value.boolean = 1; (yyval.cv).type = OCONFIG_TYPE_BOOLEAN;} break; case 6: /* Line 1806 of yacc.c */ #line 80 "parser.y" {(yyval.cv).value.boolean = 0; (yyval.cv).type = OCONFIG_TYPE_BOOLEAN;} break; case 7: /* Line 1806 of yacc.c */ #line 81 "parser.y" {(yyval.cv).value.string = (yyvsp[(1) - (1)].string); (yyval.cv).type = OCONFIG_TYPE_STRING;} break; case 8: /* Line 1806 of yacc.c */ #line 86 "parser.y" { (yyval.al) = (yyvsp[(1) - (2)].al); (yyval.al).argument_num++; (yyval.al).argument = realloc ((yyval.al).argument, (yyval.al).argument_num * sizeof (oconfig_value_t)); (yyval.al).argument[(yyval.al).argument_num-1] = (yyvsp[(2) - (2)].cv); } break; case 9: /* Line 1806 of yacc.c */ #line 93 "parser.y" { (yyval.al).argument = malloc (sizeof (oconfig_value_t)); (yyval.al).argument[0] = (yyvsp[(1) - (1)].cv); (yyval.al).argument_num = 1; } break; case 10: /* Line 1806 of yacc.c */ #line 101 "parser.y" {(yyval.string) = strdup ((yyvsp[(1) - (1)].string));} break; case 11: /* Line 1806 of yacc.c */ #line 106 "parser.y" { memset (&(yyval.ci), '\0', sizeof ((yyval.ci))); (yyval.ci).key = (yyvsp[(1) - (3)].string); (yyval.ci).values = (yyvsp[(2) - (3)].al).argument; (yyval.ci).values_num = (yyvsp[(2) - (3)].al).argument_num; } break; case 12: /* Line 1806 of yacc.c */ #line 116 "parser.y" { memset (&(yyval.ci), '\0', sizeof ((yyval.ci))); (yyval.ci).key = (yyvsp[(2) - (4)].string); } break; case 13: /* Line 1806 of yacc.c */ #line 122 "parser.y" { memset (&(yyval.ci), '\0', sizeof ((yyval.ci))); (yyval.ci).key = (yyvsp[(2) - (5)].string); (yyval.ci).values = (yyvsp[(3) - (5)].al).argument; (yyval.ci).values_num = (yyvsp[(3) - (5)].al).argument_num; } break; case 14: /* Line 1806 of yacc.c */ #line 132 "parser.y" { (yyval.string) = (yyvsp[(3) - (5)].string); } break; case 15: /* Line 1806 of yacc.c */ #line 139 "parser.y" { if (strcmp ((yyvsp[(1) - (3)].ci).key, (yyvsp[(3) - (3)].string)) != 0) { printf ("block_begin = %s; block_end = %s;\n", (yyvsp[(1) - (3)].ci).key, (yyvsp[(3) - (3)].string)); yyerror ("Block not closed..\n"); exit (1); } free ((yyvsp[(3) - (3)].string)); (yyvsp[(3) - (3)].string) = NULL; (yyval.ci) = (yyvsp[(1) - (3)].ci); (yyval.ci).children = (yyvsp[(2) - (3)].sl).statement; (yyval.ci).children_num = (yyvsp[(2) - (3)].sl).statement_num; } break; case 16: /* Line 1806 of yacc.c */ #line 152 "parser.y" { if (strcmp ((yyvsp[(1) - (2)].ci).key, (yyvsp[(2) - (2)].string)) != 0) { printf ("block_begin = %s; block_end = %s;\n", (yyvsp[(1) - (2)].ci).key, (yyvsp[(2) - (2)].string)); yyerror ("Block not closed..\n"); exit (1); } free ((yyvsp[(2) - (2)].string)); (yyvsp[(2) - (2)].string) = NULL; (yyval.ci) = (yyvsp[(1) - (2)].ci); (yyval.ci).children = NULL; (yyval.ci).children_num = 0; } break; case 17: /* Line 1806 of yacc.c */ #line 167 "parser.y" {(yyval.ci) = (yyvsp[(1) - (1)].ci);} break; case 18: /* Line 1806 of yacc.c */ #line 168 "parser.y" {(yyval.ci) = (yyvsp[(1) - (1)].ci);} break; case 19: /* Line 1806 of yacc.c */ #line 169 "parser.y" {(yyval.ci).values_num = 0;} break; case 20: /* Line 1806 of yacc.c */ #line 174 "parser.y" { (yyval.sl) = (yyvsp[(1) - (2)].sl); if (((yyvsp[(2) - (2)].ci).values_num > 0) || ((yyvsp[(2) - (2)].ci).children_num > 0)) { (yyval.sl).statement_num++; (yyval.sl).statement = realloc ((yyval.sl).statement, (yyval.sl).statement_num * sizeof (oconfig_item_t)); (yyval.sl).statement[(yyval.sl).statement_num-1] = (yyvsp[(2) - (2)].ci); } } break; case 21: /* Line 1806 of yacc.c */ #line 184 "parser.y" { if (((yyvsp[(1) - (1)].ci).values_num > 0) || ((yyvsp[(1) - (1)].ci).children_num > 0)) { (yyval.sl).statement = malloc (sizeof (oconfig_item_t)); (yyval.sl).statement[0] = (yyvsp[(1) - (1)].ci); (yyval.sl).statement_num = 1; } else { (yyval.sl).statement = NULL; (yyval.sl).statement_num = 0; } } break; case 22: /* Line 1806 of yacc.c */ #line 201 "parser.y" { ci_root = malloc (sizeof (oconfig_item_t)); memset (ci_root, '\0', sizeof (oconfig_item_t)); ci_root->children = (yyvsp[(1) - (1)].sl).statement; ci_root->children_num = (yyvsp[(1) - (1)].sl).statement_num; } break; case 23: /* Line 1806 of yacc.c */ #line 208 "parser.y" { ci_root = malloc (sizeof (oconfig_item_t)); memset (ci_root, '\0', sizeof (oconfig_item_t)); ci_root->children = NULL; ci_root->children_num = 0; } break; /* Line 1806 of yacc.c */ #line 1648 "parser.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires that yytoken be updated with the new translation. We take the approach of translating immediately before every use of yytoken. One alternative is translating here after every semantic action, but that translation would be missed if the semantic action invokes YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an incorrect destructor might then be invoked immediately. In the case of YYERROR or YYBACKUP, subsequent parser actions might lead to an incorrect destructor call or verbose syntax error message before the lookahead is translated. */ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; /*------------------------------------. | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (YY_("syntax error")); #else # define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ yyssp, yytoken) { char const *yymsgp = YY_("syntax error"); int yysyntax_error_status; yysyntax_error_status = YYSYNTAX_ERROR; if (yysyntax_error_status == 0) yymsgp = yymsg; else if (yysyntax_error_status == 1) { if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); if (!yymsg) { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; yysyntax_error_status = 2; } else { yysyntax_error_status = YYSYNTAX_ERROR; yymsgp = yymsg; } } yyerror (yymsgp); if (yysyntax_error_status == 2) goto yyexhaustedlab; } # undef YYSYNTAX_ERROR #endif } if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval); yychar = YYEMPTY; } } /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers like GCC when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (/*CONSTCOND*/ 0) goto yyerrorlab; /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (!yypact_value_is_default (yyn)) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yydestruct ("Error: popping", yystos[yystate], yyvsp); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } *++yyvsp = yylval; /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #if !defined(yyoverflow) || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif yyreturn: if (yychar != YYEMPTY) { /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = YYTRANSLATE (yychar); yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval); } /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[*yyssp], yyvsp); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif /* Make sure YYID is used. */ return YYID (yyresult); } /* Line 2067 of yacc.c */ #line 216 "parser.y" static int yyerror (const char *s) { char *text; if (*yytext == '\n') text = ""; else text = yytext; fprintf (stderr, "Parse error in file `%s', line %i near `%s': %s\n", c_file, yylineno, text, s); return (-1); } /* int yyerror */ static char *unquote (const char *orig) { char *ret = strdup (orig); int len; int i; if (ret == NULL) return (NULL); len = strlen (ret); if ((len < 2) || (ret[0] != '"') || (ret[len - 1] != '"')) return (ret); len -= 2; memmove (ret, ret + 1, len); ret[len] = '\0'; for (i = 0; i < len; i++) { if (ret[i] == '\\') { memmove (ret + i, ret + (i + 1), len - i); len--; } } return (ret); } /* char *unquote */ collectd-5.4.0/src/liboconfig/PaxHeaders.11991/AUTHORS0000644037772200116100000000013212204120331020315 xustar000000000000000030 mtime=1376821465.073973439 30 atime=1376821465.073973439 30 ctime=1376821742.014400802 collectd-5.4.0/src/liboconfig/AUTHORS0000644037772200116100000000000012204120331017047 0ustar00octoeng00000000000000collectd-5.4.0/src/liboconfig/PaxHeaders.11991/scanner.c0000644037772200116100000000013212204120755021054 xustar000000000000000030 mtime=1376821741.650394992 30 atime=1376821741.646394928 30 ctime=1376821742.014400802 collectd-5.4.0/src/liboconfig/scanner.c0000644037772200116100000016074012204120755017630 0ustar00octoeng00000000000000 #line 3 "scanner.c" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_SUBMINOR_VERSION 35 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! C99 */ #endif /* ! FLEXINT_H */ #ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ /* C99 requires __STDC__ to be defined as 1. */ #if defined (__STDC__) #define YY_USE_CONST #endif /* defined (__STDC__) */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart(yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k. * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. * Ditto for the __ia64__ case accordingly. */ #define YY_BUF_SIZE 32768 #else #define YY_BUF_SIZE 16384 #endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif extern int yyleng; extern FILE *yyin, *yyout; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires * access to the local variable yy_act. Since yyless() is a macro, it would break * existing scanners that call yyless() from OUTSIDE yylex. * One obvious solution it to make yy_act a global. I tried that, and saw * a 5% performance hit in a non-yylineno scanner, because yy_act is * normally declared as a register variable-- so it is not worth it. */ #define YY_LESS_LINENO(n) \ do { \ int yyl;\ for ( yyl = n; yyl < yyleng; ++yyl )\ if ( yytext[yyl] == '\n' )\ --yylineno;\ }while(0) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* Stack of input buffers. */ static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] /* yy_hold_char holds the character lost when yytext is formed. */ static char yy_hold_char; static int yy_n_chars; /* number of characters read into yy_ch_buf */ int yyleng; /* Points to current character in buffer. */ static char *yy_c_buf_p = (char *) 0; static int yy_init = 0; /* whether we need to initialize */ static int yy_start = 0; /* start state number */ /* Flag which is used to allow yywrap()'s to do buffer switches * instead of setting up a fresh yyin. A bit of a hack ... */ static int yy_did_buffer_switch_on_eof; void yyrestart (FILE *input_file ); void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); void yy_delete_buffer (YY_BUFFER_STATE b ); void yy_flush_buffer (YY_BUFFER_STATE b ); void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); void yypop_buffer_state (void ); static void yyensure_buffer_stack (void ); static void yy_load_buffer_state (void ); static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); #define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); void *yyalloc (yy_size_t ); void *yyrealloc (void *,yy_size_t ); void yyfree (void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer(yyin,YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer(yyin,YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ #define yywrap(n) 1 #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; typedef int yy_state_type; extern int yylineno; int yylineno = 1; extern char *yytext; #define yytext_ptr yytext static yy_state_type yy_get_previous_state (void ); static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); static int yy_get_next_buffer (void ); static void yy_fatal_error (yyconst char msg[] ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ yyleng = (size_t) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 18 #define YY_END_OF_BUFFER 19 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_accept[118] = { 0, 0, 0, 0, 0, 19, 18, 1, 4, 18, 18, 2, 18, 18, 5, 11, 11, 11, 11, 6, 7, 13, 18, 13, 13, 13, 13, 13, 18, 15, 4, 0, 12, 0, 2, 0, 11, 11, 0, 11, 11, 13, 13, 11, 11, 11, 11, 3, 0, 13, 9, 13, 8, 13, 13, 0, 17, 0, 15, 0, 14, 0, 0, 11, 11, 11, 11, 11, 13, 13, 0, 16, 0, 14, 0, 0, 11, 11, 11, 13, 16, 11, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 5, 6, 1, 1, 1, 1, 1, 1, 1, 7, 1, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 18, 19, 1, 20, 1, 21, 1, 1, 22, 22, 22, 22, 23, 22, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 24, 24, 1, 26, 1, 1, 24, 1, 27, 22, 22, 22, 28, 29, 24, 24, 24, 24, 24, 30, 24, 31, 32, 24, 24, 33, 34, 35, 36, 24, 24, 25, 37, 24, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int32_t yy_meta[38] = { 0, 1, 1, 2, 1, 1, 1, 1, 3, 1, 4, 5, 5, 5, 5, 5, 6, 6, 6, 7, 1, 1, 1, 8, 1, 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int16_t yy_base[147] = { 0, 0, 0, 415, 414, 415, 418, 418, 418, 411, 33, 0, 405, 0, 418, 52, 80, 96, 105, 418, 418, 113, 36, 385, 379, 12, 377, 381, 45, 406, 418, 46, 418, 41, 0, 0, 399, 19, 42, 48, 124, 0, 140, 0, 0, 83, 398, 418, 402, 374, 0, 374, 0, 366, 339, 52, 418, 45, 337, 117, 418, 156, 287, 158, 170, 191, 210, 0, 193, 185, 174, 418, 184, 185, 0, 92, 0, 0, 128, 169, 186, 0, 184, 180, 218, 172, 173, 152, 140, 139, 123, 114, 227, 42, 178, 39, 36, 27, 0, 237, 0, 0, 0, 246, 0, 0, 0, 0, 255, 205, 0, 0, 0, 0, 258, 418, 418, 418, 276, 284, 292, 298, 301, 307, 315, 320, 326, 332, 337, 340, 344, 348, 351, 355, 357, 361, 364, 367, 371, 374, 377, 380, 383, 386, 389, 392, 395 } ; static yyconst flex_int16_t yy_def[147] = { 0, 117, 1, 118, 118, 117, 117, 117, 117, 117, 119, 120, 121, 122, 117, 117, 15, 16, 17, 117, 117, 17, 117, 21, 21, 21, 21, 21, 123, 117, 117, 119, 117, 124, 120, 122, 121, 122, 125, 15, 15, 21, 117, 18, 18, 18, 40, 117, 117, 21, 21, 21, 21, 21, 21, 123, 117, 126, 117, 119, 117, 119, 117, 122, 127, 117, 65, 42, 21, 21, 123, 117, 123, 119, 128, 129, 66, 66, 66, 21, 123, 128, 117, 130, 117, 131, 132, 131, 131, 133, 117, 134, 117, 135, 136, 135, 135, 137, 138, 117, 139, 140, 141, 117, 142, 143, 144, 145, 117, 108, 146, 146, 146, 146, 146, 117, 117, 0, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117 } ; static yyconst flex_int16_t yy_nxt[456] = { 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 6, 19, 20, 21, 21, 21, 21, 22, 21, 21, 23, 21, 24, 25, 21, 21, 26, 21, 27, 32, 47, 48, 51, 62, 52, 60, 61, 94, 62, 71, 72, 56, 32, 63, 64, 65, 94, 35, 56, 94, 33, 38, 94, 39, 39, 39, 39, 39, 39, 39, 39, 40, 57, 33, 41, 41, 41, 41, 42, 57, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 43, 43, 43, 43, 43, 43, 43, 43, 43, 40, 40, 40, 82, 83, 84, 41, 44, 44, 44, 44, 44, 45, 46, 46, 46, 46, 46, 46, 46, 46, 46, 117, 32, 41, 41, 41, 41, 41, 41, 41, 41, 41, 35, 94, 40, 40, 40, 40, 40, 40, 40, 40, 94, 33, 37, 37, 37, 86, 86, 41, 67, 67, 67, 67, 67, 67, 67, 67, 67, 73, 86, 32, 67, 67, 41, 41, 75, 67, 67, 67, 41, 41, 41, 41, 41, 41, 41, 41, 75, 56, 86, 62, 33, 90, 91, 92, 62, 80, 86, 56, 32, 56, 86, 62, 99, 100, 100, 50, 62, 75, 57, 77, 77, 77, 77, 77, 78, 63, 63, 63, 57, 33, 57, 52, 62, 115, 115, 115, 115, 62, 63, 63, 63, 63, 63, 63, 86, 79, 88, 88, 88, 88, 88, 89, 82, 82, 82, 96, 96, 96, 96, 96, 97, 90, 90, 90, 94, 102, 102, 102, 102, 102, 103, 104, 104, 104, 107, 107, 107, 107, 107, 108, 109, 109, 109, 113, 113, 113, 114, 115, 115, 115, 115, 115, 117, 117, 117, 28, 28, 28, 28, 28, 28, 28, 28, 31, 31, 31, 31, 31, 31, 31, 31, 34, 74, 34, 34, 34, 34, 34, 34, 36, 36, 36, 36, 37, 37, 37, 55, 55, 55, 55, 55, 55, 55, 55, 59, 59, 59, 59, 59, 59, 59, 59, 66, 66, 66, 70, 70, 70, 70, 70, 70, 70, 70, 76, 76, 76, 76, 58, 76, 81, 81, 81, 85, 85, 85, 87, 87, 87, 87, 82, 82, 82, 82, 93, 93, 93, 82, 82, 82, 95, 95, 95, 95, 90, 90, 90, 90, 98, 98, 90, 90, 52, 90, 101, 101, 101, 104, 104, 104, 105, 105, 105, 106, 106, 106, 109, 109, 109, 110, 110, 110, 111, 111, 111, 112, 112, 112, 116, 116, 116, 69, 50, 68, 47, 38, 35, 58, 54, 53, 50, 49, 35, 30, 117, 29, 6, 5, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117 } ; static yyconst flex_int16_t yy_chk[456] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 10, 22, 22, 25, 37, 25, 33, 33, 97, 37, 57, 57, 28, 31, 38, 38, 38, 96, 39, 55, 95, 10, 15, 93, 15, 15, 15, 15, 15, 15, 15, 15, 15, 28, 31, 39, 15, 15, 15, 15, 55, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 45, 45, 45, 75, 75, 75, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 21, 59, 21, 21, 21, 21, 21, 21, 21, 21, 21, 40, 91, 40, 40, 40, 40, 40, 40, 40, 40, 90, 59, 78, 78, 78, 89, 88, 40, 42, 42, 42, 42, 42, 42, 42, 42, 42, 61, 87, 61, 42, 42, 42, 42, 63, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 64, 70, 85, 63, 61, 86, 86, 86, 63, 72, 83, 72, 73, 80, 82, 64, 94, 94, 94, 79, 64, 65, 70, 65, 65, 65, 65, 65, 65, 65, 65, 65, 72, 73, 80, 69, 65, 109, 109, 109, 109, 65, 66, 66, 66, 66, 66, 66, 84, 68, 84, 84, 84, 84, 84, 84, 84, 84, 84, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 99, 99, 99, 99, 99, 99, 99, 99, 99, 103, 103, 103, 103, 103, 103, 103, 103, 103, 108, 108, 108, 108, 108, 108, 108, 108, 108, 114, 114, 114, 118, 118, 118, 118, 118, 118, 118, 118, 119, 119, 119, 119, 119, 119, 119, 119, 120, 62, 120, 120, 120, 120, 120, 120, 121, 121, 121, 121, 122, 122, 122, 123, 123, 123, 123, 123, 123, 123, 123, 124, 124, 124, 124, 124, 124, 124, 124, 125, 125, 125, 126, 126, 126, 126, 126, 126, 126, 126, 127, 127, 127, 127, 58, 127, 128, 128, 128, 129, 129, 129, 130, 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, 133, 133, 133, 134, 134, 134, 134, 135, 135, 135, 135, 136, 136, 137, 137, 54, 137, 138, 138, 138, 139, 139, 139, 140, 140, 140, 141, 141, 141, 142, 142, 142, 143, 143, 143, 144, 144, 144, 145, 145, 145, 146, 146, 146, 53, 51, 49, 48, 46, 36, 29, 27, 26, 24, 23, 12, 9, 5, 4, 3, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117 } ; /* Table of booleans, true if rule could match eol. */ static yyconst flex_int32_t yy_rule_can_match_eol[19] = { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, }; static yy_state_type yy_last_accepting_state; static char *yy_last_accepting_cpos; extern int yy_flex_debug; int yy_flex_debug = 0; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET char *yytext; #line 1 "scanner.l" /** * oconfig - src/scanner.l * Copyright (C) 2007 Florian octo Forster * Copyright (C) 2008 Sebastian tokkee Harl * * 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 */ #line 21 "scanner.l" #include #include "oconfig.h" #include "aux_types.h" #include "parser.h" /* multiline string buffer */ static char *ml_buffer = NULL; static int ml_pos = 0; static int ml_len = 0; #define ml_free (ml_len - ml_pos) static void ml_append (char *); #ifdef yyterminate # undef yyterminate #endif #define yyterminate() \ do { free (ml_buffer); ml_buffer = NULL; ml_pos = 0; ml_len = 0; \ return YY_NULL; } while (0) #line 662 "scanner.c" #define INITIAL 0 #define ML 1 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif static int yy_init_globals (void ); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int yylex_destroy (void ); int yyget_debug (void ); void yyset_debug (int debug_flag ); YY_EXTRA_TYPE yyget_extra (void ); void yyset_extra (YY_EXTRA_TYPE user_defined ); FILE *yyget_in (void ); void yyset_in (FILE * in_str ); FILE *yyget_out (void ); void yyset_out (FILE * out_str ); int yyget_leng (void ); char *yyget_text (void ); int yyget_lineno (void ); void yyset_lineno (int line_number ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap (void ); #else extern int yywrap (void ); #endif #endif static void yyunput (int c,char *buf_ptr ); #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void ); #else static int input (void ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k */ #define YY_READ_BUF_SIZE 16384 #else #define YY_READ_BUF_SIZE 8192 #endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ size_t n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( yyin ) ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ else \ { \ errno=0; \ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(yyin); \ } \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yylex (void); #define YY_DECL int yylex (void) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK break; #endif #define YY_RULE_SETUP \ if ( yyleng > 0 ) \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \ (yytext[yyleng - 1] == '\n'); \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; #line 62 "scanner.l" #line 855 "scanner.c" if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin,YY_BUF_SIZE ); } yy_load_buffer_state( ); } while ( 1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); /* Support of yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_current_state += YY_AT_BOL(); yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 118 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } while ( yy_base[yy_current_state] != 418 ); yy_find_action: yy_act = yy_accept[yy_current_state]; if ( yy_act == 0 ) { /* have to back up */ yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); yy_act = yy_accept[yy_current_state]; } YY_DO_BEFORE_ACTION; if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] ) { int yyl; for ( yyl = 0; yyl < yyleng; ++yyl ) if ( yytext[yyl] == '\n' ) yylineno++; ; } do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; case 1: #line 64 "scanner.l" case 2: YY_RULE_SETUP #line 64 "scanner.l" {/* ignore */} YY_BREAK case 3: /* rule 3 can match eol */ YY_RULE_SETUP #line 66 "scanner.l" {/* continue line */} YY_BREAK case 4: /* rule 4 can match eol */ YY_RULE_SETUP #line 68 "scanner.l" {return (EOL);} YY_BREAK case 5: YY_RULE_SETUP #line 69 "scanner.l" {return (SLASH);} YY_BREAK case 6: YY_RULE_SETUP #line 70 "scanner.l" {return (OPENBRAC);} YY_BREAK case 7: YY_RULE_SETUP #line 71 "scanner.l" {return (CLOSEBRAC);} YY_BREAK case 8: YY_RULE_SETUP #line 72 "scanner.l" {yylval.boolean = 1; return (BTRUE);} YY_BREAK case 9: YY_RULE_SETUP #line 73 "scanner.l" {yylval.boolean = 0; return (BFALSE);} YY_BREAK case 10: YY_RULE_SETUP #line 75 "scanner.l" {yylval.string = yytext; return (UNQUOTED_STRING);} YY_BREAK case 11: YY_RULE_SETUP #line 77 "scanner.l" {yylval.number = strtod (yytext, NULL); return (NUMBER);} YY_BREAK case 12: /* rule 12 can match eol */ YY_RULE_SETUP #line 79 "scanner.l" {yylval.string = yytext; return (QUOTED_STRING);} YY_BREAK case 13: YY_RULE_SETUP #line 80 "scanner.l" {yylval.string = yytext; return (UNQUOTED_STRING);} YY_BREAK case 14: /* rule 14 can match eol */ YY_RULE_SETUP #line 82 "scanner.l" { int len = strlen (yytext); ml_pos = 0; /* remove "\\" */ if ('\r' == yytext[len - 2]) len -= 3; else len -= 2; yytext[len] = '\0'; ml_append (yytext); BEGIN (ML); } YY_BREAK case 15: YY_RULE_SETUP #line 97 "scanner.l" {/* remove leading white-space */} YY_BREAK case 16: /* rule 16 can match eol */ YY_RULE_SETUP #line 98 "scanner.l" { int len = strlen (yytext); /* remove "\\" */ if ('\r' == yytext[len - 2]) len -= 3; else len -= 2; yytext[len] = '\0'; ml_append(yytext); } YY_BREAK case 17: /* rule 17 can match eol */ YY_RULE_SETUP #line 110 "scanner.l" { ml_append(yytext); yylval.string = ml_buffer; BEGIN (INITIAL); return (QUOTED_STRING); } YY_BREAK case 18: YY_RULE_SETUP #line 117 "scanner.l" ECHO; YY_BREAK #line 1073 "scanner.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(ML): yyterminate(); case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_c_buf_p); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (void) { register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; register char *source = (yytext_ptr); register int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { int new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = 0; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), (size_t) num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart(yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (void) { register yy_state_type yy_current_state; register char *yy_cp; yy_current_state = (yy_start); yy_current_state += YY_AT_BOL(); for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 118 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) { register int yy_is_jam; register char *yy_cp = (yy_c_buf_p); register YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 118 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 117); return yy_is_jam ? 0 : yy_current_state; } static void yyunput (int c, register char * yy_bp ) { register char *yy_cp; yy_cp = (yy_c_buf_p); /* undo effects of setting up yytext */ *yy_cp = (yy_hold_char); if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ register int number_to_move = (yy_n_chars) + 2; register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; if ( c == '\n' ){ --yylineno; } (yytext_ptr) = yy_bp; (yy_hold_char) = *yy_cp; (yy_c_buf_p) = yy_cp; } #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void) #else static int input (void) #endif { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ int offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart(yyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) return EOF; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n'); if ( YY_CURRENT_BUFFER_LVALUE->yy_at_bol ) yylineno++; ; return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void yyrestart (FILE * input_file ) { if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin,YY_BUF_SIZE ); } yy_init_buffer(YY_CURRENT_BUFFER,input_file ); yy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } static void yy_load_buffer_state (void) { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer(b,file ); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * */ void yy_delete_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) yyfree((void *) b->yy_ch_buf ); yyfree((void *) b ); } #ifndef __cplusplus extern int isatty (int ); #endif /* __cplusplus */ /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) { int oerrno = errno; yy_flush_buffer(b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void yy_flush_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) { if (new_buffer == NULL) return; yyensure_buffer_stack(); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void yypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void yyensure_buffer_stack (void) { int num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return 0; b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = 0; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; yy_switch_to_buffer(b ); return b; } /** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan * * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * yy_scan_bytes() instead. */ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) { return yy_scan_bytes(yystr,strlen(yystr) ); } /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. * @param yybytes the byte buffer to scan * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) { YY_BUFFER_STATE b; char *buf; yy_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; buf = (char *) yyalloc(n ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = yy_scan_buffer(buf,n ); if ( ! b ) YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void yy_fatal_error (yyconst char* msg ) { (void) fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = (yy_hold_char); \ (yy_c_buf_p) = yytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the current line number. * */ int yyget_lineno (void) { return yylineno; } /** Get the input stream. * */ FILE *yyget_in (void) { return yyin; } /** Get the output stream. * */ FILE *yyget_out (void) { return yyout; } /** Get the length of the current token. * */ int yyget_leng (void) { return yyleng; } /** Get the current token. * */ char *yyget_text (void) { return yytext; } /** Set the current line number. * @param line_number * */ void yyset_lineno (int line_number ) { yylineno = line_number; } /** Set the input stream. This does not discard the current * input buffer. * @param in_str A readable stream. * * @see yy_switch_to_buffer */ void yyset_in (FILE * in_str ) { yyin = in_str ; } void yyset_out (FILE * out_str ) { yyout = out_str ; } int yyget_debug (void) { return yy_flex_debug; } void yyset_debug (int bdebug ) { yy_flex_debug = bdebug ; } static int yy_init_globals (void) { /* Initialization is the same as for the non-reentrant scanner. * This function is called from yylex_destroy(), so don't allocate here. */ /* We do not touch yylineno unless the option is enabled. */ yylineno = 1; (yy_buffer_stack) = 0; (yy_buffer_stack_top) = 0; (yy_buffer_stack_max) = 0; (yy_c_buf_p) = (char *) 0; (yy_init) = 0; (yy_start) = 0; /* Defined in main.c */ #ifdef YY_STDINIT yyin = stdin; yyout = stdout; #else yyin = (FILE *) 0; yyout = (FILE *) 0; #endif /* For future reference: Set errno on error, since we are called by * yylex_init() */ return 0; } /* yylex_destroy is for both reentrant and non-reentrant scanners. */ int yylex_destroy (void) { /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; yypop_buffer_state(); } /* Destroy the stack itself. */ yyfree((yy_buffer_stack) ); (yy_buffer_stack) = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * yylex() is called, initialization will occur. */ yy_init_globals( ); return 0; } /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *yyalloc (yy_size_t size ) { return (void *) malloc( size ); } void *yyrealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } void yyfree (void * ptr ) { free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 117 "scanner.l" static void ml_append (char *string) { int len = strlen (string); int s; if (ml_free <= len) { ml_len += len - ml_free + 1; ml_buffer = (char *)realloc (ml_buffer, ml_len); if (NULL == ml_buffer) YY_FATAL_ERROR ("out of dynamic memory in ml_append"); } s = snprintf (ml_buffer + ml_pos, ml_free, "%s", string); if ((0 > s) || (ml_free <= s)) YY_FATAL_ERROR ("failed to write to multiline buffer"); ml_pos += s; return; } /* ml_append */ collectd-5.4.0/src/liboconfig/PaxHeaders.11991/Makefile.in0000644037772200116100000000013212204120374021321 xustar000000000000000030 mtime=1376821500.366538564 30 atime=1376821537.959140215 30 ctime=1376821742.018400866 collectd-5.4.0/src/liboconfig/Makefile.in0000644037772200116100000005077012204120374020076 0ustar00octoeng00000000000000# Makefile.in generated by automake 1.11.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = src/liboconfig DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in AUTHORS \ COPYING ChangeLog parser.c parser.h scanner.c ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/src/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) liboconfig_la_LIBADD = am_liboconfig_la_OBJECTS = oconfig.lo scanner.lo parser.lo liboconfig_la_OBJECTS = $(am_liboconfig_la_OBJECTS) liboconfig_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(liboconfig_la_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src depcomp = am__depfiles_maybe = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ LEXCOMPILE = $(LEX) $(AM_LFLAGS) $(LFLAGS) LTLEXCOMPILE = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(LEX) $(AM_LFLAGS) $(LFLAGS) YLWRAP = $(top_srcdir)/libltdl/config/ylwrap YACCCOMPILE = $(YACC) $(AM_YFLAGS) $(YFLAGS) LTYACCCOMPILE = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(YACC) $(AM_YFLAGS) $(YFLAGS) SOURCES = $(liboconfig_la_SOURCES) DIST_SOURCES = $(liboconfig_la_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ ARGZ_H = @ARGZ_H@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_WITH_LIBAQUAERO5_CFLAGS = @BUILD_WITH_LIBAQUAERO5_CFLAGS@ BUILD_WITH_LIBAQUAERO5_LDFLAGS = @BUILD_WITH_LIBAQUAERO5_LDFLAGS@ BUILD_WITH_LIBCREDIS_CPPFLAGS = @BUILD_WITH_LIBCREDIS_CPPFLAGS@ BUILD_WITH_LIBCREDIS_LDFLAGS = @BUILD_WITH_LIBCREDIS_LDFLAGS@ BUILD_WITH_LIBCURL_CFLAGS = @BUILD_WITH_LIBCURL_CFLAGS@ BUILD_WITH_LIBCURL_LIBS = @BUILD_WITH_LIBCURL_LIBS@ BUILD_WITH_LIBDBI_CPPFLAGS = @BUILD_WITH_LIBDBI_CPPFLAGS@ BUILD_WITH_LIBDBI_LDFLAGS = @BUILD_WITH_LIBDBI_LDFLAGS@ BUILD_WITH_LIBDBI_LIBS = @BUILD_WITH_LIBDBI_LIBS@ BUILD_WITH_LIBHAL_CFLAGS = @BUILD_WITH_LIBHAL_CFLAGS@ BUILD_WITH_LIBHAL_LIBS = @BUILD_WITH_LIBHAL_LIBS@ BUILD_WITH_LIBIPTC_CPPFLAGS = @BUILD_WITH_LIBIPTC_CPPFLAGS@ BUILD_WITH_LIBIPTC_LDFLAGS = @BUILD_WITH_LIBIPTC_LDFLAGS@ BUILD_WITH_LIBLVM2APP_CPPFLAGS = @BUILD_WITH_LIBLVM2APP_CPPFLAGS@ BUILD_WITH_LIBLVM2APP_LDFLAGS = @BUILD_WITH_LIBLVM2APP_LDFLAGS@ BUILD_WITH_LIBLVM2APP_LIBS = @BUILD_WITH_LIBLVM2APP_LIBS@ BUILD_WITH_LIBMEMCACHED_CPPFLAGS = @BUILD_WITH_LIBMEMCACHED_CPPFLAGS@ BUILD_WITH_LIBMEMCACHED_LDFLAGS = @BUILD_WITH_LIBMEMCACHED_LDFLAGS@ BUILD_WITH_LIBMEMCACHED_LIBS = @BUILD_WITH_LIBMEMCACHED_LIBS@ BUILD_WITH_LIBMNL_CFLAGS = @BUILD_WITH_LIBMNL_CFLAGS@ BUILD_WITH_LIBMNL_LIBS = @BUILD_WITH_LIBMNL_LIBS@ BUILD_WITH_LIBMODBUS_CFLAGS = @BUILD_WITH_LIBMODBUS_CFLAGS@ BUILD_WITH_LIBMODBUS_LIBS = @BUILD_WITH_LIBMODBUS_LIBS@ BUILD_WITH_LIBMONGOC_CPPFLAGS = @BUILD_WITH_LIBMONGOC_CPPFLAGS@ BUILD_WITH_LIBMONGOC_LDFLAGS = @BUILD_WITH_LIBMONGOC_LDFLAGS@ BUILD_WITH_LIBMYSQL_CFLAGS = @BUILD_WITH_LIBMYSQL_CFLAGS@ BUILD_WITH_LIBMYSQL_LIBS = @BUILD_WITH_LIBMYSQL_LIBS@ BUILD_WITH_LIBOPING_CPPFLAGS = @BUILD_WITH_LIBOPING_CPPFLAGS@ BUILD_WITH_LIBOPING_LDFLAGS = @BUILD_WITH_LIBOPING_LDFLAGS@ BUILD_WITH_LIBOWCAPI_CPPFLAGS = @BUILD_WITH_LIBOWCAPI_CPPFLAGS@ BUILD_WITH_LIBOWCAPI_LIBS = @BUILD_WITH_LIBOWCAPI_LIBS@ BUILD_WITH_LIBPQ_CPPFLAGS = @BUILD_WITH_LIBPQ_CPPFLAGS@ BUILD_WITH_LIBPQ_LDFLAGS = @BUILD_WITH_LIBPQ_LDFLAGS@ BUILD_WITH_LIBRABBITMQ_CPPFLAGS = @BUILD_WITH_LIBRABBITMQ_CPPFLAGS@ BUILD_WITH_LIBRABBITMQ_LDFLAGS = @BUILD_WITH_LIBRABBITMQ_LDFLAGS@ BUILD_WITH_LIBRABBITMQ_LIBS = @BUILD_WITH_LIBRABBITMQ_LIBS@ BUILD_WITH_LIBROUTEROS_CPPFLAGS = @BUILD_WITH_LIBROUTEROS_CPPFLAGS@ BUILD_WITH_LIBROUTEROS_LDFLAGS = @BUILD_WITH_LIBROUTEROS_LDFLAGS@ BUILD_WITH_LIBRRD_CFLAGS = @BUILD_WITH_LIBRRD_CFLAGS@ BUILD_WITH_LIBRRD_LDFLAGS = @BUILD_WITH_LIBRRD_LDFLAGS@ BUILD_WITH_LIBSENSORS_CFLAGS = @BUILD_WITH_LIBSENSORS_CFLAGS@ BUILD_WITH_LIBSENSORS_LDFLAGS = @BUILD_WITH_LIBSENSORS_LDFLAGS@ BUILD_WITH_LIBSIGROK_CFLAGS = @BUILD_WITH_LIBSIGROK_CFLAGS@ BUILD_WITH_LIBSIGROK_LDFLAGS = @BUILD_WITH_LIBSIGROK_LDFLAGS@ BUILD_WITH_LIBSNMP_CFLAGS = @BUILD_WITH_LIBSNMP_CFLAGS@ BUILD_WITH_LIBSNMP_LIBS = @BUILD_WITH_LIBSNMP_LIBS@ BUILD_WITH_LIBSTATGRAB_CFLAGS = @BUILD_WITH_LIBSTATGRAB_CFLAGS@ BUILD_WITH_LIBSTATGRAB_LDFLAGS = @BUILD_WITH_LIBSTATGRAB_LDFLAGS@ BUILD_WITH_LIBTOKYOTYRANT_CPPFLAGS = @BUILD_WITH_LIBTOKYOTYRANT_CPPFLAGS@ BUILD_WITH_LIBTOKYOTYRANT_LDFLAGS = @BUILD_WITH_LIBTOKYOTYRANT_LDFLAGS@ BUILD_WITH_LIBTOKYOTYRANT_LIBS = @BUILD_WITH_LIBTOKYOTYRANT_LIBS@ BUILD_WITH_LIBUPSCLIENT_CFLAGS = @BUILD_WITH_LIBUPSCLIENT_CFLAGS@ BUILD_WITH_LIBUPSCLIENT_LIBS = @BUILD_WITH_LIBUPSCLIENT_LIBS@ BUILD_WITH_LIBVARNISH_CFLAGS = @BUILD_WITH_LIBVARNISH_CFLAGS@ BUILD_WITH_LIBVARNISH_LIBS = @BUILD_WITH_LIBVARNISH_LIBS@ BUILD_WITH_LIBVIRT_CFLAGS = @BUILD_WITH_LIBVIRT_CFLAGS@ BUILD_WITH_LIBVIRT_LIBS = @BUILD_WITH_LIBVIRT_LIBS@ BUILD_WITH_LIBXML2_CFLAGS = @BUILD_WITH_LIBXML2_CFLAGS@ BUILD_WITH_LIBXML2_LIBS = @BUILD_WITH_LIBXML2_LIBS@ BUILD_WITH_LIBXMMS_CFLAGS = @BUILD_WITH_LIBXMMS_CFLAGS@ BUILD_WITH_LIBXMMS_LIBS = @BUILD_WITH_LIBXMMS_LIBS@ BUILD_WITH_LIBYAJL_CPPFLAGS = @BUILD_WITH_LIBYAJL_CPPFLAGS@ BUILD_WITH_LIBYAJL_LDFLAGS = @BUILD_WITH_LIBYAJL_LDFLAGS@ BUILD_WITH_LIBYAJL_LIBS = @BUILD_WITH_LIBYAJL_LIBS@ BUILD_WITH_MIC_CPPFLAGS = @BUILD_WITH_MIC_CPPFLAGS@ BUILD_WITH_MIC_LDADD = @BUILD_WITH_MIC_LDADD@ BUILD_WITH_MIC_LIBPATH = @BUILD_WITH_MIC_LIBPATH@ BUILD_WITH_OPENIPMI_CFLAGS = @BUILD_WITH_OPENIPMI_CFLAGS@ BUILD_WITH_OPENIPMI_LIBS = @BUILD_WITH_OPENIPMI_LIBS@ BUILD_WITH_ORACLE_CFLAGS = @BUILD_WITH_ORACLE_CFLAGS@ BUILD_WITH_ORACLE_LIBS = @BUILD_WITH_ORACLE_LIBS@ BUILD_WITH_PYTHON_CPPFLAGS = @BUILD_WITH_PYTHON_CPPFLAGS@ BUILD_WITH_PYTHON_LDFLAGS = @BUILD_WITH_PYTHON_LDFLAGS@ BUILD_WITH_PYTHON_LIBS = @BUILD_WITH_PYTHON_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFAULT_LOG_LEVEL = @DEFAULT_LOG_LEVEL@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GANGLIA_CPPFLAGS = @GANGLIA_CPPFLAGS@ GANGLIA_LDFLAGS = @GANGLIA_LDFLAGS@ GANGLIA_LIBS = @GANGLIA_LIBS@ GCRYPT_CPPFLAGS = @GCRYPT_CPPFLAGS@ GCRYPT_LDFLAGS = @GCRYPT_LDFLAGS@ GCRYPT_LIBS = @GCRYPT_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_COMPILE_RESOURCES = @GLIB_COMPILE_RESOURCES@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ GLIB_MKENUMS = @GLIB_MKENUMS@ GOBJECT_QUERY = @GOBJECT_QUERY@ GREP = @GREP@ INCLTDL = @INCLTDL@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAR = @JAR@ JAVAC = @JAVAC@ JAVA_CFLAGS = @JAVA_CFLAGS@ JAVA_CPPFLAGS = @JAVA_CPPFLAGS@ JAVA_LDFLAGS = @JAVA_LDFLAGS@ JAVA_LIBS = @JAVA_LIBS@ KERNEL_CFLAGS = @KERNEL_CFLAGS@ KERNEL_DIR = @KERNEL_DIR@ LCC_VERSION_EXTRA = @LCC_VERSION_EXTRA@ LCC_VERSION_MAJOR = @LCC_VERSION_MAJOR@ LCC_VERSION_MINOR = @LCC_VERSION_MINOR@ LCC_VERSION_PATCH = @LCC_VERSION_PATCH@ LCC_VERSION_STRING = @LCC_VERSION_STRING@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBADD_DL = @LIBADD_DL@ LIBADD_DLD_LINK = @LIBADD_DLD_LINK@ LIBADD_DLOPEN = @LIBADD_DLOPEN@ LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLTDL = @LIBLTDL@ LIBNETAPP_CPPFLAGS = @LIBNETAPP_CPPFLAGS@ LIBNETAPP_LDFLAGS = @LIBNETAPP_LDFLAGS@ LIBNETAPP_LIBS = @LIBNETAPP_LIBS@ LIBNOTIFY_CFLAGS = @LIBNOTIFY_CFLAGS@ LIBNOTIFY_LIBS = @LIBNOTIFY_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LOAD_PLUGIN_CSV = @LOAD_PLUGIN_CSV@ LOAD_PLUGIN_LOGFILE = @LOAD_PLUGIN_LOGFILE@ LOAD_PLUGIN_NETWORK = @LOAD_PLUGIN_NETWORK@ LOAD_PLUGIN_RRDTOOL = @LOAD_PLUGIN_RRDTOOL@ LOAD_PLUGIN_SYSLOG = @LOAD_PLUGIN_SYSLOG@ LTDLDEPS = @LTDLDEPS@ LTDLINCL = @LTDLINCL@ LTDLOPEN = @LTDLOPEN@ LTLIBOBJS = @LTLIBOBJS@ LT_CONFIG_H = @LT_CONFIG_H@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_BINDINGS = @PERL_BINDINGS@ PERL_BINDINGS_OPTIONS = @PERL_BINDINGS_OPTIONS@ PERL_CFLAGS = @PERL_CFLAGS@ PERL_LDFLAGS = @PERL_LDFLAGS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_protoc_c = @have_protoc_c@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ ltdl_LIBOBJS = @ltdl_LIBOBJS@ ltdl_LTLIBOBJS = @ltdl_LTLIBOBJS@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sys_symbol_underscore = @sys_symbol_underscore@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign no-dependencies BUILT_SOURCES = parser.h #CLEANFILES = parser.[ch] scanner.c AM_YFLAGS = -d noinst_LTLIBRARIES = liboconfig.la liboconfig_la_LDFLAGS = -version-info 0:0:0 $(LEXLIB) liboconfig_la_SOURCES = oconfig.c oconfig.h aux_types.h scanner.l parser.y all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .c .l .lo .o .obj .y $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/liboconfig/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/liboconfig/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done parser.h: parser.c @if test ! -f $@; then rm -f parser.c; else :; fi @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) parser.c; else :; fi liboconfig.la: $(liboconfig_la_OBJECTS) $(liboconfig_la_DEPENDENCIES) $(EXTRA_liboconfig_la_DEPENDENCIES) $(liboconfig_la_LINK) $(liboconfig_la_OBJECTS) $(liboconfig_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c .c.o: $(COMPILE) -c $< .c.obj: $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: $(LTCOMPILE) -c -o $@ $< .l.c: $(am__skiplex) $(SHELL) $(YLWRAP) $< $(LEX_OUTPUT_ROOT).c $@ -- $(LEXCOMPILE) .y.c: $(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h $*.h y.output $*.output -- $(YACCCOMPILE) mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -rm -f parser.c -rm -f parser.h -rm -f scanner.c -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: all check install install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: collectd-5.4.0/src/liboconfig/PaxHeaders.11991/COPYING0000644037772200116100000000013212204120331020300 xustar000000000000000030 mtime=1376821465.073973439 30 atime=1376821477.218167931 30 ctime=1376821742.018400866 collectd-5.4.0/src/liboconfig/COPYING0000644037772200116100000004312212204120331017046 0ustar00octoeng00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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; either version 2 of the License, or (at your option) any later version. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. collectd-5.4.0/src/liboconfig/PaxHeaders.11991/parser.y0000644037772200116100000000013112204120331020732 xustar000000000000000030 mtime=1376821465.073973439 30 atime=1376821477.218167931 29 ctime=1376821742.02240093 collectd-5.4.0/src/liboconfig/parser.y0000644037772200116100000001224512204120331017503 0ustar00octoeng00000000000000/** * oconfig - src/parser.y * Copyright (C) 2007,2008 Florian octo 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 */ %{ #include #include #include "oconfig.h" #include "aux_types.h" static char *unquote (const char *orig); static int yyerror (const char *s); /* Lexer variables */ extern int yylineno; extern char *yytext; extern oconfig_item_t *ci_root; extern char *c_file; %} %start entire_file %union { double number; int boolean; char *string; oconfig_value_t cv; oconfig_item_t ci; argument_list_t al; statement_list_t sl; } %token NUMBER %token BTRUE BFALSE %token QUOTED_STRING UNQUOTED_STRING %token SLASH OPENBRAC CLOSEBRAC EOL %type string %type identifier /* arguments */ %type argument %type argument_list /* blocks */ %type block_begin %type block %type block_end /* statements */ %type option %type statement %type statement_list %type entire_file /* pass an verbose, specific error message to yyerror() */ %error-verbose %% string: QUOTED_STRING {$$ = unquote ($1);} | UNQUOTED_STRING {$$ = strdup ($1);} ; argument: NUMBER {$$.value.number = $1; $$.type = OCONFIG_TYPE_NUMBER;} | BTRUE {$$.value.boolean = 1; $$.type = OCONFIG_TYPE_BOOLEAN;} | BFALSE {$$.value.boolean = 0; $$.type = OCONFIG_TYPE_BOOLEAN;} | string {$$.value.string = $1; $$.type = OCONFIG_TYPE_STRING;} ; argument_list: argument_list argument { $$ = $1; $$.argument_num++; $$.argument = realloc ($$.argument, $$.argument_num * sizeof (oconfig_value_t)); $$.argument[$$.argument_num-1] = $2; } | argument { $$.argument = malloc (sizeof (oconfig_value_t)); $$.argument[0] = $1; $$.argument_num = 1; } ; identifier: UNQUOTED_STRING {$$ = strdup ($1);} ; option: identifier argument_list EOL { memset (&$$, '\0', sizeof ($$)); $$.key = $1; $$.values = $2.argument; $$.values_num = $2.argument_num; } ; block_begin: OPENBRAC identifier CLOSEBRAC EOL { memset (&$$, '\0', sizeof ($$)); $$.key = $2; } | OPENBRAC identifier argument_list CLOSEBRAC EOL { memset (&$$, '\0', sizeof ($$)); $$.key = $2; $$.values = $3.argument; $$.values_num = $3.argument_num; } ; block_end: OPENBRAC SLASH identifier CLOSEBRAC EOL { $$ = $3; } ; block: block_begin statement_list block_end { if (strcmp ($1.key, $3) != 0) { printf ("block_begin = %s; block_end = %s;\n", $1.key, $3); yyerror ("Block not closed..\n"); exit (1); } free ($3); $3 = NULL; $$ = $1; $$.children = $2.statement; $$.children_num = $2.statement_num; } | block_begin block_end { if (strcmp ($1.key, $2) != 0) { printf ("block_begin = %s; block_end = %s;\n", $1.key, $2); yyerror ("Block not closed..\n"); exit (1); } free ($2); $2 = NULL; $$ = $1; $$.children = NULL; $$.children_num = 0; } ; statement: option {$$ = $1;} | block {$$ = $1;} | EOL {$$.values_num = 0;} ; statement_list: statement_list statement { $$ = $1; if (($2.values_num > 0) || ($2.children_num > 0)) { $$.statement_num++; $$.statement = realloc ($$.statement, $$.statement_num * sizeof (oconfig_item_t)); $$.statement[$$.statement_num-1] = $2; } } | statement { if (($1.values_num > 0) || ($1.children_num > 0)) { $$.statement = malloc (sizeof (oconfig_item_t)); $$.statement[0] = $1; $$.statement_num = 1; } else { $$.statement = NULL; $$.statement_num = 0; } } ; entire_file: statement_list { ci_root = malloc (sizeof (oconfig_item_t)); memset (ci_root, '\0', sizeof (oconfig_item_t)); ci_root->children = $1.statement; ci_root->children_num = $1.statement_num; } | /* epsilon */ { ci_root = malloc (sizeof (oconfig_item_t)); memset (ci_root, '\0', sizeof (oconfig_item_t)); ci_root->children = NULL; ci_root->children_num = 0; } ; %% static int yyerror (const char *s) { char *text; if (*yytext == '\n') text = ""; else text = yytext; fprintf (stderr, "Parse error in file `%s', line %i near `%s': %s\n", c_file, yylineno, text, s); return (-1); } /* int yyerror */ static char *unquote (const char *orig) { char *ret = strdup (orig); int len; int i; if (ret == NULL) return (NULL); len = strlen (ret); if ((len < 2) || (ret[0] != '"') || (ret[len - 1] != '"')) return (ret); len -= 2; memmove (ret, ret + 1, len); ret[len] = '\0'; for (i = 0; i < len; i++) { if (ret[i] == '\\') { memmove (ret + i, ret + (i + 1), len - i); len--; } } return (ret); } /* char *unquote */ collectd-5.4.0/src/liboconfig/PaxHeaders.11991/oconfig.c0000644037772200116100000000013112204120331021034 xustar000000000000000030 mtime=1376821465.073973439 30 atime=1376821477.218167931 29 ctime=1376821742.02240093 collectd-5.4.0/src/liboconfig/oconfig.c0000644037772200116100000001156412204120331017610 0ustar00octoeng00000000000000/** * oconfig - src/oconfig.c * Copyright (C) 2006,2007 Florian octo 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 */ #include #include #include #include #include #include "oconfig.h" extern FILE *yyin; oconfig_item_t *ci_root; const char *c_file; static void yyset_in (FILE *fd) { yyin = fd; } /* void yyset_in */ oconfig_item_t *oconfig_parse_fh (FILE *fh) { int status; oconfig_item_t *ret; char file[10]; yyset_in (fh); if (NULL == c_file) { int status; status = snprintf (file, sizeof (file), "", fileno (fh)); if ((status < 0) || (status >= sizeof (file))) { c_file = ""; } else { file[sizeof (file) - 1] = '\0'; c_file = file; } } status = yyparse (); if (status != 0) { fprintf (stderr, "yyparse returned error #%i\n", status); return (NULL); } c_file = NULL; ret = ci_root; ci_root = NULL; yyset_in ((FILE *) 0); return (ret); } /* oconfig_item_t *oconfig_parse_fh */ oconfig_item_t *oconfig_parse_file (const char *file) { FILE *fh; oconfig_item_t *ret; c_file = file; fh = fopen (file, "r"); if (fh == NULL) { fprintf (stderr, "fopen (%s) failed: %s\n", file, strerror (errno)); return (NULL); } ret = oconfig_parse_fh (fh); fclose (fh); c_file = NULL; return (ret); } /* oconfig_item_t *oconfig_parse_file */ oconfig_item_t *oconfig_clone (const oconfig_item_t *ci_orig) { oconfig_item_t *ci_copy; ci_copy = (oconfig_item_t *) malloc (sizeof (*ci_copy)); if (ci_copy == NULL) { fprintf (stderr, "malloc failed.\n"); return (NULL); } memset (ci_copy, 0, sizeof (*ci_copy)); ci_copy->values = NULL; ci_copy->parent = NULL; ci_copy->children = NULL; ci_copy->key = strdup (ci_orig->key); if (ci_copy->key == NULL) { fprintf (stderr, "strdup failed.\n"); free (ci_copy); return (NULL); } if (ci_orig->values_num > 0) /* {{{ */ { int i; ci_copy->values = (oconfig_value_t *) calloc (ci_orig->values_num, sizeof (*ci_copy->values)); if (ci_copy->values == NULL) { fprintf (stderr, "calloc failed.\n"); free (ci_copy->key); free (ci_copy); return (NULL); } ci_copy->values_num = ci_orig->values_num; for (i = 0; i < ci_copy->values_num; i++) { ci_copy->values[i].type = ci_orig->values[i].type; if (ci_copy->values[i].type == OCONFIG_TYPE_STRING) { ci_copy->values[i].value.string = strdup (ci_orig->values[i].value.string); if (ci_copy->values[i].value.string == NULL) { fprintf (stderr, "strdup failed.\n"); oconfig_free (ci_copy); return (NULL); } } else /* ci_copy->values[i].type != OCONFIG_TYPE_STRING) */ { ci_copy->values[i].value = ci_orig->values[i].value; } } } /* }}} if (ci_orig->values_num > 0) */ if (ci_orig->children_num > 0) /* {{{ */ { int i; ci_copy->children = (oconfig_item_t *) calloc (ci_orig->children_num, sizeof (*ci_copy->children)); if (ci_copy->children == NULL) { fprintf (stderr, "calloc failed.\n"); oconfig_free (ci_copy); return (NULL); } ci_copy->children_num = ci_orig->children_num; for (i = 0; i < ci_copy->children_num; i++) { oconfig_item_t *child; child = oconfig_clone (ci_orig->children + i); if (child == NULL) { oconfig_free (ci_copy); return (NULL); } child->parent = ci_copy; ci_copy->children[i] = *child; free (child); } /* for (i = 0; i < ci_copy->children_num; i++) */ } /* }}} if (ci_orig->children_num > 0) */ return (ci_copy); } /* oconfig_item_t *oconfig_clone */ void oconfig_free (oconfig_item_t *ci) { int i; if (ci == NULL) return; if (ci->key != NULL) free (ci->key); for (i = 0; i < ci->values_num; i++) if ((ci->values[i].type == OCONFIG_TYPE_STRING) && (NULL != ci->values[i].value.string)) free (ci->values[i].value.string); if (ci->values != NULL) free (ci->values); for (i = 0; i < ci->children_num; i++) oconfig_free (ci->children + i); if (ci->children != NULL) free (ci->children); } /* * vim:shiftwidth=2:tabstop=8:softtabstop=2:fdm=marker */ collectd-5.4.0/src/PaxHeaders.11991/utils_tail.c0000644037772200116100000000013212204120331017447 xustar000000000000000030 mtime=1376821465.089973696 30 atime=1376821477.230168122 30 ctime=1376821742.026400993 collectd-5.4.0/src/utils_tail.c0000644037772200116100000001330212204120331016212 0ustar00octoeng00000000000000/** * collectd - src/utils_tail.c * Copyright (C) 2007-2008 C-Ware, Inc. * Copyright (C) 2008 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 * * Author: * Luke Heberling * Florian Forster * * Description: * Encapsulates useful code for plugins which must watch for appends to * the end of a file. **/ #include "collectd.h" #include "common.h" #include "utils_tail.h" struct cu_tail_s { char *file; FILE *fh; struct stat stat; }; static int cu_tail_reopen (cu_tail_t *obj) { int seek_end = 0; FILE *fh; struct stat stat_buf; int status; memset (&stat_buf, 0, sizeof (stat_buf)); status = stat (obj->file, &stat_buf); if (status != 0) { char errbuf[1024]; ERROR ("utils_tail: stat (%s) failed: %s", obj->file, sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } /* The file is already open.. */ if ((obj->fh != NULL) && (stat_buf.st_ino == obj->stat.st_ino)) { /* Seek to the beginning if file was truncated */ if (stat_buf.st_size < obj->stat.st_size) { INFO ("utils_tail: File `%s' was truncated.", obj->file); status = fseek (obj->fh, 0, SEEK_SET); if (status != 0) { char errbuf[1024]; ERROR ("utils_tail: fseek (%s) failed: %s", obj->file, sstrerror (errno, errbuf, sizeof (errbuf))); fclose (obj->fh); obj->fh = NULL; return (-1); } } memcpy (&obj->stat, &stat_buf, sizeof (struct stat)); return (1); } /* Seek to the end if we re-open the same file again or the file opened * is the first at all or the first after an error */ if ((obj->stat.st_ino == 0) || (obj->stat.st_ino == stat_buf.st_ino)) seek_end = 1; fh = fopen (obj->file, "r"); if (fh == NULL) { char errbuf[1024]; ERROR ("utils_tail: fopen (%s) failed: %s", obj->file, sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } if (seek_end != 0) { status = fseek (fh, 0, SEEK_END); if (status != 0) { char errbuf[1024]; ERROR ("utils_tail: fseek (%s) failed: %s", obj->file, sstrerror (errno, errbuf, sizeof (errbuf))); fclose (fh); return (-1); } } if (obj->fh != NULL) fclose (obj->fh); obj->fh = fh; memcpy (&obj->stat, &stat_buf, sizeof (struct stat)); return (0); } /* int cu_tail_reopen */ cu_tail_t *cu_tail_create (const char *file) { cu_tail_t *obj; obj = (cu_tail_t *) malloc (sizeof (cu_tail_t)); if (obj == NULL) return (NULL); memset (obj, '\0', sizeof (cu_tail_t)); obj->file = strdup (file); if (obj->file == NULL) { free (obj); return (NULL); } obj->fh = NULL; return (obj); } /* cu_tail_t *cu_tail_create */ int cu_tail_destroy (cu_tail_t *obj) { if (obj->fh != NULL) fclose (obj->fh); free (obj->file); free (obj); return (0); } /* int cu_tail_destroy */ int cu_tail_readline (cu_tail_t *obj, char *buf, int buflen) { int status; if (buflen < 1) { ERROR ("utils_tail: cu_tail_readline: buflen too small: %i bytes.", buflen); return (-1); } if (obj->fh == NULL) { status = cu_tail_reopen (obj); if (status < 0) return (status); } assert (obj->fh != NULL); /* Try to read from the filehandle. If that succeeds, everything appears to * be fine and we can return. */ clearerr (obj->fh); if (fgets (buf, buflen, obj->fh) != NULL) { buf[buflen - 1] = 0; return (0); } /* Check if we encountered an error */ if (ferror (obj->fh) != 0) { /* Jupp, error. Force `cu_tail_reopen' to reopen the file.. */ fclose (obj->fh); obj->fh = NULL; } /* else: eof -> check if the file was moved away and reopen the new file if * so.. */ status = cu_tail_reopen (obj); /* error -> return with error */ if (status < 0) return (status); /* file end reached and file not reopened -> nothing more to read */ else if (status > 0) { buf[0] = 0; return (0); } /* If we get here: file was re-opened and there may be more to read.. Let's * try again. */ if (fgets (buf, buflen, obj->fh) != NULL) { buf[buflen - 1] = 0; return (0); } if (ferror (obj->fh) != 0) { char errbuf[1024]; WARNING ("utils_tail: fgets (%s) returned an error: %s", obj->file, sstrerror (errno, errbuf, sizeof (errbuf))); fclose (obj->fh); obj->fh = NULL; return (-1); } /* EOf, well, apparently the new file is empty.. */ buf[0] = 0; return (0); } /* int cu_tail_readline */ int cu_tail_read (cu_tail_t *obj, char *buf, int buflen, tailfunc_t *callback, void *data) { int status; while (42) { size_t len; status = cu_tail_readline (obj, buf, buflen); if (status != 0) { ERROR ("utils_tail: cu_tail_read: cu_tail_readline " "failed."); break; } /* check for EOF */ if (buf[0] == 0) break; len = strlen (buf); while (len > 0) { if (buf[len - 1] != '\n') break; buf[len - 1] = '\0'; len--; } status = callback (data, buf, buflen); if (status != 0) { ERROR ("utils_tail: cu_tail_read: callback returned " "status %i.", status); break; } } return status; } /* int cu_tail_read */ collectd-5.4.0/src/PaxHeaders.11991/ted.c0000644037772200116100000000013212204120331016052 xustar000000000000000030 mtime=1376821465.085973632 30 atime=1376821477.226168058 30 ctime=1376821742.026400993 collectd-5.4.0/src/ted.c0000644037772200116100000002337412204120331014627 0ustar00octoeng00000000000000/** * collectd - src/ted.c * Copyright (C) 2009 Eric Reed * * 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; either version 2 of the License, or (at your * option) any later version. * * 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: * Eric Reed * * This is a collectd module for The Energy Detective: A low-cost whole * house energy monitoring system. For more information on TED, see * http://theenergydetective.com * * This module was not created by Energy, Inc. nor is it supported by * them in any way. It was created using information from two sources: * David Satterfield's TED module for Misterhouse, and Micah Dowty's TED * Python Module. * * This has only tested with the model 1001 RDU, with * firmware version 9.01U. The USB port is uses the very common FTDI * USB-to-serial chip, so the RDU will show up as a serial device on * Windows, Mac OS, or Linux. **/ #include "collectd.h" #include "common.h" #include "plugin.h" #include "configfile.h" #if HAVE_TERMIOS_H && HAVE_SYS_IOCTL_H && HAVE_MATH_H # include # include # include #else # error "No applicable input method." #endif #define EXPECTED_PACKAGE_LENGTH 278 #define ESCAPE 0x10 #define PKT_BEGIN 0x04 #define PKT_END 0x03 #define DEFAULT_DEVICE "/dev/ttyUSB0" static char *conf_device = NULL; static int conf_retries = 0; static int fd = -1; static const char *config_keys[] = { "Device", "Retries" }; static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); static int ted_read_value(double *ret_power, double *ret_voltage) { unsigned char receive_buffer[300]; unsigned char package_buffer[300]; char pkt_request[1] = {0xAA}; int package_buffer_pos; fd_set input; struct timeval timeout; int end_flag; int escape_flag; int status; assert (fd >= 0); /* Initialize the input set*/ FD_ZERO (&input); FD_SET (fd, &input); /* Initialize timeout structure, set to 2 seconds */ memset (&timeout, 0, sizeof (timeout)); timeout.tv_sec = 2; timeout.tv_usec = 0; /* clear out anything in the buffer */ tcflush (fd, TCIFLUSH); status = write (fd, pkt_request, sizeof(pkt_request)); if (status <= 0) { ERROR ("ted plugin: swrite failed."); return (-1); } /* Loop until we find the end of the package */ end_flag = 0; escape_flag = 0; package_buffer_pos = 0; while (end_flag == 0) { ssize_t receive_buffer_length; ssize_t i; /* check for timeout or input error*/ status = select (fd + 1, &input, NULL, NULL, &timeout); if (status == 0) /* Timeout */ { WARNING ("ted plugin: Timeout while waiting for file descriptor " "to become ready."); return (-1); } else if ((status < 0) && ((errno == EAGAIN) || (errno == EINTR))) { /* Some signal or something. Start over.. */ continue; } else if (status < 0) { char errbuf[1024]; ERROR ("ted plugin: select failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } receive_buffer_length = read (fd, receive_buffer, sizeof (receive_buffer)); if (receive_buffer_length < 0) { char errbuf[1024]; if ((errno == EAGAIN) || (errno == EINTR)) continue; ERROR ("ted plugin: read(2) failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } else if (receive_buffer_length == 0) { /* Should we close the FD in this case? */ WARNING ("ted plugin: Received EOF from file descriptor."); return (-1); } else if (receive_buffer_length > sizeof (receive_buffer)) { ERROR ("ted plugin: read(2) returned invalid value %zi.", receive_buffer_length); return (-1); } /* * packet filter loop * * Handle escape sequences in `receive_buffer' and put the * result in `package_buffer'. */ /* We need to see the begin sequence first. When we receive `ESCAPE * PKT_BEGIN', we set `package_buffer_pos' to zero to signal that * the beginning of the package has been found. */ escape_flag = 0; for (i = 0; i < receive_buffer_length; i++) { /* Check if previous byte was the escape byte. */ if (escape_flag == 1) { escape_flag = 0; /* escape escape = single escape */ if ((receive_buffer[i] == ESCAPE) && (package_buffer_pos >= 0)) { package_buffer[package_buffer_pos] = ESCAPE; package_buffer_pos++; } else if (receive_buffer[i] == PKT_BEGIN) { package_buffer_pos = 0; } else if (receive_buffer[i] == PKT_END) { end_flag = 1; break; } else { DEBUG ("ted plugin: Unknown escaped byte: %#x", (unsigned int) receive_buffer[i]); } } else if (receive_buffer[i] == ESCAPE) { escape_flag = 1; } /* if we are in a package add byte to buffer * otherwise throw away */ else if (package_buffer_pos >= 0) { package_buffer[package_buffer_pos] = receive_buffer[i]; package_buffer_pos++; } } /* for (i = 0; i < receive_buffer_length; i++) */ } /* while (end_flag == 0) */ /* Check for errors inside the loop. */ if ((end_flag == 0) || (package_buffer_pos != EXPECTED_PACKAGE_LENGTH)) return (-1); /* * Power is at positions 247 and 248 (LSB first) in [10kW]. * Voltage is at positions 251 and 252 (LSB first) in [.1V]. * * Power is in 10 Watt steps * Voltage is in volts */ *ret_power = 10.0 * (double) ((((int) package_buffer[248]) * 256) + ((int) package_buffer[247])); *ret_voltage = 0.1 * (double) ((((int) package_buffer[252]) * 256) + ((int) package_buffer[251])); /* success */ return (0); } /* int ted_read_value */ static int ted_open_device (void) { const char *dev; struct termios options; if (fd >= 0) return (0); dev = DEFAULT_DEVICE; if (conf_device != NULL) dev = conf_device; fd = open (dev, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK); if (fd < 0) { ERROR ("ted plugin: Unable to open device %s.", dev); return (-1); } /* Get the current options for the port... */ tcgetattr(fd, &options); options.c_cflag = B19200 | CS8 | CSTOPB | CREAD | CLOCAL; options.c_iflag = IGNBRK | IGNPAR; options.c_oflag = 0; options.c_lflag = 0; options.c_cc[VTIME] = 20; options.c_cc[VMIN] = 250; /* Set the new options for the port... */ tcflush(fd, TCIFLUSH); tcsetattr(fd, TCSANOW, &options); INFO ("ted plugin: Successfully opened %s.", dev); return (0); } /* int ted_open_device */ static void ted_submit (char *type, double value) { value_t values[1]; value_list_t vl = VALUE_LIST_INIT; values[0].gauge = value; vl.values = values; vl.values_len = 1; sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "ted", sizeof (vl.plugin)); sstrncpy (vl.type, type, sizeof (vl.type)); plugin_dispatch_values (&vl); } static int ted_config (const char *key, const char *value) { if (strcasecmp ("Device", key) == 0) { sfree (conf_device); conf_device = sstrdup (value); } else if (strcasecmp ("Retries", key) == 0) { int tmp; tmp = atoi (value); if (tmp < 0) { WARNING ("ted plugin: Invalid retry count: %i", tmp); return (1); } conf_retries = tmp; } else { ERROR ("ted plugin: Unknown config option: %s", key); return (-1); } return (0); } /* int ted_config */ static int ted_read (void) { double power; double voltage; int status; int i; status = ted_open_device (); if (status != 0) return (-1); power = NAN; voltage = NAN; for (i = 0; i <= conf_retries; i++) { status = ted_read_value (&power, &voltage); if (status == 0) break; } if (status != 0) return (-1); ted_submit ("power", power); ted_submit ("voltage", voltage); return (0); } /* int ted_read */ static int ted_shutdown (void) { if (fd >= 0) { close (fd); fd = -1; } return (0); } /* int ted_shutdown */ void module_register (void) { plugin_register_config ("ted", ted_config, config_keys, config_keys_num); plugin_register_read ("ted", ted_read); plugin_register_shutdown ("ted", ted_shutdown); } /* void module_register */ /* vim: set sw=4 et : */ collectd-5.4.0/src/PaxHeaders.11991/meta_data.c0000644037772200116100000000013212204120331017215 xustar000000000000000030 mtime=1376821465.077973503 30 atime=1376821477.218167931 30 ctime=1376821742.026400993 collectd-5.4.0/src/meta_data.c0000644037772200116100000003074312204120331015770 0ustar00octoeng00000000000000/** * collectd - src/meta_data.c * Copyright (C) 2008-2011 Florian octo 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: * Florian octo Forster **/ #include "collectd.h" #include "plugin.h" #include "meta_data.h" #include /* * Data types */ union meta_value_u { char *mv_string; int64_t mv_signed_int; uint64_t mv_unsigned_int; double mv_double; _Bool mv_boolean; }; typedef union meta_value_u meta_value_t; struct meta_entry_s; typedef struct meta_entry_s meta_entry_t; struct meta_entry_s { char *key; meta_value_t value; int type; meta_entry_t *next; }; struct meta_data_s { meta_entry_t *head; pthread_mutex_t lock; }; /* * Private functions */ static char *md_strdup (const char *orig) /* {{{ */ { size_t sz; char *dest; if (orig == NULL) return (NULL); sz = strlen (orig) + 1; dest = (char *) malloc (sz); if (dest == NULL) return (NULL); memcpy (dest, orig, sz); return (dest); } /* }}} char *md_strdup */ static meta_entry_t *md_entry_alloc (const char *key) /* {{{ */ { meta_entry_t *e; e = (meta_entry_t *) malloc (sizeof (*e)); if (e == NULL) { ERROR ("md_entry_alloc: malloc failed."); return (NULL); } memset (e, 0, sizeof (*e)); e->key = md_strdup (key); if (e->key == NULL) { free (e); ERROR ("md_entry_alloc: md_strdup failed."); return (NULL); } e->type = 0; e->next = NULL; return (e); } /* }}} meta_entry_t *md_entry_alloc */ static meta_entry_t *md_entry_clone (const meta_entry_t *orig) /* {{{ */ { meta_entry_t *copy; if (orig == NULL) return (NULL); copy = md_entry_alloc (orig->key); copy->type = orig->type; if (copy->type == MD_TYPE_STRING) copy->value.mv_string = strdup (orig->value.mv_string); else copy->value = orig->value; copy->next = md_entry_clone (orig->next); return (copy); } /* }}} meta_entry_t *md_entry_clone */ static void md_entry_free (meta_entry_t *e) /* {{{ */ { if (e == NULL) return; free (e->key); if (e->type == MD_TYPE_STRING) free (e->value.mv_string); if (e->next != NULL) md_entry_free (e->next); free (e); } /* }}} void md_entry_free */ static int md_entry_insert (meta_data_t *md, meta_entry_t *e) /* {{{ */ { meta_entry_t *this; meta_entry_t *prev; if ((md == NULL) || (e == NULL)) return (-EINVAL); pthread_mutex_lock (&md->lock); prev = NULL; this = md->head; while (this != NULL) { if (strcasecmp (e->key, this->key) == 0) break; prev = this; this = this->next; } if (this == NULL) { /* This key does not exist yet. */ if (md->head == NULL) md->head = e; else { assert (prev != NULL); prev->next = e; } e->next = NULL; } else /* (this != NULL) */ { if (prev == NULL) md->head = e; else prev->next = e; e->next = this->next; } pthread_mutex_unlock (&md->lock); if (this != NULL) { this->next = NULL; md_entry_free (this); } return (0); } /* }}} int md_entry_insert */ /* XXX: The lock on md must be held while calling this function! */ static meta_entry_t *md_entry_lookup (meta_data_t *md, /* {{{ */ const char *key) { meta_entry_t *e; if ((md == NULL) || (key == NULL)) return (NULL); for (e = md->head; e != NULL; e = e->next) if (strcasecmp (key, e->key) == 0) break; return (e); } /* }}} meta_entry_t *md_entry_lookup */ /* * Public functions */ meta_data_t *meta_data_create (void) /* {{{ */ { meta_data_t *md; md = (meta_data_t *) malloc (sizeof (*md)); if (md == NULL) { ERROR ("meta_data_create: malloc failed."); return (NULL); } memset (md, 0, sizeof (*md)); md->head = NULL; pthread_mutex_init (&md->lock, /* attr = */ NULL); return (md); } /* }}} meta_data_t *meta_data_create */ meta_data_t *meta_data_clone (meta_data_t *orig) /* {{{ */ { meta_data_t *copy; if (orig == NULL) return (NULL); copy = meta_data_create (); if (copy == NULL) return (NULL); pthread_mutex_lock (&orig->lock); copy->head = md_entry_clone (orig->head); pthread_mutex_unlock (&orig->lock); return (copy); } /* }}} meta_data_t *meta_data_clone */ void meta_data_destroy (meta_data_t *md) /* {{{ */ { if (md == NULL) return; pthread_mutex_destroy(&md->lock); md_entry_free (md->head); pthread_mutex_destroy (&md->lock); free (md); } /* }}} void meta_data_destroy */ int meta_data_exists (meta_data_t *md, const char *key) /* {{{ */ { meta_entry_t *e; if ((md == NULL) || (key == NULL)) return (-EINVAL); pthread_mutex_lock (&md->lock); for (e = md->head; e != NULL; e = e->next) { if (strcasecmp (key, e->key) == 0) { pthread_mutex_unlock (&md->lock); return (1); } } pthread_mutex_unlock (&md->lock); return (0); } /* }}} int meta_data_exists */ int meta_data_type (meta_data_t *md, const char *key) /* {{{ */ { meta_entry_t *e; if ((md == NULL) || (key == NULL)) return -EINVAL; pthread_mutex_lock (&md->lock); for (e = md->head; e != NULL; e = e->next) { if (strcasecmp (key, e->key) == 0) { pthread_mutex_unlock (&md->lock); return e->type; } } pthread_mutex_unlock (&md->lock); return 0; } /* }}} int meta_data_type */ int meta_data_toc (meta_data_t *md, char ***toc) /* {{{ */ { int i = 0, count = 0; meta_entry_t *e; if ((md == NULL) || (toc == NULL)) return -EINVAL; pthread_mutex_lock (&md->lock); for (e = md->head; e != NULL; e = e->next) ++count; *toc = malloc(count * sizeof(**toc)); for (e = md->head; e != NULL; e = e->next) (*toc)[i++] = strdup(e->key); pthread_mutex_unlock (&md->lock); return count; } /* }}} int meta_data_toc */ int meta_data_delete (meta_data_t *md, const char *key) /* {{{ */ { meta_entry_t *this; meta_entry_t *prev; if ((md == NULL) || (key == NULL)) return (-EINVAL); pthread_mutex_lock (&md->lock); prev = NULL; this = md->head; while (this != NULL) { if (strcasecmp (key, this->key) == 0) break; prev = this; this = this->next; } if (this == NULL) { pthread_mutex_unlock (&md->lock); return (-ENOENT); } if (prev == NULL) md->head = this->next; else prev->next = this->next; pthread_mutex_unlock (&md->lock); this->next = NULL; md_entry_free (this); return (0); } /* }}} int meta_data_delete */ /* * Add functions */ int meta_data_add_string (meta_data_t *md, /* {{{ */ const char *key, const char *value) { meta_entry_t *e; if ((md == NULL) || (key == NULL) || (value == NULL)) return (-EINVAL); e = md_entry_alloc (key); if (e == NULL) return (-ENOMEM); e->value.mv_string = md_strdup (value); if (e->value.mv_string == NULL) { ERROR ("meta_data_add_string: md_strdup failed."); md_entry_free (e); return (-ENOMEM); } e->type = MD_TYPE_STRING; return (md_entry_insert (md, e)); } /* }}} int meta_data_add_string */ int meta_data_add_signed_int (meta_data_t *md, /* {{{ */ const char *key, int64_t value) { meta_entry_t *e; if ((md == NULL) || (key == NULL)) return (-EINVAL); e = md_entry_alloc (key); if (e == NULL) return (-ENOMEM); e->value.mv_signed_int = value; e->type = MD_TYPE_SIGNED_INT; return (md_entry_insert (md, e)); } /* }}} int meta_data_add_signed_int */ int meta_data_add_unsigned_int (meta_data_t *md, /* {{{ */ const char *key, uint64_t value) { meta_entry_t *e; if ((md == NULL) || (key == NULL)) return (-EINVAL); e = md_entry_alloc (key); if (e == NULL) return (-ENOMEM); e->value.mv_unsigned_int = value; e->type = MD_TYPE_UNSIGNED_INT; return (md_entry_insert (md, e)); } /* }}} int meta_data_add_unsigned_int */ int meta_data_add_double (meta_data_t *md, /* {{{ */ const char *key, double value) { meta_entry_t *e; if ((md == NULL) || (key == NULL)) return (-EINVAL); e = md_entry_alloc (key); if (e == NULL) return (-ENOMEM); e->value.mv_double = value; e->type = MD_TYPE_DOUBLE; return (md_entry_insert (md, e)); } /* }}} int meta_data_add_double */ int meta_data_add_boolean (meta_data_t *md, /* {{{ */ const char *key, _Bool value) { meta_entry_t *e; if ((md == NULL) || (key == NULL)) return (-EINVAL); e = md_entry_alloc (key); if (e == NULL) return (-ENOMEM); e->value.mv_boolean = value; e->type = MD_TYPE_BOOLEAN; return (md_entry_insert (md, e)); } /* }}} int meta_data_add_boolean */ /* * Get functions */ int meta_data_get_string (meta_data_t *md, /* {{{ */ const char *key, char **value) { meta_entry_t *e; char *temp; if ((md == NULL) || (key == NULL) || (value == NULL)) return (-EINVAL); pthread_mutex_lock (&md->lock); e = md_entry_lookup (md, key); if (e == NULL) { pthread_mutex_unlock (&md->lock); return (-ENOENT); } if (e->type != MD_TYPE_STRING) { ERROR ("meta_data_get_signed_int: Type mismatch for key `%s'", e->key); pthread_mutex_unlock (&md->lock); return (-ENOENT); } temp = md_strdup (e->value.mv_string); if (temp == NULL) { pthread_mutex_unlock (&md->lock); ERROR ("meta_data_get_string: md_strdup failed."); return (-ENOMEM); } pthread_mutex_unlock (&md->lock); *value = temp; return (0); } /* }}} int meta_data_get_string */ int meta_data_get_signed_int (meta_data_t *md, /* {{{ */ const char *key, int64_t *value) { meta_entry_t *e; if ((md == NULL) || (key == NULL) || (value == NULL)) return (-EINVAL); pthread_mutex_lock (&md->lock); e = md_entry_lookup (md, key); if (e == NULL) { pthread_mutex_unlock (&md->lock); return (-ENOENT); } if (e->type != MD_TYPE_SIGNED_INT) { ERROR ("meta_data_get_signed_int: Type mismatch for key `%s'", e->key); pthread_mutex_unlock (&md->lock); return (-ENOENT); } *value = e->value.mv_signed_int; pthread_mutex_unlock (&md->lock); return (0); } /* }}} int meta_data_get_signed_int */ int meta_data_get_unsigned_int (meta_data_t *md, /* {{{ */ const char *key, uint64_t *value) { meta_entry_t *e; if ((md == NULL) || (key == NULL) || (value == NULL)) return (-EINVAL); pthread_mutex_lock (&md->lock); e = md_entry_lookup (md, key); if (e == NULL) { pthread_mutex_unlock (&md->lock); return (-ENOENT); } if (e->type != MD_TYPE_UNSIGNED_INT) { ERROR ("meta_data_get_unsigned_int: Type mismatch for key `%s'", e->key); pthread_mutex_unlock (&md->lock); return (-ENOENT); } *value = e->value.mv_unsigned_int; pthread_mutex_unlock (&md->lock); return (0); } /* }}} int meta_data_get_unsigned_int */ int meta_data_get_double (meta_data_t *md, /* {{{ */ const char *key, double *value) { meta_entry_t *e; if ((md == NULL) || (key == NULL) || (value == NULL)) return (-EINVAL); pthread_mutex_lock (&md->lock); e = md_entry_lookup (md, key); if (e == NULL) { pthread_mutex_unlock (&md->lock); return (-ENOENT); } if (e->type != MD_TYPE_DOUBLE) { ERROR ("meta_data_get_double: Type mismatch for key `%s'", e->key); pthread_mutex_unlock (&md->lock); return (-ENOENT); } *value = e->value.mv_double; pthread_mutex_unlock (&md->lock); return (0); } /* }}} int meta_data_get_double */ int meta_data_get_boolean (meta_data_t *md, /* {{{ */ const char *key, _Bool *value) { meta_entry_t *e; if ((md == NULL) || (key == NULL) || (value == NULL)) return (-EINVAL); pthread_mutex_lock (&md->lock); e = md_entry_lookup (md, key); if (e == NULL) { pthread_mutex_unlock (&md->lock); return (-ENOENT); } if (e->type != MD_TYPE_BOOLEAN) { ERROR ("meta_data_get_boolean: Type mismatch for key `%s'", e->key); pthread_mutex_unlock (&md->lock); return (-ENOENT); } *value = e->value.mv_boolean; pthread_mutex_unlock (&md->lock); return (0); } /* }}} int meta_data_get_boolean */ /* vim: set sw=2 sts=2 et fdm=marker : */ collectd-5.4.0/src/PaxHeaders.11991/bind.c0000644037772200116100000000013212204120331016212 xustar000000000000000030 mtime=1376821465.061973248 30 atime=1376821477.206167738 30 ctime=1376821742.030401056 collectd-5.4.0/src/bind.c0000644037772200116100000012032212204120331014756 0ustar00octoeng00000000000000/** * collectd - src/bind.c * Copyright (C) 2009 Bruno Prémont * Copyright (C) 2009,2010 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: * Bruno Prémont * Florian Forster **/ #include "config.h" #if STRPTIME_NEEDS_STANDARDS # ifndef _ISOC99_SOURCE # define _ISOC99_SOURCE 1 # endif # ifndef _POSIX_C_SOURCE # define _POSIX_C_SOURCE 200112L # endif # ifndef _XOPEN_SOURCE # define _XOPEN_SOURCE 500 # endif #endif /* STRPTIME_NEEDS_STANDARDS */ #include "collectd.h" #include "common.h" #include "plugin.h" #include "configfile.h" /* Some versions of libcurl don't include this themselves and then don't have * fd_set available. */ #if HAVE_SYS_SELECT_H # include #endif #include #include #include #ifndef BIND_DEFAULT_URL # define BIND_DEFAULT_URL "http://localhost:8053/" #endif /* * Some types used for the callback functions. `translation_table_ptr_t' and * `list_info_ptr_t' are passed to the callbacks in the `void *user_data' * pointer. */ typedef int (*list_callback_t) (const char *name, value_t value, time_t current_time, void *user_data); struct cb_view_s { char *name; int qtypes; int resolver_stats; int cacherrsets; char **zones; size_t zones_num; }; typedef struct cb_view_s cb_view_t; struct translation_info_s { const char *xml_name; const char *type; const char *type_instance; }; typedef struct translation_info_s translation_info_t; struct translation_table_ptr_s { const translation_info_t *table; size_t table_length; const char *plugin_instance; }; typedef struct translation_table_ptr_s translation_table_ptr_t; struct list_info_ptr_s { const char *plugin_instance; const char *type; }; typedef struct list_info_ptr_s list_info_ptr_t; /* FIXME: Enabled by default for backwards compatibility. */ /* TODO: Remove time parsing code. */ static _Bool config_parse_time = 1; static char *url = NULL; static int global_opcodes = 1; static int global_qtypes = 1; static int global_server_stats = 1; static int global_zone_maint_stats = 1; static int global_resolver_stats = 0; static int global_memory_stats = 1; static cb_view_t *views = NULL; static size_t views_num = 0; static CURL *curl = NULL; static char *bind_buffer = NULL; static size_t bind_buffer_size = 0; static size_t bind_buffer_fill = 0; static char bind_curl_error[CURL_ERROR_SIZE]; /* Translation table for the `nsstats' values. */ static const translation_info_t nsstats_translation_table[] = /* {{{ */ { /* Requests */ { "Requestv4", "dns_request", "IPv4" }, { "Requestv6", "dns_request", "IPv6" }, { "ReqEdns0", "dns_request", "EDNS0" }, { "ReqBadEDNSVer", "dns_request", "BadEDNSVer" }, { "ReqTSIG", "dns_request", "TSIG" }, { "ReqSIG0", "dns_request", "SIG0" }, { "ReqBadSIG", "dns_request", "BadSIG" }, { "ReqTCP", "dns_request", "TCP" }, /* Rejects */ { "AuthQryRej", "dns_reject", "authorative" }, { "RecQryRej", "dns_reject", "recursive" }, { "XfrRej", "dns_reject", "transfer" }, { "UpdateRej", "dns_reject", "update" }, /* Responses */ { "Response", "dns_response", "normal" }, { "TruncatedResp", "dns_response", "truncated" }, { "RespEDNS0", "dns_response", "EDNS0" }, { "RespTSIG", "dns_response", "TSIG" }, { "RespSIG0", "dns_response", "SIG0" }, /* Queries */ { "QryAuthAns", "dns_query", "authorative" }, { "QryNoauthAns", "dns_query", "nonauth" }, { "QryReferral", "dns_query", "referral" }, { "QryRecursion", "dns_query", "recursion" }, { "QryDuplicate", "dns_query", "dupliate" }, { "QryDropped", "dns_query", "dropped" }, { "QryFailure", "dns_query", "failure" }, /* Response codes */ { "QrySuccess", "dns_rcode", "tx-NOERROR" }, { "QryNxrrset", "dns_rcode", "tx-NXRRSET" }, { "QrySERVFAIL", "dns_rcode", "tx-SERVFAIL" }, { "QryFORMERR", "dns_rcode", "tx-FORMERR" }, { "QryNXDOMAIN", "dns_rcode", "tx-NXDOMAIN" } #if 0 { "XfrReqDone", "type", "type_instance" }, { "UpdateReqFwd", "type", "type_instance" }, { "UpdateRespFwd", "type", "type_instance" }, { "UpdateFwdFail", "type", "type_instance" }, { "UpdateDone", "type", "type_instance" }, { "UpdateFail", "type", "type_instance" }, { "UpdateBadPrereq", "type", "type_instance" }, #endif }; static int nsstats_translation_table_length = STATIC_ARRAY_SIZE (nsstats_translation_table); /* }}} */ /* Translation table for the `zonestats' values. */ static const translation_info_t zonestats_translation_table[] = /* {{{ */ { /* Notify's */ { "NotifyOutv4", "dns_notify", "tx-IPv4" }, { "NotifyOutv6", "dns_notify", "tx-IPv6" }, { "NotifyInv4", "dns_notify", "rx-IPv4" }, { "NotifyInv6", "dns_notify", "rx-IPv6" }, { "NotifyRej", "dns_notify", "rejected" }, /* SOA/AXFS/IXFS requests */ { "SOAOutv4", "dns_opcode", "SOA-IPv4" }, { "SOAOutv6", "dns_opcode", "SOA-IPv6" }, { "AXFRReqv4", "dns_opcode", "AXFR-IPv4" }, { "AXFRReqv6", "dns_opcode", "AXFR-IPv6" }, { "IXFRReqv4", "dns_opcode", "IXFR-IPv4" }, { "IXFRReqv6", "dns_opcode", "IXFR-IPv6" }, /* Domain transfers */ { "XfrSuccess", "dns_transfer", "success" }, { "XfrFail", "dns_transfer", "failure" } }; static int zonestats_translation_table_length = STATIC_ARRAY_SIZE (zonestats_translation_table); /* }}} */ /* Translation table for the `resstats' values. */ static const translation_info_t resstats_translation_table[] = /* {{{ */ { /* Generic resolver information */ { "Queryv4", "dns_query", "IPv4" }, { "Queryv6", "dns_query", "IPv6" }, { "Responsev4", "dns_response", "IPv4" }, { "Responsev6", "dns_response", "IPv6" }, /* Received response codes */ { "NXDOMAIN", "dns_rcode", "rx-NXDOMAIN" }, { "SERVFAIL", "dns_rcode", "rx-SERVFAIL" }, { "FORMERR", "dns_rcode", "rx-FORMERR" }, { "OtherError", "dns_rcode", "rx-OTHER" }, { "EDNS0Fail", "dns_rcode", "rx-EDNS0Fail"}, /* Received responses */ { "Mismatch", "dns_response", "mismatch" }, { "Truncated", "dns_response", "truncated" }, { "Lame", "dns_response", "lame" }, { "Retry", "dns_query", "retry" }, #if 0 { "GlueFetchv4", "type", "type_instance" }, { "GlueFetchv6", "type", "type_instance" }, { "GlueFetchv4Fail", "type", "type_instance" }, { "GlueFetchv6Fail", "type", "type_instance" }, #endif /* DNSSEC information */ { "ValAttempt", "dns_resolver", "DNSSEC-attempt" }, { "ValOk", "dns_resolver", "DNSSEC-okay" }, { "ValNegOk", "dns_resolver", "DNSSEC-negokay" }, { "ValFail", "dns_resolver", "DNSSEC-fail" } }; static int resstats_translation_table_length = STATIC_ARRAY_SIZE (resstats_translation_table); /* }}} */ /* Translation table for the `memory/summary' values. */ static const translation_info_t memsummary_translation_table[] = /* {{{ */ { { "TotalUse", "memory", "TotalUse" }, { "InUse", "memory", "InUse" }, { "BlockSize", "memory", "BlockSize" }, { "ContextSize", "memory", "ContextSize" }, { "Lost", "memory", "Lost" } }; static int memsummary_translation_table_length = STATIC_ARRAY_SIZE (memsummary_translation_table); /* }}} */ static void submit (time_t ts, const char *plugin_instance, /* {{{ */ const char *type, const char *type_instance, value_t value) { value_t values[1]; value_list_t vl = VALUE_LIST_INIT; values[0] = value; vl.values = values; vl.values_len = 1; if (config_parse_time) vl.time = TIME_T_TO_CDTIME_T (ts); sstrncpy(vl.host, hostname_g, sizeof(vl.host)); sstrncpy(vl.plugin, "bind", sizeof(vl.plugin)); if (plugin_instance) { sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); replace_special (vl.plugin_instance, sizeof (vl.plugin_instance)); } sstrncpy(vl.type, type, sizeof(vl.type)); if (type_instance) { sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); replace_special (vl.plugin_instance, sizeof (vl.plugin_instance)); } plugin_dispatch_values(&vl); } /* }}} void submit */ static size_t bind_curl_callback (void *buf, size_t size, /* {{{ */ size_t nmemb, void __attribute__((unused)) *stream) { size_t len = size * nmemb; if (len <= 0) return (len); if ((bind_buffer_fill + len) >= bind_buffer_size) { char *temp; temp = realloc(bind_buffer, bind_buffer_fill + len + 1); if (temp == NULL) { ERROR ("bind plugin: realloc failed."); return (0); } bind_buffer = temp; bind_buffer_size = bind_buffer_fill + len + 1; } memcpy (bind_buffer + bind_buffer_fill, (char *) buf, len); bind_buffer_fill += len; bind_buffer[bind_buffer_fill] = 0; return (len); } /* }}} size_t bind_curl_callback */ /* * Callback, that's called with a translation table. * (Plugin instance is fixed, type and type instance come from lookup table.) */ static int bind_xml_table_callback (const char *name, value_t value, /* {{{ */ time_t current_time, void *user_data) { translation_table_ptr_t *table = (translation_table_ptr_t *) user_data; size_t i; if (table == NULL) return (-1); for (i = 0; i < table->table_length; i++) { if (strcmp (table->table[i].xml_name, name) != 0) continue; submit (current_time, table->plugin_instance, table->table[i].type, table->table[i].type_instance, value); break; } return (0); } /* }}} int bind_xml_table_callback */ /* * Callback, that's used for lists. * (Plugin instance and type are fixed, xml name is used as type instance.) */ static int bind_xml_list_callback (const char *name, /* {{{ */ value_t value, time_t current_time, void *user_data) { list_info_ptr_t *list_info = (list_info_ptr_t *) user_data; if (list_info == NULL) return (-1); submit (current_time, list_info->plugin_instance, list_info->type, /* type instance = */ name, value); return (0); } /* }}} int bind_xml_list_callback */ static int bind_xml_read_derive (xmlDoc *doc, xmlNode *node, /* {{{ */ derive_t *ret_value) { char *str_ptr; value_t value; int status; str_ptr = (char *) xmlNodeListGetString (doc, node->xmlChildrenNode, 1); if (str_ptr == NULL) { ERROR ("bind plugin: bind_xml_read_derive: xmlNodeListGetString failed."); return (-1); } status = parse_value (str_ptr, &value, DS_TYPE_DERIVE); if (status != 0) { ERROR ("bind plugin: Parsing string \"%s\" to derive value failed.", str_ptr); return (-1); } *ret_value = value.derive; return (0); } /* }}} int bind_xml_read_derive */ static int bind_xml_read_gauge (xmlDoc *doc, xmlNode *node, /* {{{ */ gauge_t *ret_value) { char *str_ptr, *end_ptr; double value; str_ptr = (char *) xmlNodeListGetString (doc, node->xmlChildrenNode, 1); if (str_ptr == NULL) { ERROR ("bind plugin: bind_xml_read_gauge: xmlNodeListGetString failed."); return (-1); } errno = 0; value = strtod (str_ptr, &end_ptr); xmlFree(str_ptr); if (str_ptr == end_ptr || errno) { if (errno && (value < 0)) ERROR ("bind plugin: bind_xml_read_gauge: strtod failed with underflow."); else if (errno && (value > 0)) ERROR ("bind plugin: bind_xml_read_gauge: strtod failed with overflow."); else ERROR ("bind plugin: bind_xml_read_gauge: strtod failed."); return (-1); } *ret_value = (gauge_t) value; return (0); } /* }}} int bind_xml_read_gauge */ static int bind_xml_read_timestamp (const char *xpath_expression, /* {{{ */ xmlDoc *doc, xmlXPathContext *xpathCtx, time_t *ret_value) { xmlXPathObject *xpathObj = NULL; xmlNode *node; char *str_ptr; char *tmp; struct tm tm; xpathObj = xmlXPathEvalExpression (BAD_CAST xpath_expression, xpathCtx); if (xpathObj == NULL) { ERROR ("bind plugin: Unable to evaluate XPath expression `%s'.", xpath_expression); return (-1); } if ((xpathObj->nodesetval == NULL) || (xpathObj->nodesetval->nodeNr < 1)) { xmlXPathFreeObject (xpathObj); return (-1); } if (xpathObj->nodesetval->nodeNr != 1) { NOTICE ("bind plugin: Evaluating the XPath expression `%s' returned " "%i nodes. Only handling the first one.", xpath_expression, xpathObj->nodesetval->nodeNr); } node = xpathObj->nodesetval->nodeTab[0]; if (node->xmlChildrenNode == NULL) { ERROR ("bind plugin: bind_xml_read_timestamp: " "node->xmlChildrenNode == NULL"); xmlXPathFreeObject (xpathObj); return (-1); } str_ptr = (char *) xmlNodeListGetString (doc, node->xmlChildrenNode, 1); if (str_ptr == NULL) { ERROR ("bind plugin: bind_xml_read_timestamp: xmlNodeListGetString failed."); xmlXPathFreeObject (xpathObj); return (-1); } memset (&tm, 0, sizeof(tm)); tmp = strptime (str_ptr, "%Y-%m-%dT%T", &tm); xmlFree(str_ptr); if (tmp == NULL) { ERROR ("bind plugin: bind_xml_read_timestamp: strptime failed."); xmlXPathFreeObject (xpathObj); return (-1); } *ret_value = mktime(&tm); xmlXPathFreeObject (xpathObj); return (0); } /* }}} int bind_xml_read_timestamp */ /* * bind_parse_generic_name_value * * Reads statistics in the form: * * QUERY * 123 * */ static int bind_parse_generic_name_value (const char *xpath_expression, /* {{{ */ list_callback_t list_callback, void *user_data, xmlDoc *doc, xmlXPathContext *xpathCtx, time_t current_time, int ds_type) { xmlXPathObject *xpathObj = NULL; int num_entries; int i; xpathObj = xmlXPathEvalExpression(BAD_CAST xpath_expression, xpathCtx); if (xpathObj == NULL) { ERROR("bind plugin: Unable to evaluate XPath expression `%s'.", xpath_expression); return (-1); } num_entries = 0; /* Iterate over all matching nodes. */ for (i = 0; xpathObj->nodesetval && (i < xpathObj->nodesetval->nodeNr); i++) { xmlNode *name_node = NULL; xmlNode *counter = NULL; xmlNode *parent; xmlNode *child; parent = xpathObj->nodesetval->nodeTab[i]; DEBUG ("bind plugin: bind_parse_generic_name_value: parent->name = %s;", (char *) parent->name); /* Iterate over all child nodes. */ for (child = parent->xmlChildrenNode; child != NULL; child = child->next) { if (child->type != XML_ELEMENT_NODE) continue; if (xmlStrcmp (BAD_CAST "name", child->name) == 0) name_node = child; else if (xmlStrcmp (BAD_CAST "counter", child->name) == 0) counter = child; } if ((name_node != NULL) && (counter != NULL)) { char *name = (char *) xmlNodeListGetString (doc, name_node->xmlChildrenNode, 1); value_t value; int status; if (ds_type == DS_TYPE_GAUGE) status = bind_xml_read_gauge (doc, counter, &value.gauge); else status = bind_xml_read_derive (doc, counter, &value.derive); if (status != 0) continue; status = (*list_callback) (name, value, current_time, user_data); if (status == 0) num_entries++; xmlFree (name); } } DEBUG ("bind plugin: Found %d %s for XPath expression `%s'", num_entries, (num_entries == 1) ? "entry" : "entries", xpath_expression); xmlXPathFreeObject(xpathObj); return (0); } /* }}} int bind_parse_generic_name_value */ /* * bind_parse_generic_value_list * * Reads statistics in the form: * * 123 * 234 * 345 * : * */ static int bind_parse_generic_value_list (const char *xpath_expression, /* {{{ */ list_callback_t list_callback, void *user_data, xmlDoc *doc, xmlXPathContext *xpathCtx, time_t current_time, int ds_type) { xmlXPathObject *xpathObj = NULL; int num_entries; int i; xpathObj = xmlXPathEvalExpression(BAD_CAST xpath_expression, xpathCtx); if (xpathObj == NULL) { ERROR("bind plugin: Unable to evaluate XPath expression `%s'.", xpath_expression); return (-1); } num_entries = 0; /* Iterate over all matching nodes. */ for (i = 0; xpathObj->nodesetval && (i < xpathObj->nodesetval->nodeNr); i++) { xmlNode *child; /* Iterate over all child nodes. */ for (child = xpathObj->nodesetval->nodeTab[i]->xmlChildrenNode; child != NULL; child = child->next) { char *node_name; value_t value; int status; if (child->type != XML_ELEMENT_NODE) continue; node_name = (char *) child->name; if (ds_type == DS_TYPE_GAUGE) status = bind_xml_read_gauge (doc, child, &value.gauge); else status = bind_xml_read_derive (doc, child, &value.derive); if (status != 0) continue; status = (*list_callback) (node_name, value, current_time, user_data); if (status == 0) num_entries++; } } DEBUG ("bind plugin: Found %d %s for XPath expression `%s'", num_entries, (num_entries == 1) ? "entry" : "entries", xpath_expression); xmlXPathFreeObject(xpathObj); return (0); } /* }}} int bind_parse_generic_value_list */ static int bind_xml_stats_handle_zone (int version, xmlDoc *doc, /* {{{ */ xmlXPathContext *path_ctx, xmlNode *node, cb_view_t *view, time_t current_time) { xmlXPathObject *path_obj; char *zone_name = NULL; int i; size_t j; path_obj = xmlXPathEvalExpression (BAD_CAST "name", path_ctx); if (path_obj == NULL) { ERROR ("bind plugin: xmlXPathEvalExpression failed."); return (-1); } for (i = 0; path_obj->nodesetval && (i < path_obj->nodesetval->nodeNr); i++) { zone_name = (char *) xmlNodeListGetString (doc, path_obj->nodesetval->nodeTab[i]->xmlChildrenNode, 1); if (zone_name != NULL) break; } if (zone_name == NULL) { ERROR ("bind plugin: Could not determine zone name."); xmlXPathFreeObject (path_obj); return (-1); } for (j = 0; j < view->zones_num; j++) { if (strcasecmp (zone_name, view->zones[j]) == 0) break; } xmlFree (zone_name); zone_name = NULL; if (j >= views_num) { xmlXPathFreeObject (path_obj); return (0); } zone_name = view->zones[j]; DEBUG ("bind plugin: bind_xml_stats_handle_zone: Found zone `%s'.", zone_name); { /* Parse the tag {{{ */ char plugin_instance[DATA_MAX_NAME_LEN]; translation_table_ptr_t table_ptr = { nsstats_translation_table, nsstats_translation_table_length, plugin_instance }; ssnprintf (plugin_instance, sizeof (plugin_instance), "%s-zone-%s", view->name, zone_name); bind_parse_generic_value_list (/* xpath = */ "counters", /* callback = */ bind_xml_table_callback, /* user_data = */ &table_ptr, doc, path_ctx, current_time, DS_TYPE_COUNTER); } /* }}} */ xmlXPathFreeObject (path_obj); return (0); } /* }}} int bind_xml_stats_handle_zone */ static int bind_xml_stats_search_zones (int version, xmlDoc *doc, /* {{{ */ xmlXPathContext *path_ctx, xmlNode *node, cb_view_t *view, time_t current_time) { xmlXPathObject *zone_nodes = NULL; xmlXPathContext *zone_path_context; int i; zone_path_context = xmlXPathNewContext (doc); if (zone_path_context == NULL) { ERROR ("bind plugin: xmlXPathNewContext failed."); return (-1); } zone_nodes = xmlXPathEvalExpression (BAD_CAST "zones/zone", path_ctx); if (zone_nodes == NULL) { ERROR ("bind plugin: Cannot find any tags."); xmlXPathFreeContext (zone_path_context); return (-1); } for (i = 0; i < zone_nodes->nodesetval->nodeNr; i++) { xmlNode *node; node = zone_nodes->nodesetval->nodeTab[i]; assert (node != NULL); zone_path_context->node = node; bind_xml_stats_handle_zone (version, doc, zone_path_context, node, view, current_time); } xmlXPathFreeObject (zone_nodes); xmlXPathFreeContext (zone_path_context); return (0); } /* }}} int bind_xml_stats_search_zones */ static int bind_xml_stats_handle_view (int version, xmlDoc *doc, /* {{{ */ xmlXPathContext *path_ctx, xmlNode *node, time_t current_time) { xmlXPathObject *path_obj; char *view_name = NULL; cb_view_t *view; int i; size_t j; path_obj = xmlXPathEvalExpression (BAD_CAST "name", path_ctx); if (path_obj == NULL) { ERROR ("bind plugin: xmlXPathEvalExpression failed."); return (-1); } for (i = 0; path_obj->nodesetval && (i < path_obj->nodesetval->nodeNr); i++) { view_name = (char *) xmlNodeListGetString (doc, path_obj->nodesetval->nodeTab[i]->xmlChildrenNode, 1); if (view_name != NULL) break; } if (view_name == NULL) { ERROR ("bind plugin: Could not determine view name."); xmlXPathFreeObject (path_obj); return (-1); } for (j = 0; j < views_num; j++) { if (strcasecmp (view_name, views[j].name) == 0) break; } xmlFree (view_name); xmlXPathFreeObject (path_obj); view_name = NULL; path_obj = NULL; if (j >= views_num) return (0); view = views + j; DEBUG ("bind plugin: bind_xml_stats_handle_view: Found view `%s'.", view->name); if (view->qtypes != 0) /* {{{ */ { char plugin_instance[DATA_MAX_NAME_LEN]; list_info_ptr_t list_info = { plugin_instance, /* type = */ "dns_qtype" }; ssnprintf (plugin_instance, sizeof (plugin_instance), "%s-qtypes", view->name); bind_parse_generic_name_value (/* xpath = */ "rdtype", /* callback = */ bind_xml_list_callback, /* user_data = */ &list_info, doc, path_ctx, current_time, DS_TYPE_COUNTER); } /* }}} */ if (view->resolver_stats != 0) /* {{{ */ { char plugin_instance[DATA_MAX_NAME_LEN]; translation_table_ptr_t table_ptr = { resstats_translation_table, resstats_translation_table_length, plugin_instance }; ssnprintf (plugin_instance, sizeof (plugin_instance), "%s-resolver_stats", view->name); bind_parse_generic_name_value ("resstat", /* callback = */ bind_xml_table_callback, /* user_data = */ &table_ptr, doc, path_ctx, current_time, DS_TYPE_COUNTER); } /* }}} */ /* Record types in the cache */ if (view->cacherrsets != 0) /* {{{ */ { char plugin_instance[DATA_MAX_NAME_LEN]; list_info_ptr_t list_info = { plugin_instance, /* type = */ "dns_qtype_cached" }; ssnprintf (plugin_instance, sizeof (plugin_instance), "%s-cache_rr_sets", view->name); bind_parse_generic_name_value (/* xpath = */ "cache/rrset", /* callback = */ bind_xml_list_callback, /* user_data = */ &list_info, doc, path_ctx, current_time, DS_TYPE_GAUGE); } /* }}} */ if (view->zones_num > 0) bind_xml_stats_search_zones (version, doc, path_ctx, node, view, current_time); return (0); } /* }}} int bind_xml_stats_handle_view */ static int bind_xml_stats_search_views (int version, xmlDoc *doc, /* {{{ */ xmlXPathContext *xpathCtx, xmlNode *statsnode, time_t current_time) { xmlXPathObject *view_nodes = NULL; xmlXPathContext *view_path_context; int i; view_path_context = xmlXPathNewContext (doc); if (view_path_context == NULL) { ERROR ("bind plugin: xmlXPathNewContext failed."); return (-1); } view_nodes = xmlXPathEvalExpression (BAD_CAST "views/view", xpathCtx); if (view_nodes == NULL) { ERROR ("bind plugin: Cannot find any tags."); xmlXPathFreeContext (view_path_context); return (-1); } for (i = 0; i < view_nodes->nodesetval->nodeNr; i++) { xmlNode *node; node = view_nodes->nodesetval->nodeTab[i]; assert (node != NULL); view_path_context->node = node; bind_xml_stats_handle_view (version, doc, view_path_context, node, current_time); } xmlXPathFreeObject (view_nodes); xmlXPathFreeContext (view_path_context); return (0); } /* }}} int bind_xml_stats_search_views */ static int bind_xml_stats (int version, xmlDoc *doc, /* {{{ */ xmlXPathContext *xpathCtx, xmlNode *statsnode) { time_t current_time = 0; int status; xpathCtx->node = statsnode; /* TODO: Check `server/boot-time' to recognize server restarts. */ status = bind_xml_read_timestamp ("server/current-time", doc, xpathCtx, ¤t_time); if (status != 0) { ERROR ("bind plugin: Reading `server/current-time' failed."); return (-1); } DEBUG ("bind plugin: Current server time is %i.", (int) current_time); /* XPath: server/requests/opcode * Variables: QUERY, IQUERY, NOTIFY, UPDATE, ... * Layout: * * A * 1 * * : */ if (global_opcodes != 0) { list_info_ptr_t list_info = { /* plugin instance = */ "global-opcodes", /* type = */ "dns_opcode" }; bind_parse_generic_name_value (/* xpath = */ "server/requests/opcode", /* callback = */ bind_xml_list_callback, /* user_data = */ &list_info, doc, xpathCtx, current_time, DS_TYPE_COUNTER); } /* XPath: server/queries-in/rdtype * Variables: RESERVED0, A, NS, CNAME, SOA, MR, PTR, HINFO, MX, TXT, RP, * X25, PX, AAAA, LOC, SRV, NAPTR, A6, DS, RRSIG, NSEC, DNSKEY, * SPF, TKEY, IXFR, AXFR, ANY, ..., Others * Layout: * * A * 1 * * : */ if (global_qtypes != 0) { list_info_ptr_t list_info = { /* plugin instance = */ "global-qtypes", /* type = */ "dns_qtype" }; bind_parse_generic_name_value (/* xpath = */ "server/queries-in/rdtype", /* callback = */ bind_xml_list_callback, /* user_data = */ &list_info, doc, xpathCtx, current_time, DS_TYPE_COUNTER); } /* XPath: server/nsstats, server/nsstat * Variables: Requestv4, Requestv6, ReqEdns0, ReqBadEDNSVer, ReqTSIG, * ReqSIG0, ReqBadSIG, ReqTCP, AuthQryRej, RecQryRej, XfrRej, * UpdateRej, Response, TruncatedResp, RespEDNS0, RespTSIG, * RespSIG0, QrySuccess, QryAuthAns, QryNoauthAns, QryReferral, * QryNxrrset, QrySERVFAIL, QryFORMERR, QryNXDOMAIN, QryRecursion, * QryDuplicate, QryDropped, QryFailure, XfrReqDone, UpdateReqFwd, * UpdateRespFwd, UpdateFwdFail, UpdateDone, UpdateFail, * UpdateBadPrereq * Layout v1: * * 1 * 0 * : * * Layout v2: * * Requestv4 * 1 * * * Requestv6 * 0 * * : */ if (global_server_stats) { translation_table_ptr_t table_ptr = { nsstats_translation_table, nsstats_translation_table_length, /* plugin_instance = */ "global-server_stats" }; if (version == 1) { bind_parse_generic_value_list ("server/nsstats", /* callback = */ bind_xml_table_callback, /* user_data = */ &table_ptr, doc, xpathCtx, current_time, DS_TYPE_COUNTER); } else { bind_parse_generic_name_value ("server/nsstat", /* callback = */ bind_xml_table_callback, /* user_data = */ &table_ptr, doc, xpathCtx, current_time, DS_TYPE_COUNTER); } } /* XPath: server/zonestats, server/zonestat * Variables: NotifyOutv4, NotifyOutv6, NotifyInv4, NotifyInv6, NotifyRej, * SOAOutv4, SOAOutv6, AXFRReqv4, AXFRReqv6, IXFRReqv4, IXFRReqv6, * XfrSuccess, XfrFail * Layout v1: * * 0 * 0 * : * * Layout v2: * * NotifyOutv4 * 0 * * * NotifyOutv6 * 0 * * : */ if (global_zone_maint_stats) { translation_table_ptr_t table_ptr = { zonestats_translation_table, zonestats_translation_table_length, /* plugin_instance = */ "global-zone_maint_stats" }; if (version == 1) { bind_parse_generic_value_list ("server/zonestats", /* callback = */ bind_xml_table_callback, /* user_data = */ &table_ptr, doc, xpathCtx, current_time, DS_TYPE_COUNTER); } else { bind_parse_generic_name_value ("server/zonestat", /* callback = */ bind_xml_table_callback, /* user_data = */ &table_ptr, doc, xpathCtx, current_time, DS_TYPE_COUNTER); } } /* XPath: server/resstats * Variables: Queryv4, Queryv6, Responsev4, Responsev6, NXDOMAIN, SERVFAIL, * FORMERR, OtherError, EDNS0Fail, Mismatch, Truncated, Lame, * Retry, GlueFetchv4, GlueFetchv6, GlueFetchv4Fail, * GlueFetchv6Fail, ValAttempt, ValOk, ValNegOk, ValFail * Layout v1: * * 0 * 0 * : * * Layout v2: * * Queryv4 * 0 * * * Queryv6 * 0 * * : */ if (global_resolver_stats != 0) { translation_table_ptr_t table_ptr = { resstats_translation_table, resstats_translation_table_length, /* plugin_instance = */ "global-resolver_stats" }; if (version == 1) { bind_parse_generic_value_list ("server/resstats", /* callback = */ bind_xml_table_callback, /* user_data = */ &table_ptr, doc, xpathCtx, current_time, DS_TYPE_COUNTER); } else { bind_parse_generic_name_value ("server/resstat", /* callback = */ bind_xml_table_callback, /* user_data = */ &table_ptr, doc, xpathCtx, current_time, DS_TYPE_COUNTER); } } /* XPath: memory/summary * Variables: TotalUse, InUse, BlockSize, ContextSize, Lost * Layout: v2: * * 6587096 * 1345424 * 5505024 * 3732456 * 0 * */ if (global_memory_stats != 0) { translation_table_ptr_t table_ptr = { memsummary_translation_table, memsummary_translation_table_length, /* plugin_instance = */ "global-memory_stats" }; bind_parse_generic_value_list ("memory/summary", /* callback = */ bind_xml_table_callback, /* user_data = */ &table_ptr, doc, xpathCtx, current_time, DS_TYPE_GAUGE); } if (views_num > 0) bind_xml_stats_search_views (version, doc, xpathCtx, statsnode, current_time); return 0; } /* }}} int bind_xml_stats */ static int bind_xml (const char *data) /* {{{ */ { xmlDoc *doc = NULL; xmlXPathContext *xpathCtx = NULL; xmlXPathObject *xpathObj = NULL; int ret = -1; int i; doc = xmlParseMemory (data, strlen (data)); if (doc == NULL) { ERROR ("bind plugin: xmlParseMemory failed."); return (-1); } xpathCtx = xmlXPathNewContext (doc); if (xpathCtx == NULL) { ERROR ("bind plugin: xmlXPathNewContext failed."); xmlFreeDoc (doc); return (-1); } xpathObj = xmlXPathEvalExpression (BAD_CAST "/isc/bind/statistics", xpathCtx); if (xpathObj == NULL) { ERROR ("bind plugin: Cannot find the tag."); xmlXPathFreeContext (xpathCtx); xmlFreeDoc (doc); return (-1); } else if (xpathObj->nodesetval == NULL) { ERROR ("bind plugin: xmlXPathEvalExpression failed."); xmlXPathFreeObject (xpathObj); xmlXPathFreeContext (xpathCtx); xmlFreeDoc (doc); return (-1); } for (i = 0; i < xpathObj->nodesetval->nodeNr; i++) { xmlNode *node; char *attr_version; int parsed_version = 0; node = xpathObj->nodesetval->nodeTab[i]; assert (node != NULL); attr_version = (char *) xmlGetProp (node, BAD_CAST "version"); if (attr_version == NULL) { NOTICE ("bind plugin: Found tag doesn't have a " "`version' attribute."); continue; } DEBUG ("bind plugin: Found: ", attr_version); /* At the time this plugin was written, version "1.0" was used by * BIND 9.5.0, version "2.0" was used by BIND 9.5.1 and 9.6.0. We assume * that "1.*" and "2.*" don't introduce structural changes, so we just * check for the first two characters here. */ if (strncmp ("1.", attr_version, strlen ("1.")) == 0) parsed_version = 1; else if (strncmp ("2.", attr_version, strlen ("2.")) == 0) parsed_version = 2; else { /* TODO: Use the complaint mechanism here. */ NOTICE ("bind plugin: Found tag with version `%s'. " "Unfortunately I have no clue how to parse that. " "Please open a bug report for this.", attr_version); xmlFree (attr_version); continue; } ret = bind_xml_stats (parsed_version, doc, xpathCtx, node); xmlFree (attr_version); /* One node ought to be enough. */ break; } xmlXPathFreeObject (xpathObj); xmlXPathFreeContext (xpathCtx); xmlFreeDoc (doc); return (ret); } /* }}} int bind_xml */ static int bind_config_set_bool (const char *name, int *var, /* {{{ */ oconfig_item_t *ci) { if ((ci->values_num != 1) || ( ci->values[0].type != OCONFIG_TYPE_BOOLEAN)) { WARNING ("bind plugin: The `%s' option needs " "exactly one boolean argument.", name); return (-1); } if (ci->values[0].value.boolean) *var = 1; else *var = 0; return 0; } /* }}} int bind_config_set_bool */ static int bind_config_add_view_zone (cb_view_t *view, /* {{{ */ oconfig_item_t *ci) { char **tmp; if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { WARNING ("bind plugin: The `Zone' option needs " "exactly one string argument."); return (-1); } tmp = (char **) realloc (view->zones, sizeof (char *) * (view->zones_num + 1)); if (tmp == NULL) { ERROR ("bind plugin: realloc failed."); return (-1); } view->zones = tmp; view->zones[view->zones_num] = strdup (ci->values[0].value.string); if (view->zones[view->zones_num] == NULL) { ERROR ("bind plugin: strdup failed."); return (-1); } view->zones_num++; return (0); } /* }}} int bind_config_add_view_zone */ static int bind_config_add_view (oconfig_item_t *ci) /* {{{ */ { cb_view_t *tmp; int i; if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { WARNING ("bind plugin: `View' blocks need exactly one string argument."); return (-1); } tmp = (cb_view_t *) realloc (views, sizeof (*views) * (views_num + 1)); if (tmp == NULL) { ERROR ("bind plugin: realloc failed."); return (-1); } views = tmp; tmp = views + views_num; memset (tmp, 0, sizeof (*tmp)); tmp->qtypes = 1; tmp->resolver_stats = 1; tmp->cacherrsets = 1; tmp->zones = NULL; tmp->zones_num = 0; tmp->name = strdup (ci->values[0].value.string); if (tmp->name == NULL) { ERROR ("bind plugin: strdup failed."); free (tmp); return (-1); } for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("QTypes", child->key) == 0) bind_config_set_bool ("QTypes", &tmp->qtypes, child); else if (strcasecmp ("ResolverStats", child->key) == 0) bind_config_set_bool ("ResolverStats", &tmp->resolver_stats, child); else if (strcasecmp ("CacheRRSets", child->key) == 0) bind_config_set_bool ("CacheRRSets", &tmp->cacherrsets, child); else if (strcasecmp ("Zone", child->key) == 0) bind_config_add_view_zone (tmp, child); else { WARNING ("bind plugin: Unknown configuration option " "`%s' in view `%s' will be ignored.", child->key, tmp->name); } } /* for (i = 0; i < ci->children_num; i++) */ views_num++; return (0); } /* }}} int bind_config_add_view */ static int bind_config (oconfig_item_t *ci) /* {{{ */ { int i; for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("Url", child->key) == 0) { if ((child->values_num != 1) || (child->values[0].type != OCONFIG_TYPE_STRING)) { WARNING ("bind plugin: The `Url' option needs " "exactly one string argument."); return (-1); } url = strdup (child->values[0].value.string); } else if (strcasecmp ("OpCodes", child->key) == 0) bind_config_set_bool ("OpCodes", &global_opcodes, child); else if (strcasecmp ("QTypes", child->key) == 0) bind_config_set_bool ("QTypes", &global_qtypes, child); else if (strcasecmp ("ServerStats", child->key) == 0) bind_config_set_bool ("ServerStats", &global_server_stats, child); else if (strcasecmp ("ZoneMaintStats", child->key) == 0) bind_config_set_bool ("ZoneMaintStats", &global_zone_maint_stats, child); else if (strcasecmp ("ResolverStats", child->key) == 0) bind_config_set_bool ("ResolverStats", &global_resolver_stats, child); else if (strcasecmp ("MemoryStats", child->key) == 0) bind_config_set_bool ("MemoryStats", &global_memory_stats, child); else if (strcasecmp ("View", child->key) == 0) bind_config_add_view (child); else if (strcasecmp ("ParseTime", child->key) == 0) cf_util_get_boolean (child, &config_parse_time); else { WARNING ("bind plugin: Unknown configuration option " "`%s' will be ignored.", child->key); } } return (0); } /* }}} int bind_config */ static int bind_init (void) /* {{{ */ { if (curl != NULL) return (0); curl = curl_easy_init (); if (curl == NULL) { ERROR ("bind plugin: bind_init: curl_easy_init failed."); return (-1); } curl_easy_setopt (curl, CURLOPT_NOSIGNAL, 1L); curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, bind_curl_callback); curl_easy_setopt (curl, CURLOPT_USERAGENT, PACKAGE_NAME"/"PACKAGE_VERSION); curl_easy_setopt (curl, CURLOPT_ERRORBUFFER, bind_curl_error); curl_easy_setopt (curl, CURLOPT_URL, (url != NULL) ? url : BIND_DEFAULT_URL); curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt (curl, CURLOPT_MAXREDIRS, 50L); return (0); } /* }}} int bind_init */ static int bind_read (void) /* {{{ */ { int status; if (curl == NULL) { ERROR ("bind plugin: I don't have a CURL object."); return (-1); } bind_buffer_fill = 0; if (curl_easy_perform (curl) != CURLE_OK) { ERROR ("bind plugin: curl_easy_perform failed: %s", bind_curl_error); return (-1); } status = bind_xml (bind_buffer); if (status != 0) return (-1); else return (0); } /* }}} int bind_read */ static int bind_shutdown (void) /* {{{ */ { if (curl != NULL) { curl_easy_cleanup (curl); curl = NULL; } return (0); } /* }}} int bind_shutdown */ void module_register (void) { plugin_register_complex_config ("bind", bind_config); plugin_register_init ("bind", bind_init); plugin_register_read ("bind", bind_read); plugin_register_shutdown ("bind", bind_shutdown); } /* void module_register */ /* vim: set sw=2 sts=2 ts=8 et fdm=marker : */ collectd-5.4.0/src/PaxHeaders.11991/curl.c0000644037772200116100000000013212204120331016243 xustar000000000000000030 mtime=1376821465.069973376 30 atime=1376821477.214167866 30 ctime=1376821742.030401056 collectd-5.4.0/src/curl.c0000644037772200116100000004404512204120331015016 0ustar00octoeng00000000000000/** * collectd - src/curl.c * Copyright (C) 2006-2009 Florian octo Forster * Copyright (C) 2009 Aman Gupta * * 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: * Florian octo Forster * Aman Gupta **/ #include "collectd.h" #include "common.h" #include "plugin.h" #include "configfile.h" #include "utils_match.h" #include "utils_time.h" #include /* * Data types */ struct web_match_s; typedef struct web_match_s web_match_t; struct web_match_s /* {{{ */ { char *regex; char *exclude_regex; int dstype; char *type; char *instance; cu_match_t *match; web_match_t *next; }; /* }}} */ struct web_page_s; typedef struct web_page_s web_page_t; struct web_page_s /* {{{ */ { char *instance; char *url; char *user; char *pass; char *credentials; _Bool verify_peer; _Bool verify_host; char *cacert; struct curl_slist *headers; char *post_body; _Bool response_time; _Bool response_code; CURL *curl; char curl_errbuf[CURL_ERROR_SIZE]; char *buffer; size_t buffer_size; size_t buffer_fill; web_match_t *matches; web_page_t *next; }; /* }}} */ /* * Global variables; */ /* static CURLM *curl = NULL; */ static web_page_t *pages_g = NULL; /* * Private functions */ static size_t cc_curl_callback (void *buf, /* {{{ */ size_t size, size_t nmemb, void *user_data) { web_page_t *wp; size_t len; len = size * nmemb; if (len <= 0) return (len); wp = user_data; if (wp == NULL) return (0); if ((wp->buffer_fill + len) >= wp->buffer_size) { char *temp; size_t temp_size; temp_size = wp->buffer_fill + len + 1; temp = (char *) realloc (wp->buffer, temp_size); if (temp == NULL) { ERROR ("curl plugin: realloc failed."); return (0); } wp->buffer = temp; wp->buffer_size = temp_size; } memcpy (wp->buffer + wp->buffer_fill, (char *) buf, len); wp->buffer_fill += len; wp->buffer[wp->buffer_fill] = 0; return (len); } /* }}} size_t cc_curl_callback */ static void cc_web_match_free (web_match_t *wm) /* {{{ */ { if (wm == NULL) return; sfree (wm->regex); sfree (wm->type); sfree (wm->instance); match_destroy (wm->match); cc_web_match_free (wm->next); sfree (wm); } /* }}} void cc_web_match_free */ static void cc_web_page_free (web_page_t *wp) /* {{{ */ { if (wp == NULL) return; if (wp->curl != NULL) curl_easy_cleanup (wp->curl); wp->curl = NULL; sfree (wp->instance); sfree (wp->url); sfree (wp->user); sfree (wp->pass); sfree (wp->credentials); sfree (wp->cacert); sfree (wp->post_body); curl_slist_free_all (wp->headers); sfree (wp->buffer); cc_web_match_free (wp->matches); cc_web_page_free (wp->next); sfree (wp); } /* }}} void cc_web_page_free */ static int cc_config_append_string (const char *name, struct curl_slist **dest, /* {{{ */ oconfig_item_t *ci) { if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { WARNING ("curl plugin: `%s' needs exactly one string argument.", name); return (-1); } *dest = curl_slist_append(*dest, ci->values[0].value.string); if (*dest == NULL) return (-1); return (0); } /* }}} int cc_config_append_string */ static int cc_config_add_match_dstype (int *dstype_ret, /* {{{ */ oconfig_item_t *ci) { int dstype; if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { WARNING ("curl plugin: `DSType' needs exactly one string argument."); return (-1); } if (strncasecmp ("Gauge", ci->values[0].value.string, strlen ("Gauge")) == 0) { dstype = UTILS_MATCH_DS_TYPE_GAUGE; if (strcasecmp ("GaugeAverage", ci->values[0].value.string) == 0) dstype |= UTILS_MATCH_CF_GAUGE_AVERAGE; else if (strcasecmp ("GaugeMin", ci->values[0].value.string) == 0) dstype |= UTILS_MATCH_CF_GAUGE_MIN; else if (strcasecmp ("GaugeMax", ci->values[0].value.string) == 0) dstype |= UTILS_MATCH_CF_GAUGE_MAX; else if (strcasecmp ("GaugeLast", ci->values[0].value.string) == 0) dstype |= UTILS_MATCH_CF_GAUGE_LAST; else dstype = 0; } else if (strncasecmp ("Counter", ci->values[0].value.string, strlen ("Counter")) == 0) { dstype = UTILS_MATCH_DS_TYPE_COUNTER; if (strcasecmp ("CounterSet", ci->values[0].value.string) == 0) dstype |= UTILS_MATCH_CF_COUNTER_SET; else if (strcasecmp ("CounterAdd", ci->values[0].value.string) == 0) dstype |= UTILS_MATCH_CF_COUNTER_ADD; else if (strcasecmp ("CounterInc", ci->values[0].value.string) == 0) dstype |= UTILS_MATCH_CF_COUNTER_INC; else dstype = 0; } else if (strncasecmp ("Derive", ci->values[0].value.string, strlen ("Derive")) == 0) { dstype = UTILS_MATCH_DS_TYPE_DERIVE; if (strcasecmp ("DeriveSet", ci->values[0].value.string) == 0) dstype |= UTILS_MATCH_CF_DERIVE_SET; else if (strcasecmp ("DeriveAdd", ci->values[0].value.string) == 0) dstype |= UTILS_MATCH_CF_DERIVE_ADD; else if (strcasecmp ("DeriveInc", ci->values[0].value.string) == 0) dstype |= UTILS_MATCH_CF_DERIVE_INC; else dstype = 0; } else if (strncasecmp ("Absolute", ci->values[0].value.string, strlen ("Absolute")) == 0) { dstype = UTILS_MATCH_DS_TYPE_ABSOLUTE; if (strcasecmp ("AbsoluteSet", ci->values[0].value.string) == 0) /* Absolute DS is reset-on-read so no sense doin anything else but set */ dstype |= UTILS_MATCH_CF_ABSOLUTE_SET; else dstype = 0; } else { dstype = 0; } if (dstype == 0) { WARNING ("curl plugin: `%s' is not a valid argument to `DSType'.", ci->values[0].value.string); return (-1); } *dstype_ret = dstype; return (0); } /* }}} int cc_config_add_match_dstype */ static int cc_config_add_match (web_page_t *page, /* {{{ */ oconfig_item_t *ci) { web_match_t *match; int status; int i; if (ci->values_num != 0) { WARNING ("curl plugin: Ignoring arguments for the `Match' block."); } match = (web_match_t *) malloc (sizeof (*match)); if (match == NULL) { ERROR ("curl plugin: malloc failed."); return (-1); } memset (match, 0, sizeof (*match)); status = 0; for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("Regex", child->key) == 0) status = cf_util_get_string (child, &match->regex); else if (strcasecmp ("ExcludeRegex", child->key) == 0) status = cf_util_get_string (child, &match->exclude_regex); else if (strcasecmp ("DSType", child->key) == 0) status = cc_config_add_match_dstype (&match->dstype, child); else if (strcasecmp ("Type", child->key) == 0) status = cf_util_get_string (child, &match->type); else if (strcasecmp ("Instance", child->key) == 0) status = cf_util_get_string (child, &match->instance); else { WARNING ("curl plugin: Option `%s' not allowed here.", child->key); status = -1; } if (status != 0) break; } /* for (i = 0; i < ci->children_num; i++) */ while (status == 0) { if (match->regex == NULL) { WARNING ("curl plugin: `Regex' missing in `Match' block."); status = -1; } if (match->type == NULL) { WARNING ("curl plugin: `Type' missing in `Match' block."); status = -1; } if (match->dstype == 0) { WARNING ("curl plugin: `DSType' missing in `Match' block."); status = -1; } break; } /* while (status == 0) */ if (status != 0) return (status); match->match = match_create_simple (match->regex, match->exclude_regex, match->dstype); if (match->match == NULL) { ERROR ("curl plugin: tail_match_add_match_simple failed."); cc_web_match_free (match); return (-1); } else { web_match_t *prev; prev = page->matches; while ((prev != NULL) && (prev->next != NULL)) prev = prev->next; if (prev == NULL) page->matches = match; else prev->next = match; } return (0); } /* }}} int cc_config_add_match */ static int cc_page_init_curl (web_page_t *wp) /* {{{ */ { wp->curl = curl_easy_init (); if (wp->curl == NULL) { ERROR ("curl plugin: curl_easy_init failed."); return (-1); } curl_easy_setopt (wp->curl, CURLOPT_NOSIGNAL, 1L); curl_easy_setopt (wp->curl, CURLOPT_WRITEFUNCTION, cc_curl_callback); curl_easy_setopt (wp->curl, CURLOPT_WRITEDATA, wp); curl_easy_setopt (wp->curl, CURLOPT_USERAGENT, PACKAGE_NAME"/"PACKAGE_VERSION); curl_easy_setopt (wp->curl, CURLOPT_ERRORBUFFER, wp->curl_errbuf); curl_easy_setopt (wp->curl, CURLOPT_URL, wp->url); curl_easy_setopt (wp->curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt (wp->curl, CURLOPT_MAXREDIRS, 50L); if (wp->user != NULL) { size_t credentials_size; credentials_size = strlen (wp->user) + 2; if (wp->pass != NULL) credentials_size += strlen (wp->pass); wp->credentials = (char *) malloc (credentials_size); if (wp->credentials == NULL) { ERROR ("curl plugin: malloc failed."); return (-1); } ssnprintf (wp->credentials, credentials_size, "%s:%s", wp->user, (wp->pass == NULL) ? "" : wp->pass); curl_easy_setopt (wp->curl, CURLOPT_USERPWD, wp->credentials); } curl_easy_setopt (wp->curl, CURLOPT_SSL_VERIFYPEER, (long) wp->verify_peer); curl_easy_setopt (wp->curl, CURLOPT_SSL_VERIFYHOST, wp->verify_host ? 2L : 0L); if (wp->cacert != NULL) curl_easy_setopt (wp->curl, CURLOPT_CAINFO, wp->cacert); if (wp->headers != NULL) curl_easy_setopt (wp->curl, CURLOPT_HTTPHEADER, wp->headers); if (wp->post_body != NULL) curl_easy_setopt (wp->curl, CURLOPT_POSTFIELDS, wp->post_body); return (0); } /* }}} int cc_page_init_curl */ static int cc_config_add_page (oconfig_item_t *ci) /* {{{ */ { web_page_t *page; int status; int i; if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { WARNING ("curl plugin: `Page' blocks need exactly one string argument."); return (-1); } page = (web_page_t *) malloc (sizeof (*page)); if (page == NULL) { ERROR ("curl plugin: malloc failed."); return (-1); } memset (page, 0, sizeof (*page)); page->url = NULL; page->user = NULL; page->pass = NULL; page->verify_peer = 1; page->verify_host = 1; page->response_time = 0; page->response_code = 0; page->instance = strdup (ci->values[0].value.string); if (page->instance == NULL) { ERROR ("curl plugin: strdup failed."); sfree (page); return (-1); } /* Process all children */ status = 0; for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("URL", child->key) == 0) status = cf_util_get_string (child, &page->url); else if (strcasecmp ("User", child->key) == 0) status = cf_util_get_string (child, &page->user); else if (strcasecmp ("Password", child->key) == 0) status = cf_util_get_string (child, &page->pass); else if (strcasecmp ("VerifyPeer", child->key) == 0) status = cf_util_get_boolean (child, &page->verify_peer); else if (strcasecmp ("VerifyHost", child->key) == 0) status = cf_util_get_boolean (child, &page->verify_host); else if (strcasecmp ("MeasureResponseTime", child->key) == 0) status = cf_util_get_boolean (child, &page->response_time); else if (strcasecmp ("MeasureResponseCode", child->key) == 0) status = cf_util_get_boolean (child, &page->response_code); else if (strcasecmp ("CACert", child->key) == 0) status = cf_util_get_string (child, &page->cacert); else if (strcasecmp ("Match", child->key) == 0) /* Be liberal with failing matches => don't set `status'. */ cc_config_add_match (page, child); else if (strcasecmp ("Header", child->key) == 0) status = cc_config_append_string ("Header", &page->headers, child); else if (strcasecmp ("Post", child->key) == 0) status = cf_util_get_string (child, &page->post_body); else { WARNING ("curl plugin: Option `%s' not allowed here.", child->key); status = -1; } if (status != 0) break; } /* for (i = 0; i < ci->children_num; i++) */ /* Additionial sanity checks and libCURL initialization. */ while (status == 0) { if (page->url == NULL) { WARNING ("curl plugin: `URL' missing in `Page' block."); status = -1; } if (page->matches == NULL && !page->response_time && !page->response_code) { assert (page->instance != NULL); WARNING ("curl plugin: No (valid) `Match' block " "or MeasureResponseTime or MeasureResponseCode within " "`Page' block `%s'.", page->instance); status = -1; } if (status == 0) status = cc_page_init_curl (page); break; } /* while (status == 0) */ if (status != 0) { cc_web_page_free (page); return (status); } /* Add the new page to the linked list */ if (pages_g == NULL) pages_g = page; else { web_page_t *prev; prev = pages_g; while ((prev != NULL) && (prev->next != NULL)) prev = prev->next; prev->next = page; } return (0); } /* }}} int cc_config_add_page */ static int cc_config (oconfig_item_t *ci) /* {{{ */ { int success; int errors; int status; int i; success = 0; errors = 0; for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("Page", child->key) == 0) { status = cc_config_add_page (child); if (status == 0) success++; else errors++; } else { WARNING ("curl plugin: Option `%s' not allowed here.", child->key); errors++; } } if ((success == 0) && (errors > 0)) { ERROR ("curl plugin: All statements failed."); return (-1); } return (0); } /* }}} int cc_config */ static int cc_init (void) /* {{{ */ { if (pages_g == NULL) { INFO ("curl plugin: No pages have been defined."); return (-1); } return (0); } /* }}} int cc_init */ static void cc_submit (const web_page_t *wp, const web_match_t *wm, /* {{{ */ const cu_match_value_t *mv) { value_t values[1]; value_list_t vl = VALUE_LIST_INIT; values[0] = mv->value; vl.values = values; vl.values_len = 1; sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "curl", sizeof (vl.plugin)); sstrncpy (vl.plugin_instance, wp->instance, sizeof (vl.plugin_instance)); sstrncpy (vl.type, wm->type, sizeof (vl.type)); sstrncpy (vl.type_instance, wm->instance, sizeof (vl.type_instance)); plugin_dispatch_values (&vl); } /* }}} void cc_submit */ static void cc_submit_response_code (const web_page_t *wp, long code) /* {{{ */ { value_t values[1]; value_list_t vl = VALUE_LIST_INIT; values[0].gauge = code; vl.values = values; vl.values_len = 1; sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "curl", sizeof (vl.plugin)); sstrncpy (vl.plugin_instance, wp->instance, sizeof (vl.plugin_instance)); sstrncpy (vl.type, "response_code", sizeof (vl.type)); plugin_dispatch_values (&vl); } /* }}} void cc_submit_response_code */ static void cc_submit_response_time (const web_page_t *wp, /* {{{ */ cdtime_t response_time) { value_t values[1]; value_list_t vl = VALUE_LIST_INIT; values[0].gauge = CDTIME_T_TO_DOUBLE (response_time); vl.values = values; vl.values_len = 1; sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "curl", sizeof (vl.plugin)); sstrncpy (vl.plugin_instance, wp->instance, sizeof (vl.plugin_instance)); sstrncpy (vl.type, "response_time", sizeof (vl.type)); plugin_dispatch_values (&vl); } /* }}} void cc_submit_response_time */ static int cc_read_page (web_page_t *wp) /* {{{ */ { web_match_t *wm; int status; cdtime_t start = 0; if (wp->response_time) start = cdtime (); wp->buffer_fill = 0; status = curl_easy_perform (wp->curl); if (status != CURLE_OK) { ERROR ("curl plugin: curl_easy_perform failed with staus %i: %s", status, wp->curl_errbuf); return (-1); } if (wp->response_time) cc_submit_response_time (wp, cdtime() - start); if(wp->response_code) { long response_code = 0; status = curl_easy_getinfo(wp->curl, CURLINFO_RESPONSE_CODE, &response_code); if(status != CURLE_OK) { ERROR ("curl plugin: Fetching response code failed with staus %i: %s", status, wp->curl_errbuf); } else { cc_submit_response_code(wp, response_code); } } for (wm = wp->matches; wm != NULL; wm = wm->next) { cu_match_value_t *mv; status = match_apply (wm->match, wp->buffer); if (status != 0) { WARNING ("curl plugin: match_apply failed."); continue; } mv = match_get_user_data (wm->match); if (mv == NULL) { WARNING ("curl plugin: match_get_user_data returned NULL."); continue; } cc_submit (wp, wm, mv); } /* for (wm = wp->matches; wm != NULL; wm = wm->next) */ return (0); } /* }}} int cc_read_page */ static int cc_read (void) /* {{{ */ { web_page_t *wp; for (wp = pages_g; wp != NULL; wp = wp->next) cc_read_page (wp); return (0); } /* }}} int cc_read */ static int cc_shutdown (void) /* {{{ */ { cc_web_page_free (pages_g); pages_g = NULL; return (0); } /* }}} int cc_shutdown */ void module_register (void) { plugin_register_complex_config ("curl", cc_config); plugin_register_init ("curl", cc_init); plugin_register_read ("curl", cc_read); plugin_register_shutdown ("curl", cc_shutdown); } /* void module_register */ /* vim: set sw=2 sts=2 et fdm=marker : */ collectd-5.4.0/src/PaxHeaders.11991/write_http.c0000644037772200116100000000013212204120331017467 xustar000000000000000030 mtime=1376821465.093973759 30 atime=1376821477.230168122 30 ctime=1376821742.030401056 collectd-5.4.0/src/write_http.c0000644037772200116100000004553512204120331016247 0ustar00octoeng00000000000000/** * collectd - src/write_http.c * Copyright (C) 2009 Paul Sadauskas * Copyright (C) 2009 Doug MacEachern * Copyright (C) 2007-2009 Florian octo 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: * Florian octo Forster * Doug MacEachern * Paul Sadauskas **/ #include "collectd.h" #include "plugin.h" #include "common.h" #include "utils_cache.h" #include "utils_parse_option.h" #include "utils_format_json.h" #if HAVE_PTHREAD_H # include #endif #include /* * Private variables */ struct wh_callback_s { char *location; char *user; char *pass; char *credentials; int verify_peer; int verify_host; char *cacert; int store_rates; #define WH_FORMAT_COMMAND 0 #define WH_FORMAT_JSON 1 int format; CURL *curl; char curl_errbuf[CURL_ERROR_SIZE]; char send_buffer[4096]; size_t send_buffer_free; size_t send_buffer_fill; cdtime_t send_buffer_init_time; pthread_mutex_t send_lock; }; typedef struct wh_callback_s wh_callback_t; static void wh_reset_buffer (wh_callback_t *cb) /* {{{ */ { memset (cb->send_buffer, 0, sizeof (cb->send_buffer)); cb->send_buffer_free = sizeof (cb->send_buffer); cb->send_buffer_fill = 0; cb->send_buffer_init_time = cdtime (); if (cb->format == WH_FORMAT_JSON) { format_json_initialize (cb->send_buffer, &cb->send_buffer_fill, &cb->send_buffer_free); } } /* }}} wh_reset_buffer */ static int wh_send_buffer (wh_callback_t *cb) /* {{{ */ { int status = 0; curl_easy_setopt (cb->curl, CURLOPT_POSTFIELDS, cb->send_buffer); status = curl_easy_perform (cb->curl); if (status != CURLE_OK) { ERROR ("write_http plugin: curl_easy_perform failed with " "status %i: %s", status, cb->curl_errbuf); } return (status); } /* }}} wh_send_buffer */ static int wh_callback_init (wh_callback_t *cb) /* {{{ */ { struct curl_slist *headers; if (cb->curl != NULL) return (0); cb->curl = curl_easy_init (); if (cb->curl == NULL) { ERROR ("curl plugin: curl_easy_init failed."); return (-1); } curl_easy_setopt (cb->curl, CURLOPT_NOSIGNAL, 1L); curl_easy_setopt (cb->curl, CURLOPT_USERAGENT, PACKAGE_NAME"/"PACKAGE_VERSION); headers = NULL; headers = curl_slist_append (headers, "Accept: */*"); if (cb->format == WH_FORMAT_JSON) headers = curl_slist_append (headers, "Content-Type: application/json"); else headers = curl_slist_append (headers, "Content-Type: text/plain"); headers = curl_slist_append (headers, "Expect:"); curl_easy_setopt (cb->curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt (cb->curl, CURLOPT_ERRORBUFFER, cb->curl_errbuf); curl_easy_setopt (cb->curl, CURLOPT_URL, cb->location); if (cb->user != NULL) { size_t credentials_size; credentials_size = strlen (cb->user) + 2; if (cb->pass != NULL) credentials_size += strlen (cb->pass); cb->credentials = (char *) malloc (credentials_size); if (cb->credentials == NULL) { ERROR ("curl plugin: malloc failed."); return (-1); } ssnprintf (cb->credentials, credentials_size, "%s:%s", cb->user, (cb->pass == NULL) ? "" : cb->pass); curl_easy_setopt (cb->curl, CURLOPT_USERPWD, cb->credentials); curl_easy_setopt (cb->curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY); } curl_easy_setopt (cb->curl, CURLOPT_SSL_VERIFYPEER, (long) cb->verify_peer); curl_easy_setopt (cb->curl, CURLOPT_SSL_VERIFYHOST, cb->verify_host ? 2L : 0L); if (cb->cacert != NULL) curl_easy_setopt (cb->curl, CURLOPT_CAINFO, cb->cacert); wh_reset_buffer (cb); return (0); } /* }}} int wh_callback_init */ static int wh_flush_nolock (cdtime_t timeout, wh_callback_t *cb) /* {{{ */ { int status; DEBUG ("write_http plugin: wh_flush_nolock: timeout = %.3f; " "send_buffer_fill = %zu;", CDTIME_T_TO_DOUBLE (timeout), cb->send_buffer_fill); /* timeout == 0 => flush unconditionally */ if (timeout > 0) { cdtime_t now; now = cdtime (); if ((cb->send_buffer_init_time + timeout) > now) return (0); } if (cb->format == WH_FORMAT_COMMAND) { if (cb->send_buffer_fill <= 0) { cb->send_buffer_init_time = cdtime (); return (0); } status = wh_send_buffer (cb); wh_reset_buffer (cb); } else if (cb->format == WH_FORMAT_JSON) { if (cb->send_buffer_fill <= 2) { cb->send_buffer_init_time = cdtime (); return (0); } status = format_json_finalize (cb->send_buffer, &cb->send_buffer_fill, &cb->send_buffer_free); if (status != 0) { ERROR ("write_http: wh_flush_nolock: " "format_json_finalize failed."); wh_reset_buffer (cb); return (status); } status = wh_send_buffer (cb); wh_reset_buffer (cb); } else { ERROR ("write_http: wh_flush_nolock: " "Unknown format: %i", cb->format); return (-1); } return (status); } /* }}} wh_flush_nolock */ static int wh_flush (cdtime_t timeout, /* {{{ */ const char *identifier __attribute__((unused)), user_data_t *user_data) { wh_callback_t *cb; int status; if (user_data == NULL) return (-EINVAL); cb = user_data->data; pthread_mutex_lock (&cb->send_lock); if (cb->curl == NULL) { status = wh_callback_init (cb); if (status != 0) { ERROR ("write_http plugin: wh_callback_init failed."); pthread_mutex_unlock (&cb->send_lock); return (-1); } } status = wh_flush_nolock (timeout, cb); pthread_mutex_unlock (&cb->send_lock); return (status); } /* }}} int wh_flush */ static void wh_callback_free (void *data) /* {{{ */ { wh_callback_t *cb; if (data == NULL) return; cb = data; wh_flush_nolock (/* timeout = */ 0, cb); curl_easy_cleanup (cb->curl); sfree (cb->location); sfree (cb->user); sfree (cb->pass); sfree (cb->credentials); sfree (cb->cacert); sfree (cb); } /* }}} void wh_callback_free */ static int wh_write_command (const data_set_t *ds, const value_list_t *vl, /* {{{ */ wh_callback_t *cb) { char key[10*DATA_MAX_NAME_LEN]; char values[512]; char command[1024]; size_t command_len; int status; if (0 != strcmp (ds->type, vl->type)) { ERROR ("write_http plugin: DS type does not match " "value list type"); return -1; } /* Copy the identifier to `key' and escape it. */ status = FORMAT_VL (key, sizeof (key), vl); if (status != 0) { ERROR ("write_http plugin: error with format_name"); return (status); } escape_string (key, sizeof (key)); /* Convert the values to an ASCII representation and put that into * `values'. */ status = format_values (values, sizeof (values), ds, vl, cb->store_rates); if (status != 0) { ERROR ("write_http plugin: error with " "wh_value_list_to_string"); return (status); } command_len = (size_t) ssnprintf (command, sizeof (command), "PUTVAL %s interval=%.3f %s\r\n", key, CDTIME_T_TO_DOUBLE (vl->interval), values); if (command_len >= sizeof (command)) { ERROR ("write_http plugin: Command buffer too small: " "Need %zu bytes.", command_len + 1); return (-1); } pthread_mutex_lock (&cb->send_lock); if (cb->curl == NULL) { status = wh_callback_init (cb); if (status != 0) { ERROR ("write_http plugin: wh_callback_init failed."); pthread_mutex_unlock (&cb->send_lock); return (-1); } } if (command_len >= cb->send_buffer_free) { status = wh_flush_nolock (/* timeout = */ 0, cb); if (status != 0) { pthread_mutex_unlock (&cb->send_lock); return (status); } } assert (command_len < cb->send_buffer_free); /* `command_len + 1' because `command_len' does not include the * trailing null byte. Neither does `send_buffer_fill'. */ memcpy (cb->send_buffer + cb->send_buffer_fill, command, command_len + 1); cb->send_buffer_fill += command_len; cb->send_buffer_free -= command_len; DEBUG ("write_http plugin: <%s> buffer %zu/%zu (%g%%) \"%s\"", cb->location, cb->send_buffer_fill, sizeof (cb->send_buffer), 100.0 * ((double) cb->send_buffer_fill) / ((double) sizeof (cb->send_buffer)), command); /* Check if we have enough space for this command. */ pthread_mutex_unlock (&cb->send_lock); return (0); } /* }}} int wh_write_command */ static int wh_write_json (const data_set_t *ds, const value_list_t *vl, /* {{{ */ wh_callback_t *cb) { int status; pthread_mutex_lock (&cb->send_lock); if (cb->curl == NULL) { status = wh_callback_init (cb); if (status != 0) { ERROR ("write_http plugin: wh_callback_init failed."); pthread_mutex_unlock (&cb->send_lock); return (-1); } } status = format_json_value_list (cb->send_buffer, &cb->send_buffer_fill, &cb->send_buffer_free, ds, vl, cb->store_rates); if (status == (-ENOMEM)) { status = wh_flush_nolock (/* timeout = */ 0, cb); if (status != 0) { wh_reset_buffer (cb); pthread_mutex_unlock (&cb->send_lock); return (status); } status = format_json_value_list (cb->send_buffer, &cb->send_buffer_fill, &cb->send_buffer_free, ds, vl, cb->store_rates); } if (status != 0) { pthread_mutex_unlock (&cb->send_lock); return (status); } DEBUG ("write_http plugin: <%s> buffer %zu/%zu (%g%%)", cb->location, cb->send_buffer_fill, sizeof (cb->send_buffer), 100.0 * ((double) cb->send_buffer_fill) / ((double) sizeof (cb->send_buffer))); /* Check if we have enough space for this command. */ pthread_mutex_unlock (&cb->send_lock); return (0); } /* }}} int wh_write_json */ static int wh_write (const data_set_t *ds, const value_list_t *vl, /* {{{ */ user_data_t *user_data) { wh_callback_t *cb; int status; if (user_data == NULL) return (-EINVAL); cb = user_data->data; if (cb->format == WH_FORMAT_JSON) status = wh_write_json (ds, vl, cb); else status = wh_write_command (ds, vl, cb); return (status); } /* }}} int wh_write */ static int config_set_string (char **ret_string, /* {{{ */ oconfig_item_t *ci) { char *string; if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { WARNING ("write_http plugin: The `%s' config option " "needs exactly one string argument.", ci->key); return (-1); } string = strdup (ci->values[0].value.string); if (string == NULL) { ERROR ("write_http plugin: strdup failed."); return (-1); } if (*ret_string != NULL) free (*ret_string); *ret_string = string; return (0); } /* }}} int config_set_string */ static int config_set_boolean (int *dest, oconfig_item_t *ci) /* {{{ */ { if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_BOOLEAN)) { WARNING ("write_http plugin: The `%s' config option " "needs exactly one boolean argument.", ci->key); return (-1); } *dest = ci->values[0].value.boolean ? 1 : 0; return (0); } /* }}} int config_set_boolean */ static int config_set_format (wh_callback_t *cb, /* {{{ */ oconfig_item_t *ci) { char *string; if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { WARNING ("write_http plugin: The `%s' config option " "needs exactly one string argument.", ci->key); return (-1); } string = ci->values[0].value.string; if (strcasecmp ("Command", string) == 0) cb->format = WH_FORMAT_COMMAND; else if (strcasecmp ("JSON", string) == 0) cb->format = WH_FORMAT_JSON; else { ERROR ("write_http plugin: Invalid format string: %s", string); return (-1); } return (0); } /* }}} int config_set_string */ static int wh_config_url (oconfig_item_t *ci) /* {{{ */ { wh_callback_t *cb; user_data_t user_data; int i; cb = malloc (sizeof (*cb)); if (cb == NULL) { ERROR ("write_http plugin: malloc failed."); return (-1); } memset (cb, 0, sizeof (*cb)); cb->location = NULL; cb->user = NULL; cb->pass = NULL; cb->credentials = NULL; cb->verify_peer = 1; cb->verify_host = 1; cb->cacert = NULL; cb->format = WH_FORMAT_COMMAND; cb->curl = NULL; pthread_mutex_init (&cb->send_lock, /* attr = */ NULL); config_set_string (&cb->location, ci); if (cb->location == NULL) return (-1); for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("User", child->key) == 0) config_set_string (&cb->user, child); else if (strcasecmp ("Password", child->key) == 0) config_set_string (&cb->pass, child); else if (strcasecmp ("VerifyPeer", child->key) == 0) config_set_boolean (&cb->verify_peer, child); else if (strcasecmp ("VerifyHost", child->key) == 0) config_set_boolean (&cb->verify_host, child); else if (strcasecmp ("CACert", child->key) == 0) config_set_string (&cb->cacert, child); else if (strcasecmp ("Format", child->key) == 0) config_set_format (cb, child); else if (strcasecmp ("StoreRates", child->key) == 0) config_set_boolean (&cb->store_rates, child); else { ERROR ("write_http plugin: Invalid configuration " "option: %s.", child->key); } } DEBUG ("write_http: Registering write callback with URL %s", cb->location); memset (&user_data, 0, sizeof (user_data)); user_data.data = cb; user_data.free_func = NULL; plugin_register_flush ("write_http", wh_flush, &user_data); user_data.free_func = wh_callback_free; plugin_register_write ("write_http", wh_write, &user_data); return (0); } /* }}} int wh_config_url */ static int wh_config (oconfig_item_t *ci) /* {{{ */ { int i; for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("URL", child->key) == 0) wh_config_url (child); else { ERROR ("write_http plugin: Invalid configuration " "option: %s.", child->key); } } return (0); } /* }}} int wh_config */ void module_register (void) /* {{{ */ { plugin_register_complex_config ("write_http", wh_config); } /* }}} void module_register */ /* vim: set fdm=marker sw=8 ts=8 tw=78 et : */ collectd-5.4.0/src/PaxHeaders.11991/amqp.c0000644037772200116100000000013212204120331016234 xustar000000000000000030 mtime=1376821465.061973248 30 atime=1376821477.206167738 30 ctime=1376821742.030401056 collectd-5.4.0/src/amqp.c0000644037772200116100000007766012204120331015020 0ustar00octoeng00000000000000/** * collectd - src/amqp.c * Copyright (C) 2009 Sebastien Pahl * Copyright (C) 2010-2012 Florian Forster * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Authors: * Sebastien Pahl * Florian Forster **/ #include "collectd.h" #include "common.h" #include "plugin.h" #include "utils_cmd_putval.h" #include "utils_format_json.h" #include "utils_format_graphite.h" #include #include #include /* Defines for the delivery mode. I have no idea why they're not defined by the * library.. */ #define CAMQP_DM_VOLATILE 1 #define CAMQP_DM_PERSISTENT 2 #define CAMQP_FORMAT_COMMAND 1 #define CAMQP_FORMAT_JSON 2 #define CAMQP_FORMAT_GRAPHITE 3 #define CAMQP_CHANNEL 1 /* * Data types */ struct camqp_config_s { _Bool publish; char *name; char *host; int port; char *vhost; char *user; char *password; char *exchange; char *routing_key; /* publish only */ uint8_t delivery_mode; _Bool store_rates; int format; /* publish & graphite format only */ char *prefix; char *postfix; char escape_char; unsigned int graphite_flags; /* subscribe only */ char *exchange_type; char *queue; amqp_connection_state_t connection; pthread_mutex_t lock; }; typedef struct camqp_config_s camqp_config_t; /* * Global variables */ static const char *def_host = "localhost"; static const char *def_vhost = "/"; static const char *def_user = "guest"; static const char *def_password = "guest"; static const char *def_exchange = "amq.fanout"; static pthread_t *subscriber_threads = NULL; static size_t subscriber_threads_num = 0; static _Bool subscriber_threads_running = 1; #define CONF(c,f) (((c)->f != NULL) ? (c)->f : def_##f) /* * Functions */ static void camqp_close_connection (camqp_config_t *conf) /* {{{ */ { int sockfd; if ((conf == NULL) || (conf->connection == NULL)) return; sockfd = amqp_get_sockfd (conf->connection); amqp_channel_close (conf->connection, CAMQP_CHANNEL, AMQP_REPLY_SUCCESS); amqp_connection_close (conf->connection, AMQP_REPLY_SUCCESS); amqp_destroy_connection (conf->connection); close (sockfd); conf->connection = NULL; } /* }}} void camqp_close_connection */ static void camqp_config_free (void *ptr) /* {{{ */ { camqp_config_t *conf = ptr; if (conf == NULL) return; camqp_close_connection (conf); sfree (conf->name); sfree (conf->host); sfree (conf->vhost); sfree (conf->user); sfree (conf->password); sfree (conf->exchange); sfree (conf->exchange_type); sfree (conf->queue); sfree (conf->routing_key); sfree (conf->prefix); sfree (conf->postfix); sfree (conf); } /* }}} void camqp_config_free */ static char *camqp_bytes_cstring (amqp_bytes_t *in) /* {{{ */ { char *ret; if ((in == NULL) || (in->bytes == NULL)) return (NULL); ret = malloc (in->len + 1); if (ret == NULL) return (NULL); memcpy (ret, in->bytes, in->len); ret[in->len] = 0; return (ret); } /* }}} char *camqp_bytes_cstring */ static _Bool camqp_is_error (camqp_config_t *conf) /* {{{ */ { amqp_rpc_reply_t r; r = amqp_get_rpc_reply (conf->connection); if (r.reply_type == AMQP_RESPONSE_NORMAL) return (0); return (1); } /* }}} _Bool camqp_is_error */ static char *camqp_strerror (camqp_config_t *conf, /* {{{ */ char *buffer, size_t buffer_size) { amqp_rpc_reply_t r; r = amqp_get_rpc_reply (conf->connection); switch (r.reply_type) { case AMQP_RESPONSE_NORMAL: sstrncpy (buffer, "Success", sizeof (buffer)); break; case AMQP_RESPONSE_NONE: sstrncpy (buffer, "Missing RPC reply type", sizeof (buffer)); break; case AMQP_RESPONSE_LIBRARY_EXCEPTION: #if HAVE_AMQP_RPC_REPLY_T_LIBRARY_ERRNO if (r.library_errno) return (sstrerror (r.library_errno, buffer, buffer_size)); #else if (r.library_error) return (sstrerror (r.library_error, buffer, buffer_size)); #endif else sstrncpy (buffer, "End of stream", sizeof (buffer)); break; case AMQP_RESPONSE_SERVER_EXCEPTION: if (r.reply.id == AMQP_CONNECTION_CLOSE_METHOD) { amqp_connection_close_t *m = r.reply.decoded; char *tmp = camqp_bytes_cstring (&m->reply_text); ssnprintf (buffer, buffer_size, "Server connection error %d: %s", m->reply_code, tmp); sfree (tmp); } else if (r.reply.id == AMQP_CHANNEL_CLOSE_METHOD) { amqp_channel_close_t *m = r.reply.decoded; char *tmp = camqp_bytes_cstring (&m->reply_text); ssnprintf (buffer, buffer_size, "Server channel error %d: %s", m->reply_code, tmp); sfree (tmp); } else { ssnprintf (buffer, buffer_size, "Server error method %#"PRIx32, r.reply.id); } break; default: ssnprintf (buffer, buffer_size, "Unknown reply type %i", (int) r.reply_type); } return (buffer); } /* }}} char *camqp_strerror */ #if HAVE_AMQP_RPC_REPLY_T_LIBRARY_ERRNO static int camqp_create_exchange (camqp_config_t *conf) /* {{{ */ { amqp_exchange_declare_ok_t *ed_ret; if (conf->exchange_type == NULL) return (0); ed_ret = amqp_exchange_declare (conf->connection, /* channel = */ CAMQP_CHANNEL, /* exchange = */ amqp_cstring_bytes (conf->exchange), /* type = */ amqp_cstring_bytes (conf->exchange_type), /* passive = */ 0, /* durable = */ 0, /* auto_delete = */ 1, /* arguments = */ AMQP_EMPTY_TABLE); if ((ed_ret == NULL) && camqp_is_error (conf)) { char errbuf[1024]; ERROR ("amqp plugin: amqp_exchange_declare failed: %s", camqp_strerror (conf, errbuf, sizeof (errbuf))); camqp_close_connection (conf); return (-1); } INFO ("amqp plugin: Successfully created exchange \"%s\" " "with type \"%s\".", conf->exchange, conf->exchange_type); return (0); } /* }}} int camqp_create_exchange */ #else static int camqp_create_exchange (camqp_config_t *conf) /* {{{ */ { amqp_exchange_declare_ok_t *ed_ret; amqp_table_t argument_table; struct amqp_table_entry_t_ argument_table_entries[1]; if (conf->exchange_type == NULL) return (0); /* Valid arguments: "auto_delete", "internal" */ argument_table.num_entries = STATIC_ARRAY_SIZE (argument_table_entries); argument_table.entries = argument_table_entries; argument_table_entries[0].key = amqp_cstring_bytes ("auto_delete"); argument_table_entries[0].value.kind = AMQP_FIELD_KIND_BOOLEAN; argument_table_entries[0].value.value.boolean = 1; ed_ret = amqp_exchange_declare (conf->connection, /* channel = */ CAMQP_CHANNEL, /* exchange = */ amqp_cstring_bytes (conf->exchange), /* type = */ amqp_cstring_bytes (conf->exchange_type), /* passive = */ 0, /* durable = */ 0, /* arguments = */ argument_table); if ((ed_ret == NULL) && camqp_is_error (conf)) { char errbuf[1024]; ERROR ("amqp plugin: amqp_exchange_declare failed: %s", camqp_strerror (conf, errbuf, sizeof (errbuf))); camqp_close_connection (conf); return (-1); } INFO ("amqp plugin: Successfully created exchange \"%s\" " "with type \"%s\".", conf->exchange, conf->exchange_type); return (0); } /* }}} int camqp_create_exchange */ #endif static int camqp_setup_queue (camqp_config_t *conf) /* {{{ */ { amqp_queue_declare_ok_t *qd_ret; amqp_basic_consume_ok_t *cm_ret; qd_ret = amqp_queue_declare (conf->connection, /* channel = */ CAMQP_CHANNEL, /* queue = */ (conf->queue != NULL) ? amqp_cstring_bytes (conf->queue) : AMQP_EMPTY_BYTES, /* passive = */ 0, /* durable = */ 0, /* exclusive = */ 0, /* auto_delete = */ 1, /* arguments = */ AMQP_EMPTY_TABLE); if (qd_ret == NULL) { ERROR ("amqp plugin: amqp_queue_declare failed."); camqp_close_connection (conf); return (-1); } if (conf->queue == NULL) { conf->queue = camqp_bytes_cstring (&qd_ret->queue); if (conf->queue == NULL) { ERROR ("amqp plugin: camqp_bytes_cstring failed."); camqp_close_connection (conf); return (-1); } INFO ("amqp plugin: Created queue \"%s\".", conf->queue); } DEBUG ("amqp plugin: Successfully created queue \"%s\".", conf->queue); /* bind to an exchange */ if (conf->exchange != NULL) { amqp_queue_bind_ok_t *qb_ret; assert (conf->queue != NULL); qb_ret = amqp_queue_bind (conf->connection, /* channel = */ CAMQP_CHANNEL, /* queue = */ amqp_cstring_bytes (conf->queue), /* exchange = */ amqp_cstring_bytes (conf->exchange), /* routing_key = */ (conf->routing_key != NULL) ? amqp_cstring_bytes (conf->routing_key) : AMQP_EMPTY_BYTES, /* arguments = */ AMQP_EMPTY_TABLE); if ((qb_ret == NULL) && camqp_is_error (conf)) { char errbuf[1024]; ERROR ("amqp plugin: amqp_queue_bind failed: %s", camqp_strerror (conf, errbuf, sizeof (errbuf))); camqp_close_connection (conf); return (-1); } DEBUG ("amqp plugin: Successfully bound queue \"%s\" to exchange \"%s\".", conf->queue, conf->exchange); } /* if (conf->exchange != NULL) */ cm_ret = amqp_basic_consume (conf->connection, /* channel = */ CAMQP_CHANNEL, /* queue = */ amqp_cstring_bytes (conf->queue), /* consumer_tag = */ AMQP_EMPTY_BYTES, /* no_local = */ 0, /* no_ack = */ 1, /* exclusive = */ 0, /* arguments = */ AMQP_EMPTY_TABLE ); if ((cm_ret == NULL) && camqp_is_error (conf)) { char errbuf[1024]; ERROR ("amqp plugin: amqp_basic_consume failed: %s", camqp_strerror (conf, errbuf, sizeof (errbuf))); camqp_close_connection (conf); return (-1); } return (0); } /* }}} int camqp_setup_queue */ static int camqp_connect (camqp_config_t *conf) /* {{{ */ { amqp_rpc_reply_t reply; int sockfd; int status; if (conf->connection != NULL) return (0); conf->connection = amqp_new_connection (); if (conf->connection == NULL) { ERROR ("amqp plugin: amqp_new_connection failed."); return (ENOMEM); } sockfd = amqp_open_socket (CONF(conf, host), conf->port); if (sockfd < 0) { char errbuf[1024]; status = (-1) * sockfd; ERROR ("amqp plugin: amqp_open_socket failed: %s", sstrerror (status, errbuf, sizeof (errbuf))); amqp_destroy_connection (conf->connection); conf->connection = NULL; return (status); } amqp_set_sockfd (conf->connection, sockfd); reply = amqp_login (conf->connection, CONF(conf, vhost), /* channel max = */ 0, /* frame max = */ 131072, /* heartbeat = */ 0, /* authentication = */ AMQP_SASL_METHOD_PLAIN, CONF(conf, user), CONF(conf, password)); if (reply.reply_type != AMQP_RESPONSE_NORMAL) { ERROR ("amqp plugin: amqp_login (vhost = %s, user = %s) failed.", CONF(conf, vhost), CONF(conf, user)); amqp_destroy_connection (conf->connection); close (sockfd); conf->connection = NULL; return (1); } amqp_channel_open (conf->connection, /* channel = */ 1); /* FIXME: Is checking "reply.reply_type" really correct here? How does * it get set? --octo */ if (reply.reply_type != AMQP_RESPONSE_NORMAL) { ERROR ("amqp plugin: amqp_channel_open failed."); amqp_connection_close (conf->connection, AMQP_REPLY_SUCCESS); amqp_destroy_connection (conf->connection); close(sockfd); conf->connection = NULL; return (1); } INFO ("amqp plugin: Successfully opened connection to vhost \"%s\" " "on %s:%i.", CONF(conf, vhost), CONF(conf, host), conf->port); status = camqp_create_exchange (conf); if (status != 0) return (status); if (!conf->publish) return (camqp_setup_queue (conf)); return (0); } /* }}} int camqp_connect */ static int camqp_shutdown (void) /* {{{ */ { size_t i; DEBUG ("amqp plugin: Shutting down %zu subscriber threads.", subscriber_threads_num); subscriber_threads_running = 0; for (i = 0; i < subscriber_threads_num; i++) { /* FIXME: Sending a signal is not very elegant here. Maybe find out how * to use a timeout in the thread and check for the variable in regular * intervals. */ pthread_kill (subscriber_threads[i], SIGTERM); pthread_join (subscriber_threads[i], /* retval = */ NULL); } subscriber_threads_num = 0; sfree (subscriber_threads); DEBUG ("amqp plugin: All subscriber threads exited."); return (0); } /* }}} int camqp_shutdown */ /* * Subscribing code */ static int camqp_read_body (camqp_config_t *conf, /* {{{ */ size_t body_size, const char *content_type) { char body[body_size + 1]; char *body_ptr; size_t received; amqp_frame_t frame; int status; memset (body, 0, sizeof (body)); body_ptr = &body[0]; received = 0; while (received < body_size) { status = amqp_simple_wait_frame (conf->connection, &frame); if (status < 0) { char errbuf[1024]; status = (-1) * status; ERROR ("amqp plugin: amqp_simple_wait_frame failed: %s", sstrerror (status, errbuf, sizeof (errbuf))); camqp_close_connection (conf); return (status); } if (frame.frame_type != AMQP_FRAME_BODY) { NOTICE ("amqp plugin: Unexpected frame type: %#"PRIx8, frame.frame_type); return (-1); } if ((body_size - received) < frame.payload.body_fragment.len) { WARNING ("amqp plugin: Body is larger than indicated by header."); return (-1); } memcpy (body_ptr, frame.payload.body_fragment.bytes, frame.payload.body_fragment.len); body_ptr += frame.payload.body_fragment.len; received += frame.payload.body_fragment.len; } /* while (received < body_size) */ if (strcasecmp ("text/collectd", content_type) == 0) { status = handle_putval (stderr, body); if (status != 0) ERROR ("amqp plugin: handle_putval failed with status %i.", status); return (status); } else if (strcasecmp ("application/json", content_type) == 0) { ERROR ("amqp plugin: camqp_read_body: Parsing JSON data has not " "been implemented yet. FIXME!"); return (0); } else { ERROR ("amqp plugin: camqp_read_body: Unknown content type \"%s\".", content_type); return (EINVAL); } /* not reached */ return (0); } /* }}} int camqp_read_body */ static int camqp_read_header (camqp_config_t *conf) /* {{{ */ { int status; amqp_frame_t frame; amqp_basic_properties_t *properties; char *content_type; status = amqp_simple_wait_frame (conf->connection, &frame); if (status < 0) { char errbuf[1024]; status = (-1) * status; ERROR ("amqp plugin: amqp_simple_wait_frame failed: %s", sstrerror (status, errbuf, sizeof (errbuf))); camqp_close_connection (conf); return (status); } if (frame.frame_type != AMQP_FRAME_HEADER) { NOTICE ("amqp plugin: Unexpected frame type: %#"PRIx8, frame.frame_type); return (-1); } properties = frame.payload.properties.decoded; content_type = camqp_bytes_cstring (&properties->content_type); if (content_type == NULL) { ERROR ("amqp plugin: Unable to determine content type."); return (-1); } status = camqp_read_body (conf, (size_t) frame.payload.properties.body_size, content_type); sfree (content_type); return (status); } /* }}} int camqp_read_header */ static void *camqp_subscribe_thread (void *user_data) /* {{{ */ { camqp_config_t *conf = user_data; int status; cdtime_t interval = plugin_get_interval (); while (subscriber_threads_running) { amqp_frame_t frame; status = camqp_connect (conf); if (status != 0) { struct timespec ts_interval; ERROR ("amqp plugin: camqp_connect failed. " "Will sleep for %.3f seconds.", CDTIME_T_TO_DOUBLE (interval)); CDTIME_T_TO_TIMESPEC (interval, &ts_interval); nanosleep (&ts_interval, /* remaining = */ NULL); continue; } status = amqp_simple_wait_frame (conf->connection, &frame); if (status < 0) { struct timespec ts_interval; ERROR ("amqp plugin: amqp_simple_wait_frame failed. " "Will sleep for %.3f seconds.", CDTIME_T_TO_DOUBLE (interval)); camqp_close_connection (conf); CDTIME_T_TO_TIMESPEC (interval, &ts_interval); nanosleep (&ts_interval, /* remaining = */ NULL); continue; } if (frame.frame_type != AMQP_FRAME_METHOD) { DEBUG ("amqp plugin: Unexpected frame type: %#"PRIx8, frame.frame_type); continue; } if (frame.payload.method.id != AMQP_BASIC_DELIVER_METHOD) { DEBUG ("amqp plugin: Unexpected method id: %#"PRIx32, frame.payload.method.id); continue; } status = camqp_read_header (conf); amqp_maybe_release_buffers (conf->connection); } /* while (subscriber_threads_running) */ camqp_config_free (conf); pthread_exit (NULL); return (NULL); } /* }}} void *camqp_subscribe_thread */ static int camqp_subscribe_init (camqp_config_t *conf) /* {{{ */ { int status; pthread_t *tmp; tmp = realloc (subscriber_threads, sizeof (*subscriber_threads) * (subscriber_threads_num + 1)); if (tmp == NULL) { ERROR ("amqp plugin: realloc failed."); camqp_config_free (conf); return (ENOMEM); } subscriber_threads = tmp; tmp = subscriber_threads + subscriber_threads_num; memset (tmp, 0, sizeof (*tmp)); status = plugin_thread_create (tmp, /* attr = */ NULL, camqp_subscribe_thread, conf); if (status != 0) { char errbuf[1024]; ERROR ("amqp plugin: pthread_create failed: %s", sstrerror (status, errbuf, sizeof (errbuf))); camqp_config_free (conf); return (status); } subscriber_threads_num++; return (0); } /* }}} int camqp_subscribe_init */ /* * Publishing code */ /* XXX: You must hold "conf->lock" when calling this function! */ static int camqp_write_locked (camqp_config_t *conf, /* {{{ */ const char *buffer, const char *routing_key) { amqp_basic_properties_t props; int status; status = camqp_connect (conf); if (status != 0) return (status); memset (&props, 0, sizeof (props)); props._flags = AMQP_BASIC_CONTENT_TYPE_FLAG | AMQP_BASIC_DELIVERY_MODE_FLAG | AMQP_BASIC_APP_ID_FLAG; if (conf->format == CAMQP_FORMAT_COMMAND) props.content_type = amqp_cstring_bytes("text/collectd"); else if (conf->format == CAMQP_FORMAT_JSON) props.content_type = amqp_cstring_bytes("application/json"); else if (conf->format == CAMQP_FORMAT_GRAPHITE) props.content_type = amqp_cstring_bytes("text/graphite"); else assert (23 == 42); props.delivery_mode = conf->delivery_mode; props.app_id = amqp_cstring_bytes("collectd"); status = amqp_basic_publish(conf->connection, /* channel = */ 1, amqp_cstring_bytes(CONF(conf, exchange)), amqp_cstring_bytes (routing_key), /* mandatory = */ 0, /* immediate = */ 0, &props, amqp_cstring_bytes(buffer)); if (status != 0) { ERROR ("amqp plugin: amqp_basic_publish failed with status %i.", status); camqp_close_connection (conf); } return (status); } /* }}} int camqp_write_locked */ static int camqp_write (const data_set_t *ds, const value_list_t *vl, /* {{{ */ user_data_t *user_data) { camqp_config_t *conf = user_data->data; char routing_key[6 * DATA_MAX_NAME_LEN]; char buffer[4096]; int status; if ((ds == NULL) || (vl == NULL) || (conf == NULL)) return (EINVAL); memset (buffer, 0, sizeof (buffer)); if (conf->routing_key != NULL) { sstrncpy (routing_key, conf->routing_key, sizeof (routing_key)); } else { size_t i; ssnprintf (routing_key, sizeof (routing_key), "collectd/%s/%s/%s/%s/%s", vl->host, vl->plugin, vl->plugin_instance, vl->type, vl->type_instance); /* Switch slashes (the only character forbidden by collectd) and dots * (the separation character used by AMQP). */ for (i = 0; routing_key[i] != 0; i++) { if (routing_key[i] == '.') routing_key[i] = '/'; else if (routing_key[i] == '/') routing_key[i] = '.'; } } if (conf->format == CAMQP_FORMAT_COMMAND) { status = create_putval (buffer, sizeof (buffer), ds, vl); if (status != 0) { ERROR ("amqp plugin: create_putval failed with status %i.", status); return (status); } } else if (conf->format == CAMQP_FORMAT_JSON) { size_t bfree = sizeof (buffer); size_t bfill = 0; format_json_initialize (buffer, &bfill, &bfree); format_json_value_list (buffer, &bfill, &bfree, ds, vl, conf->store_rates); format_json_finalize (buffer, &bfill, &bfree); } else if (conf->format == CAMQP_FORMAT_GRAPHITE) { status = format_graphite (buffer, sizeof (buffer), ds, vl, conf->prefix, conf->postfix, conf->escape_char, conf->graphite_flags); if (status != 0) { ERROR ("amqp plugin: format_graphite failed with status %i.", status); return (status); } } else { ERROR ("amqp plugin: Invalid format (%i).", conf->format); return (-1); } pthread_mutex_lock (&conf->lock); status = camqp_write_locked (conf, buffer, routing_key); pthread_mutex_unlock (&conf->lock); return (status); } /* }}} int camqp_write */ /* * Config handling */ static int camqp_config_set_format (oconfig_item_t *ci, /* {{{ */ camqp_config_t *conf) { char *string; int status; string = NULL; status = cf_util_get_string (ci, &string); if (status != 0) return (status); assert (string != NULL); if (strcasecmp ("Command", string) == 0) conf->format = CAMQP_FORMAT_COMMAND; else if (strcasecmp ("JSON", string) == 0) conf->format = CAMQP_FORMAT_JSON; else if (strcasecmp ("Graphite", string) == 0) conf->format = CAMQP_FORMAT_GRAPHITE; else { WARNING ("amqp plugin: Invalid format string: %s", string); } free (string); return (0); } /* }}} int config_set_string */ static int camqp_config_connection (oconfig_item_t *ci, /* {{{ */ _Bool publish) { camqp_config_t *conf; int status; int i; conf = malloc (sizeof (*conf)); if (conf == NULL) { ERROR ("amqp plugin: malloc failed."); return (ENOMEM); } /* Initialize "conf" {{{ */ memset (conf, 0, sizeof (*conf)); conf->publish = publish; conf->name = NULL; conf->format = CAMQP_FORMAT_COMMAND; conf->host = NULL; conf->port = 5672; conf->vhost = NULL; conf->user = NULL; conf->password = NULL; conf->exchange = NULL; conf->routing_key = NULL; /* publish only */ conf->delivery_mode = CAMQP_DM_VOLATILE; conf->store_rates = 0; conf->graphite_flags = 0; /* publish & graphite only */ conf->prefix = NULL; conf->postfix = NULL; conf->escape_char = '_'; /* subscribe only */ conf->exchange_type = NULL; conf->queue = NULL; /* general */ conf->connection = NULL; pthread_mutex_init (&conf->lock, /* attr = */ NULL); /* }}} */ status = cf_util_get_string (ci, &conf->name); if (status != 0) { sfree (conf); return (status); } for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("Host", child->key) == 0) status = cf_util_get_string (child, &conf->host); else if (strcasecmp ("Port", child->key) == 0) { status = cf_util_get_port_number (child); if (status > 0) { conf->port = status; status = 0; } } else if (strcasecmp ("VHost", child->key) == 0) status = cf_util_get_string (child, &conf->vhost); else if (strcasecmp ("User", child->key) == 0) status = cf_util_get_string (child, &conf->user); else if (strcasecmp ("Password", child->key) == 0) status = cf_util_get_string (child, &conf->password); else if (strcasecmp ("Exchange", child->key) == 0) status = cf_util_get_string (child, &conf->exchange); else if ((strcasecmp ("ExchangeType", child->key) == 0) && !publish) status = cf_util_get_string (child, &conf->exchange_type); else if ((strcasecmp ("Queue", child->key) == 0) && !publish) status = cf_util_get_string (child, &conf->queue); else if (strcasecmp ("RoutingKey", child->key) == 0) status = cf_util_get_string (child, &conf->routing_key); else if ((strcasecmp ("Persistent", child->key) == 0) && publish) { _Bool tmp = 0; status = cf_util_get_boolean (child, &tmp); if (tmp) conf->delivery_mode = CAMQP_DM_PERSISTENT; else conf->delivery_mode = CAMQP_DM_VOLATILE; } else if ((strcasecmp ("StoreRates", child->key) == 0) && publish) { status = cf_util_get_boolean (child, &conf->store_rates); (void) cf_util_get_flag (child, &conf->graphite_flags, GRAPHITE_STORE_RATES); } else if ((strcasecmp ("Format", child->key) == 0) && publish) status = camqp_config_set_format (child, conf); else if ((strcasecmp ("GraphiteSeparateInstances", child->key) == 0) && publish) status = cf_util_get_flag (child, &conf->graphite_flags, GRAPHITE_SEPARATE_INSTANCES); else if ((strcasecmp ("GraphiteAlwaysAppendDS", child->key) == 0) && publish) status = cf_util_get_flag (child, &conf->graphite_flags, GRAPHITE_ALWAYS_APPEND_DS); else if ((strcasecmp ("GraphitePrefix", child->key) == 0) && publish) status = cf_util_get_string (child, &conf->prefix); else if ((strcasecmp ("GraphitePostfix", child->key) == 0) && publish) status = cf_util_get_string (child, &conf->postfix); else if ((strcasecmp ("GraphiteEscapeChar", child->key) == 0) && publish) { char *tmp_buff = NULL; status = cf_util_get_string (child, &tmp_buff); if (strlen (tmp_buff) > 1) WARNING ("amqp plugin: The option \"GraphiteEscapeChar\" handles " "only one character. Others will be ignored."); conf->escape_char = tmp_buff[0]; sfree (tmp_buff); } else WARNING ("amqp plugin: Ignoring unknown " "configuration option \"%s\".", child->key); if (status != 0) break; } /* for (i = 0; i < ci->children_num; i++) */ if ((status == 0) && (conf->exchange == NULL)) { if (conf->exchange_type != NULL) WARNING ("amqp plugin: The option \"ExchangeType\" was given " "without the \"Exchange\" option. It will be ignored."); if (!publish && (conf->routing_key != NULL)) WARNING ("amqp plugin: The option \"RoutingKey\" was given " "without the \"Exchange\" option. It will be ignored."); } if (status != 0) { camqp_config_free (conf); return (status); } if (conf->exchange != NULL) { DEBUG ("amqp plugin: camqp_config_connection: exchange = %s;", conf->exchange); } if (publish) { char cbname[128]; user_data_t ud = { conf, camqp_config_free }; ssnprintf (cbname, sizeof (cbname), "amqp/%s", conf->name); status = plugin_register_write (cbname, camqp_write, &ud); if (status != 0) { camqp_config_free (conf); return (status); } } else { status = camqp_subscribe_init (conf); if (status != 0) { camqp_config_free (conf); return (status); } } return (0); } /* }}} int camqp_config_connection */ static int camqp_config (oconfig_item_t *ci) /* {{{ */ { int i; for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("Publish", child->key) == 0) camqp_config_connection (child, /* publish = */ 1); else if (strcasecmp ("Subscribe", child->key) == 0) camqp_config_connection (child, /* publish = */ 0); else WARNING ("amqp plugin: Ignoring unknown config option \"%s\".", child->key); } /* for (ci->children_num) */ return (0); } /* }}} int camqp_config */ void module_register (void) { plugin_register_complex_config ("amqp", camqp_config); plugin_register_shutdown ("amqp", camqp_shutdown); } /* void module_register */ /* vim: set sw=4 sts=4 et fdm=marker : */ collectd-5.4.0/src/PaxHeaders.11991/notify_desktop.c0000644037772200116100000000013112204120331020336 xustar000000000000000030 mtime=1376821465.081973567 30 atime=1376821477.222167995 29 ctime=1376821742.03440112 collectd-5.4.0/src/notify_desktop.c0000644037772200116100000001132012204120331017100 0ustar00octoeng00000000000000/** * collectd - src/notify_desktop.c * Copyright (C) 2008 Sebastian Harl * * 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 * * Author: * Sebastian Harl **/ /* * This plugin sends desktop notifications to a notification daemon. */ #include "collectd.h" #include "common.h" #include "plugin.h" #include "configfile.h" #include #include #ifndef NOTIFY_CHECK_VERSION # define NOTIFY_CHECK_VERSION(x,y,z) 0 #endif #define log_info(...) INFO ("notify_desktop: " __VA_ARGS__) #define log_warn(...) WARNING ("notify_desktop: " __VA_ARGS__) #define log_err(...) ERROR ("notify_desktop: " __VA_ARGS__) #define DEFAULT_TIMEOUT 5000 static int okay_timeout = DEFAULT_TIMEOUT; static int warn_timeout = DEFAULT_TIMEOUT; static int fail_timeout = DEFAULT_TIMEOUT; static int set_timeout (oconfig_item_t *ci, int *timeout) { if ((0 != ci->children_num) || (1 != ci->values_num) || (OCONFIG_TYPE_NUMBER != ci->values[0].type)) { log_err ("%s expects a single number argument.", ci->key); return 1; } *timeout = (int)ci->values[0].value.number; if (0 > *timeout) *timeout = DEFAULT_TIMEOUT; return 0; } /* set_timeout */ static int c_notify_config (oconfig_item_t *ci) { int i = 0; for (i = 0; i < ci->children_num; ++i) { oconfig_item_t *c = ci->children + i; if (0 == strcasecmp (c->key, "OkayTimeout")) set_timeout (c, &okay_timeout); else if (0 == strcasecmp (c->key, "WarningTimeout")) set_timeout (c, &warn_timeout); else if (0 == strcasecmp (c->key, "FailureTimeout")) set_timeout (c, &fail_timeout); } return 0; } /* c_notify_config */ static int c_notify (const notification_t *n, user_data_t __attribute__((unused)) *user_data) { NotifyNotification *notification = NULL; NotifyUrgency urgency = NOTIFY_URGENCY_LOW; int timeout = okay_timeout; char summary[1024]; if (NOTIF_WARNING == n->severity) { urgency = NOTIFY_URGENCY_NORMAL; timeout = warn_timeout; } else if (NOTIF_FAILURE == n->severity) { urgency = NOTIFY_URGENCY_CRITICAL; timeout = fail_timeout; } ssnprintf (summary, sizeof (summary), "collectd %s notification", (NOTIF_FAILURE == n->severity) ? "FAILURE" : (NOTIF_WARNING == n->severity) ? "WARNING" : (NOTIF_OKAY == n->severity) ? "OKAY" : "UNKNOWN"); notification = notify_notification_new (summary, n->message, NULL #if NOTIFY_CHECK_VERSION (0, 7, 0) ); #else , NULL); #endif if (NULL == notification) { log_err ("Failed to create a new notification."); return -1; } notify_notification_set_urgency (notification, urgency); notify_notification_set_timeout (notification, timeout); if (! notify_notification_show (notification, NULL)) log_err ("Failed to display notification."); g_object_unref (G_OBJECT (notification)); return 0; } /* c_notify */ static int c_notify_shutdown (void) { plugin_unregister_init ("notify_desktop"); plugin_unregister_notification ("notify_desktop"); plugin_unregister_shutdown ("notify_desktop"); if (notify_is_initted ()) notify_uninit (); return 0; } /* c_notify_shutdown */ static int c_notify_init (void) { char *name = NULL; char *vendor = NULL; char *version = NULL; char *spec_version = NULL; if (! notify_init (PACKAGE_STRING)) { log_err ("Failed to initialize libnotify."); return -1; } if (! notify_get_server_info (&name, &vendor, &version, &spec_version)) log_warn ("Failed to get the notification server info. " "Check if you have a notification daemon running."); else { log_info ("Found notification daemon: %s (%s) %s (spec version %s)", name, vendor, version, spec_version); free (name); free (vendor); free (version); free (spec_version); } plugin_register_notification ("notify_desktop", c_notify, /* user_data = */ NULL); plugin_register_shutdown ("notify_desktop", c_notify_shutdown); return 0; } /* c_notify_init */ void module_register (void) { plugin_register_complex_config ("notify_desktop", c_notify_config); plugin_register_init ("notify_desktop", c_notify_init); return; } /* module_register */ /* vim: set sw=4 ts=4 tw=78 noexpandtab : */ collectd-5.4.0/src/PaxHeaders.11991/utils_tail.h0000644037772200116100000000013112204120331017453 xustar000000000000000030 mtime=1376821465.089973696 30 atime=1376821477.230168122 29 ctime=1376821742.03440112 collectd-5.4.0/src/utils_tail.h0000644037772200116100000000465612204120331016233 0ustar00octoeng00000000000000/** * collectd - src/utils_tail.h * Copyright (C) 2007-2008 C-Ware, Inc. * * 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 * * Author: * Luke Heberling * * DESCRIPTION * Facilitates reading information that is appended to a file, taking into * account that the file may be rotated and a new file created under the * same name. **/ #ifndef UTILS_TAIL_H #define UTILS_TAIL_H 1 struct cu_tail_s; typedef struct cu_tail_s cu_tail_t; typedef int tailfunc_t(void *data, char *buf, int buflen); /* * NAME * cu_tail_create * * DESCRIPTION * Allocates a new tail object.. * * PARAMETERS * `file' The name of the file to be tailed. */ cu_tail_t *cu_tail_create (const char *file); /* * cu_tail_destroy * * Takes a tail object returned by `cu_tail_create' and destroys it, freeing * all internal memory. * * Returns 0 when successful and non-zero otherwise. */ int cu_tail_destroy (cu_tail_t *obj); /* * cu_tail_readline * * Reads from the file until `buflen' characters are read, a newline * character is read, or an eof condition is encountered. `buf' is * always null-terminated on successful return and isn't touched when non-zero * is returned. * * You can check if the EOF condition is reached by looking at the buffer: If * the length of the string stored in the buffer is zero, EOF occurred. * Otherwise at least the newline character will be in the buffer. * * Returns 0 when successful and non-zero otherwise. */ int cu_tail_readline (cu_tail_t *obj, char *buf, int buflen); /* * cu_tail_readline * * Reads from the file until eof condition or an error is encountered. * * Returns 0 when successful and non-zero otherwise. */ int cu_tail_read (cu_tail_t *obj, char *buf, int buflen, tailfunc_t *callback, void *data); #endif /* UTILS_TAIL_H */ collectd-5.4.0/src/PaxHeaders.11991/ntpd.c0000644037772200116100000000013212204120331016243 xustar000000000000000030 mtime=1376821465.081973567 30 atime=1376821477.222167995 30 ctime=1376821742.038401184 collectd-5.4.0/src/ntpd.c0000644037772200116100000006740412204120331015022 0ustar00octoeng00000000000000/** * collectd - src/ntpd.c * Copyright (C) 2006-2012 Florian octo 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: * Florian octo Forster **/ #define _BSD_SOURCE /* For NI_MAXHOST */ #include "collectd.h" #include "common.h" #include "plugin.h" #include "configfile.h" #if HAVE_STDINT_H # include #endif #if HAVE_NETDB_H # include #endif #if HAVE_SYS_SOCKET_H # include #endif #if HAVE_NETINET_IN_H # include #endif #if HAVE_ARPA_INET_H # include /* inet_ntoa */ #endif #if HAVE_NETINET_TCP_H # include #endif #if HAVE_POLL_H # include #endif static const char *config_keys[] = { "Host", "Port", "ReverseLookups", "IncludeUnitID" }; static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); static _Bool do_reverse_lookups = 1; /* This option only exists for backward compatibility. If it is false and two * ntpd peers use the same refclock driver, the plugin will try to write * simultaneous measurements from both to the same type instance. */ static _Bool include_unit_id = 0; # define NTPD_DEFAULT_HOST "localhost" # define NTPD_DEFAULT_PORT "123" static int sock_descr = -1; static char *ntpd_host = NULL; static char ntpd_port[16]; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * The following definitions were copied from the NTPd distribution * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #define MAXFILENAME 128 #define MAXSEQ 127 #define MODE_PRIVATE 7 #define NTP_OLDVERSION ((uint8_t) 1) /* oldest credible version */ #define IMPL_XNTPD 3 #define FP_FRAC 65536.0 #define REFCLOCK_ADDR 0x7f7f0000 /* 127.127.0.0 */ #define REFCLOCK_MASK 0xffff0000 /* 255.255.0.0 */ /* This structure is missing the message authentication code, since collectd * doesn't use it. */ struct req_pkt { uint8_t rm_vn_mode; uint8_t auth_seq; uint8_t implementation; /* implementation number */ uint8_t request; /* request number */ uint16_t err_nitems; /* error code/number of data items */ uint16_t mbz_itemsize; /* item size */ char data[MAXFILENAME + 48]; /* data area [32 prev](176 byte max) */ /* struct conf_peer must fit */ }; #define REQ_LEN_NOMAC (sizeof(struct req_pkt)) /* * A response packet. The length here is variable, this is a * maximally sized one. Note that this implementation doesn't * authenticate responses. */ #define RESP_HEADER_SIZE (8) #define RESP_DATA_SIZE (500) struct resp_pkt { uint8_t rm_vn_mode; /* response, more, version, mode */ uint8_t auth_seq; /* key, sequence number */ uint8_t implementation; /* implementation number */ uint8_t request; /* request number */ uint16_t err_nitems; /* error code/number of data items */ uint16_t mbz_itemsize; /* item size */ char data[RESP_DATA_SIZE]; /* data area */ }; /* * Bit setting macros for multifield items. */ #define RESP_BIT 0x80 #define MORE_BIT 0x40 #define ISRESPONSE(rm_vn_mode) (((rm_vn_mode)&RESP_BIT)!=0) #define ISMORE(rm_vn_mode) (((rm_vn_mode)&MORE_BIT)!=0) #define INFO_VERSION(rm_vn_mode) ((uint8_t)(((rm_vn_mode)>>3)&0x7)) #define INFO_MODE(rm_vn_mode) ((rm_vn_mode)&0x7) #define RM_VN_MODE(resp, more, version) \ ((uint8_t)(((resp)?RESP_BIT:0)\ |((more)?MORE_BIT:0)\ |((version?version:(NTP_OLDVERSION+1))<<3)\ |(MODE_PRIVATE))) #define INFO_IS_AUTH(auth_seq) (((auth_seq) & 0x80) != 0) #define INFO_SEQ(auth_seq) ((auth_seq)&0x7f) #define AUTH_SEQ(auth, seq) ((uint8_t)((((auth)!=0)?0x80:0)|((seq)&0x7f))) #define INFO_ERR(err_nitems) ((uint16_t)((ntohs(err_nitems)>>12)&0xf)) #define INFO_NITEMS(err_nitems) ((uint16_t)(ntohs(err_nitems)&0xfff)) #define ERR_NITEMS(err, nitems) (htons((uint16_t)((((uint16_t)(err)<<12)&0xf000)\ |((uint16_t)(nitems)&0xfff)))) #define INFO_MBZ(mbz_itemsize) ((ntohs(mbz_itemsize)>>12)&0xf) #define INFO_ITEMSIZE(mbz_itemsize) ((uint16_t)(ntohs(mbz_itemsize)&0xfff)) #define MBZ_ITEMSIZE(itemsize) (htons((uint16_t)(itemsize))) /* negate a long float type */ #define M_NEG(v_i, v_f) \ do { \ if ((v_f) == 0) \ (v_i) = -((uint32_t)(v_i)); \ else { \ (v_f) = -((uint32_t)(v_f)); \ (v_i) = ~(v_i); \ } \ } while(0) /* l_fp to double */ #define M_LFPTOD(r_i, r_uf, d) \ do { \ register int32_t i; \ register uint32_t f; \ \ i = (r_i); \ f = (r_uf); \ if (i < 0) { \ M_NEG(i, f); \ (d) = -((double) i + ((double) f) / 4294967296.0); \ } else { \ (d) = (double) i + ((double) f) / 4294967296.0; \ } \ } while (0) #define REQ_PEER_LIST_SUM 1 struct info_peer_summary { uint32_t dstadr; /* local address (zero for undetermined) */ uint32_t srcadr; /* source address */ uint16_t srcport; /* source port */ uint8_t stratum; /* stratum of peer */ int8_t hpoll; /* host polling interval */ int8_t ppoll; /* peer polling interval */ uint8_t reach; /* reachability register */ uint8_t flags; /* flags, from above */ uint8_t hmode; /* peer mode */ int32_t delay; /* peer.estdelay; s_fp */ int32_t offset_int; /* peer.estoffset; integral part */ int32_t offset_frc; /* peer.estoffset; fractional part */ uint32_t dispersion; /* peer.estdisp; u_fp */ uint32_t v6_flag; /* is this v6 or not */ uint32_t unused1; /* (unused) padding for dstadr6 */ struct in6_addr dstadr6; /* local address (v6) */ struct in6_addr srcadr6; /* source address (v6) */ }; #define REQ_SYS_INFO 4 struct info_sys { uint32_t peer; /* system peer address (v4) */ uint8_t peer_mode; /* mode we are syncing to peer in */ uint8_t leap; /* system leap bits */ uint8_t stratum; /* our stratum */ int8_t precision; /* local clock precision */ int32_t rootdelay; /* distance from sync source */ uint32_t rootdispersion; /* dispersion from sync source */ uint32_t refid; /* reference ID of sync source */ uint64_t reftime; /* system reference time */ uint32_t poll; /* system poll interval */ uint8_t flags; /* system flags */ uint8_t unused1; /* unused */ uint8_t unused2; /* unused */ uint8_t unused3; /* unused */ int32_t bdelay; /* default broadcast offset */ int32_t frequency; /* frequency residual (scaled ppm) */ uint64_t authdelay; /* default authentication delay */ uint32_t stability; /* clock stability (scaled ppm) */ int32_t v6_flag; /* is this v6 or not */ int32_t unused4; /* unused, padding for peer6 */ struct in6_addr peer6; /* system peer address (v6) */ }; #define REQ_GET_KERNEL 38 struct info_kernel { int32_t offset; int32_t freq; int32_t maxerror; int32_t esterror; uint16_t status; uint16_t shift; int32_t constant; int32_t precision; int32_t tolerance; /* pps stuff */ int32_t ppsfreq; int32_t jitter; int32_t stabil; int32_t jitcnt; int32_t calcnt; int32_t errcnt; int32_t stbcnt; }; /* List of reference clock names */ static char *refclock_names[] = { "UNKNOWN", "LOCAL", "GPS_TRAK", "WWV_PST", /* 0- 3 */ "SPECTRACOM", "TRUETIME", "IRIG_AUDIO", "CHU_AUDIO", /* 4- 7 */ "GENERIC", "GPS_MX4200", "GPS_AS2201", "GPS_ARBITER", /* 8-11 */ "IRIG_TPRO", "ATOM_LEITCH", "MSF_EES", "GPSTM_TRUE", /* 12-15 */ "GPS_BANC", "GPS_DATUM", "ACTS_NIST", "WWV_HEATH", /* 16-19 */ "GPS_NMEA", "GPS_VME", "PPS", "ACTS_PTB", /* 20-23 */ "ACTS_USNO", "TRUETIME", "GPS_HP", "MSF_ARCRON", /* 24-27 */ "SHM", "GPS_PALISADE", "GPS_ONCORE", "GPS_JUPITER", /* 28-31 */ "CHRONOLOG", "DUMBCLOCK", "ULINK_M320", "PCF", /* 32-35 */ "WWV_AUDIO", "GPS_FG", "HOPF_S", "HOPF_P", /* 36-39 */ "JJY", "TT_IRIG", "GPS_ZYFER", "GPS_RIPENCC", /* 40-43 */ "NEOCLK4X" /* 44 */ }; static int refclock_names_num = STATIC_ARRAY_SIZE (refclock_names); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * End of the copied stuff.. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ static int ntpd_config (const char *key, const char *value) { if (strcasecmp (key, "Host") == 0) { if (ntpd_host != NULL) free (ntpd_host); if ((ntpd_host = strdup (value)) == NULL) return (1); } else if (strcasecmp (key, "Port") == 0) { int port = (int) (atof (value)); if ((port > 0) && (port <= 65535)) ssnprintf (ntpd_port, sizeof (ntpd_port), "%i", port); else sstrncpy (ntpd_port, value, sizeof (ntpd_port)); } else if (strcasecmp (key, "ReverseLookups") == 0) { if (IS_TRUE (value)) do_reverse_lookups = 1; else do_reverse_lookups = 0; } else if (strcasecmp (key, "IncludeUnitID") == 0) { if (IS_TRUE (value)) include_unit_id = 1; else include_unit_id = 0; } else { return (-1); } return (0); } static void ntpd_submit (char *type, char *type_inst, double value) { value_t values[1]; value_list_t vl = VALUE_LIST_INIT; values[0].gauge = value; vl.values = values; vl.values_len = 1; sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "ntpd", sizeof (vl.plugin)); sstrncpy (vl.plugin_instance, "", sizeof (vl.plugin_instance)); sstrncpy (vl.type, type, sizeof (vl.type)); sstrncpy (vl.type_instance, type_inst, sizeof (vl.type_instance)); plugin_dispatch_values (&vl); } /* Each time a peer is polled, ntpd shifts the reach register to the left and * sets the LSB based on whether the peer was reachable. If the LSB is zero, * the values are out of date. */ static void ntpd_submit_reach (char *type, char *type_inst, uint8_t reach, double value) { if (!(reach & 1)) value = NAN; ntpd_submit (type, type_inst, value); } static int ntpd_connect (void) { char *host; char *port; struct addrinfo ai_hints; struct addrinfo *ai_list; struct addrinfo *ai_ptr; int status; if (sock_descr >= 0) return (sock_descr); DEBUG ("Opening a new socket"); host = ntpd_host; if (host == NULL) host = NTPD_DEFAULT_HOST; port = ntpd_port; if (strlen (port) == 0) port = NTPD_DEFAULT_PORT; memset (&ai_hints, '\0', sizeof (ai_hints)); ai_hints.ai_flags = 0; #ifdef AI_ADDRCONFIG ai_hints.ai_flags |= AI_ADDRCONFIG; #endif ai_hints.ai_family = PF_UNSPEC; ai_hints.ai_socktype = SOCK_DGRAM; ai_hints.ai_protocol = IPPROTO_UDP; if ((status = getaddrinfo (host, port, &ai_hints, &ai_list)) != 0) { char errbuf[1024]; ERROR ("ntpd plugin: getaddrinfo (%s, %s): %s", host, port, (status == EAI_SYSTEM) ? sstrerror (errno, errbuf, sizeof (errbuf)) : gai_strerror (status)); return (-1); } for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) { /* create our socket descriptor */ if ((sock_descr = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol)) < 0) continue; /* connect to the ntpd */ if (connect (sock_descr, ai_ptr->ai_addr, ai_ptr->ai_addrlen)) { close (sock_descr); sock_descr = -1; continue; } break; } freeaddrinfo (ai_list); if (sock_descr < 0) { ERROR ("ntpd plugin: Unable to connect to server."); } return (sock_descr); } /* For a description of the arguments see `ntpd_do_query' below. */ static int ntpd_receive_response (int *res_items, int *res_size, char **res_data, int res_item_size) { int sd; struct pollfd poll_s; struct resp_pkt res; int status; int done; int i; char *items; size_t items_num; struct timeval time_end; struct timeval time_now; int timeout; int pkt_item_num; /* items in this packet */ int pkt_item_len; /* size of the items in this packet */ int pkt_sequence; char pkt_recvd[MAXSEQ+1]; /* sequence numbers that have been received */ int pkt_recvd_num; /* number of packets that have been received */ int pkt_lastseq; /* the last sequence number */ ssize_t pkt_padding; /* Padding in this packet */ if ((sd = ntpd_connect ()) < 0) return (-1); items = NULL; items_num = 0; memset (pkt_recvd, '\0', sizeof (pkt_recvd)); pkt_recvd_num = 0; pkt_lastseq = -1; *res_items = 0; *res_size = 0; *res_data = NULL; if (gettimeofday (&time_end, NULL) < 0) { char errbuf[1024]; ERROR ("ntpd plugin: gettimeofday failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } time_end.tv_sec++; /* wait for a most one second */ done = 0; while (done == 0) { struct timeval time_left; if (gettimeofday (&time_now, NULL) < 0) { char errbuf[1024]; ERROR ("ntpd plugin: gettimeofday failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } if (timeval_cmp (time_end, time_now, &time_left) <= 0) timeout = 0; else timeout = 1000 * time_left.tv_sec + ((time_left.tv_usec + 500) / 1000); /* timeout reached */ if (timeout <= 0) break; poll_s.fd = sd; poll_s.events = POLLIN | POLLPRI; poll_s.revents = 0; DEBUG ("Polling for %ims", timeout); status = poll (&poll_s, 1, timeout); if ((status < 0) && ((errno == EAGAIN) || (errno == EINTR))) continue; if (status < 0) { char errbuf[1024]; ERROR ("ntpd plugin: poll failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } if (status == 0) /* timeout */ { DEBUG ("timeout reached."); break; } memset ((void *) &res, '\0', sizeof (res)); status = recv (sd, (void *) &res, sizeof (res), 0 /* no flags */); if ((status < 0) && ((errno == EAGAIN) || (errno == EINTR))) continue; if (status < 0) { char errbuf[1024]; INFO ("recv(2) failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); DEBUG ("Closing socket #%i", sd); close (sd); sock_descr = sd = -1; return (-1); } DEBUG ("recv'd %i bytes", status); /* * Do some sanity checks first */ if (status < RESP_HEADER_SIZE) { WARNING ("ntpd plugin: Short (%i bytes) packet received", (int) status); continue; } if (INFO_MODE (res.rm_vn_mode) != MODE_PRIVATE) { NOTICE ("ntpd plugin: Packet received with mode %i", INFO_MODE (res.rm_vn_mode)); continue; } if (INFO_IS_AUTH (res.auth_seq)) { NOTICE ("ntpd plugin: Encrypted packet received"); continue; } if (!ISRESPONSE (res.rm_vn_mode)) { NOTICE ("ntpd plugin: Received request packet, " "wanted response"); continue; } if (INFO_MBZ (res.mbz_itemsize)) { WARNING ("ntpd plugin: Received packet with nonzero " "MBZ field!"); continue; } if (res.implementation != IMPL_XNTPD) { WARNING ("ntpd plugin: Asked for request of type %i, " "got %i", (int) IMPL_XNTPD, (int) res.implementation); continue; } /* Check for error code */ if (INFO_ERR (res.err_nitems) != 0) { ERROR ("ntpd plugin: Received error code %i", (int) INFO_ERR(res.err_nitems)); return ((int) INFO_ERR (res.err_nitems)); } /* extract number of items in this packet and the size of these items */ pkt_item_num = INFO_NITEMS (res.err_nitems); pkt_item_len = INFO_ITEMSIZE (res.mbz_itemsize); DEBUG ("pkt_item_num = %i; pkt_item_len = %i;", pkt_item_num, pkt_item_len); /* Check if the reported items fit in the packet */ if ((pkt_item_num * pkt_item_len) > (status - RESP_HEADER_SIZE)) { ERROR ("ntpd plugin: %i items * %i bytes > " "%i bytes - %i bytes header", (int) pkt_item_num, (int) pkt_item_len, (int) status, (int) RESP_HEADER_SIZE); continue; } if (pkt_item_len > res_item_size) { ERROR ("ntpd plugin: (pkt_item_len = %i) " ">= (res_item_size = %i)", pkt_item_len, res_item_size); continue; } /* If this is the first packet (time wise, not sequence wise), * set `res_size'. If it's not the first packet check if the * items have the same size. Discard invalid packets. */ if (items_num == 0) /* first packet */ { DEBUG ("*res_size = %i", pkt_item_len); *res_size = pkt_item_len; } else if (*res_size != pkt_item_len) { DEBUG ("Error: *res_size = %i; pkt_item_len = %i;", *res_size, pkt_item_len); ERROR ("Item sizes differ."); continue; } /* * Because the items in the packet may be smaller than the * items requested, the following holds true: */ assert ((*res_size == pkt_item_len) && (pkt_item_len <= res_item_size)); /* Calculate the padding. No idea why there might be any padding.. */ pkt_padding = 0; if (pkt_item_len < res_item_size) pkt_padding = res_item_size - pkt_item_len; DEBUG ("res_item_size = %i; pkt_padding = %zi;", res_item_size, pkt_padding); /* Extract the sequence number */ pkt_sequence = INFO_SEQ (res.auth_seq); if ((pkt_sequence < 0) || (pkt_sequence > MAXSEQ)) { ERROR ("ntpd plugin: Received packet with sequence %i", pkt_sequence); continue; } /* Check if this sequence has been received before. If so, discard it. */ if (pkt_recvd[pkt_sequence] != '\0') { NOTICE ("ntpd plugin: Sequence %i received twice", pkt_sequence); continue; } /* If `pkt_lastseq != -1' another packet without `more bit' has * been received. */ if (!ISMORE (res.rm_vn_mode)) { if (pkt_lastseq != -1) { ERROR ("ntpd plugin: Two packets which both " "claim to be the last one in the " "sequence have been received."); continue; } pkt_lastseq = pkt_sequence; DEBUG ("Last sequence = %i;", pkt_lastseq); } /* * Enough with the checks. Copy the data now. * We start by allocating some more memory. */ DEBUG ("realloc (%p, %zu)", (void *) *res_data, (items_num + pkt_item_num) * res_item_size); items = realloc ((void *) *res_data, (items_num + pkt_item_num) * res_item_size); if (items == NULL) { items = *res_data; ERROR ("ntpd plugin: realloc failed."); continue; } items_num += pkt_item_num; *res_data = items; for (i = 0; i < pkt_item_num; i++) { /* dst: There are already `*res_items' items with * res_item_size bytes each in in `*res_data'. Set * dst to the first byte after that. */ void *dst = (void *) (*res_data + ((*res_items) * res_item_size)); /* src: We use `pkt_item_len' to calculate the offset * from the beginning of the packet, because the * items in the packet may be smaller than the * items that were requested. We skip `i' such * items. */ void *src = (void *) (((char *) res.data) + (i * pkt_item_len)); /* Set the padding to zeros */ if (pkt_padding != 0) memset (dst, '\0', res_item_size); memcpy (dst, src, (size_t) pkt_item_len); /* Increment `*res_items' by one, so `dst' will end up * one further in the next round. */ (*res_items)++; } /* for (pkt_item_num) */ pkt_recvd[pkt_sequence] = (char) 1; pkt_recvd_num++; if ((pkt_recvd_num - 1) == pkt_lastseq) done = 1; } /* while (done == 0) */ return (0); } /* int ntpd_receive_response */ /* For a description of the arguments see `ntpd_do_query' below. */ static int ntpd_send_request (int req_code, int req_items, int req_size, char *req_data) { int sd; struct req_pkt req; size_t req_data_len; int status; assert (req_items >= 0); assert (req_size >= 0); if ((sd = ntpd_connect ()) < 0) return (-1); memset ((void *) &req, '\0', sizeof (req)); req.rm_vn_mode = RM_VN_MODE(0, 0, 0); req.auth_seq = AUTH_SEQ (0, 0); req.implementation = IMPL_XNTPD; req.request = (unsigned char) req_code; req_data_len = (size_t) (req_items * req_size); assert (((req_data != NULL) && (req_data_len > 0)) || ((req_data == NULL) && (req_items == 0) && (req_size == 0))); req.err_nitems = ERR_NITEMS (0, req_items); req.mbz_itemsize = MBZ_ITEMSIZE (req_size); if (req_data != NULL) memcpy ((void *) req.data, (const void *) req_data, req_data_len); DEBUG ("req_items = %i; req_size = %i; req_data = %p;", req_items, req_size, (void *) req_data); status = swrite (sd, (const char *) &req, REQ_LEN_NOMAC); if (status < 0) { DEBUG ("`swrite' failed. Closing socket #%i", sd); close (sd); sock_descr = sd = -1; return (status); } return (0); } /* * ntpd_do_query: * * req_code: Type of request packet * req_items: Numver of items in the request * req_size: Size of one item in the request * req_data: Data of the request packet * res_items: Pointer to where the number returned items will be stored. * res_size: Pointer to where the size of one returned item will be stored. * res_data: This is where a pointer to the (allocated) data will be stored. * res_item_size: Size of one returned item. (used to calculate padding) * * returns: zero upon success, non-zero otherwise. */ static int ntpd_do_query (int req_code, int req_items, int req_size, char *req_data, int *res_items, int *res_size, char **res_data, int res_item_size) { int status; status = ntpd_send_request (req_code, req_items, req_size, req_data); if (status != 0) return (status); status = ntpd_receive_response (res_items, res_size, res_data, res_item_size); return (status); } static double ntpd_read_fp (int32_t val_int) { double val_double; val_int = ntohl (val_int); val_double = ((double) val_int) / FP_FRAC; return (val_double); } static uint32_t ntpd_get_refclock_id (struct info_peer_summary const *peer_info) { uint32_t addr = ntohl (peer_info->srcadr); uint32_t refclock_id = (addr >> 8) & 0x00FF; return (refclock_id); } static int ntpd_get_name_from_address (char *buffer, size_t buffer_size, struct info_peer_summary const *peer_info, _Bool do_reverse_lookup) { struct sockaddr_storage sa; socklen_t sa_len; int flags = 0; int status; memset (&sa, 0, sizeof (sa)); if (peer_info->v6_flag) { struct sockaddr_in6 sa6; assert (sizeof (sa) >= sizeof (sa6)); memset (&sa6, 0, sizeof (sa6)); sa6.sin6_family = AF_INET6; sa6.sin6_port = htons (123); memcpy (&sa6.sin6_addr, &peer_info->srcadr6, sizeof (struct in6_addr)); sa_len = sizeof (sa6); memcpy (&sa, &sa6, sizeof (sa6)); } else { struct sockaddr_in sa4; assert (sizeof (sa) >= sizeof (sa4)); memset (&sa4, 0, sizeof (sa4)); sa4.sin_family = AF_INET; sa4.sin_port = htons (123); memcpy (&sa4.sin_addr, &peer_info->srcadr, sizeof (struct in_addr)); sa_len = sizeof (sa4); memcpy (&sa, &sa4, sizeof (sa4)); } if (!do_reverse_lookup) flags |= NI_NUMERICHOST; status = getnameinfo ((struct sockaddr const *) &sa, sa_len, buffer, buffer_size, NULL, 0, /* No port name */ flags); if (status != 0) { char errbuf[1024]; ERROR ("ntpd plugin: getnameinfo failed: %s", (status == EAI_SYSTEM) ? sstrerror (errno, errbuf, sizeof (errbuf)) : gai_strerror (status)); return (-1); } return (0); } /* ntpd_get_name_from_address */ static int ntpd_get_name_refclock (char *buffer, size_t buffer_size, struct info_peer_summary const *peer_info) { uint32_t refclock_id = ntpd_get_refclock_id (peer_info); uint32_t unit_id = ntohl (peer_info->srcadr) & 0x00FF; if (refclock_id >= refclock_names_num) return (ntpd_get_name_from_address (buffer, buffer_size, peer_info, /* do_reverse_lookup = */ 0)); if (include_unit_id) ssnprintf (buffer, buffer_size, "%s-%"PRIu32, refclock_names[refclock_id], unit_id); else sstrncpy (buffer, refclock_names[refclock_id], buffer_size); return (0); } /* int ntpd_get_name_refclock */ static int ntpd_get_name (char *buffer, size_t buffer_size, struct info_peer_summary const *peer_info) { uint32_t addr = ntohl (peer_info->srcadr); if (!peer_info->v6_flag && ((addr & REFCLOCK_MASK) == REFCLOCK_ADDR)) return (ntpd_get_name_refclock (buffer, buffer_size, peer_info)); else return (ntpd_get_name_from_address (buffer, buffer_size, peer_info, do_reverse_lookups)); } /* int ntpd_addr_to_name */ static int ntpd_read (void) { struct info_kernel *ik; int ik_num; int ik_size; struct info_peer_summary *ps; int ps_num; int ps_size; int status; int i; ik = NULL; ik_num = 0; ik_size = 0; status = ntpd_do_query (REQ_GET_KERNEL, 0, 0, NULL, /* request data */ &ik_num, &ik_size, (char **) ((void *) &ik), /* response data */ sizeof (struct info_kernel)); if (status != 0) { ERROR ("ntpd plugin: ntpd_do_query (REQ_GET_KERNEL) failed with status %i", status); return (status); } else if ((ik == NULL) || (ik_num == 0) || (ik_size == 0)) { ERROR ("ntpd plugin: ntpd_do_query returned unexpected data. " "(ik = %p; ik_num = %i; ik_size = %i)", (void *) ik, ik_num, ik_size); return (-1); } /* kerninfo -> estimated error */ DEBUG ("info_kernel:\n" " pll offset = %.8f\n" " pll frequency = %.8f\n" /* drift compensation */ " est error = %.8f\n", ntpd_read_fp (ik->offset), ntpd_read_fp (ik->freq), ntpd_read_fp (ik->esterror)); ntpd_submit ("frequency_offset", "loop", ntpd_read_fp (ik->freq)); ntpd_submit ("time_offset", "loop", ntpd_read_fp (ik->offset)); ntpd_submit ("time_offset", "error", ntpd_read_fp (ik->esterror)); free (ik); ik = NULL; status = ntpd_do_query (REQ_PEER_LIST_SUM, 0, 0, NULL, /* request data */ &ps_num, &ps_size, (char **) ((void *) &ps), /* response data */ sizeof (struct info_peer_summary)); if (status != 0) { ERROR ("ntpd plugin: ntpd_do_query (REQ_PEER_LIST_SUM) failed with status %i", status); return (status); } else if ((ps == NULL) || (ps_num == 0) || (ps_size == 0)) { ERROR ("ntpd plugin: ntpd_do_query returned unexpected data. " "(ps = %p; ps_num = %i; ps_size = %i)", (void *) ps, ps_num, ps_size); return (-1); } for (i = 0; i < ps_num; i++) { struct info_peer_summary *ptr; double offset; char peername[NI_MAXHOST]; uint32_t refclock_id; ptr = ps + i; status = ntpd_get_name (peername, sizeof (peername), ptr); if (status != 0) { ERROR ("ntpd plugin: Determining name of peer failed."); continue; } refclock_id = ntpd_get_refclock_id (ptr); /* Convert the `long floating point' offset value to double */ M_LFPTOD (ntohl (ptr->offset_int), ntohl (ptr->offset_frc), offset); DEBUG ("peer %i:\n" " peername = %s\n" " srcadr = 0x%08x\n" " reach = 0%03o\n" " delay = %f\n" " offset_int = %i\n" " offset_frc = %i\n" " offset = %f\n" " dispersion = %f\n", i, peername, ntohl (ptr->srcadr), ptr->reach, ntpd_read_fp (ptr->delay), ntohl (ptr->offset_int), ntohl (ptr->offset_frc), offset, ntpd_read_fp (ptr->dispersion)); if (refclock_id != 1) /* not the system clock (offset will always be zero.. */ ntpd_submit_reach ("time_offset", peername, ptr->reach, offset); ntpd_submit_reach ("time_dispersion", peername, ptr->reach, ntpd_read_fp (ptr->dispersion)); if (refclock_id == 0) /* not a reference clock */ ntpd_submit_reach ("delay", peername, ptr->reach, ntpd_read_fp (ptr->delay)); } free (ps); ps = NULL; return (0); } /* int ntpd_read */ void module_register (void) { plugin_register_config ("ntpd", ntpd_config, config_keys, config_keys_num); plugin_register_read ("ntpd", ntpd_read); } /* void module_register */ collectd-5.4.0/src/PaxHeaders.11991/utils_heap.c0000644037772200116100000000013212204120331017433 xustar000000000000000030 mtime=1376821465.089973696 30 atime=1376821477.230168122 30 ctime=1376821742.038401184 collectd-5.4.0/src/utils_heap.c0000644037772200116100000001110512204120331016175 0ustar00octoeng00000000000000/** * collectd - src/utils_heap.c * Copyright (C) 2009 Florian octo 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; either version 2 of the License, or (at your * option) any later version. * * 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: * Florian octo Forster **/ #include #include #include #include #include #include "utils_heap.h" struct c_heap_s { pthread_mutex_t lock; int (*compare) (const void *, const void *); void **list; size_t list_len; /* # entries used */ size_t list_size; /* # entries allocated */ }; enum reheap_direction { DIR_UP, DIR_DOWN }; static void reheap (c_heap_t *h, size_t root, enum reheap_direction dir) { size_t left; size_t right; size_t min; int status; /* Calculate the positions of the children */ left = (2 * root) + 1; if (left >= h->list_len) left = 0; right = (2 * root) + 2; if (right >= h->list_len) right = 0; /* Check which one of the children is smaller. */ if ((left == 0) && (right == 0)) return; else if (left == 0) min = right; else if (right == 0) min = left; else { status = h->compare (h->list[left], h->list[right]); if (status > 0) min = right; else min = left; } status = h->compare (h->list[root], h->list[min]); if (status <= 0) { /* We didn't need to change anything, so the rest of the tree should be * okay now. */ return; } else /* if (status > 0) */ { void *tmp; tmp = h->list[root]; h->list[root] = h->list[min]; h->list[min] = tmp; } if ((dir == DIR_UP) && (root == 0)) return; if (dir == DIR_UP) reheap (h, (root - 1) / 2, dir); else if (dir == DIR_DOWN) reheap (h, min, dir); } /* void reheap */ c_heap_t *c_heap_create (int (*compare) (const void *, const void *)) { c_heap_t *h; if (compare == NULL) return (NULL); h = malloc (sizeof (*h)); if (h == NULL) return (NULL); memset (h, 0, sizeof (*h)); pthread_mutex_init (&h->lock, /* attr = */ NULL); h->compare = compare; h->list = NULL; h->list_len = 0; h->list_size = 0; return (h); } /* c_heap_t *c_heap_create */ void c_heap_destroy (c_heap_t *h) { if (h == NULL) return; h->list_len = 0; h->list_size = 0; free (h->list); h->list = NULL; pthread_mutex_destroy (&h->lock); free (h); } /* void c_heap_destroy */ int c_heap_insert (c_heap_t *h, void *ptr) { size_t index; if ((h == NULL) || (ptr == NULL)) return (-EINVAL); pthread_mutex_lock (&h->lock); assert (h->list_len <= h->list_size); if (h->list_len == h->list_size) { void **tmp; tmp = realloc (h->list, (h->list_size + 16) * sizeof (*h->list)); if (tmp == NULL) { pthread_mutex_unlock (&h->lock); return (-ENOMEM); } h->list = tmp; h->list_size += 16; } /* Insert the new node as a leaf. */ index = h->list_len; h->list[index] = ptr; h->list_len++; /* Reorganize the heap from bottom up. */ reheap (h, /* parent of this node = */ (index - 1) / 2, DIR_UP); pthread_mutex_unlock (&h->lock); return (0); } /* int c_heap_insert */ void *c_heap_get_root (c_heap_t *h) { void *ret = NULL; if (h == NULL) return (NULL); pthread_mutex_lock (&h->lock); if (h->list_len == 0) { pthread_mutex_unlock (&h->lock); return (NULL); } else if (h->list_len == 1) { ret = h->list[0]; h->list[0] = NULL; h->list_len = 0; } else /* if (h->list_len > 1) */ { ret = h->list[0]; h->list[0] = h->list[h->list_len - 1]; h->list[h->list_len - 1] = NULL; h->list_len--; reheap (h, /* root = */ 0, DIR_DOWN); } /* free some memory */ if ((h->list_len + 32) < h->list_size) { void **tmp; tmp = realloc (h->list, (h->list_len + 16) * sizeof (*h->list)); if (tmp != NULL) { h->list = tmp; h->list_size = h->list_len + 16; } } pthread_mutex_unlock (&h->lock); return (ret); } /* void *c_heap_get_root */ /* vim: set sw=2 sts=2 et fdm=marker : */ collectd-5.4.0/src/PaxHeaders.11991/match_regex.c0000644037772200116100000000013212204120331017564 xustar000000000000000030 mtime=1376821465.077973503 30 atime=1376821477.218167931 30 ctime=1376821742.042401248 collectd-5.4.0/src/match_regex.c0000644037772200116100000001600712204120331016334 0ustar00octoeng00000000000000/** * collectd - src/match_regex.c * Copyright (C) 2008 Sebastian Harl * Copyright (C) 2008 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: * Sebastian Harl * Florian Forster **/ /* * This module allows to filter and rewrite value lists based on * Perl-compatible regular expressions. */ #include "collectd.h" #include "filter_chain.h" #include #include #define log_err(...) ERROR ("`regex' match: " __VA_ARGS__) #define log_warn(...) WARNING ("`regex' match: " __VA_ARGS__) /* * private data types */ struct mr_regex_s; typedef struct mr_regex_s mr_regex_t; struct mr_regex_s { regex_t re; char *re_str; mr_regex_t *next; }; struct mr_match_s; typedef struct mr_match_s mr_match_t; struct mr_match_s { mr_regex_t *host; mr_regex_t *plugin; mr_regex_t *plugin_instance; mr_regex_t *type; mr_regex_t *type_instance; _Bool invert; }; /* * internal helper functions */ static void mr_free_regex (mr_regex_t *r) /* {{{ */ { if (r == NULL) return; regfree (&r->re); memset (&r->re, 0, sizeof (r->re)); free (r->re_str); if (r->next != NULL) mr_free_regex (r->next); } /* }}} void mr_free_regex */ static void mr_free_match (mr_match_t *m) /* {{{ */ { if (m == NULL) return; mr_free_regex (m->host); mr_free_regex (m->plugin); mr_free_regex (m->plugin_instance); mr_free_regex (m->type); mr_free_regex (m->type_instance); free (m); } /* }}} void mr_free_match */ static int mr_match_regexen (mr_regex_t *re_head, /* {{{ */ const char *string) { mr_regex_t *re; if (re_head == NULL) return (FC_MATCH_MATCHES); for (re = re_head; re != NULL; re = re->next) { int status; status = regexec (&re->re, string, /* nmatch = */ 0, /* pmatch = */ NULL, /* eflags = */ 0); if (status == 0) { DEBUG ("regex match: Regular expression `%s' matches `%s'.", re->re_str, string); } else { DEBUG ("regex match: Regular expression `%s' does not match `%s'.", re->re_str, string); return (FC_MATCH_NO_MATCH); } } return (FC_MATCH_MATCHES); } /* }}} int mr_match_regexen */ static int mr_config_add_regex (mr_regex_t **re_head, /* {{{ */ oconfig_item_t *ci) { mr_regex_t *re; int status; if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { log_warn ("`%s' needs exactly one string argument.", ci->key); return (-1); } re = (mr_regex_t *) malloc (sizeof (*re)); if (re == NULL) { log_err ("mr_config_add_regex: malloc failed."); return (-1); } memset (re, 0, sizeof (*re)); re->next = NULL; re->re_str = strdup (ci->values[0].value.string); if (re->re_str == NULL) { free (re); log_err ("mr_config_add_regex: strdup failed."); return (-1); } status = regcomp (&re->re, re->re_str, REG_EXTENDED | REG_NOSUB); if (status != 0) { char errmsg[1024]; regerror (status, &re->re, errmsg, sizeof (errmsg)); errmsg[sizeof (errmsg) - 1] = 0; log_err ("Compiling regex `%s' for `%s' failed: %s.", re->re_str, ci->key, errmsg); free (re->re_str); free (re); return (-1); } if (*re_head == NULL) { *re_head = re; } else { mr_regex_t *ptr; ptr = *re_head; while (ptr->next != NULL) ptr = ptr->next; ptr->next = re; } return (0); } /* }}} int mr_config_add_regex */ static int mr_create (const oconfig_item_t *ci, void **user_data) /* {{{ */ { mr_match_t *m; int status; int i; m = (mr_match_t *) malloc (sizeof (*m)); if (m == NULL) { log_err ("mr_create: malloc failed."); return (-ENOMEM); } memset (m, 0, sizeof (*m)); m->invert = 0; status = 0; for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if ((strcasecmp ("Host", child->key) == 0) || (strcasecmp ("Hostname", child->key) == 0)) status = mr_config_add_regex (&m->host, child); else if (strcasecmp ("Plugin", child->key) == 0) status = mr_config_add_regex (&m->plugin, child); else if (strcasecmp ("PluginInstance", child->key) == 0) status = mr_config_add_regex (&m->plugin_instance, child); else if (strcasecmp ("Type", child->key) == 0) status = mr_config_add_regex (&m->type, child); else if (strcasecmp ("TypeInstance", child->key) == 0) status = mr_config_add_regex (&m->type_instance, child); else if (strcasecmp ("Invert", child->key) == 0) status = cf_util_get_boolean(child, &m->invert); else { log_err ("The `%s' configuration option is not understood and " "will be ignored.", child->key); status = 0; } if (status != 0) break; } /* Additional sanity-checking */ while (status == 0) { if ((m->host == NULL) && (m->plugin == NULL) && (m->plugin_instance == NULL) && (m->type == NULL) && (m->type_instance == NULL)) { log_err ("No (valid) regular expressions have been configured. " "This match will be ignored."); status = -1; } break; } if (status != 0) { mr_free_match (m); return (status); } *user_data = m; return (0); } /* }}} int mr_create */ static int mr_destroy (void **user_data) /* {{{ */ { if ((user_data != NULL) && (*user_data != NULL)) mr_free_match (*user_data); return (0); } /* }}} int mr_destroy */ static int mr_match (const data_set_t __attribute__((unused)) *ds, /* {{{ */ const value_list_t *vl, notification_meta_t __attribute__((unused)) **meta, void **user_data) { mr_match_t *m; int match_value = FC_MATCH_MATCHES; int nomatch_value = FC_MATCH_NO_MATCH; if ((user_data == NULL) || (*user_data == NULL)) return (-1); m = *user_data; if (m->invert) { match_value = FC_MATCH_NO_MATCH; nomatch_value = FC_MATCH_MATCHES; } if (mr_match_regexen (m->host, vl->host) == FC_MATCH_NO_MATCH) return (nomatch_value); if (mr_match_regexen (m->plugin, vl->plugin) == FC_MATCH_NO_MATCH) return (nomatch_value); if (mr_match_regexen (m->plugin_instance, vl->plugin_instance) == FC_MATCH_NO_MATCH) return (nomatch_value); if (mr_match_regexen (m->type, vl->type) == FC_MATCH_NO_MATCH) return (nomatch_value); if (mr_match_regexen (m->type_instance, vl->type_instance) == FC_MATCH_NO_MATCH) return (nomatch_value); return (match_value); } /* }}} int mr_match */ void module_register (void) { match_proc_t mproc; memset (&mproc, 0, sizeof (mproc)); mproc.create = mr_create; mproc.destroy = mr_destroy; mproc.match = mr_match; fc_register_match ("regex", mproc); } /* module_register */ /* vim: set sw=4 ts=4 tw=78 noexpandtab fdm=marker : */ collectd-5.4.0/src/PaxHeaders.11991/collectd-nagios.c0000644037772200116100000000013212204120331020345 xustar000000000000000030 mtime=1376821465.061973248 30 atime=1376821477.206167738 30 ctime=1376821742.042401248 collectd-5.4.0/src/collectd-nagios.c0000644037772200116100000004140212204120331017112 0ustar00octoeng00000000000000/** * collectd-nagios - src/collectd-nagios.c * Copyright (C) 2008-2010 Florian octo 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: * Florian octo Forster **/ #if HAVE_CONFIG_H # include "config.h" #endif #if !defined(__GNUC__) || !__GNUC__ # define __attribute__(x) /**/ #endif #include #include #include #include #include #include #include #if NAN_STATIC_DEFAULT # include /* #endif NAN_STATIC_DEFAULT*/ #elif NAN_STATIC_ISOC # ifndef __USE_ISOC99 # define DISABLE_ISOC99 1 # define __USE_ISOC99 1 # endif /* !defined(__USE_ISOC99) */ # include # if DISABLE_ISOC99 # undef DISABLE_ISOC99 # undef __USE_ISOC99 # endif /* DISABLE_ISOC99 */ /* #endif NAN_STATIC_ISOC */ #elif NAN_ZERO_ZERO # include # ifdef NAN # undef NAN # endif # define NAN (0.0 / 0.0) # ifndef isnan # define isnan(f) ((f) != (f)) # endif /* !defined(isnan) */ # ifndef isfinite # define isfinite(f) (((f) - (f)) == 0.0) # endif # ifndef isinf # define isinf(f) (!isfinite(f) && !isnan(f)) # endif #endif /* NAN_ZERO_ZERO */ #include "libcollectdclient/collectd/client.h" #define RET_OKAY 0 #define RET_WARNING 1 #define RET_CRITICAL 2 #define RET_UNKNOWN 3 #define CON_NONE 0 #define CON_AVERAGE 1 #define CON_SUM 2 #define CON_PERCENTAGE 3 struct range_s { double min; double max; int invert; }; typedef struct range_s range_t; extern char *optarg; extern int optind, opterr, optopt; static char *socket_file_g = NULL; static char *value_string_g = NULL; static char *hostname_g = NULL; static range_t range_critical_g; static range_t range_warning_g; static int consolitation_g = CON_NONE; static _Bool nan_is_error_g = 0; static char **match_ds_g = NULL; static int match_ds_num_g = 0; /* `strdup' is an XSI extension. I don't want to pull in all of XSI just for * that, so here's an own implementation.. It's easy enough. The GCC attributes * are supposed to get good performance.. -octo */ __attribute__((malloc, nonnull (1))) static char *cn_strdup (const char *str) /* {{{ */ { size_t strsize; char *ret; strsize = strlen (str) + 1; ret = (char *) malloc (strsize); if (ret != NULL) memcpy (ret, str, strsize); return (ret); } /* }}} char *cn_strdup */ static int filter_ds (size_t *values_num, double **values, char ***values_names) { gauge_t *new_values; char **new_names; size_t i; if (match_ds_g == NULL) return (RET_OKAY); new_values = (gauge_t *)calloc (match_ds_num_g, sizeof (*new_values)); if (new_values == NULL) { fprintf (stderr, "malloc failed: %s\n", strerror (errno)); return (RET_UNKNOWN); } new_names = (char **)calloc (match_ds_num_g, sizeof (*new_names)); if (new_names == NULL) { fprintf (stderr, "malloc failed: %s\n", strerror (errno)); free (new_values); return (RET_UNKNOWN); } for (i = 0; i < (size_t) match_ds_num_g; i++) { size_t j; /* match_ds_g keeps pointers into argv but the names will be freed */ new_names[i] = cn_strdup (match_ds_g[i]); if (new_names[i] == NULL) { fprintf (stderr, "cn_strdup failed: %s\n", strerror (errno)); free (new_values); for (j = 0; j < i; j++) free (new_names[j]); free (new_names); return (RET_UNKNOWN); } for (j = 0; j < *values_num; j++) if (strcasecmp (new_names[i], (*values_names)[j]) == 0) break; if (j == *values_num) { printf ("ERROR: DS `%s' is not available.\n", new_names[i]); free (new_values); for (j = 0; j <= i; j++) free (new_names[j]); free (new_names); return (RET_CRITICAL); } new_values[i] = (*values)[j]; } free (*values); for (i = 0; i < *values_num; i++) free ((*values_names)[i]); free (*values_names); *values = new_values; *values_names = new_names; *values_num = match_ds_num_g; return (RET_OKAY); } /* int filter_ds */ static void parse_range (char *string, range_t *range) { char *min_ptr; char *max_ptr; if (*string == '@') { range->invert = 1; string++; } max_ptr = strchr (string, ':'); if (max_ptr == NULL) { min_ptr = NULL; max_ptr = string; } else { min_ptr = string; *max_ptr = '\0'; max_ptr++; } assert (max_ptr != NULL); /* `10' == `0:10' */ if (min_ptr == NULL) range->min = 0.0; /* :10 == ~:10 == -inf:10 */ else if ((*min_ptr == '\0') || (*min_ptr == '~')) range->min = NAN; else range->min = atof (min_ptr); if ((*max_ptr == '\0') || (*max_ptr == '~')) range->max = NAN; else range->max = atof (max_ptr); } /* void parse_range */ static int match_range (range_t *range, double value) { int ret = 0; if (!isnan (range->min) && (range->min > value)) ret = 1; if (!isnan (range->max) && (range->max < value)) ret = 1; return (((ret - range->invert) == 0) ? 0 : 1); } /* int match_range */ static void usage (const char *name) { fprintf (stderr, "Usage: %s <-s socket> <-n value_spec> <-H hostname> [options]\n" "\n" "Valid options are:\n" " -s Path to collectd's UNIX-socket.\n" " -n Value specification to get from collectd.\n" " Format: `plugin-instance/type-instance'\n" " -d Select the DS to examine. May be repeated to examine multiple\n" " DSes. By default all DSes are used.\n" " -g Method to use to consolidate several DSes.\n" " See below for a list of valid arguments.\n" " -H Hostname to query the values for.\n" " -c Critical range\n" " -w Warning range\n" " -m Treat \"Not a Number\" (NaN) as critical (default: warning)\n" "\n" "Consolidation functions:\n" " none: Apply the warning- and critical-ranges to each data-source\n" " individually.\n" " average: Calculate the average of all matching DSes and apply the\n" " warning- and critical-ranges to the calculated average.\n" " sum: Apply the ranges to the sum of all DSes.\n" " percentage: Apply the ranges to the ratio (in percent) of the first value\n" " and the sum of all values." "\n", name); exit (1); } /* void usage */ static int do_listval (lcc_connection_t *connection) { lcc_identifier_t *ret_ident = NULL; size_t ret_ident_num = 0; char *hostname = NULL; int status; size_t i; status = lcc_listval (connection, &ret_ident, &ret_ident_num); if (status != 0) { printf ("UNKNOWN: %s\n", lcc_strerror (connection)); if (ret_ident != NULL) free (ret_ident); return (RET_UNKNOWN); } status = lcc_sort_identifiers (connection, ret_ident, ret_ident_num); if (status != 0) { printf ("UNKNOWN: %s\n", lcc_strerror (connection)); if (ret_ident != NULL) free (ret_ident); return (RET_UNKNOWN); } for (i = 0; i < ret_ident_num; ++i) { char id[1024]; if ((hostname_g != NULL) && (strcasecmp (hostname_g, ret_ident[i].host))) continue; if ((hostname == NULL) || strcasecmp (hostname, ret_ident[i].host)) { if (hostname != NULL) free (hostname); hostname = strdup (ret_ident[i].host); printf ("Host: %s\n", hostname); } /* empty hostname; not to be printed again */ ret_ident[i].host[0] = '\0'; status = lcc_identifier_to_string (connection, id, sizeof (id), ret_ident + i); if (status != 0) { printf ("ERROR: listval: Failed to convert returned " "identifier to a string: %s\n", lcc_strerror (connection)); continue; } /* skip over the (empty) hostname and following '/' */ printf ("\t%s\n", id + 1); } if (ret_ident != NULL) free (ret_ident); return (RET_OKAY); } /* int do_listval */ static int do_check_con_none (size_t values_num, double *values, char **values_names) { int num_critical = 0; int num_warning = 0; int num_okay = 0; const char *status_str = "UNKNOWN"; int status_code = RET_UNKNOWN; size_t i; for (i = 0; i < values_num; i++) { if (isnan (values[i])) { if (nan_is_error_g) num_critical++; else num_warning++; } else if (match_range (&range_critical_g, values[i]) != 0) num_critical++; else if (match_range (&range_warning_g, values[i]) != 0) num_warning++; else num_okay++; } if ((num_critical == 0) && (num_warning == 0) && (num_okay == 0)) { printf ("WARNING: No defined values found\n"); return (RET_WARNING); } else if ((num_critical == 0) && (num_warning == 0)) { status_str = "OKAY"; status_code = RET_OKAY; } else if (num_critical == 0) { status_str = "WARNING"; status_code = RET_WARNING; } else { status_str = "CRITICAL"; status_code = RET_CRITICAL; } printf ("%s: %i critical, %i warning, %i okay", status_str, num_critical, num_warning, num_okay); if (values_num > 0) { printf (" |"); for (i = 0; i < values_num; i++) printf (" %s=%f;;;;", values_names[i], values[i]); } printf ("\n"); return (status_code); } /* int do_check_con_none */ static int do_check_con_average (size_t values_num, double *values, char **values_names) { size_t i; double total; int total_num; double average; const char *status_str = "UNKNOWN"; int status_code = RET_UNKNOWN; total = 0.0; total_num = 0; for (i = 0; i < values_num; i++) { if (isnan (values[i])) { if (!nan_is_error_g) continue; printf ("CRITICAL: Data source \"%s\" is NaN\n", values_names[i]); return (RET_CRITICAL); } total += values[i]; total_num++; } if (total_num == 0) { printf ("WARNING: No defined values found\n"); return (RET_WARNING); } average = total / total_num; if (match_range (&range_critical_g, average) != 0) { status_str = "CRITICAL"; status_code = RET_CRITICAL; } else if (match_range (&range_warning_g, average) != 0) { status_str = "WARNING"; status_code = RET_WARNING; } else { status_str = "OKAY"; status_code = RET_OKAY; } printf ("%s: %g average |", status_str, average); for (i = 0; i < values_num; i++) printf (" %s=%f;;;;", values_names[i], values[i]); printf ("\n"); return (status_code); } /* int do_check_con_average */ static int do_check_con_sum (size_t values_num, double *values, char **values_names) { size_t i; double total; int total_num; const char *status_str = "UNKNOWN"; int status_code = RET_UNKNOWN; total = 0.0; total_num = 0; for (i = 0; i < values_num; i++) { if (isnan (values[i])) { if (!nan_is_error_g) continue; printf ("CRITICAL: Data source \"%s\" is NaN\n", values_names[i]); return (RET_CRITICAL); } total += values[i]; total_num++; } if (total_num == 0) { printf ("WARNING: No defined values found\n"); return (RET_WARNING); } if (match_range (&range_critical_g, total) != 0) { status_str = "CRITICAL"; status_code = RET_CRITICAL; } else if (match_range (&range_warning_g, total) != 0) { status_str = "WARNING"; status_code = RET_WARNING; } else { status_str = "OKAY"; status_code = RET_OKAY; } printf ("%s: %g sum |", status_str, total); for (i = 0; i < values_num; i++) printf (" %s=%f;;;;", values_names[i], values[i]); printf ("\n"); return (status_code); } /* int do_check_con_sum */ static int do_check_con_percentage (size_t values_num, double *values, char **values_names) { size_t i; double sum = 0.0; double percentage; const char *status_str = "UNKNOWN"; int status_code = RET_UNKNOWN; if ((values_num < 1) || (isnan (values[0]))) { printf ("WARNING: The first value is not defined\n"); return (RET_WARNING); } for (i = 0; i < values_num; i++) { if (isnan (values[i])) { if (!nan_is_error_g) continue; printf ("CRITICAL: Data source \"%s\" is NaN\n", values_names[i]); return (RET_CRITICAL); } sum += values[i]; } if (sum == 0.0) { printf ("WARNING: Values sum up to zero\n"); return (RET_WARNING); } percentage = 100.0 * values[0] / sum; if (match_range (&range_critical_g, percentage) != 0) { status_str = "CRITICAL"; status_code = RET_CRITICAL; } else if (match_range (&range_warning_g, percentage) != 0) { status_str = "WARNING"; status_code = RET_WARNING; } else { status_str = "OKAY"; status_code = RET_OKAY; } printf ("%s: %lf percent |", status_str, percentage); for (i = 0; i < values_num; i++) printf (" %s=%lf;;;;", values_names[i], values[i]); return (status_code); } /* int do_check_con_percentage */ static int do_check (lcc_connection_t *connection) { gauge_t *values; char **values_names; size_t values_num; char ident_str[1024]; lcc_identifier_t ident; size_t i; int status; snprintf (ident_str, sizeof (ident_str), "%s/%s", hostname_g, value_string_g); ident_str[sizeof (ident_str) - 1] = 0; memset (&ident, 0, sizeof (ident)); status = lcc_string_to_identifier (connection, &ident, ident_str); if (status != 0) { printf ("ERROR: Creating an identifier failed: %s.\n", lcc_strerror (connection)); LCC_DESTROY (connection); return (RET_CRITICAL); } status = lcc_getval (connection, &ident, &values_num, &values, &values_names); if (status != 0) { printf ("ERROR: Retrieving values from the daemon failed: %s.\n", lcc_strerror (connection)); LCC_DESTROY (connection); return (RET_CRITICAL); } LCC_DESTROY (connection); status = filter_ds (&values_num, &values, &values_names); if (status != RET_OKAY) return (status); status = RET_UNKNOWN; if (consolitation_g == CON_NONE) status = do_check_con_none (values_num, values, values_names); else if (consolitation_g == CON_AVERAGE) status = do_check_con_average (values_num, values, values_names); else if (consolitation_g == CON_SUM) status = do_check_con_sum (values_num, values, values_names); else if (consolitation_g == CON_PERCENTAGE) status = do_check_con_percentage (values_num, values, values_names); free (values); if (values_names != NULL) for (i = 0; i < values_num; i++) free (values_names[i]); free (values_names); return (status); } /* int do_check */ int main (int argc, char **argv) { char address[1024]; lcc_connection_t *connection; int status; range_critical_g.min = NAN; range_critical_g.max = NAN; range_critical_g.invert = 0; range_warning_g.min = NAN; range_warning_g.max = NAN; range_warning_g.invert = 0; while (42) { int c; c = getopt (argc, argv, "w:c:s:n:H:g:d:hm"); if (c < 0) break; switch (c) { case 'c': parse_range (optarg, &range_critical_g); break; case 'w': parse_range (optarg, &range_warning_g); break; case 's': socket_file_g = optarg; break; case 'n': value_string_g = optarg; break; case 'H': hostname_g = optarg; break; case 'g': if (strcasecmp (optarg, "none") == 0) consolitation_g = CON_NONE; else if (strcasecmp (optarg, "average") == 0) consolitation_g = CON_AVERAGE; else if (strcasecmp (optarg, "sum") == 0) consolitation_g = CON_SUM; else if (strcasecmp (optarg, "percentage") == 0) consolitation_g = CON_PERCENTAGE; else { fprintf (stderr, "Unknown consolidation function `%s'.\n", optarg); usage (argv[0]); } break; case 'd': { char **tmp; tmp = (char **) realloc (match_ds_g, (match_ds_num_g + 1) * sizeof (char *)); if (tmp == NULL) { fprintf (stderr, "realloc failed: %s\n", strerror (errno)); return (RET_UNKNOWN); } match_ds_g = tmp; match_ds_g[match_ds_num_g] = cn_strdup (optarg); if (match_ds_g[match_ds_num_g] == NULL) { fprintf (stderr, "cn_strdup failed: %s\n", strerror (errno)); return (RET_UNKNOWN); } match_ds_num_g++; break; } case 'm': nan_is_error_g = 1; break; default: usage (argv[0]); } /* switch (c) */ } if ((socket_file_g == NULL) || (value_string_g == NULL) || ((hostname_g == NULL) && (strcasecmp (value_string_g, "LIST")))) { fprintf (stderr, "Missing required arguments.\n"); usage (argv[0]); } snprintf (address, sizeof (address), "unix:%s", socket_file_g); address[sizeof (address) - 1] = 0; connection = NULL; status = lcc_connect (address, &connection); if (status != 0) { printf ("ERROR: Connecting to daemon at %s failed.\n", socket_file_g); return (RET_CRITICAL); } if (0 == strcasecmp (value_string_g, "LIST")) return (do_listval (connection)); return (do_check (connection)); } /* int main */ collectd-5.4.0/src/PaxHeaders.11991/exec.c0000644037772200116100000000013212204120331016222 xustar000000000000000030 mtime=1376821465.069973376 30 atime=1376821477.214167866 30 ctime=1376821742.042401248 collectd-5.4.0/src/exec.c0000644037772200116100000005306612204120331015000 0ustar00octoeng00000000000000/** * collectd - src/exec.c * Copyright (C) 2007-2010 Florian octo Forster * Copyright (C) 2007-2009 Sebastian Harl * Copyright (C) 2008 Peter Holik * * 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: * Florian octo Forster * Sebastian Harl * Peter Holik **/ #define _BSD_SOURCE /* For setgroups */ #include "collectd.h" #include "common.h" #include "plugin.h" #include "utils_cmd_putval.h" #include "utils_cmd_putnotif.h" #include #include #include #include #include #define PL_NORMAL 0x01 #define PL_NOTIF_ACTION 0x02 #define PL_RUNNING 0x10 /* * Private data types */ /* * Access to this structure is serialized using the `pl_lock' lock and the * `PL_RUNNING' flag. The execution of notifications is *not* serialized, so * all functions used to handle notifications MUST NOT write to this structure. * The `pid' and `status' fields are thus unused if the `PL_NOTIF_ACTION' flag * is set. * The `PL_RUNNING' flag is set in `exec_read' and unset in `exec_read_one'. */ struct program_list_s; typedef struct program_list_s program_list_t; struct program_list_s { char *user; char *group; char *exec; char **argv; int pid; int status; int flags; program_list_t *next; }; typedef struct program_list_and_notification_s { program_list_t *pl; notification_t n; } program_list_and_notification_t; /* * Private variables */ static program_list_t *pl_head = NULL; static pthread_mutex_t pl_lock = PTHREAD_MUTEX_INITIALIZER; /* * Functions */ static void sigchld_handler (int __attribute__((unused)) signal) /* {{{ */ { pid_t pid; int status; while ((pid = waitpid (-1, &status, WNOHANG)) > 0) { program_list_t *pl; for (pl = pl_head; pl != NULL; pl = pl->next) if (pl->pid == pid) break; if (pl != NULL) pl->status = status; } /* while (waitpid) */ } /* void sigchld_handler }}} */ static int exec_config_exec (oconfig_item_t *ci) /* {{{ */ { program_list_t *pl; char buffer[128]; int i; if (ci->children_num != 0) { WARNING ("exec plugin: The config option `%s' may not be a block.", ci->key); return (-1); } if (ci->values_num < 2) { WARNING ("exec plugin: The config option `%s' needs at least two " "arguments.", ci->key); return (-1); } if ((ci->values[0].type != OCONFIG_TYPE_STRING) || (ci->values[1].type != OCONFIG_TYPE_STRING)) { WARNING ("exec plugin: The first two arguments to the `%s' option must " "be string arguments.", ci->key); return (-1); } pl = (program_list_t *) malloc (sizeof (program_list_t)); if (pl == NULL) { ERROR ("exec plugin: malloc failed."); return (-1); } memset (pl, '\0', sizeof (program_list_t)); if (strcasecmp ("NotificationExec", ci->key) == 0) pl->flags |= PL_NOTIF_ACTION; else pl->flags |= PL_NORMAL; pl->user = strdup (ci->values[0].value.string); if (pl->user == NULL) { ERROR ("exec plugin: strdup failed."); sfree (pl); return (-1); } pl->group = strchr (pl->user, ':'); if (pl->group != NULL) { *pl->group = '\0'; pl->group++; } pl->exec = strdup (ci->values[1].value.string); if (pl->exec == NULL) { ERROR ("exec plugin: strdup failed."); sfree (pl->user); sfree (pl); return (-1); } pl->argv = (char **) malloc (ci->values_num * sizeof (char *)); if (pl->argv == NULL) { ERROR ("exec plugin: malloc failed."); sfree (pl->exec); sfree (pl->user); sfree (pl); return (-1); } memset (pl->argv, '\0', ci->values_num * sizeof (char *)); { char *tmp = strrchr (ci->values[1].value.string, '/'); if (tmp == NULL) sstrncpy (buffer, ci->values[1].value.string, sizeof (buffer)); else sstrncpy (buffer, tmp + 1, sizeof (buffer)); } pl->argv[0] = strdup (buffer); if (pl->argv[0] == NULL) { ERROR ("exec plugin: malloc failed."); sfree (pl->argv); sfree (pl->exec); sfree (pl->user); sfree (pl); return (-1); } for (i = 1; i < (ci->values_num - 1); i++) { if (ci->values[i + 1].type == OCONFIG_TYPE_STRING) { pl->argv[i] = strdup (ci->values[i + 1].value.string); } else { if (ci->values[i + 1].type == OCONFIG_TYPE_NUMBER) { ssnprintf (buffer, sizeof (buffer), "%lf", ci->values[i + 1].value.number); } else { if (ci->values[i + 1].value.boolean) sstrncpy (buffer, "true", sizeof (buffer)); else sstrncpy (buffer, "false", sizeof (buffer)); } pl->argv[i] = strdup (buffer); } if (pl->argv[i] == NULL) { ERROR ("exec plugin: strdup failed."); break; } } /* for (i) */ if (i < (ci->values_num - 1)) { while ((--i) >= 0) { sfree (pl->argv[i]); } sfree (pl->argv); sfree (pl->exec); sfree (pl->user); sfree (pl); return (-1); } for (i = 0; pl->argv[i] != NULL; i++) { DEBUG ("exec plugin: argv[%i] = %s", i, pl->argv[i]); } pl->next = pl_head; pl_head = pl; return (0); } /* int exec_config_exec }}} */ static int exec_config (oconfig_item_t *ci) /* {{{ */ { int i; for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if ((strcasecmp ("Exec", child->key) == 0) || (strcasecmp ("NotificationExec", child->key) == 0)) exec_config_exec (child); else { WARNING ("exec plugin: Unknown config option `%s'.", child->key); } } /* for (i) */ return (0); } /* int exec_config }}} */ static void set_environment (void) /* {{{ */ { char buffer[1024]; #ifdef HAVE_SETENV ssnprintf (buffer, sizeof (buffer), "%.3f", CDTIME_T_TO_DOUBLE (plugin_get_interval ())); setenv ("COLLECTD_INTERVAL", buffer, /* overwrite = */ 1); ssnprintf (buffer, sizeof (buffer), "%s", hostname_g); setenv ("COLLECTD_HOSTNAME", buffer, /* overwrite = */ 1); #else ssnprintf (buffer, sizeof (buffer), "COLLECTD_INTERVAL=%.3f", CDTIME_T_TO_DOUBLE (plugin_get_interval ())); putenv (buffer); ssnprintf (buffer, sizeof (buffer), "COLLECTD_HOSTNAME=%s", hostname_g); putenv (buffer); #endif } /* }}} void set_environment */ __attribute__((noreturn)) static void exec_child (program_list_t *pl, int uid, int gid, int egid) /* {{{ */ { int status; char errbuf[1024]; #if HAVE_SETGROUPS if (getuid () == 0) { gid_t glist[2]; size_t glist_len; glist[0] = gid; glist_len = 1; if ((gid != egid) && (egid != -1)) { glist[1] = egid; glist_len = 2; } setgroups (glist_len, glist); } #endif /* HAVE_SETGROUPS */ status = setgid (gid); if (status != 0) { ERROR ("exec plugin: setgid (%i) failed: %s", gid, sstrerror (errno, errbuf, sizeof (errbuf))); exit (-1); } if (egid != -1) { status = setegid (egid); if (status != 0) { ERROR ("exec plugin: setegid (%i) failed: %s", egid, sstrerror (errno, errbuf, sizeof (errbuf))); exit (-1); } } status = setuid (uid); if (status != 0) { ERROR ("exec plugin: setuid (%i) failed: %s", uid, sstrerror (errno, errbuf, sizeof (errbuf))); exit (-1); } status = execvp (pl->exec, pl->argv); ERROR ("exec plugin: Failed to execute ``%s'': %s", pl->exec, sstrerror (errno, errbuf, sizeof (errbuf))); exit (-1); } /* void exec_child }}} */ static void reset_signal_mask (void) /* {{{ */ { sigset_t ss; memset (&ss, 0, sizeof (ss)); sigemptyset (&ss); sigprocmask (SIG_SETMASK, &ss, /* old mask = */ NULL); } /* }}} void reset_signal_mask */ /* * Creates three pipes (one for reading, one for writing and one for errors), * forks a child, sets up the pipes so that fd_in is connected to STDIN of * the child and fd_out is connected to STDOUT and fd_err is connected to STDERR * of the child. Then is calls `exec_child'. */ static int fork_child (program_list_t *pl, int *fd_in, int *fd_out, int *fd_err) /* {{{ */ { int fd_pipe_in[2]; int fd_pipe_out[2]; int fd_pipe_err[2]; char errbuf[1024]; int status; int pid; int uid; int gid; int egid; struct passwd *sp_ptr; struct passwd sp; char nambuf[2048]; if (pl->pid != 0) return (-1); status = pipe (fd_pipe_in); if (status != 0) { ERROR ("exec plugin: pipe failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } status = pipe (fd_pipe_out); if (status != 0) { ERROR ("exec plugin: pipe failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } status = pipe (fd_pipe_err); if (status != 0) { ERROR ("exec plugin: pipe failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } sp_ptr = NULL; status = getpwnam_r (pl->user, &sp, nambuf, sizeof (nambuf), &sp_ptr); if (status != 0) { ERROR ("exec plugin: Failed to get user information for user ``%s'': %s", pl->user, sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } if (sp_ptr == NULL) { ERROR ("exec plugin: No such user: `%s'", pl->user); return (-1); } uid = sp.pw_uid; gid = sp.pw_gid; if (uid == 0) { ERROR ("exec plugin: Cowardly refusing to exec program as root."); return (-1); } /* The group configured in the configfile is set as effective group, because * this way the forked process can (re-)gain the user's primary group. */ egid = -1; if (NULL != pl->group) { if ('\0' != *pl->group) { struct group *gr_ptr = NULL; struct group gr; status = getgrnam_r (pl->group, &gr, nambuf, sizeof (nambuf), &gr_ptr); if (0 != status) { ERROR ("exec plugin: Failed to get group information " "for group ``%s'': %s", pl->group, sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } if (NULL == gr_ptr) { ERROR ("exec plugin: No such group: `%s'", pl->group); return (-1); } egid = gr.gr_gid; } else { egid = gid; } } /* if (pl->group == NULL) */ pid = fork (); if (pid < 0) { ERROR ("exec plugin: fork failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } else if (pid == 0) { int fd_num; int fd; /* Close all file descriptors but the pipe end we need. */ fd_num = getdtablesize (); for (fd = 0; fd < fd_num; fd++) { if ((fd == fd_pipe_in[0]) || (fd == fd_pipe_out[1]) || (fd == fd_pipe_err[1])) continue; close (fd); } /* Connect the `in' pipe to STDIN */ if (fd_pipe_in[0] != STDIN_FILENO) { dup2 (fd_pipe_in[0], STDIN_FILENO); close (fd_pipe_in[0]); } /* Now connect the `out' pipe to STDOUT */ if (fd_pipe_out[1] != STDOUT_FILENO) { dup2 (fd_pipe_out[1], STDOUT_FILENO); close (fd_pipe_out[1]); } /* Now connect the `err' pipe to STDERR */ if (fd_pipe_err[1] != STDERR_FILENO) { dup2 (fd_pipe_err[1], STDERR_FILENO); close (fd_pipe_err[1]); } set_environment (); /* Unblock all signals */ reset_signal_mask (); exec_child (pl, uid, gid, egid); /* does not return */ } close (fd_pipe_in[0]); close (fd_pipe_out[1]); close (fd_pipe_err[1]); if (fd_in != NULL) *fd_in = fd_pipe_in[1]; else close (fd_pipe_in[1]); if (fd_out != NULL) *fd_out = fd_pipe_out[0]; else close (fd_pipe_out[0]); if (fd_err != NULL) *fd_err = fd_pipe_err[0]; else close (fd_pipe_err[0]); return (pid); } /* int fork_child }}} */ static int parse_line (char *buffer) /* {{{ */ { if (strncasecmp ("PUTVAL", buffer, strlen ("PUTVAL")) == 0) return (handle_putval (stdout, buffer)); else if (strncasecmp ("PUTNOTIF", buffer, strlen ("PUTNOTIF")) == 0) return (handle_putnotif (stdout, buffer)); else { ERROR ("exec plugin: Unable to parse command, ignoring line: \"%s\"", buffer); return (-1); } } /* int parse_line }}} */ static void *exec_read_one (void *arg) /* {{{ */ { program_list_t *pl = (program_list_t *) arg; int fd, fd_err, highest_fd; fd_set fdset, copy; int status; char buffer[1200]; /* if not completely read */ char buffer_err[1024]; char *pbuffer = buffer; char *pbuffer_err = buffer_err; status = fork_child (pl, NULL, &fd, &fd_err); if (status < 0) { /* Reset the "running" flag */ pthread_mutex_lock (&pl_lock); pl->flags &= ~PL_RUNNING; pthread_mutex_unlock (&pl_lock); pthread_exit ((void *) 1); } pl->pid = status; assert (pl->pid != 0); FD_ZERO( &fdset ); FD_SET(fd, &fdset); FD_SET(fd_err, &fdset); /* Determine the highest file descriptor */ highest_fd = (fd > fd_err) ? fd : fd_err; /* We use a copy of fdset, as select modifies it */ copy = fdset; while (1) { int len; status = select (highest_fd + 1, ©, NULL, NULL, NULL); if (status < 0) { if (errno == EINTR) continue; break; } if (FD_ISSET(fd, ©)) { char *pnl; len = read(fd, pbuffer, sizeof(buffer) - 1 - (pbuffer - buffer)); if (len < 0) { if (errno == EAGAIN || errno == EINTR) continue; break; } else if (len == 0) break; /* We've reached EOF */ pbuffer[len] = '\0'; len += pbuffer - buffer; pbuffer = buffer; while ((pnl = strchr(pbuffer, '\n'))) { *pnl = '\0'; if (*(pnl-1) == '\r' ) *(pnl-1) = '\0'; parse_line (pbuffer); pbuffer = ++pnl; } /* not completely read ? */ if (pbuffer - buffer < len) { len -= pbuffer - buffer; memmove(buffer, pbuffer, len); pbuffer = buffer + len; } else pbuffer = buffer; } else if (FD_ISSET(fd_err, ©)) { char *pnl; len = read(fd_err, pbuffer_err, sizeof(buffer_err) - 1 - (pbuffer_err - buffer_err)); if (len < 0) { if (errno == EAGAIN || errno == EINTR) continue; break; } else if (len == 0) { /* We've reached EOF */ NOTICE ("exec plugin: Program `%s' has closed STDERR.", pl->exec); /* Remove file descriptor form select() set. */ FD_CLR (fd_err, &fdset); copy = fdset; highest_fd = fd; /* Clean up file descriptor */ close (fd_err); fd_err = -1; continue; } pbuffer_err[len] = '\0'; len += pbuffer_err - buffer_err; pbuffer_err = buffer_err; while ((pnl = strchr(pbuffer_err, '\n'))) { *pnl = '\0'; if (*(pnl-1) == '\r' ) *(pnl-1) = '\0'; ERROR ("exec plugin: exec_read_one: error = %s", pbuffer_err); pbuffer_err = ++pnl; } /* not completely read ? */ if (pbuffer_err - buffer_err < len) { len -= pbuffer_err - buffer_err; memmove(buffer_err, pbuffer_err, len); pbuffer_err = buffer_err + len; } else pbuffer_err = buffer_err; } /* reset copy */ copy = fdset; } DEBUG ("exec plugin: exec_read_one: Waiting for `%s' to exit.", pl->exec); if (waitpid (pl->pid, &status, 0) > 0) pl->status = status; DEBUG ("exec plugin: Child %i exited with status %i.", (int) pl->pid, pl->status); pl->pid = 0; pthread_mutex_lock (&pl_lock); pl->flags &= ~PL_RUNNING; pthread_mutex_unlock (&pl_lock); close (fd); if (fd_err >= 0) close (fd_err); pthread_exit ((void *) 0); return (NULL); } /* void *exec_read_one }}} */ static void *exec_notification_one (void *arg) /* {{{ */ { program_list_t *pl = ((program_list_and_notification_t *) arg)->pl; notification_t *n = &((program_list_and_notification_t *) arg)->n; notification_meta_t *meta; int fd; FILE *fh; int pid; int status; const char *severity; pid = fork_child (pl, &fd, NULL, NULL); if (pid < 0) { sfree (arg); pthread_exit ((void *) 1); } fh = fdopen (fd, "w"); if (fh == NULL) { char errbuf[1024]; ERROR ("exec plugin: fdopen (%i) failed: %s", fd, sstrerror (errno, errbuf, sizeof (errbuf))); kill (pl->pid, SIGTERM); pl->pid = 0; close (fd); sfree (arg); pthread_exit ((void *) 1); } severity = "FAILURE"; if (n->severity == NOTIF_WARNING) severity = "WARNING"; else if (n->severity == NOTIF_OKAY) severity = "OKAY"; fprintf (fh, "Severity: %s\n" "Time: %.3f\n", severity, CDTIME_T_TO_DOUBLE (n->time)); /* Print the optional fields */ if (strlen (n->host) > 0) fprintf (fh, "Host: %s\n", n->host); if (strlen (n->plugin) > 0) fprintf (fh, "Plugin: %s\n", n->plugin); if (strlen (n->plugin_instance) > 0) fprintf (fh, "PluginInstance: %s\n", n->plugin_instance); if (strlen (n->type) > 0) fprintf (fh, "Type: %s\n", n->type); if (strlen (n->type_instance) > 0) fprintf (fh, "TypeInstance: %s\n", n->type_instance); for (meta = n->meta; meta != NULL; meta = meta->next) { if (meta->type == NM_TYPE_STRING) fprintf (fh, "%s: %s\n", meta->name, meta->nm_value.nm_string); else if (meta->type == NM_TYPE_SIGNED_INT) fprintf (fh, "%s: %"PRIi64"\n", meta->name, meta->nm_value.nm_signed_int); else if (meta->type == NM_TYPE_UNSIGNED_INT) fprintf (fh, "%s: %"PRIu64"\n", meta->name, meta->nm_value.nm_unsigned_int); else if (meta->type == NM_TYPE_DOUBLE) fprintf (fh, "%s: %e\n", meta->name, meta->nm_value.nm_double); else if (meta->type == NM_TYPE_BOOLEAN) fprintf (fh, "%s: %s\n", meta->name, meta->nm_value.nm_boolean ? "true" : "false"); } fprintf (fh, "\n%s\n", n->message); fflush (fh); fclose (fh); waitpid (pid, &status, 0); DEBUG ("exec plugin: Child %i exited with status %i.", pid, status); if (n->meta != NULL) plugin_notification_meta_free (n->meta); n->meta = NULL; sfree (arg); pthread_exit ((void *) 0); return (NULL); } /* void *exec_notification_one }}} */ static int exec_init (void) /* {{{ */ { struct sigaction sa; memset (&sa, '\0', sizeof (sa)); sa.sa_handler = sigchld_handler; sigaction (SIGCHLD, &sa, NULL); return (0); } /* int exec_init }}} */ static int exec_read (void) /* {{{ */ { program_list_t *pl; for (pl = pl_head; pl != NULL; pl = pl->next) { pthread_t t; pthread_attr_t attr; /* Only execute `normal' style executables here. */ if ((pl->flags & PL_NORMAL) == 0) continue; pthread_mutex_lock (&pl_lock); /* Skip if a child is already running. */ if ((pl->flags & PL_RUNNING) != 0) { pthread_mutex_unlock (&pl_lock); continue; } pl->flags |= PL_RUNNING; pthread_mutex_unlock (&pl_lock); pthread_attr_init (&attr); pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); plugin_thread_create (&t, &attr, exec_read_one, (void *) pl); pthread_attr_destroy (&attr); } /* for (pl) */ return (0); } /* int exec_read }}} */ static int exec_notification (const notification_t *n, /* {{{ */ user_data_t __attribute__((unused)) *user_data) { program_list_t *pl; program_list_and_notification_t *pln; for (pl = pl_head; pl != NULL; pl = pl->next) { pthread_t t; pthread_attr_t attr; /* Only execute `notification' style executables here. */ if ((pl->flags & PL_NOTIF_ACTION) == 0) continue; /* Skip if a child is already running. */ if (pl->pid != 0) continue; pln = (program_list_and_notification_t *) malloc (sizeof (program_list_and_notification_t)); if (pln == NULL) { ERROR ("exec plugin: malloc failed."); continue; } pln->pl = pl; memcpy (&pln->n, n, sizeof (notification_t)); /* Set the `meta' member to NULL, otherwise `plugin_notification_meta_copy' * will run into an endless loop. */ pln->n.meta = NULL; plugin_notification_meta_copy (&pln->n, n); pthread_attr_init (&attr); pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); plugin_thread_create (&t, &attr, exec_notification_one, (void *) pln); pthread_attr_destroy (&attr); } /* for (pl) */ return (0); } /* }}} int exec_notification */ static int exec_shutdown (void) /* {{{ */ { program_list_t *pl; program_list_t *next; pl = pl_head; while (pl != NULL) { next = pl->next; if (pl->pid > 0) { kill (pl->pid, SIGTERM); INFO ("exec plugin: Sent SIGTERM to %hu", (unsigned short int) pl->pid); } sfree (pl->user); sfree (pl); pl = next; } /* while (pl) */ pl_head = NULL; return (0); } /* int exec_shutdown }}} */ void module_register (void) { plugin_register_complex_config ("exec", exec_config); plugin_register_init ("exec", exec_init); plugin_register_read ("exec", exec_read); plugin_register_notification ("exec", exec_notification, /* user_data = */ NULL); plugin_register_shutdown ("exec", exec_shutdown); } /* void module_register */ /* * vim:shiftwidth=2:softtabstop=2:tabstop=8:fdm=marker */ collectd-5.4.0/src/PaxHeaders.11991/utils_latency.c0000644037772200116100000000013212204120331020155 xustar000000000000000030 mtime=1376821465.089973696 30 atime=1376821477.230168122 30 ctime=1376821742.046401311 collectd-5.4.0/src/utils_latency.c0000644037772200116100000001157612204120331016733 0ustar00octoeng00000000000000/** * collectd - src/utils_latency.c * Copyright (C) 2013 Florian Forster * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Authors: * Florian Forster **/ #include "collectd.h" #include "utils_latency.h" #include "common.h" #ifndef LATENCY_HISTOGRAM_SIZE # define LATENCY_HISTOGRAM_SIZE 1000 #endif struct latency_counter_s { cdtime_t start_time; cdtime_t sum; size_t num; cdtime_t min; cdtime_t max; int histogram[LATENCY_HISTOGRAM_SIZE]; }; latency_counter_t *latency_counter_create () /* {{{ */ { latency_counter_t *lc; lc = malloc (sizeof (*lc)); if (lc == NULL) return (NULL); latency_counter_reset (lc); return (lc); } /* }}} latency_counter_t *latency_counter_create */ void latency_counter_destroy (latency_counter_t *lc) /* {{{ */ { sfree (lc); } /* }}} void latency_counter_destroy */ void latency_counter_add (latency_counter_t *lc, cdtime_t latency) /* {{{ */ { size_t latency_ms; if ((lc == NULL) || (latency == 0)) return; lc->sum += latency; lc->num++; if ((lc->min == 0) && (lc->max == 0)) lc->min = lc->max = latency; if (lc->min > latency) lc->min = latency; if (lc->max < latency) lc->max = latency; /* A latency of _exactly_ 1.0 ms should be stored in the buffer 0, so * subtract one from the cdtime_t value so that exactly 1.0 ms get sorted * accordingly. */ latency_ms = (size_t) CDTIME_T_TO_MS (latency - 1); if (latency_ms < STATIC_ARRAY_SIZE (lc->histogram)) lc->histogram[latency_ms]++; } /* }}} void latency_counter_add */ void latency_counter_reset (latency_counter_t *lc) /* {{{ */ { if (lc == NULL) return; memset (lc, 0, sizeof (*lc)); lc->start_time = cdtime (); } /* }}} void latency_counter_reset */ cdtime_t latency_counter_get_min (latency_counter_t *lc) /* {{{ */ { if (lc == NULL) return (0); return (lc->min); } /* }}} cdtime_t latency_counter_get_min */ cdtime_t latency_counter_get_max (latency_counter_t *lc) /* {{{ */ { if (lc == NULL) return (0); return (lc->max); } /* }}} cdtime_t latency_counter_get_max */ cdtime_t latency_counter_get_sum (latency_counter_t *lc) /* {{{ */ { if (lc == NULL) return (0); return (lc->sum); } /* }}} cdtime_t latency_counter_get_sum */ size_t latency_counter_get_num (latency_counter_t *lc) /* {{{ */ { if (lc == NULL) return (0); return (lc->num); } /* }}} size_t latency_counter_get_num */ cdtime_t latency_counter_get_average (latency_counter_t *lc) /* {{{ */ { double average; if (lc == NULL) return (0); average = CDTIME_T_TO_DOUBLE (lc->sum) / ((double) lc->num); return (DOUBLE_TO_CDTIME_T (average)); } /* }}} cdtime_t latency_counter_get_average */ cdtime_t latency_counter_get_percentile (latency_counter_t *lc, double percent) { double percent_upper; double percent_lower; double ms_upper; double ms_lower; double ms_interpolated; int sum; size_t i; if ((lc == NULL) || !((percent > 0.0) && (percent < 100.0))) return (0); /* Find index i so that at least "percent" events are within i+1 ms. */ percent_upper = 0.0; percent_lower = 0.0; sum = 0; for (i = 0; i < LATENCY_HISTOGRAM_SIZE; i++) { percent_lower = percent_upper; sum += lc->histogram[i]; if (sum == 0) percent_upper = 0.0; else percent_upper = 100.0 * ((double) sum) / ((double) lc->num); if (percent_upper >= percent) break; } if (i >= LATENCY_HISTOGRAM_SIZE) return (0); assert (percent_upper >= percent); assert (percent_lower < percent); ms_upper = (double) (i + 1); ms_lower = (double) i; if (i == 0) return (MS_TO_CDTIME_T (ms_upper)); ms_interpolated = (((percent_upper - percent) * ms_lower) + ((percent - percent_lower) * ms_upper)) / (percent_upper - percent_lower); return (MS_TO_CDTIME_T (ms_interpolated)); } /* }}} cdtime_t latency_counter_get_percentile */ /* vim: set sw=2 sts=2 et fdm=marker : */ collectd-5.4.0/src/PaxHeaders.11991/aquaero.c0000644037772200116100000000013212204120331016733 xustar000000000000000030 mtime=1376821465.061973248 30 atime=1376821477.206167738 30 ctime=1376821742.046401311 collectd-5.4.0/src/aquaero.c0000644037772200116100000001204712204120331015503 0ustar00octoeng00000000000000/** * collectd - src/aquaero.c * Copyright (C) 2013 Alex Deymo * * 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: * Alex Deymo **/ #include "collectd.h" #include "common.h" #include "plugin.h" #include /* * Private variables */ /* Default values for contacting daemon */ static char *conf_device = NULL; static int aquaero_config (oconfig_item_t *ci) { int i; for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("Device", child->key)) cf_util_get_string (child, &conf_device); else { ERROR ("aquaero plugin: Unknown config option \"%s\".", child->key); } } return (0); } static int aquaero_shutdown (void) { libaquaero5_exit(); return (0); } /* int aquaero_shutdown */ static void aquaero_submit (const char *type, const char *type_instance, double value) { const char *instance = conf_device?conf_device:"default"; value_t values[1]; value_list_t vl = VALUE_LIST_INIT; /* Don't report undefined values. */ if (value == AQ5_FLOAT_UNDEF) return; values[0].gauge = value; vl.values = values; vl.values_len = 1; sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "aquaero", sizeof (vl.plugin)); sstrncpy (vl.plugin_instance, instance, sizeof (vl.plugin_instance)); sstrncpy (vl.type, type, sizeof (vl.type)); sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); plugin_dispatch_values (&vl); } /* int aquaero_submit */ /* aquaero_submit_array submits every value of a given array of values */ static void aquaero_submit_array (const char *type, const char *type_instance_prefix, double *value_array, int len) { char type_instance[DATA_MAX_NAME_LEN]; int i; for (i = 0; i < len; i++) { if (value_array[i] == AQ5_FLOAT_UNDEF) continue; snprintf (type_instance, sizeof (type_instance), "%s%d", type_instance_prefix, i + 1); aquaero_submit (type, type_instance, value_array[i]); } } static int aquaero_read (void) { aq5_data_t aq_data; aq5_settings_t aq_sett; char *err_msg = NULL; char type_instance[DATA_MAX_NAME_LEN]; int i; if (libaquaero5_poll(conf_device, &aq_data, &err_msg) < 0) { char errbuf[1024]; ERROR ("aquaero plugin: Failed to poll device \"%s\": %s (%s)", conf_device ? conf_device : "default", err_msg, sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } if (libaquaero5_getsettings(conf_device, &aq_sett, &err_msg) < 0) { char errbuf[1024]; ERROR ("aquaero plugin: Failed to get settings " "for device \"%s\": %s (%s)", conf_device ? conf_device : "default", err_msg, sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } /* CPU Temperature sensor */ aquaero_submit("temperature", "cpu", aq_data.cpu_temp[0]); /* Temperature sensors */ aquaero_submit_array("temperature", "sensor", aq_data.temp, AQ5_NUM_TEMP); /* Virtual temperature sensors */ aquaero_submit_array("temperature", "virtual", aq_data.vtemp, AQ5_NUM_VIRT_SENSORS); /* Software temperature sensors */ aquaero_submit_array("temperature", "software", aq_data.stemp, AQ5_NUM_SOFT_SENSORS); /* Other temperature sensors */ aquaero_submit_array("temperature", "other", aq_data.otemp, AQ5_NUM_OTHER_SENSORS); /* Fans */ for (i = 0; i < AQ5_NUM_FAN; i++) { if ((aq_sett.fan_data_source[i] == NONE) || (aq_data.fan_vrm_temp[i] != AQ5_FLOAT_UNDEF)) continue; snprintf (type_instance, sizeof (type_instance), "fan%d", i + 1); aquaero_submit ("fanspeed", type_instance, aq_data.fan_rpm[i]); aquaero_submit ("percentage", type_instance, aq_data.fan_duty[i]); aquaero_submit ("voltage", type_instance, aq_data.fan_voltage[i]); aquaero_submit ("current", type_instance, aq_data.fan_current[i]); /* Report the voltage reglator module (VRM) temperature with a * different type instance. */ snprintf (type_instance, sizeof (type_instance), "fan%d-vrm", i + 1); aquaero_submit ("temperature", type_instance, aq_data.fan_vrm_temp[i]); } /* Flow sensors */ aquaero_submit_array("flow", "sensor", aq_data.flow, AQ5_NUM_FLOW); /* Liquid level */ aquaero_submit_array("percentage", "waterlevel", aq_data.level, AQ5_NUM_LEVEL); return (0); } void module_register (void) { plugin_register_complex_config ("aquaero", aquaero_config); plugin_register_read ("aquaero", aquaero_read); plugin_register_shutdown ("aquaero", aquaero_shutdown); } /* void module_register */ /* vim: set sw=8 sts=8 noet : */ collectd-5.4.0/src/PaxHeaders.11991/collectd-nagios.10000644037772200116100000000013212204120752020272 xustar000000000000000030 mtime=1376821738.754348775 30 atime=1376821738.762348903 30 ctime=1376821742.046401311 collectd-5.4.0/src/collectd-nagios.10000644037772200116100000002031312204120752017035 0ustar00octoeng00000000000000.\" Automatically generated by Pod::Man 2.25 (Pod::Simple 3.16) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .ie \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .el \{\ . de IX .. .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "COLLECTD-NAGIOS 1" .TH COLLECTD-NAGIOS 1 "2013-08-18" "5.4.0" "collectd" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" collectd\-nagios \- Nagios plugin for querying collectd .SH "SYNOPSIS" .IX Header "SYNOPSIS" collectd-nagios \fB\-s\fR \fIsocket\fR \fB\-n\fR \fIvalue_spec\fR \fB\-H\fR \fIhostname\fR \fI[options]\fR .SH "DESCRIPTION" .IX Header "DESCRIPTION" This small program is the glue between collectd and nagios. collectd collects various performance statistics which it provides via the \f(CW\*(C`unixsock plugin\*(C'\fR, see \fIcollectd\-unixsock\fR\|(5). This program is called by Nagios, connects to the \&\s-1UNIX\s0 socket and reads the values from collectd. It then returns \fB\s-1OKAY\s0\fR, \&\fB\s-1WARNING\s0\fR or \fB\s-1CRITICAL\s0\fR depending on the values and the ranges provided by Nagios. .SH "ARGUMENTS AND OPTIONS" .IX Header "ARGUMENTS AND OPTIONS" The following arguments and options are required and understood by collectd-nagios. The order of the arguments generally doesn't matter, as long as no argument is passed more than once. .IP "\fB\-s\fR \fIsocket\fR" 4 .IX Item "-s socket" Path of the \s-1UNIX\s0 socket opened by collectd's \f(CW\*(C`unixsock plugin\*(C'\fR. .IP "\fB\-n\fR \fIvalue_spec\fR" 4 .IX Item "-n value_spec" The value to read from collectd. The argument is in the form \&\f(CW\*(C`plugin[\-instance]/type[\-instance]\*(C'\fR. .IP "\fB\-H\fR \fIhostname\fR" 4 .IX Item "-H hostname" Hostname to query the values for. .IP "\fB\-d\fR \fIdata_source\fR" 4 .IX Item "-d data_source" Each \fIvalue_spec\fR may be made of multiple \*(L"data sources\*(R". With this option you can select one or more data sources. To select multiple data sources simply specify this option again. If multiple data sources are examined they are handled according to the consolidation function given with the \fB\-g\fR option. .IP "\fB\-g\fR \fBnone\fR\fI|\fR\fBaverage\fR\fI|\fR\fBsum\fR" 4 .IX Item "-g none|average|sum" When multiple data sources are selected from a value spec, they can be handled differently depending on this option. The values of the following meaning: .RS 4 .IP "\fBnone\fR" 4 .IX Item "none" No consolidation if done and the warning and critical regions are applied to each value independently. .IP "\fBaverage\fR" 4 .IX Item "average" The warning and critical ranges are applied to the average of all values. .IP "\fBsum\fR" 4 .IX Item "sum" The warning and critical ranges are applied to the sum of all values. .IP "\fBpercentage\fR" 4 .IX Item "percentage" The warning and critical ranges are applied to the ratio (in percent) of the first value and the sum of all values. A warning is returned if the first value is not defined or if all values sum up to zero. .RE .RS 4 .RE .IP "\fB\-c\fR \fIrange\fR" 4 .IX Item "-c range" .PD 0 .IP "\fB\-w\fR \fIrange\fR" 4 .IX Item "-w range" .PD Set the critical (\fB\-c\fR) and warning (\fB\-w\fR) ranges. These options mostly follow the normal syntax of Nagios plugins. The general format is "\fImin\fR\fB:\fR\fImax\fR". If a value is smaller than \fImin\fR or bigger than \fImax\fR, a \&\fIwarning\fR or \fIcritical\fR status is returned, otherwise the status is \&\fIsuccess\fR. .Sp The tilde sign (\fB~\fR) can be used to explicitly specify infinity. If \fB~\fR is used as a \fImin\fR value, negative infinity is used. In case of \fImax\fR, it is interpreted as positive infinity. .Sp If the first character of the \fIrange\fR is the at\ sign (\fB@\fR), the meaning of the range will be inverted. I.\ e. all values \fIwithin\fR the range will yield a \fIwarning\fR or \fIcritical\fR status, while all values \fIoutside\fR the range will result in a \fIsuccess\fR status. .Sp \&\fImin\fR (and the colon) may be omitted, \&\fImin\fR is then assumed to be zero. If \fImax\fR (but not the trailing colon) is omitted, \fImax\fR is assumed to be positive infinity. .IP "\fB\-m\fR" 4 .IX Item "-m" If this option is given, \*(L"Not a Number\*(R" (NaN) is treated as \fIcritical\fR. By default, the \fInone\fR consolidation reports NaNs as \fIwarning\fR. Other consolidations simply ignore NaN values. .SH "RETURN VALUE" .IX Header "RETURN VALUE" As usual for Nagios plugins, this program writes a short, one line status message to \s-1STDOUT\s0 and signals success or failure with it's return value. It exits with a return value of \fB0\fR for \fIsuccess\fR, \fB1\fR for \fIwarning\fR and \fB2\fR for \fIcritical\fR. If the values are not available or some other error occurred, it returns \fB3\fR for \fIunknown\fR. .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIcollectd\fR\|(1), \&\fIcollectd.conf\fR\|(5), \&\fIcollectd\-unixsock\fR\|(5), .SH "AUTHOR" .IX Header "AUTHOR" Florian Forster collectd-5.4.0/src/PaxHeaders.11991/utils_match.h0000644037772200116100000000013212204120331017617 xustar000000000000000030 mtime=1376821465.089973696 30 atime=1376821477.230168122 30 ctime=1376821742.050401375 collectd-5.4.0/src/utils_match.h0000644037772200116100000001142012204120331016361 0ustar00octoeng00000000000000/** * collectd - src/utils_match.h * Copyright (C) 2008 Florian octo 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; either version 2 of the License, or (at your * option) any later version. * * 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: * Florian octo Forster **/ #ifndef UTILS_MATCH_H #define UTILS_MATCH_H 1 #include "plugin.h" /* * Defines */ #define UTILS_MATCH_DS_TYPE_GAUGE 0x10 #define UTILS_MATCH_DS_TYPE_COUNTER 0x20 #define UTILS_MATCH_DS_TYPE_DERIVE 0x40 #define UTILS_MATCH_DS_TYPE_ABSOLUTE 0x80 #define UTILS_MATCH_CF_GAUGE_AVERAGE 0x01 #define UTILS_MATCH_CF_GAUGE_MIN 0x02 #define UTILS_MATCH_CF_GAUGE_MAX 0x04 #define UTILS_MATCH_CF_GAUGE_LAST 0x08 #define UTILS_MATCH_CF_COUNTER_SET 0x01 #define UTILS_MATCH_CF_COUNTER_ADD 0x02 #define UTILS_MATCH_CF_COUNTER_INC 0x04 #define UTILS_MATCH_CF_DERIVE_SET 0x01 #define UTILS_MATCH_CF_DERIVE_ADD 0x02 #define UTILS_MATCH_CF_DERIVE_INC 0x04 #define UTILS_MATCH_CF_ABSOLUTE_SET 0x01 #define UTILS_MATCH_CF_ABSOLUTE_ADD 0x02 #define UTILS_MATCH_CF_ABSOLUTE_INC 0x04 /* * Data types */ struct cu_match_s; typedef struct cu_match_s cu_match_t; struct cu_match_value_s { int ds_type; value_t value; unsigned int values_num; }; typedef struct cu_match_value_s cu_match_value_t; /* * Prototypes */ /* * NAME * match_create_callback * * DESCRIPTION * Creates a new `cu_match_t' object which will use the regular expression * `regex' to match lines, see the `match_apply' method below. If the line * matches, the callback passed in `callback' will be called along with the * pointer `user_pointer'. * The string that's passed to the callback depends on the regular expression: * If the regular expression includes a sub-match, i. e. something like * "value=([0-9][0-9]*)" * then only the submatch (the part in the parenthesis) will be passed to the * callback. If there is no submatch, then the entire string is passed to the * callback. * The optional `excluderegex' allows to exclude the line from the match, if * the excluderegex matches. */ cu_match_t *match_create_callback (const char *regex, const char *excluderegex, int (*callback) (const char *str, char * const *matches, size_t matches_num, void *user_data), void *user_data); /* * NAME * match_create_simple * * DESCRIPTION * Creates a new `cu_match_t' with a default callback. The user data for that * default callback will be a `cu_match_value_t' structure, with * `ds_type' copied to the structure. The default callback will handle the * string as containing a number (see strtoll(3) and strtod(3)) and store that * number in the `value' member. How that is done depends on `ds_type': * * UTILS_MATCH_DS_TYPE_GAUGE * The function will search for a floating point number in the string and * store it in value.gauge. * UTILS_MATCH_DS_TYPE_COUNTER_SET * The function will search for an integer in the string and store it in * value.counter. * UTILS_MATCH_DS_TYPE_COUNTER_ADD * The function will search for an integer in the string and add it to the * value in value.counter. * UTILS_MATCH_DS_TYPE_COUNTER_INC * The function will not search for anything in the string and increase * value.counter by one. */ cu_match_t *match_create_simple (const char *regex, const char *excluderegex, int ds_type); /* * NAME * match_destroy * * DESCRIPTION * Destroys the object and frees all internal resources. */ void match_destroy (cu_match_t *obj); /* * NAME * match_apply * * DESCRIPTION * Tries to match the string `str' with the regular expression of `obj'. If * the string matches, calls the callback in `obj' with the (sub-)match. * * The user_data pointer passed to `match_create_callback' is NOT freed * automatically. The `cu_match_value_t' structure allocated by * `match_create_callback' is freed automatically. */ int match_apply (cu_match_t *obj, const char *str); /* * NAME * match_get_user_data * * DESCRIPTION * Returns the pointer passed to `match_create_callback' or a pointer to the * `cu_match_value_t' structure allocated by `match_create_simple'. */ void *match_get_user_data (cu_match_t *obj); #endif /* UTILS_MATCH_H */ /* vim: set sw=2 sts=2 ts=8 : */ collectd-5.4.0/src/PaxHeaders.11991/lvm.c0000644037772200116100000000013212204120331016074 xustar000000000000000030 mtime=1376821465.073973439 30 atime=1376821477.218167931 30 ctime=1376821742.050401375 collectd-5.4.0/src/lvm.c0000644037772200116100000000531212204120331014641 0ustar00octoeng00000000000000/** * collectd - src/lvm.c * Copyright (C) 2013 Chad Malfait * * 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: * Chad Malfait **/ #include #include "collectd.h" #include "common.h" #include "plugin.h" static void lvm_submit (char const *plugin_instance, char const *type_instance, uint64_t ivalue) { value_t v; value_list_t vl = VALUE_LIST_INIT; v.gauge = (gauge_t) ivalue; vl.values = &v; vl.values_len = 1; sstrncpy(vl.host, hostname_g, sizeof (vl.host)); sstrncpy(vl.plugin, "lvm", sizeof (vl.plugin)); sstrncpy(vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance)); sstrncpy(vl.type, "df_complex", sizeof (vl.type)); sstrncpy(vl.type_instance, type_instance, sizeof (vl.type_instance)); plugin_dispatch_values (&vl); } static int vg_read(vg_t vg, char const *vg_name) { struct dm_list *lvs; struct lvm_lv_list *lvl; lvm_submit (vg_name, "free", lvm_vg_get_free_size(vg)); lvs = lvm_vg_list_lvs(vg); dm_list_iterate_items(lvl, lvs) { lvm_submit(vg_name, lvm_lv_get_name(lvl->lv), lvm_lv_get_size(lvl->lv)); } return (0); } static int lvm_read(void) { lvm_t lvm; struct dm_list *vg_names; struct lvm_str_list *name_list; lvm = lvm_init(NULL); if (!lvm) { ERROR("lvm plugin: lvm_init failed."); return (-1); } vg_names = lvm_list_vg_names(lvm); if (!vg_names) { ERROR("lvm plugin lvm_list_vg_name failed %s", lvm_errmsg(lvm)); lvm_quit(lvm); return (-1); } dm_list_iterate_items(name_list, vg_names) { vg_t vg; vg = lvm_vg_open(lvm, name_list->str, "r", 0); if (!vg) { ERROR ("lvm plugin: lvm_vg_open (%s) failed: %s", name_list->str, lvm_errmsg(lvm)); continue; } vg_read(vg, name_list->str); lvm_vg_close(vg); } lvm_quit(lvm); return (0); } /*lvm_read */ void module_register(void) { plugin_register_read("lvm", lvm_read); } /* void module_register */ collectd-5.4.0/src/PaxHeaders.11991/utils_cache.h0000644037772200116100000000013212204120331017566 xustar000000000000000030 mtime=1376821465.089973696 30 atime=1376821477.230168122 30 ctime=1376821742.050401375 collectd-5.4.0/src/utils_cache.h0000644037772200116100000000612512204120331016336 0ustar00octoeng00000000000000/** * collectd - src/utils_cache.h * Copyright (C) 2007 Florian octo 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 * * Author: * Florian octo Forster **/ #ifndef UTILS_CACHE_H #define UTILS_CACHE_H 1 #include "plugin.h" #define STATE_OKAY 0 #define STATE_WARNING 1 #define STATE_ERROR 2 #define STATE_MISSING 15 int uc_init (void); int uc_check_timeout (void); int uc_update (const data_set_t *ds, const value_list_t *vl); int uc_get_rate_by_name (const char *name, gauge_t **ret_values, size_t *ret_values_num); gauge_t *uc_get_rate (const data_set_t *ds, const value_list_t *vl); int uc_get_names (char ***ret_names, cdtime_t **ret_times, size_t *ret_number); int uc_get_state (const data_set_t *ds, const value_list_t *vl); int uc_set_state (const data_set_t *ds, const value_list_t *vl, int state); int uc_get_hits (const data_set_t *ds, const value_list_t *vl); int uc_set_hits (const data_set_t *ds, const value_list_t *vl, int hits); int uc_inc_hits (const data_set_t *ds, const value_list_t *vl, int step); int uc_get_history (const data_set_t *ds, const value_list_t *vl, gauge_t *ret_history, size_t num_steps, size_t num_ds); int uc_get_history_by_name (const char *name, gauge_t *ret_history, size_t num_steps, size_t num_ds); /* * Meta data interface */ int uc_meta_data_exists (const value_list_t *vl, const char *key); int uc_meta_data_delete (const value_list_t *vl, const char *key); int uc_meta_data_add_string (const value_list_t *vl, const char *key, const char *value); int uc_meta_data_add_signed_int (const value_list_t *vl, const char *key, int64_t value); int uc_meta_data_add_unsigned_int (const value_list_t *vl, const char *key, uint64_t value); int uc_meta_data_add_double (const value_list_t *vl, const char *key, double value); int uc_meta_data_add_boolean (const value_list_t *vl, const char *key, _Bool value); int uc_meta_data_get_string (const value_list_t *vl, const char *key, char **value); int uc_meta_data_get_signed_int (const value_list_t *vl, const char *key, int64_t *value); int uc_meta_data_get_unsigned_int (const value_list_t *vl, const char *key, uint64_t *value); int uc_meta_data_get_double (const value_list_t *vl, const char *key, double *value); int uc_meta_data_get_boolean (const value_list_t *vl, const char *key, _Bool *value); /* vim: set shiftwidth=2 softtabstop=2 tabstop=8 : */ #endif /* !UTILS_CACHE_H */ collectd-5.4.0/src/PaxHeaders.11991/Makefile.am0000644037772200116100000000013112204120331017165 xustar000000000000000030 mtime=1376821465.061973248 30 atime=1376821477.206167738 29 ctime=1376821742.05440144 collectd-5.4.0/src/Makefile.am0000644037772200116100000012751412204120331015744 0ustar00octoeng00000000000000SUBDIRS = libcollectdclient if BUILD_WITH_OWN_LIBOCONFIG SUBDIRS += liboconfig endif if COMPILER_IS_GCC AM_CFLAGS = -Wall -Werror endif AM_CPPFLAGS = -DPREFIX='"${prefix}"' AM_CPPFLAGS += -DCONFIGFILE='"${sysconfdir}/${PACKAGE_NAME}.conf"' AM_CPPFLAGS += -DLOCALSTATEDIR='"${localstatedir}"' AM_CPPFLAGS += -DPKGLOCALSTATEDIR='"${localstatedir}/lib/${PACKAGE_NAME}"' if BUILD_FEATURE_DAEMON AM_CPPFLAGS += -DPIDFILE='"${localstatedir}/run/${PACKAGE_NAME}.pid"' endif AM_CPPFLAGS += -DPLUGINDIR='"${pkglibdir}"' AM_CPPFLAGS += -DPKGDATADIR='"${pkgdatadir}"' sbin_PROGRAMS = collectd collectdmon bin_PROGRAMS = collectd-nagios collectdctl collectd-tg collectd_SOURCES = collectd.c collectd.h \ common.c common.h \ configfile.c configfile.h \ filter_chain.c filter_chain.h \ meta_data.c meta_data.h \ plugin.c plugin.h \ utils_avltree.c utils_avltree.h \ utils_cache.c utils_cache.h \ utils_complain.c utils_complain.h \ utils_heap.c utils_heap.h \ utils_ignorelist.c utils_ignorelist.h \ utils_llist.c utils_llist.h \ utils_parse_option.c utils_parse_option.h \ utils_random.c utils_random.h \ utils_tail_match.c utils_tail_match.h \ utils_match.c utils_match.h \ utils_subst.c utils_subst.h \ utils_tail.c utils_tail.h \ utils_time.c utils_time.h \ types_list.c types_list.h collectd_CPPFLAGS = $(AM_CPPFLAGS) $(LTDLINCL) collectd_CFLAGS = $(AM_CFLAGS) collectd_LDFLAGS = -export-dynamic collectd_LDADD = -lm collectd_DEPENDENCIES = # Link to these libraries.. if BUILD_WITH_LIBRT collectd_LDADD += -lrt endif if BUILD_WITH_LIBPOSIX4 collectd_LDADD += -lposix4 endif if BUILD_WITH_LIBSOCKET collectd_LDADD += -lsocket endif if BUILD_WITH_LIBRESOLV collectd_LDADD += -lresolv endif if BUILD_WITH_LIBPTHREAD collectd_LDADD += -lpthread endif if BUILD_WITH_LIBKSTAT collectd_LDADD += -lkstat endif if BUILD_WITH_LIBDEVINFO collectd_LDADD += -ldevinfo endif if BUILD_AIX collectd_LDFLAGS += -Wl,-bexpall,-brtllib endif # The daemon needs to call sg_init, so we need to link it against libstatgrab, # too. -octo if BUILD_WITH_LIBSTATGRAB collectd_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) collectd_LDADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) endif if BUILD_WITH_OWN_LIBOCONFIG collectd_LDADD += $(LIBLTDL) liboconfig/liboconfig.la collectd_DEPENDENCIES += liboconfig/liboconfig.la else collectd_LDADD += -loconfig endif collectdmon_SOURCES = collectdmon.c collectdmon_CPPFLAGS = $(AM_CPPFLAGS) collectd_nagios_SOURCES = collectd-nagios.c collectd_nagios_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_builddir)/src/libcollectdclient/collectd collectd_nagios_LDADD = if BUILD_WITH_LIBSOCKET collectd_nagios_LDADD += -lsocket endif if BUILD_AIX collectd_nagios_LDADD += -lm endif collectd_nagios_LDADD += libcollectdclient/libcollectdclient.la collectd_nagios_DEPENDENCIES = libcollectdclient/libcollectdclient.la collectdctl_SOURCES = collectdctl.c collectdctl_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_builddir)/src/libcollectdclient/collectd collectdctl_LDADD = if BUILD_WITH_LIBSOCKET collectdctl_LDADD += -lsocket endif if BUILD_AIX collectdctl_LDADD += -lm endif collectdctl_LDADD += libcollectdclient/libcollectdclient.la collectdctl_DEPENDENCIES = libcollectdclient/libcollectdclient.la collectd_tg_SOURCES = collectd-tg.c \ utils_heap.c utils_heap.h collectd_tg_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_builddir)/src/libcollectdclient/collectd collectd_tg_LDADD = if BUILD_WITH_LIBSOCKET collectd_tg_LDADD += -lsocket endif if BUILD_WITH_LIBRT collectd_tg_LDADD += -lrt endif if BUILD_AIX collectd_tg_LDADD += -lm endif collectd_tg_LDADD += libcollectdclient/libcollectdclient.la collectd_tg_DEPENDENCIES = libcollectdclient/libcollectdclient.la pkglib_LTLIBRARIES = BUILT_SOURCES = CLEANFILES = if BUILD_PLUGIN_AGGREGATION pkglib_LTLIBRARIES += aggregation.la aggregation_la_SOURCES = aggregation.c \ utils_vl_lookup.c utils_vl_lookup.h aggregation_la_LDFLAGS = -module -avoid-version aggregation_la_LIBADD = collectd_LDADD += "-dlopen" aggregation.la collectd_DEPENDENCIES += aggregation.la endif if BUILD_PLUGIN_AMQP pkglib_LTLIBRARIES += amqp.la amqp_la_SOURCES = amqp.c \ utils_cmd_putval.c utils_cmd_putval.h \ utils_format_graphite.c utils_format_graphite.h \ utils_format_json.c utils_format_json.h amqp_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBRABBITMQ_LDFLAGS) amqp_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBRABBITMQ_CPPFLAGS) amqp_la_LIBADD = $(BUILD_WITH_LIBRABBITMQ_LIBS) collectd_LDADD += "-dlopen" amqp.la collectd_DEPENDENCIES += amqp.la endif if BUILD_PLUGIN_APACHE pkglib_LTLIBRARIES += apache.la apache_la_SOURCES = apache.c apache_la_LDFLAGS = -module -avoid-version apache_la_CFLAGS = $(AM_CFLAGS) apache_la_LIBADD = collectd_LDADD += "-dlopen" apache.la if BUILD_WITH_LIBCURL apache_la_CFLAGS += $(BUILD_WITH_LIBCURL_CFLAGS) apache_la_LIBADD += $(BUILD_WITH_LIBCURL_LIBS) endif collectd_DEPENDENCIES += apache.la endif if BUILD_PLUGIN_APCUPS pkglib_LTLIBRARIES += apcups.la apcups_la_SOURCES = apcups.c apcups_la_LDFLAGS = -module -avoid-version apcups_la_LIBADD = if BUILD_WITH_LIBSOCKET apcups_la_LIBADD += -lsocket endif collectd_LDADD += "-dlopen" apcups.la collectd_DEPENDENCIES += apcups.la endif if BUILD_PLUGIN_APPLE_SENSORS pkglib_LTLIBRARIES += apple_sensors.la apple_sensors_la_SOURCES = apple_sensors.c apple_sensors_la_LDFLAGS = -module -avoid-version apple_sensors_la_LIBADD = -lIOKit collectd_LDADD += "-dlopen" apple_sensors.la collectd_DEPENDENCIES += apple_sensors.la endif if BUILD_PLUGIN_AQUAERO pkglib_LTLIBRARIES += aquaero.la aquaero_la_SOURCES = aquaero.c aquaero_la_LDFLAGS = -module -avoid-version aquaero_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBAQUAERO5_CFLAGS) aquaero_la_LIBADD = $(BUILD_WITH_LIBAQUAERO5_LDFLAGS) -laquaero5 collectd_LDADD += "-dlopen" aquaero.la collectd_DEPENDENCIES += aquaero.la endif if BUILD_PLUGIN_ASCENT pkglib_LTLIBRARIES += ascent.la ascent_la_SOURCES = ascent.c ascent_la_LDFLAGS = -module -avoid-version ascent_la_CFLAGS = $(AM_CFLAGS) \ $(BUILD_WITH_LIBCURL_CFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS) ascent_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) $(BUILD_WITH_LIBXML2_LIBS) collectd_LDADD += "-dlopen" ascent.la collectd_DEPENDENCIES += ascent.la endif if BUILD_PLUGIN_BATTERY pkglib_LTLIBRARIES += battery.la battery_la_SOURCES = battery.c battery_la_LDFLAGS = -module -avoid-version battery_la_LIBADD = if BUILD_WITH_LIBIOKIT battery_la_LIBADD += -lIOKit endif collectd_LDADD += "-dlopen" battery.la collectd_DEPENDENCIES += battery.la endif if BUILD_PLUGIN_BIND pkglib_LTLIBRARIES += bind.la bind_la_SOURCES = bind.c bind_la_LDFLAGS = -module -avoid-version bind_la_CFLAGS = $(AM_CFLAGS) \ $(BUILD_WITH_LIBCURL_CFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS) bind_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) $(BUILD_WITH_LIBXML2_LIBS) collectd_LDADD += "-dlopen" bind.la collectd_DEPENDENCIES += bind.la endif 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 pkglib_LTLIBRARIES += conntrack.la conntrack_la_SOURCES = conntrack.c conntrack_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" conntrack.la collectd_DEPENDENCIES += conntrack.la endif if BUILD_PLUGIN_CONTEXTSWITCH pkglib_LTLIBRARIES += contextswitch.la contextswitch_la_SOURCES = contextswitch.c contextswitch_la_LDFLAGS = -module -avoid-version contextswitch_la_LIBADD = if BUILD_WITH_PERFSTAT contextswitch_la_LIBADD += -lperfstat endif collectd_LDADD += "-dlopen" contextswitch.la collectd_DEPENDENCIES += contextswitch.la endif if BUILD_PLUGIN_CPU pkglib_LTLIBRARIES += cpu.la cpu_la_SOURCES = cpu.c cpu_la_CFLAGS = $(AM_CFLAGS) cpu_la_LDFLAGS = -module -avoid-version cpu_la_LIBADD = if BUILD_WITH_LIBKSTAT cpu_la_LIBADD += -lkstat endif if BUILD_WITH_LIBDEVINFO cpu_la_LIBADD += -ldevinfo endif if BUILD_WITH_LIBSTATGRAB cpu_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) cpu_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) endif if BUILD_WITH_PERFSTAT cpu_la_LIBADD += -lperfstat endif collectd_LDADD += "-dlopen" cpu.la collectd_DEPENDENCIES += cpu.la endif if BUILD_PLUGIN_CPUFREQ pkglib_LTLIBRARIES += cpufreq.la cpufreq_la_SOURCES = cpufreq.c cpufreq_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" cpufreq.la collectd_DEPENDENCIES += cpufreq.la endif if BUILD_PLUGIN_CSV pkglib_LTLIBRARIES += csv.la csv_la_SOURCES = csv.c csv_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" csv.la collectd_DEPENDENCIES += csv.la endif if BUILD_PLUGIN_CURL pkglib_LTLIBRARIES += curl.la curl_la_SOURCES = curl.c curl_la_LDFLAGS = -module -avoid-version curl_la_CFLAGS = $(AM_CFLAGS) curl_la_LIBADD = collectd_LDADD += "-dlopen" curl.la if BUILD_WITH_LIBCURL curl_la_CFLAGS += $(BUILD_WITH_LIBCURL_CFLAGS) curl_la_LIBADD += $(BUILD_WITH_LIBCURL_LIBS) endif collectd_DEPENDENCIES += curl.la endif if BUILD_PLUGIN_CURL_JSON pkglib_LTLIBRARIES += curl_json.la curl_json_la_SOURCES = curl_json.c curl_json_la_CFLAGS = $(AM_CFLAGS) curl_json_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBYAJL_LDFLAGS) curl_json_la_CPPFLAGS = $(BUILD_WITH_LIBYAJL_CPPFLAGS) curl_json_la_LIBADD = $(BUILD_WITH_LIBYAJL_LIBS) if BUILD_WITH_LIBCURL curl_json_la_CFLAGS += $(BUILD_WITH_LIBCURL_CFLAGS) curl_json_la_LIBADD += $(BUILD_WITH_LIBCURL_LIBS) endif collectd_LDADD += "-dlopen" curl_json.la collectd_DEPENDENCIES += curl_json.la endif if BUILD_PLUGIN_CURL_XML pkglib_LTLIBRARIES += curl_xml.la curl_xml_la_SOURCES = curl_xml.c curl_xml_la_LDFLAGS = -module -avoid-version curl_xml_la_CFLAGS = $(AM_CFLAGS) \ $(BUILD_WITH_LIBCURL_CFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS) curl_xml_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) $(BUILD_WITH_LIBXML2_LIBS) collectd_LDADD += "-dlopen" curl_xml.la collectd_DEPENDENCIES += curl_xml.la endif if BUILD_PLUGIN_DBI pkglib_LTLIBRARIES += dbi.la dbi_la_SOURCES = dbi.c \ utils_db_query.c utils_db_query.h dbi_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBDBI_CPPFLAGS) dbi_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBDBI_LDFLAGS) dbi_la_LIBADD = $(BUILD_WITH_LIBDBI_LIBS) collectd_LDADD += "-dlopen" dbi.la collectd_DEPENDENCIES += dbi.la endif if BUILD_PLUGIN_DF pkglib_LTLIBRARIES += df.la df_la_SOURCES = df.c utils_mount.c utils_mount.h df_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" df.la collectd_DEPENDENCIES += df.la endif if BUILD_PLUGIN_DISK pkglib_LTLIBRARIES += disk.la disk_la_SOURCES = disk.c disk_la_CFLAGS = $(AM_CFLAGS) disk_la_LDFLAGS = -module -avoid-version disk_la_LIBADD = if BUILD_WITH_LIBKSTAT disk_la_LIBADD += -lkstat endif if BUILD_WITH_LIBDEVINFO disk_la_LIBADD += -ldevinfo endif if BUILD_WITH_LIBIOKIT disk_la_LIBADD += -lIOKit endif if BUILD_WITH_LIBSTATGRAB disk_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) disk_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) endif if BUILD_WITH_PERFSTAT disk_la_LIBADD += -lperfstat endif collectd_LDADD += "-dlopen" disk.la collectd_DEPENDENCIES += disk.la endif if BUILD_PLUGIN_DNS pkglib_LTLIBRARIES += dns.la dns_la_SOURCES = dns.c utils_dns.c utils_dns.h dns_la_LDFLAGS = -module -avoid-version dns_la_LIBADD = -lpcap -lpthread collectd_LDADD += "-dlopen" dns.la collectd_DEPENDENCIES += dns.la endif if BUILD_PLUGIN_EMAIL pkglib_LTLIBRARIES += email.la email_la_SOURCES = email.c email_la_LDFLAGS = -module -avoid-version email_la_LIBADD = -lpthread collectd_LDADD += "-dlopen" email.la collectd_DEPENDENCIES += email.la endif if BUILD_PLUGIN_ENTROPY pkglib_LTLIBRARIES += entropy.la entropy_la_SOURCES = entropy.c entropy_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" entropy.la collectd_DEPENDENCIES += entropy.la endif if BUILD_PLUGIN_EXEC pkglib_LTLIBRARIES += exec.la exec_la_SOURCES = exec.c \ utils_cmd_putnotif.c utils_cmd_putnotif.h \ utils_cmd_putval.c utils_cmd_putval.h exec_la_LDFLAGS = -module -avoid-version exec_la_LIBADD = -lpthread collectd_LDADD += "-dlopen" exec.la collectd_DEPENDENCIES += exec.la endif if BUILD_PLUGIN_ETHSTAT pkglib_LTLIBRARIES += ethstat.la ethstat_la_SOURCES = ethstat.c ethstat_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" ethstat.la collectd_DEPENDENCIES += ethstat.la endif if BUILD_PLUGIN_FILECOUNT pkglib_LTLIBRARIES += filecount.la filecount_la_SOURCES = filecount.c filecount_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" filecount.la collectd_DEPENDENCIES += filecount.la endif if BUILD_PLUGIN_GMOND pkglib_LTLIBRARIES += gmond.la gmond_la_SOURCES = gmond.c gmond_la_CPPFLAGS = $(AM_CPPFLAGS) $(GANGLIA_CPPFLAGS) gmond_la_LDFLAGS = -module -avoid-version $(GANGLIA_LDFLAGS) gmond_la_LIBADD = $(GANGLIA_LIBS) collectd_LDADD += "-dlopen" gmond.la collectd_DEPENDENCIES += gmond.la endif if BUILD_PLUGIN_HDDTEMP pkglib_LTLIBRARIES += hddtemp.la hddtemp_la_SOURCES = hddtemp.c hddtemp_la_LDFLAGS = -module -avoid-version hddtemp_la_LIBADD = if BUILD_WITH_LIBSOCKET hddtemp_la_LIBADD += -lsocket endif collectd_LDADD += "-dlopen" hddtemp.la collectd_DEPENDENCIES += hddtemp.la endif if BUILD_PLUGIN_INTERFACE pkglib_LTLIBRARIES += interface.la interface_la_SOURCES = interface.c interface_la_CFLAGS = $(AM_CFLAGS) interface_la_LDFLAGS = -module -avoid-version interface_la_LIBADD = collectd_LDADD += "-dlopen" interface.la collectd_DEPENDENCIES += interface.la if BUILD_WITH_LIBSTATGRAB interface_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) interface_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) else if BUILD_WITH_LIBKSTAT interface_la_LIBADD += -lkstat endif if BUILD_WITH_LIBDEVINFO interface_la_LIBADD += -ldevinfo endif # BUILD_WITH_LIBDEVINFO endif # !BUILD_WITH_LIBSTATGRAB if BUILD_WITH_PERFSTAT interface_la_LIBADD += -lperfstat endif endif # BUILD_PLUGIN_INTERFACE if BUILD_PLUGIN_IPTABLES pkglib_LTLIBRARIES += iptables.la iptables_la_SOURCES = iptables.c iptables_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBIPTC_CPPFLAGS) iptables_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBIPTC_LDFLAGS) iptables_la_LIBADD = -liptc collectd_LDADD += "-dlopen" iptables.la collectd_DEPENDENCIES += iptables.la endif if BUILD_PLUGIN_IPMI pkglib_LTLIBRARIES += ipmi.la ipmi_la_SOURCES = ipmi.c ipmi_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_OPENIPMI_CFLAGS) ipmi_la_LDFLAGS = -module -avoid-version ipmi_la_LIBADD = $(BUILD_WITH_OPENIPMI_LIBS) collectd_LDADD += "-dlopen" ipmi.la collectd_DEPENDENCIES += ipmi.la endif if BUILD_PLUGIN_IPVS pkglib_LTLIBRARIES += ipvs.la ipvs_la_SOURCES = ipvs.c if IP_VS_H_NEEDS_KERNEL_CFLAGS ipvs_la_CFLAGS = $(AM_CFLAGS) $(KERNEL_CFLAGS) endif ipvs_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" ipvs.la collectd_DEPENDENCIES += ipvs.la endif if BUILD_PLUGIN_IRQ pkglib_LTLIBRARIES += irq.la irq_la_SOURCES = irq.c irq_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" irq.la collectd_DEPENDENCIES += irq.la endif if BUILD_PLUGIN_JAVA pkglib_LTLIBRARIES += java.la java_la_SOURCES = java.c java_la_CPPFLAGS = $(AM_CPPFLAGS) $(JAVA_CPPFLAGS) java_la_CFLAGS = $(AM_CFLAGS) $(JAVA_CFLAGS) java_la_LDFLAGS = -module -avoid-version $(JAVA_LDFLAGS) java_la_LIBADD = $(JAVA_LIBS) collectd_LDADD += "-dlopen" java.la collectd_DEPENDENCIES += java.la endif if BUILD_PLUGIN_LIBVIRT pkglib_LTLIBRARIES += libvirt.la libvirt_la_SOURCES = libvirt.c libvirt_la_CFLAGS = $(AM_CFLAGS) \ $(BUILD_WITH_LIBVIRT_CFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS) libvirt_la_LIBADD = $(BUILD_WITH_LIBVIRT_LIBS) $(BUILD_WITH_LIBXML2_LIBS) libvirt_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" libvirt.la collectd_DEPENDENCIES += libvirt.la endif if BUILD_PLUGIN_LOAD pkglib_LTLIBRARIES += load.la load_la_SOURCES = load.c load_la_CFLAGS = $(AM_CFLAGS) load_la_LDFLAGS = -module -avoid-version load_la_LIBADD = collectd_LDADD += "-dlopen" load.la collectd_DEPENDENCIES += load.la if BUILD_WITH_LIBSTATGRAB load_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) load_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) endif # BUILD_WITH_LIBSTATGRAB if BUILD_WITH_PERFSTAT load_la_LIBADD += -lperfstat endif endif # BUILD_PLUGIN_LOAD if BUILD_PLUGIN_LOGFILE pkglib_LTLIBRARIES += logfile.la logfile_la_SOURCES = logfile.c logfile_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" logfile.la collectd_DEPENDENCIES += logfile.la endif if BUILD_PLUGIN_LPAR pkglib_LTLIBRARIES += lpar.la lpar_la_SOURCES = lpar.c lpar_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" lpar.la collectd_DEPENDENCIES += lpar.la lpar_la_LIBADD = -lperfstat endif if BUILD_PLUGIN_LVM pkglib_LTLIBRARIES += lvm.la lvm_la_SOURCES = lvm.c lvm_la_LDFLAGS = -module -avoid-version lvm_la_LIBADD = $(BUILD_WITH_LIBLVM2APP_LIBS) collectd_LDADD += "-dlopen" lvm.la collectd_DEPENDENCIES += lvm.la endif if BUILD_PLUGIN_MADWIFI pkglib_LTLIBRARIES += madwifi.la madwifi_la_SOURCES = madwifi.c madwifi.h madwifi_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" madwifi.la collectd_DEPENDENCIES += madwifi.la endif if BUILD_PLUGIN_MATCH_EMPTY_COUNTER pkglib_LTLIBRARIES += match_empty_counter.la match_empty_counter_la_SOURCES = match_empty_counter.c match_empty_counter_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" match_empty_counter.la collectd_DEPENDENCIES += match_empty_counter.la endif if BUILD_PLUGIN_MATCH_HASHED pkglib_LTLIBRARIES += match_hashed.la match_hashed_la_SOURCES = match_hashed.c match_hashed_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" match_hashed.la collectd_DEPENDENCIES += match_hashed.la endif if BUILD_PLUGIN_MATCH_REGEX pkglib_LTLIBRARIES += match_regex.la match_regex_la_SOURCES = match_regex.c match_regex_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" match_regex.la collectd_DEPENDENCIES += match_regex.la endif if BUILD_PLUGIN_MATCH_TIMEDIFF pkglib_LTLIBRARIES += match_timediff.la match_timediff_la_SOURCES = match_timediff.c match_timediff_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" match_timediff.la collectd_DEPENDENCIES += match_timediff.la endif if BUILD_PLUGIN_MATCH_VALUE pkglib_LTLIBRARIES += match_value.la match_value_la_SOURCES = match_value.c match_value_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" match_value.la collectd_DEPENDENCIES += match_value.la endif if BUILD_PLUGIN_MBMON pkglib_LTLIBRARIES += mbmon.la mbmon_la_SOURCES = mbmon.c mbmon_la_LDFLAGS = -module -avoid-version mbmon_la_LIBADD = if BUILD_WITH_LIBSOCKET mbmon_la_LIBADD += -lsocket endif collectd_LDADD += "-dlopen" mbmon.la collectd_DEPENDENCIES += mbmon.la endif if BUILD_PLUGIN_MD pkglib_LTLIBRARIES += md.la md_la_SOURCES = md.c md_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" md.la collectd_DEPENDENCIES += md.la endif if BUILD_PLUGIN_MEMCACHEC pkglib_LTLIBRARIES += memcachec.la memcachec_la_SOURCES = memcachec.c memcachec_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBMEMCACHED_LDFLAGS) memcachec_la_CPPFLAGS = $(BUILD_WITH_LIBMEMCACHED_CPPFLAGS) memcachec_la_LIBADD = $(BUILD_WITH_LIBMEMCACHED_LIBS) collectd_LDADD += "-dlopen" memcachec.la collectd_DEPENDENCIES += memcachec.la endif if BUILD_PLUGIN_MEMCACHED pkglib_LTLIBRARIES += memcached.la memcached_la_SOURCES = memcached.c memcached_la_LDFLAGS = -module -avoid-version memcached_la_LIBADD = if BUILD_WITH_LIBSOCKET memcached_la_LIBADD += -lsocket endif collectd_LDADD += "-dlopen" memcached.la collectd_DEPENDENCIES += memcached.la endif if BUILD_PLUGIN_MEMORY pkglib_LTLIBRARIES += memory.la memory_la_SOURCES = memory.c memory_la_CFLAGS = $(AM_CFLAGS) memory_la_LDFLAGS = -module -avoid-version memory_la_LIBADD = collectd_LDADD += "-dlopen" memory.la collectd_DEPENDENCIES += memory.la if BUILD_WITH_LIBKSTAT memory_la_LIBADD += -lkstat endif if BUILD_WITH_LIBDEVINFO memory_la_LIBADD += -ldevinfo endif if BUILD_WITH_LIBSTATGRAB memory_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) memory_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) endif if BUILD_WITH_PERFSTAT memory_la_LIBADD += -lperfstat endif endif if BUILD_PLUGIN_MODBUS pkglib_LTLIBRARIES += modbus.la modbus_la_SOURCES = modbus.c modbus_la_LDFLAGS = -module -avoid-version modbus_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBMODBUS_CFLAGS) modbus_la_LIBADD = $(BUILD_WITH_LIBMODBUS_LIBS) collectd_LDADD += "-dlopen" modbus.la collectd_DEPENDENCIES += modbus.la endif if BUILD_PLUGIN_MULTIMETER pkglib_LTLIBRARIES += multimeter.la multimeter_la_SOURCES = multimeter.c multimeter_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" multimeter.la collectd_DEPENDENCIES += multimeter.la endif if BUILD_PLUGIN_MYSQL pkglib_LTLIBRARIES += mysql.la mysql_la_SOURCES = mysql.c mysql_la_LDFLAGS = -module -avoid-version mysql_la_CFLAGS = $(AM_CFLAGS) mysql_la_LIBADD = collectd_LDADD += "-dlopen" mysql.la if BUILD_WITH_LIBMYSQL mysql_la_CFLAGS += $(BUILD_WITH_LIBMYSQL_CFLAGS) mysql_la_LIBADD += $(BUILD_WITH_LIBMYSQL_LIBS) endif collectd_DEPENDENCIES += mysql.la endif if BUILD_PLUGIN_NETAPP pkglib_LTLIBRARIES += netapp.la netapp_la_SOURCES = netapp.c netapp_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBNETAPP_CPPFLAGS) netapp_la_LDFLAGS = -module -avoid-version $(LIBNETAPP_LDFLAGS) netapp_la_LIBADD = $(LIBNETAPP_LIBS) collectd_LDADD += "-dlopen" netapp.la collectd_DEPENDENCIES += netapp.la endif if BUILD_PLUGIN_NETLINK pkglib_LTLIBRARIES += netlink.la netlink_la_SOURCES = netlink.c netlink_la_LDFLAGS = -module -avoid-version netlink_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBMNL_CFLAGS) netlink_la_LIBADD = $(BUILD_WITH_LIBMNL_LIBS) collectd_LDADD += "-dlopen" netlink.la collectd_DEPENDENCIES += netlink.la endif if BUILD_PLUGIN_NETWORK pkglib_LTLIBRARIES += network.la network_la_SOURCES = network.c network.h \ utils_fbhash.c utils_fbhash.h network_la_CPPFLAGS = $(AM_CPPFLAGS) network_la_LDFLAGS = -module -avoid-version network_la_LIBADD = -lpthread if BUILD_WITH_LIBSOCKET network_la_LIBADD += -lsocket endif if BUILD_WITH_LIBGCRYPT network_la_CPPFLAGS += $(GCRYPT_CPPFLAGS) network_la_LDFLAGS += $(GCRYPT_LDFLAGS) network_la_LIBADD += $(GCRYPT_LIBS) endif collectd_LDADD += "-dlopen" network.la collectd_DEPENDENCIES += network.la endif if BUILD_PLUGIN_NFS pkglib_LTLIBRARIES += nfs.la nfs_la_SOURCES = nfs.c nfs_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" nfs.la collectd_DEPENDENCIES += nfs.la endif if BUILD_PLUGIN_FSCACHE pkglib_LTLIBRARIES += fscache.la fscache_la_SOURCES = fscache.c fscache_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" fscache.la collectd_DEPENDENCIES += fscache.la endif if BUILD_PLUGIN_NGINX pkglib_LTLIBRARIES += nginx.la nginx_la_SOURCES = nginx.c nginx_la_CFLAGS = $(AM_CFLAGS) nginx_la_LIBADD = nginx_la_LDFLAGS = -module -avoid-version if BUILD_WITH_LIBCURL nginx_la_CFLAGS += $(BUILD_WITH_LIBCURL_CFLAGS) nginx_la_LIBADD += $(BUILD_WITH_LIBCURL_LIBS) endif collectd_LDADD += "-dlopen" nginx.la collectd_DEPENDENCIES += nginx.la endif if BUILD_PLUGIN_NOTIFY_DESKTOP pkglib_LTLIBRARIES += notify_desktop.la notify_desktop_la_SOURCES = notify_desktop.c notify_desktop_la_CFLAGS = $(AM_CFLAGS) $(LIBNOTIFY_CFLAGS) notify_desktop_la_LDFLAGS = -module -avoid-version notify_desktop_la_LIBADD = $(LIBNOTIFY_LIBS) collectd_LDADD += "-dlopen" notify_desktop.la collectd_DEPENDENCIES += notify_desktop.la endif if BUILD_PLUGIN_NOTIFY_EMAIL pkglib_LTLIBRARIES += notify_email.la notify_email_la_SOURCES = notify_email.c notify_email_la_LDFLAGS = -module -avoid-version notify_email_la_LIBADD = -lesmtp -lssl -lcrypto -lpthread -ldl collectd_LDADD += "-dlopen" notify_email.la collectd_DEPENDENCIES += notify_email.la endif if BUILD_PLUGIN_NTPD pkglib_LTLIBRARIES += ntpd.la ntpd_la_SOURCES = ntpd.c ntpd_la_LDFLAGS = -module -avoid-version ntpd_la_LIBADD = if BUILD_WITH_LIBSOCKET ntpd_la_LIBADD += -lsocket endif collectd_LDADD += "-dlopen" ntpd.la collectd_DEPENDENCIES += ntpd.la endif if BUILD_PLUGIN_NUMA pkglib_LTLIBRARIES += numa.la numa_la_SOURCES = numa.c numa_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" numa.la collectd_DEPENDENCIES += numa.la endif if BUILD_PLUGIN_NUT pkglib_LTLIBRARIES += nut.la nut_la_SOURCES = nut.c nut_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBUPSCLIENT_CFLAGS) nut_la_LDFLAGS = -module -avoid-version nut_la_LIBADD = -lpthread $(BUILD_WITH_LIBUPSCLIENT_LIBS) collectd_LDADD += "-dlopen" nut.la collectd_DEPENDENCIES += nut.la endif if BUILD_PLUGIN_OLSRD pkglib_LTLIBRARIES += olsrd.la olsrd_la_SOURCES = olsrd.c olsrd_la_LDFLAGS = -module -avoid-version olsrd_la_LIBADD = if BUILD_WITH_LIBSOCKET olsrd_la_LIBADD += -lsocket endif collectd_LDADD += "-dlopen" olsrd.la collectd_DEPENDENCIES += olsrd.la endif if BUILD_PLUGIN_ONEWIRE pkglib_LTLIBRARIES += onewire.la onewire_la_SOURCES = onewire.c onewire_la_CFLAGS = $(AM_CFLAGS) onewire_la_CPPFLAGS = $(BUILD_WITH_LIBOWCAPI_CPPFLAGS) onewire_la_LIBADD = $(BUILD_WITH_LIBOWCAPI_LIBS) onewire_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" onewire.la collectd_DEPENDENCIES += onewire.la endif if BUILD_PLUGIN_OPENVPN pkglib_LTLIBRARIES += openvpn.la openvpn_la_SOURCES = openvpn.c openvpn_la_CFLAGS = $(AM_CFLAGS) openvpn_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" openvpn.la collectd_DEPENDENCIES += openvpn.la endif if BUILD_PLUGIN_ORACLE pkglib_LTLIBRARIES += oracle.la oracle_la_SOURCES = oracle.c \ utils_db_query.c utils_db_query.h oracle_la_CFLAGS = $(AM_CFLAGS) oracle_la_CPPFLAGS = $(BUILD_WITH_ORACLE_CFLAGS) oracle_la_LIBADD = $(BUILD_WITH_ORACLE_LIBS) oracle_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" oracle.la collectd_DEPENDENCIES += oracle.la endif if BUILD_PLUGIN_PERL pkglib_LTLIBRARIES += perl.la perl_la_SOURCES = perl.c # Despite C99 providing the "bool" type thru stdbool.h, Perl defines its own # version of that type if HAS_BOOL is not defined... *sigh* perl_la_CPPFLAGS = $(AM_CPPFLAGS) -DHAS_BOOL=1 perl_la_CFLAGS = $(AM_CFLAGS) \ $(PERL_CFLAGS) \ -DXS_VERSION=\"$(VERSION)\" -DVERSION=\"$(VERSION)\" # Work-around for issues #41 and #42 - Perl 5.10 incorrectly introduced # __attribute__nonnull__(3) for Perl_load_module(). if HAVE_BROKEN_PERL_LOAD_MODULE perl_la_CFLAGS += -Wno-nonnull endif perl_la_LDFLAGS = -module -avoid-version \ $(PERL_LDFLAGS) collectd_LDADD += "-dlopen" perl.la collectd_DEPENDENCIES += perl.la endif if BUILD_PLUGIN_PF pkglib_LTLIBRARIES += pf.la pf_la_SOURCES = pf.c pf_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" pf.la collectd_DEPENDENCIES += pf.la endif if BUILD_PLUGIN_PINBA pkglib_LTLIBRARIES += pinba.la pinba_la_SOURCES = pinba.c nodist_pinba_la_SOURCES = pinba.pb-c.c pinba.pb-c.h pinba_la_LDFLAGS = -module -avoid-version pinba_la_LIBADD = -lprotobuf-c collectd_LDADD += "-dlopen" pinba.la collectd_DEPENDENCIES += pinba.la endif if BUILD_PLUGIN_PING pkglib_LTLIBRARIES += ping.la ping_la_SOURCES = ping.c ping_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBOPING_CPPFLAGS) ping_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBOPING_LDFLAGS) ping_la_LIBADD = -loping -lm collectd_LDADD += "-dlopen" ping.la collectd_DEPENDENCIES += ping.la endif if BUILD_PLUGIN_POSTGRESQL pkglib_LTLIBRARIES += postgresql.la postgresql_la_SOURCES = postgresql.c \ utils_db_query.c utils_db_query.h postgresql_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBPQ_CPPFLAGS) postgresql_la_LDFLAGS = -module -avoid-version \ $(BUILD_WITH_LIBPQ_LDFLAGS) postgresql_la_LIBADD = -lpq collectd_LDADD += "-dlopen" postgresql.la collectd_DEPENDENCIES += postgresql.la endif if BUILD_PLUGIN_POWERDNS pkglib_LTLIBRARIES += powerdns.la powerdns_la_SOURCES = powerdns.c powerdns_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" powerdns.la collectd_DEPENDENCIES += powerdns.la endif if BUILD_PLUGIN_PYTHON pkglib_LTLIBRARIES += python.la python_la_SOURCES = python.c pyconfig.c pyvalues.c cpython.h python_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_PYTHON_CPPFLAGS) python_la_CFLAGS = $(AM_CFLAGS) if COMPILER_IS_GCC python_la_CFLAGS += -fno-strict-aliasing -Wno-strict-aliasing endif python_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_PYTHON_LDFLAGS) python_la_LIBADD = $(BUILD_WITH_PYTHON_LIBS) collectd_LDADD += "-dlopen" python.la collectd_DEPENDENCIES += python.la endif if BUILD_PLUGIN_PROCESSES pkglib_LTLIBRARIES += processes.la processes_la_SOURCES = processes.c processes_la_LDFLAGS = -module -avoid-version processes_la_LIBADD = collectd_LDADD += "-dlopen" processes.la collectd_DEPENDENCIES += processes.la if BUILD_WITH_LIBKVM_GETPROCS processes_la_LIBADD += -lkvm endif endif if BUILD_PLUGIN_PROTOCOLS pkglib_LTLIBRARIES += protocols.la protocols_la_SOURCES = protocols.c protocols_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" protocols.la collectd_DEPENDENCIES += protocols.la endif if BUILD_PLUGIN_REDIS pkglib_LTLIBRARIES += redis.la redis_la_SOURCES = redis.c redis_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBCREDIS_LDFLAGS) redis_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCREDIS_CPPFLAGS) redis_la_LIBADD = -lcredis collectd_LDADD += "-dlopen" redis.la collectd_DEPENDENCIES += redis.la endif if BUILD_PLUGIN_ROUTEROS pkglib_LTLIBRARIES += routeros.la routeros_la_SOURCES = routeros.c routeros_la_CPPFLAGS = $(BUILD_WITH_LIBROUTEROS_CPPFLAGS) routeros_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBROUTEROS_LDFLAGS) routeros_la_LIBADD = -lrouteros collectd_LDADD += "-dlopen" routeros.la collectd_DEPENDENCIES += routeros.la endif if BUILD_PLUGIN_RRDCACHED pkglib_LTLIBRARIES += rrdcached.la rrdcached_la_SOURCES = rrdcached.c utils_rrdcreate.c utils_rrdcreate.h rrdcached_la_LDFLAGS = -module -avoid-version rrdcached_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBRRD_CFLAGS) rrdcached_la_LIBADD = $(BUILD_WITH_LIBRRD_LDFLAGS) collectd_LDADD += "-dlopen" rrdcached.la collectd_DEPENDENCIES += rrdcached.la endif if BUILD_PLUGIN_RRDTOOL pkglib_LTLIBRARIES += rrdtool.la rrdtool_la_SOURCES = rrdtool.c utils_rrdcreate.c utils_rrdcreate.h rrdtool_la_LDFLAGS = -module -avoid-version rrdtool_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBRRD_CFLAGS) rrdtool_la_LIBADD = $(BUILD_WITH_LIBRRD_LDFLAGS) collectd_LDADD += "-dlopen" rrdtool.la collectd_DEPENDENCIES += rrdtool.la endif if BUILD_PLUGIN_SENSORS pkglib_LTLIBRARIES += sensors.la sensors_la_SOURCES = sensors.c sensors_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBSENSORS_CFLAGS) sensors_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBSENSORS_LDFLAGS) sensors_la_LIBADD = -lsensors collectd_LDADD += "-dlopen" sensors.la collectd_DEPENDENCIES += sensors.la endif if BUILD_PLUGIN_SERIAL pkglib_LTLIBRARIES += serial.la serial_la_SOURCES = serial.c serial_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" serial.la collectd_DEPENDENCIES += serial.la endif if BUILD_PLUGIN_SIGROK pkglib_LTLIBRARIES += sigrok.la sigrok_la_SOURCES = sigrok.c sigrok_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBSIGROK_CFLAGS) sigrok_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBSIGROK_LDFLAGS) sigrok_la_LIBADD = -lsigrok collectd_LDADD += "-dlopen" sigrok.la collectd_DEPENDENCIES += sigrok.la endif if BUILD_PLUGIN_SNMP pkglib_LTLIBRARIES += snmp.la snmp_la_SOURCES = snmp.c snmp_la_LDFLAGS = -module -avoid-version snmp_la_CFLAGS = $(AM_CFLAGS) snmp_la_LIBADD = if BUILD_WITH_LIBNETSNMP snmp_la_CFLAGS += $(BUILD_WITH_LIBSNMP_CFLAGS) snmp_la_LIBADD += $(BUILD_WITH_LIBSNMP_LIBS) endif if BUILD_WITH_LIBPTHREAD snmp_la_LIBADD += -lpthread endif collectd_LDADD += "-dlopen" snmp.la collectd_DEPENDENCIES += snmp.la endif if BUILD_PLUGIN_STATSD pkglib_LTLIBRARIES += statsd.la statsd_la_SOURCES = statsd.c \ utils_latency.h utils_latency.c statsd_la_LDFLAGS = -module -avoid-version statsd_la_LIBADD = -lpthread collectd_LDADD += "-dlopen" statsd.la collectd_DEPENDENCIES += statsd.la endif if BUILD_PLUGIN_SWAP pkglib_LTLIBRARIES += swap.la swap_la_SOURCES = swap.c swap_la_CFLAGS = $(AM_CFLAGS) swap_la_LDFLAGS = -module -avoid-version swap_la_LIBADD = collectd_LDADD += "-dlopen" swap.la collectd_DEPENDENCIES += swap.la if BUILD_WITH_LIBKSTAT swap_la_LIBADD += -lkstat endif if BUILD_WITH_LIBDEVINFO swap_la_LIBADD += -ldevinfo endif if BUILD_WITH_LIBKVM_GETSWAPINFO swap_la_LIBADD += -lkvm endif if BUILD_WITH_LIBSTATGRAB swap_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) swap_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) endif if BUILD_WITH_PERFSTAT swap_la_LIBADD += -lperfstat endif endif if BUILD_PLUGIN_SYSLOG pkglib_LTLIBRARIES += syslog.la syslog_la_SOURCES = syslog.c syslog_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" syslog.la collectd_DEPENDENCIES += syslog.la endif if BUILD_PLUGIN_TABLE pkglib_LTLIBRARIES += table.la table_la_SOURCES = table.c table_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" table.la collectd_DEPENDENCIES += table.la endif if BUILD_PLUGIN_TAIL pkglib_LTLIBRARIES += tail.la tail_la_SOURCES = tail.c tail_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" tail.la collectd_DEPENDENCIES += tail.la endif if BUILD_PLUGIN_TAIL_CSV pkglib_LTLIBRARIES += tail_csv.la tail_csv_la_SOURCES = tail_csv.c tail_csv_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" tail_csv.la collectd_DEPENDENCIES += tail_csv.la endif if BUILD_PLUGIN_TAPE pkglib_LTLIBRARIES += tape.la tape_la_SOURCES = tape.c tape_la_LDFLAGS = -module -avoid-version tape_la_LIBADD = -lkstat -ldevinfo collectd_LDADD += "-dlopen" tape.la collectd_DEPENDENCIES += tape.la endif if BUILD_PLUGIN_TARGET_NOTIFICATION pkglib_LTLIBRARIES += target_notification.la target_notification_la_SOURCES = target_notification.c target_notification_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" target_notification.la collectd_DEPENDENCIES += target_notification.la endif if BUILD_PLUGIN_TARGET_REPLACE pkglib_LTLIBRARIES += target_replace.la target_replace_la_SOURCES = target_replace.c target_replace_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" target_replace.la collectd_DEPENDENCIES += target_replace.la endif if BUILD_PLUGIN_TARGET_SCALE pkglib_LTLIBRARIES += target_scale.la target_scale_la_SOURCES = target_scale.c target_scale_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" target_scale.la collectd_DEPENDENCIES += target_scale.la endif if BUILD_PLUGIN_TARGET_SET pkglib_LTLIBRARIES += target_set.la target_set_la_SOURCES = target_set.c target_set_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" target_set.la collectd_DEPENDENCIES += target_set.la endif if BUILD_PLUGIN_TARGET_V5UPGRADE pkglib_LTLIBRARIES += target_v5upgrade.la target_v5upgrade_la_SOURCES = target_v5upgrade.c target_v5upgrade_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" target_v5upgrade.la collectd_DEPENDENCIES += target_v5upgrade.la endif if BUILD_PLUGIN_TCPCONNS pkglib_LTLIBRARIES += tcpconns.la tcpconns_la_SOURCES = tcpconns.c tcpconns_la_LDFLAGS = -module -avoid-version tcpconns_la_LIBADD = collectd_LDADD += "-dlopen" tcpconns.la collectd_DEPENDENCIES += tcpconns.la if BUILD_WITH_LIBKVM_NLIST tcpconns_la_LIBADD += -lkvm endif endif if BUILD_PLUGIN_TEAMSPEAK2 pkglib_LTLIBRARIES += teamspeak2.la teamspeak2_la_SOURCES = teamspeak2.c teamspeak2_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" teamspeak2.la collectd_DEPENDENCIES += teamspeak2.la endif if BUILD_PLUGIN_TED pkglib_LTLIBRARIES += ted.la ted_la_SOURCES = ted.c ted_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" ted.la collectd_DEPENDENCIES += ted.la endif if BUILD_PLUGIN_THERMAL pkglib_LTLIBRARIES += thermal.la thermal_la_SOURCES = thermal.c thermal_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" thermal.la collectd_DEPENDENCIES += thermal.la endif if BUILD_PLUGIN_THRESHOLD pkglib_LTLIBRARIES += threshold.la threshold_la_SOURCES = threshold.c threshold_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" threshold.la collectd_DEPENDENCIES += threshold.la endif if BUILD_PLUGIN_TOKYOTYRANT pkglib_LTLIBRARIES += tokyotyrant.la tokyotyrant_la_SOURCES = tokyotyrant.c tokyotyrant_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBTOKYOTYRANT_CPPFLAGS) tokyotyrant_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBTOKYOTYRANT_LDFLAGS) tokyotyrant_la_LIBADD = $(BUILD_WITH_LIBTOKYOTYRANT_LIBS) if BUILD_WITH_LIBSOCKET tokyotyrant_la_LIBADD += -lsocket endif collectd_LDADD += "-dlopen" tokyotyrant.la collectd_DEPENDENCIES += tokyotyrant.la endif if BUILD_PLUGIN_UNIXSOCK pkglib_LTLIBRARIES += unixsock.la unixsock_la_SOURCES = unixsock.c \ utils_cmd_flush.h utils_cmd_flush.c \ utils_cmd_getval.h utils_cmd_getval.c \ utils_cmd_listval.h utils_cmd_listval.c \ utils_cmd_putval.h utils_cmd_putval.c \ utils_cmd_putnotif.h utils_cmd_putnotif.c unixsock_la_LDFLAGS = -module -avoid-version unixsock_la_LIBADD = -lpthread collectd_LDADD += "-dlopen" unixsock.la collectd_DEPENDENCIES += unixsock.la endif if BUILD_PLUGIN_UPTIME pkglib_LTLIBRARIES += uptime.la uptime_la_SOURCES = uptime.c uptime_la_CFLAGS = $(AM_CFLAGS) uptime_la_LDFLAGS = -module -avoid-version uptime_la_LIBADD = if BUILD_WITH_LIBKSTAT uptime_la_LIBADD += -lkstat endif if BUILD_WITH_PERFSTAT uptime_la_LIBADD += -lperfstat endif collectd_LDADD += "-dlopen" uptime.la collectd_DEPENDENCIES += uptime.la endif if BUILD_PLUGIN_USERS pkglib_LTLIBRARIES += users.la users_la_SOURCES = users.c users_la_CFLAGS = $(AM_CFLAGS) users_la_LDFLAGS = -module -avoid-version users_la_LIBADD = if BUILD_WITH_LIBSTATGRAB users_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) users_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) endif collectd_LDADD += "-dlopen" users.la collectd_DEPENDENCIES += users.la endif if BUILD_PLUGIN_UUID pkglib_LTLIBRARIES += uuid.la uuid_la_SOURCES = uuid.c uuid_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBHAL_CFLAGS) uuid_la_LIBADD = $(BUILD_WITH_LIBHAL_LIBS) uuid_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" uuid.la collectd_DEPENDENCIES += uuid.la endif if BUILD_PLUGIN_MIC pkglib_LTLIBRARIES += mic.la mic_la_SOURCES = mic.c mic_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_MIC_LIBPATH) mic_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_MIC_CPPFLAGS) mic_la_LIBADD = $(BUILD_WITH_MIC_LDADD) collectd_LDADD += "-dlopen" mic.la collectd_DEPENDENCIES += mic.la endif if BUILD_PLUGIN_VARNISH pkglib_LTLIBRARIES += varnish.la varnish_la_SOURCES = varnish.c varnish_la_LDFLAGS = -module -avoid-version varnish_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBVARNISH_CFLAGS) varnish_la_LIBADD = $(BUILD_WITH_LIBVARNISH_LIBS) collectd_LDADD += "-dlopen" varnish.la collectd_DEPENDENCIES += varnish.la endif if BUILD_PLUGIN_VMEM pkglib_LTLIBRARIES += vmem.la vmem_la_SOURCES = vmem.c vmem_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" vmem.la collectd_DEPENDENCIES += vmem.la endif if BUILD_PLUGIN_VSERVER pkglib_LTLIBRARIES += vserver.la vserver_la_SOURCES = vserver.c vserver_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" vserver.la collectd_DEPENDENCIES += vserver.la endif if BUILD_PLUGIN_WIRELESS pkglib_LTLIBRARIES += wireless.la wireless_la_SOURCES = wireless.c wireless_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" wireless.la collectd_DEPENDENCIES += wireless.la endif if BUILD_PLUGIN_WRITE_GRAPHITE pkglib_LTLIBRARIES += write_graphite.la write_graphite_la_SOURCES = write_graphite.c \ utils_format_graphite.c utils_format_graphite.h \ utils_format_json.c utils_format_json.h write_graphite_la_LDFLAGS = -module -avoid-version collectd_LDADD += "-dlopen" write_graphite.la collectd_DEPENDENCIES += write_graphite.la endif if BUILD_PLUGIN_WRITE_HTTP pkglib_LTLIBRARIES += write_http.la write_http_la_SOURCES = write_http.c \ utils_format_json.c utils_format_json.h write_http_la_LDFLAGS = -module -avoid-version write_http_la_CFLAGS = $(AM_CFLAGS) write_http_la_LIBADD = collectd_LDADD += "-dlopen" write_http.la if BUILD_WITH_LIBCURL write_http_la_CFLAGS += $(BUILD_WITH_LIBCURL_CFLAGS) write_http_la_LIBADD += $(BUILD_WITH_LIBCURL_LIBS) endif collectd_DEPENDENCIES += write_http.la endif if BUILD_PLUGIN_WRITE_MONGODB pkglib_LTLIBRARIES += write_mongodb.la write_mongodb_la_SOURCES = write_mongodb.c write_mongodb_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBMONGOC_CPPFLAGS) write_mongodb_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBMONGOC_LDFLAGS) write_mongodb_la_LIBADD = -lmongoc collectd_LDADD += "-dlopen" write_mongodb.la collectd_DEPENDENCIES += write_mongodb.la endif if BUILD_PLUGIN_WRITE_REDIS pkglib_LTLIBRARIES += write_redis.la write_redis_la_SOURCES = write_redis.c write_redis_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBCREDIS_LDFLAGS) write_redis_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCREDIS_CPPFLAGS) write_redis_la_LIBADD = -lcredis collectd_LDADD += "-dlopen" write_redis.la collectd_DEPENDENCIES += write_redis.la endif if BUILD_PLUGIN_WRITE_RIEMANN pkglib_LTLIBRARIES += write_riemann.la write_riemann_la_SOURCES = write_riemann.c nodist_write_riemann_la_SOURCES = riemann.pb-c.c riemann.pb-c.h write_riemann_la_LDFLAGS = -module -avoid-version write_riemann_la_LIBADD = -lprotobuf-c collectd_LDADD += "-dlopen" write_riemann.la collectd_DEPENDENCIES += write_riemann.la endif if BUILD_PLUGIN_XMMS pkglib_LTLIBRARIES += xmms.la xmms_la_SOURCES = xmms.c xmms_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBXMMS_CFLAGS) xmms_la_LDFLAGS = -module -avoid-version xmms_la_LIBADD = $(BUILD_WITH_LIBXMMS_LIBS) collectd_LDADD += "-dlopen" xmms.la collectd_DEPENDENCIES += xmms.la endif if BUILD_PLUGIN_ZFS_ARC pkglib_LTLIBRARIES += zfs_arc.la zfs_arc_la_SOURCES = zfs_arc.c zfs_arc_la_CFLAGS = $(AM_CFLAGS) zfs_arc_la_LDFLAGS = -module -avoid-version if BUILD_FREEBSD zfs_arc_la_LIBADD = -lm else zfs_arc_la_LIBADD = -lkstat endif collectd_LDADD += "-dlopen" zfs_arc.la collectd_DEPENDENCIES += zfs_arc.la endif BUILT_SOURCES += $(dist_man_MANS) dist_man_MANS = collectd.1 \ collectd.conf.5 \ collectd-email.5 \ collectd-exec.5 \ collectdctl.1 \ collectd-java.5 \ collectdmon.1 \ collectd-nagios.1 \ collectd-perl.5 \ collectd-python.5 \ collectd-snmp.5 \ collectd-tg.1 \ collectd-threshold.5 \ collectd-unixsock.5 \ types.db.5 #collectd_1_SOURCES = collectd.pod EXTRA_DIST = types.db EXTRA_DIST += collectd.conf.pod \ collectd-email.pod \ collectd-exec.pod \ collectdctl.pod \ collectd-java.pod \ collectdmon.pod \ collectd-nagios.pod \ collectd-perl.pod \ collectd-python.pod \ collectd.pod \ collectd-snmp.pod \ collectd-tg.pod \ collectd-threshold.pod \ collectd-unixsock.pod \ postgresql_default.conf \ types.db.pod .pod.1: pod2man --release=$(VERSION) --center=$(PACKAGE) $< \ >.pod2man.tmp.$$$$ 2>/dev/null && mv -f .pod2man.tmp.$$$$ $@ || true @if grep '\' $@ >/dev/null 2>&1; \ then \ echo "$@ has some POD errors!"; false; \ fi .pod.5: pod2man --section=5 --release=$(VERSION) --center=$(PACKAGE) $< \ >.pod2man.tmp.$$$$ 2>/dev/null && mv -f .pod2man.tmp.$$$$ $@ || true @if grep '\' $@ >/dev/null 2>&1; \ then \ echo "$@ has some POD errors!"; false; \ fi # Protocol buffer for the "pinba" plugin. EXTRA_DIST += pinba.proto if HAVE_PROTOC_C CLEANFILES += pinba.pb-c.c pinba.pb-c.h BUILT_SOURCES += pinba.pb-c.c pinba.pb-c.h pinba.pb-c.c pinba.pb-c.h: pinba.proto protoc-c -I$(srcdir) --c_out . $(srcdir)/pinba.proto endif # Protocol buffer for the "write_riemann" plugin. EXTRA_DIST += riemann.proto if HAVE_PROTOC_C CLEANFILES += riemann.pb-c.c riemann.pb-c.h BUILT_SOURCES += riemann.pb-c.c riemann.pb-c.h riemann.pb-c.c riemann.pb-c.h: riemann.proto protoc-c -I$(srcdir) --c_out . $(srcdir)/riemann.proto endif install-exec-hook: $(mkinstalldirs) $(DESTDIR)$(sysconfdir) if test -e $(DESTDIR)$(sysconfdir)/collectd.conf; \ then \ $(INSTALL) -m 0640 collectd.conf $(DESTDIR)$(sysconfdir)/collectd.conf.pkg-orig; \ else \ $(INSTALL) -m 0640 collectd.conf $(DESTDIR)$(sysconfdir)/collectd.conf; \ fi; \ $(mkinstalldirs) $(DESTDIR)$(pkgdatadir) $(INSTALL) -m 0644 $(srcdir)/types.db $(DESTDIR)$(pkgdatadir)/types.db; $(INSTALL) -m 0644 $(srcdir)/postgresql_default.conf \ $(DESTDIR)$(pkgdatadir)/postgresql_default.conf; uninstall-hook: rm -f $(DESTDIR)$(pkgdatadir)/types.db; rm -f $(DESTDIR)$(sysconfdir)/collectd.conf rm -f $(DESTDIR)$(pkgdatadir)/postgresql_default.conf; if BUILD_FEATURE_DEBUG bin_PROGRAMS += utils_vl_lookup_test utils_vl_lookup_test_SOURCES = utils_vl_lookup_test.c \ utils_vl_lookup.h utils_vl_lookup.c \ utils_avltree.c utils_avltree.h \ common.h utils_vl_lookup_test_CPPFLAGS = $(AM_CPPFLAGS) $(LTDLINCL) -DBUILD_TEST=1 utils_vl_lookup_test_CFLAGS = $(AM_CFLAGS) utils_vl_lookup_test_LDFLAGS = -export-dynamic utils_vl_lookup_test_LDADD = endif collectd-5.4.0/src/PaxHeaders.11991/collectd.conf.pod0000644037772200116100000000013112204120331020352 xustar000000000000000030 mtime=1376821465.069973376 30 atime=1376821477.210167802 29 ctime=1376821742.05440144 collectd-5.4.0/src/collectd.conf.pod0000644037772200116100000071571512204120331017137 0ustar00octoeng00000000000000=encoding UTF-8 =head1 NAME collectd.conf - Configuration for the system statistics collection daemon B =head1 SYNOPSIS BaseDir "/path/to/data/" PIDFile "/path/to/pidfile/collectd.pid" Server "123.123.123.123" 12345 LoadPlugin cpu LoadPlugin load Interval 3600 LoadPlugin ping Host "example.org" Host "provider.net" =head1 DESCRIPTION This config file controls how the system statistics collection daemon B behaves. The most significant option is B, which controls which plugins to load. These plugins ultimately define collectd's behavior. The syntax of this config file is similar to the config file of the famous I webserver. Each line contains either an option (a key and a list of one or more values) or a section-start or -end. Empty lines and everything after a non-quoted hash-symbol (C<#>) is ignored. I are unquoted strings, consisting only of alphanumeric characters and the underscore (C<_>) character. Keys are handled case insensitive by I itself and all plugins included with it. I can either be an I, a I (enclosed in double-quotes) a I or a I expression. I consist of only alphanumeric characters and underscores (C<_>) and do not need to be quoted. I are enclosed in double quotes (C<">). You can use the backslash character (C<\>) to include double quotes as part of the string. I can be specified in decimal and floating point format (using a dot C<.> as decimal separator), hexadecimal when using the C<0x> prefix and octal with a leading zero (C<0>). I values are either B or B. Lines may be wrapped by using C<\> as the last character before the newline. This allows long lines to be split into multiple lines. Quoted strings may be wrapped as well. However, those are treated special in that whitespace at the beginning of the following lines will be ignored, which allows for nicely indenting the wrapped lines. The configuration is read and processed in order, i.e. from top to bottom. So the plugins are loaded in the order listed in this config file. It is a good idea to load any logging plugins first in order to catch messages from plugins during configuration. Also, the C option B occur B the appropriate CPlugin ...E> block. =head1 GLOBAL OPTIONS =over 4 =item B I Sets the base directory. This is the directory beneath all RRD-files are created. Possibly more subdirectories are created. This is also the working directory for the daemon. =item B I Loads the plugin I. This is required to load plugins, unless the B option is enabled (see below). Without any loaded plugins, I will be mostly useless. Only the first B statement or block for a given plugin name has any effect. This is useful when you want to split up the configuration into smaller files and want each file to be "self contained", i.e. it contains a B block I then appropriate B statement. The downside is that if you have multiple conflicting B blocks, e.g. when they specify different intervals, only one of them (the first one encountered) will take effect and all others will be silently ignored. B may either be a simple configuration I or a I with additional options, affecting the behavior of B. A simple statement looks like this: LoadPlugin "cpu" Options inside a B block can override default settings and influence the way plugins are loaded, e.g.: Globals true Interval 60 The following options are valid inside B blocks: =over 4 =item B B If enabled, collectd will export all global symbols of the plugin (and of all libraries loaded as dependencies of the plugin) and, thus, makes those symbols available for resolving unresolved symbols in subsequently loaded plugins if that is supported by your system. This is useful (or possibly even required), e.g., when loading a plugin that embeds some scripting language into the daemon (e.g. the I and I). Scripting languages usually provide means to load extensions written in C. Those extensions require symbols provided by the interpreter, which is loaded as a dependency of the respective collectd plugin. See the documentation of those plugins (e.g., L or L) for details. By default, this is disabled. As a special exception, if the plugin name is either C or C, the default is changed to enabled in order to keep the average user from ever having to deal with this low level linking stuff. =item B I Sets a plugin-specific interval for collecting metrics. This overrides the global B setting. If a plugin provides own support for specifying an interval, that setting will take precedence. =back =item B B|B When set to B (the default), each plugin needs to be loaded explicitly, using the B statement documented above. If a BPluginE...E> block is encountered and no configuration handling callback for this plugin has been registered, a warning is logged and the block is ignored. When set to B, explicit B statements are not required. Each BPluginE...E> block acts as if it was immediately preceded by a B statement. B statements are still required for plugins that don't provide any configuration, e.g. the I. =item B I [I] If I points to a file, includes that file. If I points to a directory, recursively includes all files within that directory and its subdirectories. If the C function is available on your system, shell-like wildcards are expanded before files are included. This means you can use statements like the following: Include "/etc/collectd.d/*.conf" Starting with version 5.3, this may also be a block in which further options affecting the behavior of B may be specified. The following option is currently allowed: Filter "*.conf" =over 4 =item B I If the C function is available on your system, a shell-like wildcard I may be specified to filter which files to include. This may be used in combination with recursively including a directory to easily be able to arbitrarily mix configuration files and other documents (e.g. README files). The given example is similar to the first example above but includes all files matching C<*.conf> in any subdirectory of C: Include "/etc/collectd.d" "*.conf" =back If more than one files are included by a single B option, the files will be included in lexicographical order (as defined by the C function). Thus, you can e.Eg. use numbered prefixes to specify the order in which the files are loaded. To prevent loops and shooting yourself in the foot in interesting ways the nesting is limited to a depth of 8Elevels, which should be sufficient for most uses. Since symlinks are followed it is still possible to crash the daemon by looping symlinks. In our opinion significant stupidity should result in an appropriate amount of pain. It is no problem to have a block like CPlugin fooE> in more than one file, but you cannot include files from within blocks. =item B I Sets where to write the PID file to. This file is overwritten when it exists and deleted when the program is stopped. Some init-scripts might override this setting using the B<-P> command-line option. =item B I Path to the plugins (shared objects) of collectd. =item B I [I ...] Set one or more files that contain the data-set descriptions. See L for a description of the format of this file. =item B I Configures the interval in which to query the read plugins. Obviously smaller values lead to a higher system load produced by collectd, while higher values lead to more coarse statistics. B You should set this once and then never touch it again. If you do, I or know some serious RRDtool magic! (Assuming you're using the I or I plugin.) =item B I Consider a value list "missing" when no update has been read or received for I iterations. By default, I considers a value list missing when no update has been received for twice the update interval. Since this setting uses iterations, the maximum allowed time without update depends on the I information contained in each value list. This is used in the I configuration to dispatch notifications about missing values, see L for details. =item B I Number of threads to start for reading plugins. The default value is B<5>, but you may want to increase this if you have more than five plugins that take a long time to read. Mostly those are plugins that do network-IO. Setting this to a value higher than the number of registered read callbacks is not recommended. =item B I Number of threads to start for dispatching value lists to write plugins. The default value is B<5>, but you may want to increase this if you have more than five plugins that may take relatively long to write to. =item B I =item B I Metrics are read by the I and then put into a queue to be handled by the I. If one of the I is slow (e.g. network timeouts, I/O saturation of the disk) this queue will grow. In order to avoid running into memory issues in such a case, you can limit the size of this queue. By default, there is no limit and memory may grow indefinitely. This is most likely not an issue for clients, i.e. instances that only handle the local metrics. For servers it is recommended to set this to a non-zero value, though. You can set the limits using B and B. Each of them takes a numerical argument which is the number of metrics in the queue. If there are I metrics in the queue, any new metrics I be dropped. If there are less than I metrics in the queue, all new metrics I be enqueued. If the number of metrics currently in the queue is between I and I, the metric is dropped with a probability that is proportional to the number of metrics in the queue (i.e. it increases linearly until it reaches 100%.) If B is set to non-zero and B is unset, the latter will default to half of B. If you do not want to randomly drop values when the queue size is between I and I, set If B and B to same value. =item B I Sets the hostname that identifies a host. If you omit this setting, the hostname will be determined using the L system call. =item B B If B is determined automatically this setting controls whether or not the daemon should try to figure out the "fully qualified domain name", FQDN. This is done using a lookup of the name returned by C. This option is enabled by default. =item B I =item B I Configure the name of the "pre-cache chain" and the "post-cache chain". Please see L below on information on chains and how these setting change the daemon's behavior. =back =head1 PLUGIN OPTIONS Some plugins may register own options. These options must be enclosed in a C-Section. Which options exist depends on the plugin used. Some plugins require external configuration, too. The C, for example, required C to be configured in the webserver you're going to collect data from. These plugins are listed below as well, even if they don't require any configuration within collectd's configuration file. A list of all plugins and a short summary for each plugin can be found in the F file shipped with the sourcecode and hopefully binary packets as well. =head2 Plugin C The I makes it possible to aggregate several values into one using aggregation functions such as I, I, I and I. This can be put to a wide variety of uses, e.g. average and total CPU statistics for your entire fleet. The grouping is powerful but, as with many powerful tools, may be a bit difficult to wrap your head around. The grouping will therefore be demonstrated using an example: The average and sum of the CPU usage across all CPUs of each host is to be calculated. To select all the affected values for our example, set C and C. The other values are left unspecified, meaning "all values". The I, I, I, I and I options work as if they were specified in the C clause of an C
I [I [I]] Select the rules to count. If only I
and I are given, this plugin will collect the counters of all rules which have a comment-match. The comment is then used as type-instance. If I or I is given, only the rule with the matching comment or the Ith rule will be collected. Again, the comment (or the number) will be used as the type-instance. If I is supplied, it will be used as the type-instance instead of the comment or the number. =back =head2 Plugin C =over 4 =item B I Select this irq. By default these irqs will then be collected. For a more detailed description see B below. =item B I|I If no configuration if given, the B-plugin will collect data from all irqs. This may not be practical, especially if no interrupts happen. Thus, you can use the B-option to pick the interrupt you're interested in. Sometimes, however, it's easier/preferred to collect all interrupts I a few ones. This option enables you to do that: By setting B to I the effect of B is inverted: All selected interrupts are ignored and all other interrupts are collected. =back =head2 Plugin C The I plugin makes it possible to write extensions for collectd in Java. This section only discusses the syntax and semantic of the configuration options. For more in-depth information on the I plugin, please read L. Synopsis: JVMArg "-verbose:jni" JVMArg "-Djava.class.path=/opt/collectd/lib/collectd/bindings/java" LoadPlugin "org.collectd.java.Foobar" # To be parsed by the plugin Available configuration options: =over 4 =item B I Argument that is to be passed to the I (JVM). This works exactly the way the arguments to the I binary on the command line work. Execute C--help> for details. Please note that B these options must appear B (i.Ee. above) any other options! When another option is found, the JVM will be started and later options will have to be ignored! =item B I Instantiates a new I object. The constructor of this object very likely then registers one or more callback methods with the server. See L for details. When the first such option is found, the virtual machine (JVM) is created. This means that all B options must appear before (i.Ee. above) all B options! =item B I The entire block is passed to the Java plugin as an I object. For this to work, the plugin has to register a configuration callback first, see L. This means, that the B block must appear after the appropriate B block. Also note, that I depends on the (Java) plugin registering the callback and is completely independent from the I argument passed to B. =back =head2 Plugin C This plugin allows CPU, disk and network load to be collected for virtualized guests on the machine. This means that these characteristics can be collected for guest systems without installing any software on them - collectd only runs on the hosting system. The statistics are collected through libvirt (L). Only I is required. =over 4 =item B I Connect to the hypervisor given by I. For example if using Xen use: Connection "xen:///" Details which URIs allowed are given at L. =item B I Refresh the list of domains and devices every I. The default is 60 seconds. Setting this to be the same or smaller than the I will cause the list of domains and devices to be refreshed on every iteration. Refreshing the devices in particular is quite a costly operation, so if your virtualization setup is static you might consider increasing this. If this option is set to 0, refreshing is disabled completely. =item B I =item B I =item B I =item B I|I Select which domains and devices are collected. If I is not given or I then only the listed domains and disk/network devices are collected. If I is I then the test is reversed and the listed domains and disk/network devices are ignored, while the rest are collected. The domain name and device names may use a regular expression, if the name is surrounded by I and collectd was compiled with support for regexps. The default is to collect statistics for all domains and all their devices. Example: BlockDevice "/:hdb/" IgnoreSelected "true" Ignore all I devices on any domain, but other block devices (eg. I) will be collected. =item B B When the libvirt plugin logs data, it sets the hostname of the collected data according to this setting. The default is to use the guest name as provided by the hypervisor, which is equal to setting B. B means use the guest's UUID. This is useful if you want to track the same guest across migrations. B means to use the global B setting, which is probably not useful on its own because all guests will appear to have the same name. You can also specify combinations of these fields. For example B means to concatenate the guest name and UUID (with a literal colon character between, thus I<"foo:1234-1234-1234-1234">). =item B B|B
When the libvirt plugin logs interface data, it sets the name of the collected data according to this setting. The default is to use the path as provided by the hypervisor (the "dev" property of the target node), which is equal to setting B. B
means use the interface's mac address. This is useful since the interface path might change between reboots of a guest or across migrations. =back =head2 Plugin C =over 4 =item B B Sets the log-level. If, for example, set to B, then all events with severity B, B, or B will be written to the logfile. Please note that B is only available if collectd has been compiled with debugging support. =item B I Sets the file to write log messages to. The special strings B and B can be used to write to the standard output and standard error channels, respectively. This, of course, only makes much sense when I is running in foreground- or non-daemon-mode. =item B B|B Prefix all lines printed by the current time. Defaults to B. =item B B|B When enabled, all lines are prefixed by the severity of the log message, for example "warning". Defaults to B. =back B: There is no need to notify the daemon after moving or removing the log file (e.Eg. when rotating the logs). The plugin reopens the file for each line it writes. =head2 Plugin C The I reads CPU statistics of I, a virtualization technique for IBM POWER processors. It takes into account CPU time stolen from or donated to a partition, in addition to the usual user, system, I/O statistics. The following configuration options are available: =over 4 =item B B|B When enabled, statistics about the processor pool are read, too. The partition needs to have pool authority in order to be able to acquire this information. Defaults to false. =item B B|B If enabled, the serial of the physical machine the partition is currently running on is reported as I and the logical hostname of the machine is reported in the I. Otherwise, the logical hostname will be used (just like other plugins) and the I will be empty. Defaults to false. =back =head2 Plugin C The C uses mbmon to retrieve temperature, voltage, etc. Be default collectd connects to B (127.0.0.1), port B<411/tcp>. The B and B options can be used to change these values, see below. C has to be running to work correctly. If C is not running timeouts may appear which may interfere with other statistics.. C must be run with the -r option ("print TAG and Value format"); Debian's F script already does this, other people will need to ensure that this is the case. =over 4 =item B I Hostname to connect to. Defaults to B<127.0.0.1>. =item B I TCP-Port to connect to. Defaults to B<411>. =back =head2 Plugin C The C collects information from Linux Software-RAID devices (md). All reported values are of the type C. Reported type instances are I, I (present but not operational), I (hot stand-by) and I (physically absent) disks. =over 4 =item B I Select md devices based on device name. The I is the basename of the device, i.e. the name of the block device without the leading C. See B for more details. =item B B|B Invert device selection: If set to B, all md devices B those listed using B are collected. If B (the default), only those listed are collected. If no configuration is given, the B plugin will collect data from all md devices. =back =head2 Plugin C The C connects to a memcached server, queries one or more given I and parses the returned data according to user specification. The I used are the same as the matches used in the C and C plugins. In order to talk to the memcached server, this plugin uses the I library. Please note that there is another library with a very similar name, libmemcache (notice the missing `d'), which is not applicable. Synopsis of the configuration: Server "localhost" Key "page_key" Regex "(\\d+) bytes sent" DSType CounterAdd Type "ipt_octets" Instance "type_instance" The configuration options are: =over 4 =item EB IE Each B block defines one I to be queried from the memcached server. The block requires one string argument which is used as I. =item B I
Sets the server address to connect to when querying the page. Must be inside a B block. =item B I When connected to the memcached server, asks for the page I. =item EBE Match blocks define which strings to look for and how matches substrings are interpreted. For a description of match blocks, please see L<"Plugin tail">. =back =head2 Plugin C The B connects to a memcached server and queries statistics about cache utilization, memory and bandwidth used. L Host "memcache.example.com" Port 11211 The plugin configuration consists of one or more B blocks which specify one I connection each. Within the B blocks, the following options are allowed: =over 4 =item B I Hostname to connect to. Defaults to B<127.0.0.1>. =item B I TCP-Port to connect to. Defaults to B<11211>. =item B I Connect to I using the UNIX domain socket at I. If this setting is given, the B and B settings are ignored. =back =head2 Plugin C The B gathers CPU statistics, memory usage and temperatures from Intel's Many Integrated Core (MIC) systems. B ShowCPU true ShowCPUCores true ShowMemory true ShowTemperatures true Temperature vddg Temperature vddq IgnoreSelectedTemperature true ShowPower true Power total0 Power total1 IgnoreSelectedPower true The following options are valid inside the Bmic> block: =over 4 =item B B|B If enabled (the default) a sum of the CPU usage accross all cores is reported. =item B B|B If enabled (the default) per-core CPU usage is reported. =item B B|B If enabled (the default) the physical memory usage of the MIC system is reported. =item B B|B If enabled (the default) various temperatures of the MIC system are reported. =item B I This option controls which temperatures are being reported. Whether matching temperatures are being ignored or I matching temperatures are reported depends on the B setting below. By default I temperatures are reported. =item B B|B Controls the behavior of the B setting above. If set to B (the default) only temperatures matching a B option are reported or, if no B option is specified, all temperatures are reported. If set to B, matching temperatures are I and all other temperatures are reported. Known temperature names are: =over 4 =item die Die of the CPU =item devmem Device Memory =item fin Fan In =item fout Fan Out =item vccp Voltage ccp =item vddg Voltage ddg =item vddq Voltage ddq =back =item B B|B If enabled (the default) various temperatures of the MIC system are reported. =item B I This option controls which power readings are being reported. Whether matching power readings are being ignored or I matching power readings are reported depends on the B setting below. By default I power readings are reported. =item B B|B Controls the behavior of the B setting above. If set to B (the default) only power readings matching a B option are reported or, if no B option is specified, all power readings are reported. If set to B, matching power readings are I and all other power readings are reported. Known power names are: =over 4 =item total0 Total power utilization averaged over Time Window 0 (uWatts). =item total1 Total power utilization averaged over Time Window 0 (uWatts). =item inst Instantaneous power (uWatts). =item imax Max instantaneous power (uWatts). =item pcie PCI-E connector power (uWatts). =item c2x3 2x3 connector power (uWatts). =item c2x4 2x4 connector power (uWatts). =item vccp Core rail (uVolts). =item vddg Uncore rail (uVolts). =item vddq Memory subsystem rail (uVolts). =back =back =head2 Plugin C The B connects to a Modbus "slave" via Modbus/TCP and reads register values. It supports reading single registers (unsigned 16Ebit values), large integer values (unsigned 32Ebit values) and floating point values (two registers interpreted as IEEE floats in big endian notation). B RegisterBase 0 RegisterType float Type voltage Instance "input-1" RegisterBase 2 RegisterType float Type voltage Instance "input-2" Address "192.168.0.42" Port "502" Interval 60 Instance "power-supply" Collect "voltage-input-1" Collect "voltage-input-2" =over 4 =item EB IE blocks Data blocks define a mapping between register numbers and the "types" used by I. Within EDataE/E blocks, the following options are allowed: =over 4 =item B I Configures the base register to read from the device. If the option B has been set to B or B, this and the next register will be read (the register number is increased by one). =item B B|B|B|B|B Specifies what kind of data is returned by the device. If the type is B, B or B, two 16Ebit registers will be read and the data is combined into one value. Defaults to B. =item B I Specifies the "type" (data set) to use when dispatching the value to I. Currently, only data sets with exactly one data source are supported. =item B I Sets the type instance to use when dispatching the value to I. If unset, an empty string (no type instance) is used. =back =item EB IE blocks Host blocks are used to specify to which hosts to connect and what data to read from their "slaves". The string argument I is used as hostname when dispatching the values to I. Within EHostE/E blocks, the following options are allowed: =over 4 =item B
I Specifies the node name (the actual network address) used to connect to the host. This may be an IP address or a hostname. Please note that the used I library only supports IPv4 at the moment. =item B I Specifies the port used to connect to the host. The port can either be given as a number or as a service name. Please note that the I argument must be a string, even if ports are given in their numerical form. Defaults to "502". =item B I Sets the interval (in seconds) in which the values will be collected from this host. By default the global B setting will be used. =item EB IE Over each TCP connection, multiple Modbus devices may be reached. The slave ID is used to specify which device should be addressed. For each device you want to query, one B block must be given. Within ESlaveE/E blocks, the following options are allowed: =over 4 =item B I Specify the plugin instance to use when dispatching the values to I. By default "slave_I" is used. =item B I Specifies which data to retrieve from the device. I must be the same string as the I argument passed to a B block. You can specify this option multiple times to collect more than one value from a slave. At least one B option is mandatory. =back =back =back =head2 Plugin C The C requires B to be installed. It connects to one or more databases when started and keeps the connection up as long as possible. When the connection is interrupted for whatever reason it will try to re-connect. The plugin will complain loudly in case anything goes wrong. This plugin issues the MySQL C / C command and collects information about MySQL network traffic, executed statements, requests, the query cache and threads by evaluating the C, C, C, C and C return values. Please refer to the B, I<5.1.6. Server Status Variables> for an explanation of these values. Optionally, master and slave statistics may be collected in a MySQL replication setup. In that case, information about the synchronization state of the nodes are collected by evaluating the C return value of the C command and the C, C and C return values of the C command. See the B, I<12.5.5.21 SHOW MASTER STATUS Syntax> and I<12.5.5.31 SHOW SLAVE STATUS Syntax> for details. Synopsis: Host "hostname" User "username" Password "password" Port "3306" MasterStats true Host "localhost" Socket "/var/run/mysql/mysqld.sock" SlaveStats true SlaveNotifications true A B block defines one connection to a MySQL database. It accepts a single argument which specifies the name of the database. None of the other options are required. MySQL will use default values as documented in the section "mysql_real_connect()" in the B. =over 4 =item B I Hostname of the database server. Defaults to B. =item B I Username to use when connecting to the database. The user does not have to be granted any privileges (which is synonym to granting the C privilege), unless you want to collectd replication statistics (see B and B below). In this case, the user needs the C (or C) privileges. Else, any existing MySQL user will do. =item B I Password needed to log into the database. =item B I Select this database. Defaults to I which is a perfectly reasonable option for what this plugin does. =item B I TCP-port to connect to. The port must be specified in its numeric form, but it must be passed as a string nonetheless. For example: Port "3306" If B is set to B (the default), this setting has no effect. See the documentation for the C function for details. =item B I Specifies the path to the UNIX domain socket of the MySQL server. This option only has any effect, if B is set to B (the default). Otherwise, use the B option above. See the documentation for the C function for details. =item B I =item B I Enable the collection of master / slave statistics in a replication setup. In order to be able to get access to these statistics, the user needs special privileges. See the B documentation above. =item B I If enabled, the plugin sends a notification if the replication slave I/O and / or SQL threads are not running. =back =head2 Plugin C The netapp plugin can collect various performance and capacity information from a NetApp filer using the NetApp API. Please note that NetApp has a wide line of products and a lot of different software versions for each of these products. This plugin was developed for a NetApp FAS3040 running OnTap 7.2.3P8 and tested on FAS2050 7.3.1.1L1, FAS3140 7.2.5.1 and FAS3020 7.2.4P9. It I work for most combinations of model and software version but it is very hard to test this. If you have used this plugin with other models and/or software version, feel free to send us a mail to tell us about the results, even if it's just a short "It works". To collect these data collectd will log in to the NetApp via HTTP(S) and HTTP basic authentication. B Create a special collectd user with just the minimum of capabilities needed. The user only needs the "login-http-admin" capability as well as a few more depending on which data will be collected. Required capabilities are documented below. =head3 Synopsis Protocol "https" Address "10.0.0.1" Port 443 User "username" Password "aef4Aebe" Interval 30 Interval 30 GetNameCache true GetDirCache true GetBufferCache true GetInodeCache true Interval 30 GetBusy true Interval 30 GetIO "volume0" IgnoreSelectedIO false GetOps "volume0" IgnoreSelectedOps false GetLatency "volume0" IgnoreSelectedLatency false Interval 30 GetCapacity "vol0" GetCapacity "vol1" IgnoreSelectedCapacity false GetSnapshot "vol1" GetSnapshot "vol3" IgnoreSelectedSnapshot false Interval 60 Interval 30 Interval 30 GetCPULoad true GetInterfaces true GetDiskOps true GetDiskIO true Interval 60 SnapVault true # ... The netapp plugin accepts the following configuration options: =over 4 =item B I A host block defines one NetApp filer. It will appear in collectd with the name you specify here which does not have to be its real name nor its hostname (see the B
option below). =item B I A B block may only be used inside a host block. It accepts all the same options as the B block (except for cascaded B blocks) and will execute all NetApp API commands in the context of the specified VFiler(R). It will appear in collectd with the name you specify here which does not have to be its real name. The VFiler name may be specified using the B option. If this is not specified, it will default to the name you specify here. The VFiler block inherits all connection related settings from the surrounding B block (which appear before the B block) but they may be overwritten inside the B block. This feature is useful, for example, when using a VFiler as SnapVault target (supported since OnTap 8.1). In that case, the SnapVault statistics are not available in the host filer (vfiler0) but only in the respective VFiler context. =item B B|B The protocol collectd will use to query this host. Optional Type: string Default: https Valid options: http, https =item B
I
The hostname or IP address of the host. Optional Type: string Default: The "host" block's name. =item B I The TCP port to connect to on the host. Optional Type: integer Default: 80 for protocol "http", 443 for protocol "https" =item B I =item B I The username and password to use to login to the NetApp. Mandatory Type: string =item B I The name of the VFiler in which context to execute API commands. If not specified, the name provided to the B block will be used instead. Optional Type: string Default: name of the B block B This option may only be used inside B blocks. =item B I B =back The following options decide what kind of data will be collected. You can either use them as a block and fine tune various parameters inside this block, use them as a single statement to just accept all default values, or omit it to not collect any data. The following options are valid inside all blocks: =over 4 =item B I Collect the respective statistics every I seconds. Defaults to the host specific setting. =back =head3 The System block This will collect various performance data about the whole system. B To get this data the collectd user needs the "api-perf-object-get-instances" capability. =over 4 =item B I Collect disk statistics every I seconds. =item B B|B If you set this option to true the current CPU usage will be read. This will be the average usage between all CPUs in your NetApp without any information about individual CPUs. B These are the same values that the NetApp CLI command "sysstat" returns in the "CPU" field. Optional Type: boolean Default: true Result: Two value lists of type "cpu", and type instances "idle" and "system". =item B B|B If you set this option to true the current traffic of the network interfaces will be read. This will be the total traffic over all interfaces of your NetApp without any information about individual interfaces. B This is the same values that the NetApp CLI command "sysstat" returns in the "Net kB/s" field. B Optional Type: boolean Default: true Result: One value list of type "if_octects". =item B B|B If you set this option to true the current IO throughput will be read. This will be the total IO of your NetApp without any information about individual disks, volumes or aggregates. B This is the same values that the NetApp CLI command "sysstat" returns in the "DiskEkB/s" field. Optional Type: boolean Default: true Result: One value list of type "disk_octets". =item B B|B If you set this option to true the current number of HTTP, NFS, CIFS, FCP, iSCSI, etc. operations will be read. This will be the total number of operations on your NetApp without any information about individual volumes or aggregates. B These are the same values that the NetApp CLI command "sysstat" returns in the "NFS", "CIFS", "HTTP", "FCP" and "iSCSI" fields. Optional Type: boolean Default: true Result: A variable number of value lists of type "disk_ops_complex". Each type of operation will result in one value list with the name of the operation as type instance. =back =head3 The WAFL block This will collect various performance data about the WAFL file system. At the moment this just means cache performance. B To get this data the collectd user needs the "api-perf-object-get-instances" capability. B The interface to get these values is classified as "Diagnostics" by NetApp. This means that it is not guaranteed to be stable even between minor releases. =over 4 =item B I Collect disk statistics every I seconds. =item B B|B Optional Type: boolean Default: true Result: One value list of type "cache_ratio" and type instance "name_cache_hit". =item B B|B Optional Type: boolean Default: true Result: One value list of type "cache_ratio" and type instance "find_dir_hit". =item B B|B Optional Type: boolean Default: true Result: One value list of type "cache_ratio" and type instance "inode_cache_hit". =item B B|B B This is the same value that the NetApp CLI command "sysstat" returns in the "Cache hit" field. Optional Type: boolean Default: true Result: One value list of type "cache_ratio" and type instance "buf_hash_hit". =back =head3 The Disks block This will collect performance data about the individual disks in the NetApp. B To get this data the collectd user needs the "api-perf-object-get-instances" capability. =over 4 =item B I Collect disk statistics every I seconds. =item B B|B If you set this option to true the busy time of all disks will be calculated and the value of the busiest disk in the system will be written. B This is the same values that the NetApp CLI command "sysstat" returns in the "Disk util" field. Probably. Optional Type: boolean Default: true Result: One value list of type "percent" and type instance "disk_busy". =back =head3 The VolumePerf block This will collect various performance data about the individual volumes. You can select which data to collect about which volume using the following options. They follow the standard ignorelist semantic. B To get this data the collectd user needs the I capability. =over 4 =item B I Collect volume performance data every I seconds. =item B I =item B I =item B I Select the given volume for IO, operations or latency statistics collection. The argument is the name of the volume without the C prefix. Since the standard ignorelist functionality is used here, you can use a string starting and ending with a slash to specify regular expression matching: To match the volumes "vol0", "vol2" and "vol7", you can use this regular expression: GetIO "/^vol[027]$/" If no regular expression is specified, an exact match is required. Both, regular and exact matching are case sensitive. If no volume was specified at all for either of the three options, that data will be collected for all available volumes. =item B B|B =item B B|B =item B B|B When set to B, the volumes selected for IO, operations or latency statistics collection will be ignored and the data will be collected for all other volumes. When set to B, data will only be collected for the specified volumes and all other volumes will be ignored. If no volumes have been specified with the above B options, all volumes will be collected regardless of the B option. Defaults to B =back =head3 The VolumeUsage block This will collect capacity data about the individual volumes. B To get this data the collectd user needs the I capability. =over 4 =item B I Collect volume usage statistics every I seconds. =item B I The current capacity of the volume will be collected. This will result in two to four value lists, depending on the configuration of the volume. All data sources are of type "df_complex" with the name of the volume as plugin_instance. There will be type_instances "used" and "free" for the number of used and available bytes on the volume. If the volume has some space reserved for snapshots, a type_instance "snap_reserved" will be available. If the volume has SIS enabled, a type_instance "sis_saved" will be available. This is the number of bytes saved by the SIS feature. B The current NetApp API has a bug that results in this value being reported as a 32Ebit number. This plugin tries to guess the correct number which works most of the time. If you see strange values here, bug NetApp support to fix this. Repeat this option to specify multiple volumes. =item B B|B Specify whether to collect only the volumes selected by the B option or to ignore those volumes. B defaults to B. However, if no B option is specified at all, all capacities will be selected anyway. =item B I Select volumes from which to collect snapshot information. Usually, the space used for snapshots is included in the space reported as "used". If snapshot information is collected as well, the space used for snapshots is subtracted from the used space. To make things even more interesting, it is possible to reserve space to be used for snapshots. If the space required for snapshots is less than that reserved space, there is "reserved free" and "reserved used" space in addition to "free" and "used". If the space required for snapshots exceeds the reserved space, that part allocated in the normal space is subtracted from the "used" space again. Repeat this option to specify multiple volumes. =item B Specify whether to collect only the volumes selected by the B option or to ignore those volumes. B defaults to B. However, if no B option is specified at all, all capacities will be selected anyway. =back =head3 The Quota block This will collect (tree) quota statistics (used disk space and number of used files). This mechanism is useful to get usage information for single qtrees. In case the quotas are not used for any other purpose, an entry similar to the following in C would be sufficient: /vol/volA/some_qtree tree - - - - - After adding the entry, issue C on the NetApp filer. =over 4 =item B I Collect SnapVault(R) statistics every I seconds. =back =head3 The SnapVault block This will collect statistics about the time and traffic of SnapVault(R) transfers. =over 4 =item B I Collect SnapVault(R) statistics every I seconds. =back =head2 Plugin C The C plugin uses a netlink socket to query the Linux kernel about statistics of various interface and routing aspects. =over 4 =item B I =item B I Instruct the plugin to collect interface statistics. This is basically the same as the statistics provided by the C plugin (see above) but potentially much more detailed. When configuring with B only the basic statistics will be collected, namely octets, packets, and errors. These statistics are collected by the C plugin, too, so using both at the same time is no benefit. When configured with B all counters B the basic ones, so that no data needs to be collected twice if you use the C plugin. This includes dropped packets, received multicast packets, collisions and a whole zoo of differentiated RX and TX errors. You can try the following command to get an idea of what awaits you: ip -s -s link list If I is B, all interfaces will be selected. =item B I [I] =item B I [I] =item B I [I] Collect the octets and packets that pass a certain qdisc, class or filter. QDiscs and classes are identified by their type and handle (or classid). Filters don't necessarily have a handle, therefore the parent's handle is used. The notation used in collectd differs from that used in tc(1) in that it doesn't skip the major or minor number if it's zero and doesn't print special ids by their name. So, for example, a qdisc may be identified by C even though the minor number of B qdiscs is zero and thus not displayed by tc(1). If B, B, or B is given without the second argument, i.E.e. without an identifier, all qdiscs, classes, or filters that are associated with that interface will be collected. Since a filter itself doesn't necessarily have a handle, the parent's handle is used. This may lead to problems when more than one filter is attached to a qdisc or class. This isn't nice, but we don't know how this could be done any better. If you have a idea, please don't hesitate to tell us. As with the B option you can specify B as the interface, meaning all interfaces. Here are some examples to help you understand the above text more easily: VerboseInterface "All" QDisc "eth0" "pfifo_fast-1:0" QDisc "ppp0" Class "ppp0" "htb-1:10" Filter "ppp0" "u32-1:0" =item B The behavior is the same as with all other similar plugins: If nothing is selected at all, everything is collected. If some things are selected using the options described above, only these statistics are collected. If you set B to B, this behavior is inverted, i.Ee. the specified statistics will not be collected. =back =head2 Plugin C The Network plugin sends data to a remote instance of collectd, receives data from a remote instance, or both at the same time. Data which has been received from the network is usually not transmitted again, but this can be activated, see the B option below. The default IPv6 multicast group is C. The default IPv4 multicast group is C<239.192.74.66>. The default I port is B<25826>. Both, B and B can be used as single option or as block. When used as block, given options are valid for this socket only. The following example will export the metrics twice: Once to an "internal" server (without encryption and signing) and one to an external server (with cryptographic signature): # Export to an internal server # (demonstrates usage without additional options) Server "collectd.internal.tld" # Export to an external server # (demonstrates usage with signature options) SecurityLevel "sign" Username "myhostname" Password "ohl0eQue" =over 4 =item BServer> I [I]B> The B statement/block sets the server to send datagrams to. The statement may occur multiple times to send each datagram to multiple destinations. The argument I may be a hostname, an IPv4 address or an IPv6 address. The optional second argument specifies a port number or a service name. If not given, the default, B<25826>, is used. The following options are recognized within B blocks: =over 4 =item B B|B|B Set the security you require for network communication. When the security level has been set to B, data sent over the network will be encrypted using I. The integrity of encrypted packets is ensured using I. When set to B, transmitted data is signed using the I message authentication code. When set to B, data is sent without any security. This feature is only available if the I plugin was linked with I. =item B I Sets the username to transmit. This is used by the server to lookup the password. See B below. All security levels except B require this setting. This feature is only available if the I plugin was linked with I. =item B I Sets a password (shared secret) for this socket. All security levels except B require this setting. This feature is only available if the I plugin was linked with I. =item B I Set the outgoing interface for IP packets. This applies at least to IPv6 packets and if possible to IPv4. If this option is not applicable, undefined or a non-existent interface name is specified, the default behavior is to let the kernel choose the appropriate interface. Be warned that the manual selection of an interface for unicast traffic is only necessary in rare cases. =back =item BListen> I [I]B> The B statement sets the interfaces to bind to. When multiple statements are found the daemon will bind to multiple interfaces. The argument I may be a hostname, an IPv4 address or an IPv6 address. If the argument is a multicast address the daemon will join that multicast group. The optional second argument specifies a port number or a service name. If not given, the default, B<25826>, is used. The following options are recognized within CListenE> blocks: =over 4 =item B B|B|B Set the security you require for network communication. When the security level has been set to B, only encrypted data will be accepted. The integrity of encrypted packets is ensured using I. When set to B, only signed and encrypted data is accepted. When set to B, all data will be accepted. If an B option was given (see below), encrypted data is decrypted if possible. This feature is only available if the I plugin was linked with I. =item B I Sets a file in which usernames are mapped to passwords. These passwords are used to verify signatures and to decrypt encrypted network packets. If B is set to B, this is optional. If given, signed data is verified and encrypted packets are decrypted. Otherwise, signed data is accepted without checking the signature and encrypted data cannot be decrypted. For the other security levels this option is mandatory. The file format is very simple: Each line consists of a username followed by a colon and any number of spaces followed by the password. To demonstrate, an example file could look like this: user0: foo user1: bar Each time a packet is received, the modification time of the file is checked using L. If the file has been changed, the contents is re-read. While the file is being read, it is locked using L. =item B I Set the incoming interface for IP packets explicitly. This applies at least to IPv6 packets and if possible to IPv4. If this option is not applicable, undefined or a non-existent interface name is specified, the default behavior is, to let the kernel choose the appropriate interface. Thus incoming traffic gets only accepted, if it arrives on the given interface. =back =item B I<1-255> Set the time-to-live of sent packets. This applies to all, unicast and multicast, and IPv4 and IPv6 packets. The default is to not change this value. That means that multicast packets will be sent with a TTL of C<1> (one) on most operating systems. =item B I<1024-65535> Set the maximum size for datagrams received over the network. Packets larger than this will be truncated. Defaults to 1452Ebytes, which is the maximum payload size that can be transmitted in one Ethernet frame using IPv6E/ UDP. On the server side, this limit should be set to the largest value used on I client. Likewise, the value on the client must not be larger than the value on the server, or data will be lost. B Versions prior to I4.8> used a fixed sized buffer of 1024Ebytes. Versions I<4.8>, I<4.9> and I<4.10> used a default value of 1024Ebytes to avoid problems when sending data to an older server. =item B I If set to I, write packets that were received via the network plugin to the sending sockets. This should only be activated when the B- and B-statements differ. Otherwise packets may be send multiple times to the same multicast group. While this results in more network traffic than necessary it's not a huge problem since the plugin has a duplicate detection, so the values will not loop. =item B B|B The network plugin cannot only receive and send statistics, it can also create statistics about itself. Collected data included the number of received and sent octets and packets, the length of the receive queue and the number of values handled. When set to B, the I will make these statistics available. Defaults to B. =back =head2 Plugin C This plugin collects the number of connections and requests handled by the C (speak: engineEX), a HTTP and mail server/proxy. It queries the page provided by the C module, which isn't compiled by default. Please refer to L for more information on how to compile and configure nginx and this module. The following options are accepted by the C: =over 4 =item B I Sets the URL of the C output. =item B I Optional user name needed for authentication. =item B I Optional password needed for authentication. =item B B Enable or disable peer SSL certificate verification. See L for details. Enabled by default. =item B B Enable or disable peer host name verification. If enabled, the plugin checks if the C or a C field of the SSL certificate matches the host name provided by the B option. If this identity check fails, the connection is aborted. Obviously, only works when connecting to a SSL enabled server. Enabled by default. =item B I File that holds one or more SSL certificates. If you want to use HTTPS you will possibly need this option. What CA certificates come bundled with C and are checked by default depends on the distribution you use. =back =head2 Plugin C This plugin sends a desktop notification to a notification daemon, as defined in the Desktop Notification Specification. To actually display the notifications, B is required and B has to be able to access the X server (i.Ee., the C and C environment variables have to be set correctly) and the D-Bus message bus. The Desktop Notification Specification can be found at L. =over 4 =item B I =item B I =item B I Set the I, in milliseconds, after which to expire the notification for C, C and C severities respectively. If zero has been specified, the displayed notification will not be closed at all - the user has to do so herself. These options default to 5000. If a negative number has been specified, the default is used as well. =back =head2 Plugin C The I plugin uses the I library to send notifications to a configured email address. I is available from L. Available configuration options: =over 4 =item B I
Email address from which the emails should appear to come from. Default: C =item B I
Configures the email address(es) to which the notifications should be mailed. May be repeated to send notifications to multiple addresses. At least one B must be present for the plugin to work correctly. =item B I Hostname of the SMTP server to connect to. Default: C =item B I TCP port to connect to. Default: C<25> =item B I Username for ASMTP authentication. Optional. =item B I Password for ASMTP authentication. Optional. =item B I Subject-template to use when sending emails. There must be exactly two string-placeholders in the subject, given in the standard I syntax, i.Ee. C<%s>. The first will be replaced with the severity, the second with the hostname. Default: C =back =head2 Plugin C =over 4 =item B I Hostname of the host running B. Defaults to B. =item B I UDP-Port to connect to. Defaults to B<123>. =item B B|B Sets whether or not to perform reverse lookups on peers. Since the name or IP-address may be used in a filename it is recommended to disable reverse lookups. The default is to do reverse lookups to preserve backwards compatibility, though. =item B B|B When a peer is a refclock, include the unit ID in the I. Defaults to B for backward compatibility. If two refclock peers use the same driver and this is B, the plugin will try to write simultaneous measurements from both to the same type instance. This will result in error messages in the log and only one set of measurements making it through. =back =head2 Plugin C =over 4 =item B IB<@>I[B<:>I] Add a UPS to collect data from. The format is identical to the one accepted by L. =back =head2 Plugin C The I plugin connects to the TCP port opened by the I plugin of the Optimized Link State Routing daemon and reads information about the current state of the meshed network. The following configuration options are understood: =over 4 =item B I Connect to I. Defaults to B<"localhost">. =item B I Specifies the port to connect to. This must be a string, even if you give the port as a number rather than a service name. Defaults to B<"2006">. =item B B|B|B Specifies what information to collect about links, i.Ee. direct connections of the daemon queried. If set to B, no information is collected. If set to B, the number of links and the average of all I (LQ) and I (NLQ) values is calculated. If set to B LQ and NLQ are collected per link. Defaults to B. =item B B|B|B Specifies what information to collect about routes of the daemon queried. If set to B, no information is collected. If set to B, the number of routes and the average I and I is calculated. If set to B metric and ETX are collected per route. Defaults to B. =item B B|B|B Specifies what information to collect about the global topology. If set to B, no information is collected. If set to B, the number of links in the entire topology and the average I (LQ) is calculated. If set to B LQ and NLQ are collected for each link in the entire topology. Defaults to B. =back =head2 Plugin C B See notes below. The C plugin uses the B library from the B project L to read sensors connected via the onewire bus. Currently only temperature sensors (sensors with the family code C<10>, e.Eg. DS1820, DS18S20, DS1920) can be read. If you have other sensors you would like to have included, please send a sort request to the mailing list. Hubs (the DS2409 chips) are working, but read the note, why this plugin is experimental, below. =over 4 =item B I Sets the device to read the values from. This can either be a "real" hardware device, such as a serial port or an USB port, or the address of the L socket, usually B. Though the documentation claims to automatically recognize the given address format, with versionE2.7p4 we had to specify the type explicitly. So with that version, the following configuration worked for us: Device "-s localhost:4304" This directive is B and does not have a default value. =item B I Selects sensors to collect or to ignore, depending on B, see below. Sensors are specified without the family byte at the beginning, to you'd use C, and B include the leading C<10.> family byte and point. =item B I|I If no configuration if given, the B plugin will collect data from all sensors found. This may not be practical, especially if sensors are added and removed regularly. Sometimes, however, it's easier/preferred to collect only specific sensors or all sensors I a few specified ones. This option enables you to do that: By setting B to I the effect of B is inverted: All selected interfaces are ignored and all other interfaces are collected. =item B I Sets the interval in which all sensors should be read. If not specified, the global B setting is used. =back B The C plugin is experimental, because it doesn't yet work with big setups. It works with one sensor being attached to one controller, but as soon as you throw in a couple more senors and maybe a hub or two, reading all values will take more than ten seconds (the default interval). We will probably add some separate thread for reading the sensors and some cache or something like that, but it's not done yet. We will try to maintain backwards compatibility in the future, but we can't promise. So in short: If it works for you: Great! But keep in mind that the config I change, though this is unlikely. Oh, and if you want to help improving this plugin, just send a short notice to the mailing list. ThanksE:) =head2 Plugin C The OpenVPN plugin reads a status file maintained by OpenVPN and gathers traffic statistics about connected clients. To set up OpenVPN to write to the status file periodically, use the B<--status> option of OpenVPN. Since OpenVPN can write two different formats, you need to set the required format, too. This is done by setting B<--status-version> to B<2>. So, in a nutshell you need: openvpn $OTHER_OPTIONS \ --status "/var/run/openvpn-status" 10 \ --status-version 2 Available options: =over 4 =item B I Specifies the location of the status file. =item B B|B When enabled, the filename of the status file will be used as plugin instance and the client's "common name" will be used as type instance. This is required when reading multiple status files. Enabling this option is recommended, but to maintain backwards compatibility this option is disabled by default. =item B B|B Sets whether or not statistics about the compression used by OpenVPN should be collected. This information is only available in I mode. Enabled by default. =item B B|B Sets whether or not traffic information is collected for each connected client individually. If set to false, currently no traffic data is collected at all because aggregating this data in a save manner is tricky. Defaults to B. =item B B|B When enabled, the number of currently connected clients or users is collected. This is especially interesting when B is disabled, but can be configured independently from that option. Defaults to B. =back =head2 Plugin C The "oracle" plugin uses the Oracle® Call Interface I<(OCI)> to connect to an Oracle® Database and lets you execute SQL statements there. It is very similar to the "dbi" plugin, because it was written around the same time. See the "dbi" plugin's documentation above for details. Statement "SELECT category, COUNT(*) AS value FROM products WHERE in_stock = 0 GROUP BY category" Type "gauge" # InstancePrefix "foo" InstancesFrom "category" ValuesFrom "value" ConnectID "db01" Username "oracle" Password "secret" Query "out_of_stock" =head3 B blocks The Query blocks are handled identically to the Query blocks of the "dbi" plugin. Please see its documentation above for details on how to specify queries. =head3 B blocks Database blocks define a connection to a database and which queries should be sent to that database. Each database needs a "name" as string argument in the starting tag of the block. This name will be used as "PluginInstance" in the values submitted to the daemon. Other than that, that name is not used. =over 4 =item B I Defines the "database alias" or "service name" to connect to. Usually, these names are defined in the file named C<$ORACLE_HOME/network/admin/tnsnames.ora>. =item B I Hostname to use when dispatching values for this database. Defaults to using the global hostname of the I instance. =item B I Username used for authentication. =item B I Password used for authentication. =item B I Associates the query named I with this database connection. The query needs to be defined I this statement, i.Ee. all query blocks you want to refer to must be placed above the database block you want to refer to them from. =back =head2 Plugin C This plugin embeds a Perl-interpreter into collectd and provides an interface to collectd's plugin system. See L for its documentation. =head2 Plugin C The I receives profiling information from I, an extension for the I interpreter. At the end of executing a script, i.e. after a PHP-based webpage has been delivered, the extension will send a UDP packet containing timing information, peak memory usage and so on. The plugin will wait for such packets, parse them and account the provided information, which is then dispatched to the daemon once per interval. Synopsis: Address "::0" Port "30002" # Overall statistics for the website. Server "www.example.com" # Statistics for www-a only Host "www-a.example.com" Server "www.example.com" # Statistics for www-b only Host "www-b.example.com" Server "www.example.com" The plugin provides the following configuration options: =over 4 =item B
I Configures the address used to open a listening socket. By default, plugin will bind to the I address C<::0>. =item B I Configures the port (service) to bind to. By default the default Pinba port "30002" will be used. The option accepts service names in addition to port numbers and thus requires a I argument. =item EB IE block The packets sent by the Pinba extension include the hostname of the server, the server name (the name of the virtual host) and the script that was executed. Using B blocks it is possible to separate the data into multiple groups to get more meaningful statistics. Each packet is added to all matching groups, so that a packet may be accounted for more than once. =over 4 =item B I Matches the hostname of the system the webserver / script is running on. This will contain the result of the L system call. If not configured, all hostnames will be accepted. =item B I Matches the name of the I, i.e. the contents of the C<$_SERVER["SERVER_NAME"]> variable when within PHP. If not configured, all server names will be accepted. =item B

Collectd browser for system statistics graphs

Host: R
Plugin: R
Plugin instance: R
Type: R
Type instance: R
Graph settings:

Graph list favorites: S
LD
Please use above graph selection tool to add graphs to this area.Config error: $config["datadirs"] is not set

'; else if (!is_array($config['datadirs'])) echo '

Config error: $config["datadirs"] is not an array

'; else if (count($config['datadirs']) == 0) echo '

Config error: $config["datadirs"] is empty

'; else foreach ($config['datadirs'] as $datadir) if (!is_dir($datadir)) echo '

Config error: $config["datadirs"], '.htmlspecialchars($datadir).' does not exist

'; if (!isset($config['rrd_width'])) echo '

Config error: $config["rrd_width"] is not set

'; else if (10 > (int)$config['rrd_width']) echo '

Config error: $config["rrd_width"] is invalid. Integer >= 10 expected

'; if (!isset($config['rrd_height'])) echo '

Config error: $config["rrd_height"] is not set

'; else if (10 > (int)$config['rrd_height']) echo '

Config error: $config["rrd_height"] is invalid. Integer >= 10 expected

'; if (!isset($config['rrd_opts'])) echo '

Config error: $config["rrd_opts"] is not set

'; else if (!is_array($config['rrd_opts'])) echo '

Config error: $config["rrd_opts"] is not an array

'; if (!isset($config['timespan'])) echo '

Config error: $config["timespan"] is not set

'; else if (!is_array($config['timespan'])) echo '

Config error: $config["timespan"] is not an array

'; else if (count($config['timespan']) == 0) echo '

Config error: $config["timespan"] is empty

'; else foreach ($config['timespan'] as &$timespan) if (!is_array($timespan) || !isset($timespan['name']) || !isset($timespan['label']) || !isset($timespan['seconds']) || 10 > (int)$timespan['seconds']) echo '

Config error: $config["timespan"], invalid entry found

'; if (!is_null($config['collectd_sock']) && strncmp('unix://', $config['collectd_sock'], 7) != 0) echo '

Config error: $config["collectd_sock"] is not valid

'; if (!defined('RRDTOOL')) echo '

Config error: RRDTOOL is not defined

'; else if (!is_executable(RRDTOOL)) echo '

Config error: RRDTOOL ('.htmlspecialchars(RRDTOOL).') is not executable

'; ?>
1) array_unshift($hosts, '@all'); return dhtml_response_list($hosts, 'ListOfHost'); case 'list_plugins': // Generate list of plugins for selected hosts $arg_hosts = read_var('host', $_POST, ''); if (is_array($arg_hosts)) $arg_hosts = reset($arg_hosts); $plugins = collectd_list_plugins($arg_hosts); if (count($plugins) > 1) array_unshift($plugins, '@all'); return dhtml_response_list($plugins, 'ListOfPlugin'); case 'list_pinsts': // Generate list of plugin_instances for selected hosts and plugin $arg_hosts = read_var('host', $_POST, ''); if (is_array($arg_hosts)) $arg_hosts = reset($arg_hosts); $arg_plugin = read_var('plugin', $_POST, ''); $pinsts = collectd_list_plugins($arg_hosts, $arg_plugin); if (count($pinsts) > 1) array_unshift($pinsts, '@all' /* , '@merge_sum', '@merge_avg', '@merge_stack', '@merge_line' */); return dhtml_response_list($pinsts, 'ListOfPluginInstance'); case 'list_types': // Generate list of types for selected hosts, plugin and plugin-instance $arg_hosts = read_var('host', $_POST, ''); if (is_array($arg_hosts)) $arg_hosts = reset($arg_hosts); $arg_plugin = read_var('plugin', $_POST, ''); $arg_pinst = read_var('plugin_instance', $_POST, ''); $types = collectd_list_types($arg_hosts, $arg_plugin, $arg_pinst); if (count($types) > 1) array_unshift($types, '@all'); return dhtml_response_list($types, 'ListOfType'); case 'list_tinsts': // Generate list of types for selected hosts, plugin and plugin-instance $arg_hosts = read_var('host', $_POST, ''); if (is_array($arg_hosts)) $arg_hosts = reset($arg_hosts); $arg_plugin = read_var('plugin', $_POST, ''); $arg_pinst = read_var('plugin_instance', $_POST, ''); $arg_type = read_var('type', $_POST, ''); $tinsts = collectd_list_types($arg_hosts, $arg_plugin, $arg_pinst, $arg_type); if (count($tinsts)) if ($arg_type != '@all') { require('definitions.php'); load_graph_definitions(); if (isset($MetaGraphDefs[$arg_type])) array_unshift($tinsts, '@merge'); if (count($tinsts) > 1) array_unshift($tinsts, '@all'); } else { array_unshift($tinsts, /* '@merge_sum', '@merge_avg', '@merge_stack', '@merge_line', */ '@merge'); if (count($tinsts) > 1) array_unshift($tinsts, '@all'); } return dhtml_response_list($tinsts, 'ListOfTypeInstance'); case 'list_graphs': // Generate list of types for selected hosts, plugin and plugin-instance $arg_hosts = read_var('host', $_POST, ''); if (is_array($arg_hosts)) $arg_hosts = reset($arg_hosts); $arg_plugin = read_var('plugin', $_POST, ''); $arg_pinst = read_var('plugin_instance', $_POST, ''); $arg_type = read_var('type', $_POST, ''); $arg_tinst = read_var('type_instance', $_POST, ''); $arg_log = (int)read_var('logarithmic', $_POST, '0'); $arg_legend = (int)read_var('tinyLegend', $_POST, '0'); $arg_period = read_var('timespan', $_POST, ''); $graphs = collectd_list_graphs($arg_hosts, $arg_plugin, $arg_pinst, $arg_type, $arg_tinst); foreach ($graphs as &$graph) { $graph['logarithmic'] = $arg_log; $graph['tinyLegend'] = $arg_legend; $graph['timespan'] = $arg_period; } return dhtml_response_graphs($graphs, 'ListOfGraph'); case 'overview': default: return build_page(); break; } ?> collectd-5.4.0/contrib/php-collection/PaxHeaders.11991/functions.php0000644037772200116100000000013212204120331023444 xustar000000000000000030 mtime=1376821465.057973183 30 atime=1376821477.202167674 30 ctime=1376821742.442407632 collectd-5.4.0/contrib/php-collection/functions.php0000644037772200116100000006532212204120331022220 0ustar00octoeng00000000000000 * * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. */ define('REGEXP_HOST', '/^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/'); define('REGEXP_PLUGIN', '/^[a-zA-Z0-9_.-]+$/'); /** * Read input variable from GET, POST or COOKIE taking * care of magic quotes * @name Name of value to return * @array User-input array ($_GET, $_POST or $_COOKIE) * @default Default value * @return $default if name in unknown in $array, otherwise * input value with magic quotes stripped off */ function read_var($name, &$array, $default = null) { if (isset($array[$name])) { if (is_array($array[$name])) { if (get_magic_quotes_gpc()) { $ret = array(); while (list($k, $v) = each($array[$name])) $ret[stripslashes($k)] = stripslashes($v); return $ret; } else return $array[$name]; } else if (is_string($array[$name]) && get_magic_quotes_gpc()) { return stripslashes($array[$name]); } else return $array[$name]; } else return $default; } /** * Alphabetically compare host names, comparing label * from tld to node name */ function collectd_compare_host($a, $b) { $ea = explode('.', $a); $eb = explode('.', $b); $i = count($ea) - 1; $j = count($eb) - 1; while ($i >= 0 && $j >= 0) if (($r = strcmp($ea[$i--], $eb[$j--])) != 0) return $r; return 0; } function collectd_walk(&$options) { global $config; foreach($config['datadirs'] as $datadir) if ($dh = @opendir($datadir)) { while (($hdent = readdir($dh)) !== false) { if ($hdent == '.' || $hdent == '..' || !is_dir($datadir.'/'.$hdent)) continue; if (!preg_match(REGEXP_HOST, $hdent)) continue; if (isset($options['cb_host']) && ($options['cb_host'] === false || !$options['cb_host']($options, $hdent))) continue; if ($dp = @opendir($datadir.'/'.$hdent)) { while (($pdent = readdir($dp)) !== false) { if ($pdent == '.' || $pdent == '..' || !is_dir($datadir.'/'.$hdent.'/'.$pdent)) continue; if ($i = strpos($pdent, '-')) { $plugin = substr($pdent, 0, $i); $pinst = substr($pdent, $i+1); } else { $plugin = $pdent; $pinst = ''; } if (isset($options['cb_plugin']) && ($options['cb_plugin'] === false || !$options['cb_plugin']($options, $hdent, $plugin))) continue; if (isset($options['cb_pinst']) && ($options['cb_pinst'] === false || !$options['cb_pinst']($options, $hdent, $plugin, $pinst))) continue; if ($dt = @opendir($datadir.'/'.$hdent.'/'.$pdent)) { while (($tdent = readdir($dt)) !== false) { if ($tdent == '.' || $tdent == '..' || !is_file($datadir.'/'.$hdent.'/'.$pdent.'/'.$tdent)) continue; if (substr($tdent, strlen($tdent)-4) != '.rrd') continue; $tdent = substr($tdent, 0, strlen($tdent)-4); if ($i = strpos($tdent, '-')) { $type = substr($tdent, 0, $i); $tinst = substr($tdent, $i+1); } else { $type = $tdent; $tinst = ''; } if (isset($options['cb_type']) && ($options['cb_type'] === false || !$options['cb_type']($options, $hdent, $plugin, $pinst, $type))) continue; if (isset($options['cb_tinst']) && ($options['cb_tinst'] === false || !$options['cb_tinst']($options, $hdent, $plugin, $pinst, $type, $tinst))) continue; } closedir($dt); } } closedir($dp); } } closedir($dh); } else error_log('Failed to open datadir: '.$datadir); return true; } function _collectd_list_cb_host(&$options, $host) { if ($options['cb_plugin'] === false) { $options['result'][] = $host; return false; } else if (isset($options['filter_host'])) { if ($options['filter_host'] == '@all') { return true; // We take anything } else if (substr($options['filter_host'], 0, 2) == '@.') { if ($host == substr($options['filter_host'], 2) || substr($host, 0, 1-strlen($options['filter_host'])) == substr($options['filter_host'], 1)) return true; // Host part of domain else return false; } else if ($options['filter_host'] == $host) { return true; } else return false; } else return true; } function _collectd_list_cb_plugin(&$options, $host, $plugin) { if ($options['cb_pinst'] === false) { $options['result'][] = $plugin; return false; } else if (isset($options['filter_plugin'])) { if ($options['filter_plugin'] == '@all') return true; else if ($options['filter_plugin'] == $plugin) return true; else return false; } else return true; } function _collectd_list_cb_pinst(&$options, $host, $plugin, $pinst) { if ($options['cb_type'] === false) { $options['result'][] = $pinst; return false; } else if (isset($options['filter_pinst'])) { if ($options['filter_pinst'] == '@all') return true; else if (strncmp($options['filter_pinst'], '@merge_', 7) == 0) return true; else if ($options['filter_pinst'] == $pinst) return true; else return false; } else return true; } function _collectd_list_cb_type(&$options, $host, $plugin, $pinst, $type) { if ($options['cb_tinst'] === false) { $options['result'][] = $type; return false; } else if (isset($options['filter_type'])) { if ($options['filter_type'] == '@all') return true; else if ($options['filter_type'] == $type) return true; else return false; } else return true; } function _collectd_list_cb_tinst(&$options, $host, $plugin, $pinst, $type, $tinst) { $options['result'][] = $tinst; return false; } function _collectd_list_cb_graph(&$options, $host, $plugin, $pinst, $type, $tinst) { if (isset($options['filter_tinst'])) { if ($options['filter_tinst'] == '@all') { } else if ($options['filter_tinst'] == $tinst) { } else if (strncmp($options['filter_tinst'], '@merge', 6) == 0) { // Need to exclude @merge with non-existent meta graph } else return false; } if (isset($options['filter_pinst']) && strncmp($options['filter_pinst'], '@merge', 6) == 0) $pinst = $options['filter_pinst']; if (isset($options['filter_tinst']) && strncmp($options['filter_tinst'], '@merge', 6) == 0) $tinst = $options['filter_tinst']; $ident = collectd_identifier($host, $plugin, $pinst, $type, $tinst); if (!in_array($ident, $options['ridentifiers'])) { $options['ridentifiers'][] = $ident; $options['result'][] = array('host'=>$host, 'plugin'=>$plugin, 'pinst'=>$pinst, 'type'=>$type, 'tinst'=>$tinst); } } /** * Fetch list of hosts found in collectd's datadirs. * @return Sorted list of hosts (sorted by label from rigth to left) */ function collectd_list_hosts() { $options = array( 'result' => array(), 'cb_host' => '_collectd_list_cb_host', 'cb_plugin' => false, 'cb_pinst' => false, 'cb_type' => false, 'cb_tinst' => false ); collectd_walk($options); $hosts = array_unique($options['result']); usort($hosts, 'collectd_compare_host'); return $hosts; } /** * Fetch list of plugins found in collectd's datadirs for given host. * @arg_host Name of host for which to return plugins * @return Sorted list of plugins (sorted alphabetically) */ function collectd_list_plugins($arg_host, $arg_plugin = null) { $options = array( 'result' => array(), 'cb_host' => '_collectd_list_cb_host', 'cb_plugin' => '_collectd_list_cb_plugin', 'cb_pinst' => is_null($arg_plugin) ? false : '_collectd_list_cb_pinst', 'cb_type' => false, 'cb_tinst' => false, 'filter_host' => $arg_host, 'filter_plugin' => $arg_plugin ); collectd_walk($options); $plugins = array_unique($options['result']); sort($plugins); return $plugins; } /** * Fetch list of types found in collectd's datadirs for given host+plugin+instance * @arg_host Name of host * @arg_plugin Name of plugin * @arg_pinst Plugin instance * @return Sorted list of types (sorted alphabetically) */ function collectd_list_types($arg_host, $arg_plugin, $arg_pinst, $arg_type = null) { $options = array( 'result' => array(), 'cb_host' => '_collectd_list_cb_host', 'cb_plugin' => '_collectd_list_cb_plugin', 'cb_pinst' => '_collectd_list_cb_pinst', 'cb_type' => '_collectd_list_cb_type', 'cb_tinst' => is_null($arg_type) ? false : '_collectd_list_cb_tinst', 'filter_host' => $arg_host, 'filter_plugin' => $arg_plugin, 'filter_pinst' => $arg_pinst, 'filter_type' => $arg_type ); collectd_walk($options); $types = array_unique($options['result']); sort($types); return $types; } function collectd_list_graphs($arg_host, $arg_plugin, $arg_pinst, $arg_type, $arg_tinst) { $options = array( 'result' => array(), 'ridentifiers' => array(), 'cb_host' => '_collectd_list_cb_host', 'cb_plugin' => '_collectd_list_cb_plugin', 'cb_pinst' => '_collectd_list_cb_pinst', 'cb_type' => '_collectd_list_cb_type', 'cb_tinst' => '_collectd_list_cb_graph', 'filter_host' => $arg_host, 'filter_plugin' => $arg_plugin, 'filter_pinst' => $arg_pinst, 'filter_type' => $arg_type, 'filter_tinst' => $arg_tinst == '@' ? '@merge' : $arg_tinst ); collectd_walk($options); return $options['result']; } /** * Parse symlinks in order to get an identifier that collectd understands * (e.g. virtualisation is collected on host for individual VMs and can be * symlinked to the VM's hostname, support FLUSH for these by flushing * on the host-identifier instead of VM-identifier) * @host Host name * @plugin Plugin name * @pinst Plugin instance * @type Type name * @tinst Type instance * @return Identifier that collectd's FLUSH command understands */ function collectd_identifier($host, $plugin, $pinst, $type, $tinst) { global $config; $rrd_realpath = null; $orig_identifier = sprintf('%s/%s%s%s/%s%s%s', $host, $plugin, strlen($pinst) ? '-' : '', $pinst, $type, strlen($tinst) ? '-' : '', $tinst); $identifier = null; foreach ($config['datadirs'] as $datadir) if (is_file($datadir.'/'.$orig_identifier.'.rrd')) { $rrd_realpath = realpath($datadir.'/'.$orig_identifier.'.rrd'); break; } if ($rrd_realpath) { $identifier = basename($rrd_realpath); $identifier = substr($identifier, 0, strlen($identifier)-4); $rrd_realpath = dirname($rrd_realpath); $identifier = basename($rrd_realpath).'/'.$identifier; $rrd_realpath = dirname($rrd_realpath); $identifier = basename($rrd_realpath).'/'.$identifier; } if (is_null($identifier)) return $orig_identifier; else return $identifier; } /** * Tell collectd that it should FLUSH all data it has regarding the * graph we are about to generate. * @host Host name * @plugin Plugin name * @pinst Plugin instance * @type Type name * @tinst Type instance */ function collectd_flush($identifier) { global $config; if (!$config['collectd_sock']) return false; if (is_null($identifier) || (is_array($identifier) && count($identifier) == 0) || !(is_string($identifier) || is_array($identifier))) return false; $u_errno = 0; $u_errmsg = ''; if ($socket = @fsockopen($config['collectd_sock'], 0, $u_errno, $u_errmsg)) { $cmd = 'FLUSH plugin=rrdtool'; if (is_array($identifier)) { foreach ($identifier as $val) $cmd .= sprintf(' identifier="%s"', $val); } else $cmd .= sprintf(' identifier="%s"', $identifier); $cmd .= "\n"; $r = fwrite($socket, $cmd, strlen($cmd)); if ($r === false || $r != strlen($cmd)) error_log(sprintf("graph.php: Failed to write whole command to unix-socket: %d out of %d written", $r === false ? -1 : $r, strlen($cmd))); $resp = fgets($socket); if ($resp === false) error_log(sprintf("graph.php: Failed to read response from collectd for command: %s", trim($cmd))); $n = (int)$resp; while ($n-- > 0) fgets($socket); fclose($socket); } else error_log(sprintf("graph.php: Failed to open unix-socket to collectd: %d: %s", $u_errno, $u_errmsg)); } class CollectdColor { private $r = 0; private $g = 0; private $b = 0; function __construct($value = null) { if (is_null($value)) { } else if (is_array($value)) { if (isset($value['r'])) $this->r = $value['r'] > 0 ? ($value['r'] > 1 ? 1 : $value['r']) : 0; if (isset($value['g'])) $this->g = $value['g'] > 0 ? ($value['g'] > 1 ? 1 : $value['g']) : 0; if (isset($value['b'])) $this->b = $value['b'] > 0 ? ($value['b'] > 1 ? 1 : $value['b']) : 0; } else if (is_string($value)) { $matches = array(); if ($value == 'random') { $this->randomize(); } else if (preg_match('/([0-9A-Fa-f][0-9A-Fa-f])([0-9A-Fa-f][0-9A-Fa-f])([0-9A-Fa-f][0-9A-Fa-f])/', $value, $matches)) { $this->r = ('0x'.$matches[1]) / 255.0; $this->g = ('0x'.$matches[2]) / 255.0; $this->b = ('0x'.$matches[3]) / 255.0; } } else if (is_a($value, 'CollectdColor')) { $this->r = $value->r; $this->g = $value->g; $this->b = $value->b; } } function randomize() { $this->r = rand(0, 255) / 255.0; $this->g = rand(0, 255) / 255.0; $this->b = 0.0; $min = 0.0; $max = 1.0; if (($this->r + $this->g) < 1.0) { $min = 1.0 - ($this->r + $this->g); } else { $max = 2.0 - ($this->r + $this->g); } $this->b = $min + ((rand(0, 255)/255.0) * ($max - $min)); } function fade($bkgnd = null, $alpha = 0.25) { if (is_null($bkgnd) || !is_a($bkgnd, 'CollectdColor')) { $bg_r = 1.0; $bg_g = 1.0; $bg_b = 1.0; } else { $bg_r = $bkgnd->r; $bg_g = $bkgnd->g; $bg_b = $bkgnd->b; } $this->r = $alpha * $this->r + ((1.0 - $alpha) * $bg_r); $this->g = $alpha * $this->g + ((1.0 - $alpha) * $bg_g); $this->b = $alpha * $this->b + ((1.0 - $alpha) * $bg_b); } function as_array() { return array('r'=>$this->r, 'g'=>$this->g, 'b'=>$this->b); } function as_string() { $r = (int)($this->r*255); $g = (int)($this->g*255); $b = (int)($this->b*255); return sprintf('%02x%02x%02x', $r > 255 ? 255 : $r, $g > 255 ? 255 : $g, $b > 255 ? 255 : $b); } } /** * Helper function to strip quotes from RRD output * @str RRD-Info generated string * @return String with one surrounding pair of quotes stripped */ function rrd_strip_quotes($str) { if ($str[0] == '"' && $str[strlen($str)-1] == '"') return substr($str, 1, strlen($str)-2); else return $str; } function rrd_escape($str) { return str_replace(array('\\', ':'), array('\\\\', '\\:'), $str); } /** * Determine useful information about RRD file * @file Name of RRD file to analyse * @return Array describing the RRD file */ function rrd_info($file) { $info = array('filename'=>$file); $rrd = popen(RRDTOOL.' info '.escapeshellarg($file), 'r'); if ($rrd) { while (($s = fgets($rrd)) !== false) { $p = strpos($s, '='); if ($p === false) continue; $key = trim(substr($s, 0, $p)); $value = trim(substr($s, $p+1)); if (strncmp($key,'ds[', 3) == 0) { /* DS definition */ $p = strpos($key, ']'); $ds = substr($key, 3, $p-3); if (!isset($info['DS'])) $info['DS'] = array(); $ds_key = substr($key, $p+2); if (strpos($ds_key, '[') === false) { if (!isset($info['DS']["$ds"])) $info['DS']["$ds"] = array(); $info['DS']["$ds"]["$ds_key"] = rrd_strip_quotes($value); } } else if (strncmp($key, 'rra[', 4) == 0) { /* RRD definition */ $p = strpos($key, ']'); $rra = substr($key, 4, $p-4); if (!isset($info['RRA'])) $info['RRA'] = array(); $rra_key = substr($key, $p+2); if (strpos($rra_key, '[') === false) { if (!isset($info['RRA']["$rra"])) $info['RRA']["$rra"] = array(); $info['RRA']["$rra"]["$rra_key"] = rrd_strip_quotes($value); } } else if (strpos($key, '[') === false) { $info[$key] = rrd_strip_quotes($value); } } pclose($rrd); } return $info; } function rrd_get_color($code, $line = true) { global $config; $name = ($line ? 'f_' : 'h_').$code; if (!isset($config['rrd_colors'][$name])) { $c_f = new CollectdColor('random'); $c_h = new CollectdColor($c_f); $c_h->fade(); $config['rrd_colors']['f_'.$code] = $c_f->as_string(); $config['rrd_colors']['h_'.$code] = $c_h->as_string(); } return $config['rrd_colors'][$name]; } /** * Draw RRD file based on it's structure * @host * @plugin * @pinst * @type * @tinst * @opts * @return Commandline to call RRDGraph in order to generate the final graph */ function collectd_draw_rrd($host, $plugin, $pinst = null, $type, $tinst = null, $opts = array()) { global $config; $timespan_def = null; if (!isset($opts['timespan'])) $timespan_def = reset($config['timespan']); else foreach ($config['timespan'] as &$ts) if ($ts['name'] == $opts['timespan']) $timespan_def = $ts; if (!isset($opts['rrd_opts'])) $opts['rrd_opts'] = array(); if (isset($opts['logarithmic']) && $opts['logarithmic']) array_unshift($opts['rrd_opts'], '-o'); $rrdinfo = null; $rrdfile = sprintf('%s/%s%s%s/%s%s%s', $host, $plugin, is_null($pinst) ? '' : '-', $pinst, $type, is_null($tinst) ? '' : '-', $tinst); foreach ($config['datadirs'] as $datadir) if (is_file($datadir.'/'.$rrdfile.'.rrd')) { $rrdinfo = rrd_info($datadir.'/'.$rrdfile.'.rrd'); if (isset($rrdinfo['RRA']) && is_array($rrdinfo['RRA'])) break; else $rrdinfo = null; } if (is_null($rrdinfo)) return false; $graph = array(); $has_avg = false; $has_max = false; $has_min = false; reset($rrdinfo['RRA']); $l_max = 0; while (list($k, $v) = each($rrdinfo['RRA'])) { if ($v['cf'] == 'MAX') $has_max = true; else if ($v['cf'] == 'AVERAGE') $has_avg = true; else if ($v['cf'] == 'MIN') $has_min = true; } reset($rrdinfo['DS']); while (list($k, $v) = each($rrdinfo['DS'])) { if (strlen($k) > $l_max) $l_max = strlen($k); if ($has_min) $graph[] = sprintf('DEF:%s_min=%s:%s:MIN', $k, rrd_escape($rrdinfo['filename']), $k); if ($has_avg) $graph[] = sprintf('DEF:%s_avg=%s:%s:AVERAGE', $k, rrd_escape($rrdinfo['filename']), $k); if ($has_max) $graph[] = sprintf('DEF:%s_max=%s:%s:MAX', $k, rrd_escape($rrdinfo['filename']), $k); } if ($has_min && $has_max || $has_min && $has_avg || $has_avg && $has_max) { $n = 1; reset($rrdinfo['DS']); while (list($k, $v) = each($rrdinfo['DS'])) { $graph[] = sprintf('LINE:%s_%s', $k, $has_min ? 'min' : 'avg'); $graph[] = sprintf('CDEF:%s_var=%s_%s,%s_%s,-', $k, $k, $has_max ? 'max' : 'avg', $k, $has_min ? 'min' : 'avg'); $graph[] = sprintf('AREA:%s_var#%s::STACK', $k, rrd_get_color($n++, false)); } } reset($rrdinfo['DS']); $n = 1; while (list($k, $v) = each($rrdinfo['DS'])) { $graph[] = sprintf('LINE1:%s_avg#%s:%s ', $k, rrd_get_color($n++, true), $k.substr(' ', 0, $l_max-strlen($k))); if (isset($opts['tinylegend']) && $opts['tinylegend']) continue; if ($has_avg) $graph[] = sprintf('GPRINT:%s_avg:AVERAGE:%%5.1lf%%s Avg%s', $k, $has_max || $has_min || $has_avg ? ',' : "\\l"); if ($has_min) $graph[] = sprintf('GPRINT:%s_min:MIN:%%5.1lf%%s Max%s', $k, $has_max || $has_avg ? ',' : "\\l"); if ($has_max) $graph[] = sprintf('GPRINT:%s_max:MAX:%%5.1lf%%s Max%s', $k, $has_avg ? ',' : "\\l"); if ($has_avg) $graph[] = sprintf('GPRINT:%s_avg:LAST:%%5.1lf%%s Last\\l', $k); } $rrd_cmd = array(RRDTOOL, 'graph', '-', '-a', 'PNG', '-w', $config['rrd_width'], '-h', $config['rrd_height'], '-s', -1*$timespan_def['seconds'], '-t', $rrdfile); $rrd_cmd = array_merge($rrd_cmd, $config['rrd_opts'], $opts['rrd_opts'], $graph); $cmd = RRDTOOL; for ($i = 1; $i < count($rrd_cmd); $i++) $cmd .= ' '.escapeshellarg($rrd_cmd[$i]); return $cmd; } /** * Draw RRD file based on it's structure * @timespan * @host * @plugin * @pinst * @type * @tinst * @opts * @return Commandline to call RRDGraph in order to generate the final graph */ function collectd_draw_generic($timespan, $host, $plugin, $pinst = null, $type, $tinst = null) { global $config, $GraphDefs; $timespan_def = null; foreach ($config['timespan'] as &$ts) if ($ts['name'] == $timespan) $timespan_def = $ts; if (is_null($timespan_def)) $timespan_def = reset($config['timespan']); if (!isset($GraphDefs[$type])) return false; $rrd_file = sprintf('%s/%s%s%s/%s%s%s', $host, $plugin, is_null($pinst) ? '' : '-', $pinst, $type, is_null($tinst) ? '' : '-', $tinst); $rrd_cmd = array(RRDTOOL, 'graph', '-', '-a', 'PNG', '-w', $config['rrd_width'], '-h', $config['rrd_height'], '-s', -1*$timespan_def['seconds'], '-t', $rrd_file); $rrd_cmd = array_merge($rrd_cmd, $config['rrd_opts']); $rrd_args = $GraphDefs[$type]; foreach ($config['datadirs'] as $datadir) { $file = $datadir.'/'.$rrd_file.'.rrd'; if (!is_file($file)) continue; $file = str_replace(":", "\\:", $file); $rrd_args = str_replace('{file}', rrd_escape($file), $rrd_args); $rrdgraph = array_merge($rrd_cmd, $rrd_args); $cmd = RRDTOOL; for ($i = 1; $i < count($rrdgraph); $i++) $cmd .= ' '.escapeshellarg($rrdgraph[$i]); return $cmd; } return false; } /** * Draw stack-graph for set of RRD files * @opts Graph options like colors * @sources List of array(name, file, ds) * @return Commandline to call RRDGraph in order to generate the final graph */ function collectd_draw_meta_stack(&$opts, &$sources) { global $config; $timespan_def = null; if (!isset($opts['timespan'])) $timespan_def = reset($config['timespan']); else foreach ($config['timespan'] as &$ts) if ($ts['name'] == $opts['timespan']) $timespan_def = $ts; if (!isset($opts['title'])) $opts['title'] = 'Unknown title'; if (!isset($opts['rrd_opts'])) $opts['rrd_opts'] = array(); if (!isset($opts['colors'])) $opts['colors'] = array(); if (isset($opts['logarithmic']) && $opts['logarithmic']) array_unshift($opts['rrd_opts'], '-o'); $cmd = array(RRDTOOL, 'graph', '-', '-a', 'PNG', '-w', $config['rrd_width'], '-h', $config['rrd_height'], '-s', -1*$timespan_def['seconds'], '-t', $opts['title']); $cmd = array_merge($cmd, $config['rrd_opts'], $opts['rrd_opts']); $max_inst_name = 0; foreach($sources as &$inst_data) { $inst_name = str_replace('!', '_', $inst_data['name']); $file = $inst_data['file']; $ds = isset($inst_data['ds']) ? $inst_data['ds'] : 'value'; if (strlen($inst_name) > $max_inst_name) $max_inst_name = strlen($inst_name); if (!is_file($file)) continue; $cmd[] = 'DEF:'.$inst_name.'_min='.rrd_escape($file).':'.$ds.':MIN'; $cmd[] = 'DEF:'.$inst_name.'_avg='.rrd_escape($file).':'.$ds.':AVERAGE'; $cmd[] = 'DEF:'.$inst_name.'_max='.rrd_escape($file).':'.$ds.':MAX'; $cmd[] = 'CDEF:'.$inst_name.'_nnl='.$inst_name.'_avg,UN,0,'.$inst_name.'_avg,IF'; } $inst_data = end($sources); $inst_name = $inst_data['name']; $cmd[] = 'CDEF:'.$inst_name.'_stk='.$inst_name.'_nnl'; $inst_data1 = end($sources); while (($inst_data0 = prev($sources)) !== false) { $inst_name0 = str_replace('!', '_', $inst_data0['name']); $inst_name1 = str_replace('!', '_', $inst_data1['name']); $cmd[] = 'CDEF:'.$inst_name0.'_stk='.$inst_name0.'_nnl,'.$inst_name1.'_stk,+'; $inst_data1 = $inst_data0; } foreach($sources as &$inst_data) { $inst_name = str_replace('!', '_', $inst_data['name']); $legend = sprintf('%s', $inst_data['name']); while (strlen($legend) < $max_inst_name) $legend .= ' '; $number_format = isset($opts['number_format']) ? $opts['number_format'] : '%6.1lf'; if (isset($opts['colors'][$inst_name])) $line_color = new CollectdColor($opts['colors'][$inst_name]); else $line_color = new CollectdColor('random'); $area_color = new CollectdColor($line_color); $area_color->fade(); $cmd[] = 'AREA:'.$inst_name.'_stk#'.$area_color->as_string(); $cmd[] = 'LINE1:'.$inst_name.'_stk#'.$line_color->as_string().':'.$legend; if (!(isset($opts['tinylegend']) && $opts['tinylegend'])) { $cmd[] = 'GPRINT:'.$inst_name.'_min:MIN:'.$number_format.' Min,'; $cmd[] = 'GPRINT:'.$inst_name.'_avg:AVERAGE:'.$number_format.' Avg,'; $cmd[] = 'GPRINT:'.$inst_name.'_max:MAX:'.$number_format.' Max,'; $cmd[] = 'GPRINT:'.$inst_name.'_avg:LAST:'.$number_format.' Last\\l'; } } $rrdcmd = RRDTOOL; for ($i = 1; $i < count($cmd); $i++) $rrdcmd .= ' '.escapeshellarg($cmd[$i]); return $rrdcmd; } /** * Draw stack-graph for set of RRD files * @opts Graph options like colors * @sources List of array(name, file, ds) * @return Commandline to call RRDGraph in order to generate the final graph */ function collectd_draw_meta_line(&$opts, &$sources) { global $config; $timespan_def = null; if (!isset($opts['timespan'])) $timespan_def = reset($config['timespan']); else foreach ($config['timespan'] as &$ts) if ($ts['name'] == $opts['timespan']) $timespan_def = $ts; if (!isset($opts['title'])) $opts['title'] = 'Unknown title'; if (!isset($opts['rrd_opts'])) $opts['rrd_opts'] = array(); if (!isset($opts['colors'])) $opts['colors'] = array(); if (isset($opts['logarithmic']) && $opts['logarithmic']) array_unshift($opts['rrd_opts'], '-o'); $cmd = array(RRDTOOL, 'graph', '-', '-a', 'PNG', '-w', $config['rrd_width'], '-h', $config['rrd_height'], '-s', -1*$timespan_def['seconds'], '-t', $opts['title']); $cmd = array_merge($cmd, $config['rrd_opts'], $opts['rrd_opts']); $max_inst_name = 0; foreach ($sources as &$inst_data) { $inst_name = str_replace('!', '_', $inst_data['name']); $file = $inst_data['file']; $ds = isset($inst_data['ds']) ? $inst_data['ds'] : 'value'; if (strlen($inst_name) > $max_inst_name) $max_inst_name = strlen($inst_name); if (!is_file($file)) continue; $cmd[] = 'DEF:'.$inst_name.'_min='.rrd_escape($file).':'.$ds.':MIN'; $cmd[] = 'DEF:'.$inst_name.'_avg='.rrd_escape($file).':'.$ds.':AVERAGE'; $cmd[] = 'DEF:'.$inst_name.'_max='.rrd_escape($file).':'.$ds.':MAX'; } foreach ($sources as &$inst_data) { $inst_name = str_replace('!', '_', $inst_data['name']); $legend = sprintf('%s', $inst_name); while (strlen($legend) < $max_inst_name) $legend .= ' '; $number_format = isset($opts['number_format']) ? $opts['number_format'] : '%6.1lf'; if (isset($opts['colors'][$inst_name])) $line_color = new CollectdColor($opts['colors'][$inst_name]); else $line_color = new CollectdColor('random'); $cmd[] = 'LINE1:'.$inst_name.'_avg#'.$line_color->as_string().':'.$legend; if (!(isset($opts['tinylegend']) && $opts['tinylegend'])) { $cmd[] = 'GPRINT:'.$inst_name.'_min:MIN:'.$number_format.' Min,'; $cmd[] = 'GPRINT:'.$inst_name.'_avg:AVERAGE:'.$number_format.' Avg,'; $cmd[] = 'GPRINT:'.$inst_name.'_max:MAX:'.$number_format.' Max,'; $cmd[] = 'GPRINT:'.$inst_name.'_avg:LAST:'.$number_format.' Last\\l'; } } $rrdcmd = RRDTOOL; for ($i = 1; $i < count($cmd); $i++) $rrdcmd .= ' '.escapeshellarg($cmd[$i]); return $rrdcmd; } ?> collectd-5.4.0/contrib/php-collection/PaxHeaders.11991/definitions.php0000644037772200116100000000013212204120331023747 xustar000000000000000030 mtime=1376821465.057973183 30 atime=1376821477.202167674 30 ctime=1376821742.442407632 collectd-5.4.0/contrib/php-collection/definitions.php0000644037772200116100000022253112204120331022520 0ustar00octoeng00000000000000 * * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * Most RRD Graph definitions copied from collection.cgi */ $GraphDefs = array(); $MetaGraphDefs = array(); if (is_file('definitions.local.php')) require_once('definitions.local.php'); function load_graph_definitions($logarithmic = false, $tinylegend = false) { global $GraphDefs, $MetaGraphDefs; $Canvas = 'FFFFFF'; $FullRed = 'FF0000'; $FullGreen = '00E000'; $FullBlue = '0000FF'; $FullYellow = 'F0A000'; $FullCyan = '00A0FF'; $FullMagenta= 'A000FF'; $HalfRed = 'F7B7B7'; $HalfGreen = 'B7EFB7'; $HalfBlue = 'B7B7F7'; $HalfYellow = 'F3DFB7'; $HalfCyan = 'B7DFF7'; $HalfMagenta= 'DFB7F7'; $HalfBlueGreen = '89B3C9'; $GraphDefs = array(); $GraphDefs['apache_bytes'] = array( '-v', 'Bits/s', 'DEF:min_raw={file}:value:MIN', 'DEF:avg_raw={file}:value:AVERAGE', 'DEF:max_raw={file}:value:MAX', 'CDEF:min=min_raw,8,*', 'CDEF:avg=avg_raw,8,*', 'CDEF:max=max_raw,8,*', 'CDEF:mytime=avg_raw,TIME,TIME,IF', 'CDEF:sample_len_raw=mytime,PREV(mytime),-', 'CDEF:sample_len=sample_len_raw,UN,0,sample_len_raw,IF', 'CDEF:avg_sample=avg_raw,UN,0,avg_raw,IF,sample_len,*', 'CDEF:avg_sum=PREV,UN,0,PREV,IF,avg_sample,+', "AREA:avg#$HalfBlue", "LINE1:avg#$FullBlue:Bit/s", 'GPRINT:min:MIN:%5.1lf%s Min,', 'GPRINT:avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:max:MAX:%5.1lf%s Max,', 'GPRINT:avg:LAST:%5.1lf%s Last', 'GPRINT:avg_sum:LAST:(ca. %5.1lf%sB Total)\l'); $GraphDefs['apache_requests'] = array( '-v', 'Requests/s', 'DEF:min={file}:value:MIN', 'DEF:avg={file}:value:AVERAGE', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Requests/s", 'GPRINT:min:MIN:%6.2lf Min,', 'GPRINT:avg:AVERAGE:%6.2lf Avg,', 'GPRINT:max:MAX:%6.2lf Max,', 'GPRINT:avg:LAST:%6.2lf Last'); $GraphDefs['apache_scoreboard'] = array( 'DEF:min={file}:value:MIN', 'DEF:avg={file}:value:AVERAGE', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Processes", 'GPRINT:min:MIN:%6.2lf Min,', 'GPRINT:avg:AVERAGE:%6.2lf Avg,', 'GPRINT:max:MAX:%6.2lf Max,', 'GPRINT:avg:LAST:%6.2lf Last'); $GraphDefs['bitrate'] = array( '-v', 'Bits/s', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Bits/s", 'GPRINT:min:MIN:%5.1lf%s Min,', 'GPRINT:avg:AVERAGE:%5.1lf%s Average,', 'GPRINT:max:MAX:%5.1lf%s Max,', 'GPRINT:avg:LAST:%5.1lf%s Last\l'); $GraphDefs['charge'] = array( '-v', 'Ah', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Charge", 'GPRINT:min:MIN:%5.1lf%sAh Min,', 'GPRINT:avg:AVERAGE:%5.1lf%sAh Avg,', 'GPRINT:max:MAX:%5.1lf%sAh Max,', 'GPRINT:avg:LAST:%5.1lf%sAh Last\l'); $GraphDefs['counter'] = array( '-v', 'Events', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Percent", 'GPRINT:min:MIN:%6.2lf%% Min,', 'GPRINT:avg:AVERAGE:%6.2lf%% Avg,', 'GPRINT:max:MAX:%6.2lf%% Max,', 'GPRINT:avg:LAST:%6.2lf%% Last\l'); $GraphDefs['cpu'] = array( '-v', 'CPU load', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Percent", 'GPRINT:min:MIN:%6.2lf%% Min,', 'GPRINT:avg:AVERAGE:%6.2lf%% Avg,', 'GPRINT:max:MAX:%6.2lf%% Max,', 'GPRINT:avg:LAST:%6.2lf%% Last\l'); $GraphDefs['current'] = array( '-v', 'Ampere', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Current", 'GPRINT:min:MIN:%5.1lf%sA Min,', 'GPRINT:avg:AVERAGE:%5.1lf%sA Avg,', 'GPRINT:max:MAX:%5.1lf%sA Max,', 'GPRINT:avg:LAST:%5.1lf%sA Last\l'); $GraphDefs['df'] = array( '-v', 'Percent', '-l', '0', 'DEF:free_avg={file}:free:AVERAGE', 'DEF:free_min={file}:free:MIN', 'DEF:free_max={file}:free:MAX', 'DEF:used_avg={file}:used:AVERAGE', 'DEF:used_min={file}:used:MIN', 'DEF:used_max={file}:used:MAX', 'CDEF:total=free_avg,used_avg,+', 'CDEF:free_pct=100,free_avg,*,total,/', 'CDEF:used_pct=100,used_avg,*,total,/', 'CDEF:free_acc=free_pct,used_pct,+', 'CDEF:used_acc=used_pct', "AREA:free_acc#$HalfGreen", "AREA:used_acc#$HalfRed", "LINE1:free_acc#$FullGreen:Free", 'GPRINT:free_min:MIN:%5.1lf%sB Min,', 'GPRINT:free_avg:AVERAGE:%5.1lf%sB Avg,', 'GPRINT:free_max:MAX:%5.1lf%sB Max,', 'GPRINT:free_avg:LAST:%5.1lf%sB Last\l', "LINE1:used_acc#$FullRed:Used", 'GPRINT:used_min:MIN:%5.1lf%sB Min,', 'GPRINT:used_avg:AVERAGE:%5.1lf%sB Avg,', 'GPRINT:used_max:MAX:%5.1lf%sB Max,', 'GPRINT:used_avg:LAST:%5.1lf%sB Last\l'); $GraphDefs['disk'] = array( 'DEF:rtime_avg={file}:rtime:AVERAGE', 'DEF:rtime_min={file}:rtime:MIN', 'DEF:rtime_max={file}:rtime:MAX', 'DEF:wtime_avg={file}:wtime:AVERAGE', 'DEF:wtime_min={file}:wtime:MIN', 'DEF:wtime_max={file}:wtime:MAX', 'CDEF:rtime_avg_ms=rtime_avg,1000,/', 'CDEF:rtime_min_ms=rtime_min,1000,/', 'CDEF:rtime_max_ms=rtime_max,1000,/', 'CDEF:wtime_avg_ms=wtime_avg,1000,/', 'CDEF:wtime_min_ms=wtime_min,1000,/', 'CDEF:wtime_max_ms=wtime_max,1000,/', 'CDEF:total_avg_ms=rtime_avg_ms,wtime_avg_ms,+', 'CDEF:total_min_ms=rtime_min_ms,wtime_min_ms,+', 'CDEF:total_max_ms=rtime_max_ms,wtime_max_ms,+', "AREA:total_max_ms#$HalfRed", "AREA:total_min_ms#$Canvas", "LINE1:wtime_avg_ms#$FullGreen:Write", 'GPRINT:wtime_min_ms:MIN:%5.1lf%s Min,', 'GPRINT:wtime_avg_ms:AVERAGE:%5.1lf%s Avg,', 'GPRINT:wtime_max_ms:MAX:%5.1lf%s Max,', 'GPRINT:wtime_avg_ms:LAST:%5.1lf%s Last\n', "LINE1:rtime_avg_ms#$FullBlue:Read ", 'GPRINT:rtime_min_ms:MIN:%5.1lf%s Min,', 'GPRINT:rtime_avg_ms:AVERAGE:%5.1lf%s Avg,', 'GPRINT:rtime_max_ms:MAX:%5.1lf%s Max,', 'GPRINT:rtime_avg_ms:LAST:%5.1lf%s Last\n', "LINE1:total_avg_ms#$FullRed:Total", 'GPRINT:total_min_ms:MIN:%5.1lf%s Min,', 'GPRINT:total_avg_ms:AVERAGE:%5.1lf%s Avg,', 'GPRINT:total_max_ms:MAX:%5.1lf%s Max,', 'GPRINT:total_avg_ms:LAST:%5.1lf%s Last'); $GraphDefs['disk_octets'] = array( '-v', 'Bytes/s', '--units=si', 'DEF:out_min={file}:write:MIN', 'DEF:out_avg={file}:write:AVERAGE', 'DEF:out_max={file}:write:MAX', 'DEF:inc_min={file}:read:MIN', 'DEF:inc_avg={file}:read:AVERAGE', 'DEF:inc_max={file}:read:MAX', 'CDEF:overlap=out_avg,inc_avg,GT,inc_avg,out_avg,IF', 'CDEF:mytime=out_avg,TIME,TIME,IF', 'CDEF:sample_len_raw=mytime,PREV(mytime),-', 'CDEF:sample_len=sample_len_raw,UN,0,sample_len_raw,IF', 'CDEF:out_avg_sample=out_avg,UN,0,out_avg,IF,sample_len,*', 'CDEF:out_avg_sum=PREV,UN,0,PREV,IF,out_avg_sample,+', 'CDEF:inc_avg_sample=inc_avg,UN,0,inc_avg,IF,sample_len,*', 'CDEF:inc_avg_sum=PREV,UN,0,PREV,IF,inc_avg_sample,+', "AREA:out_avg#$HalfGreen", "AREA:inc_avg#$HalfBlue", "AREA:overlap#$HalfBlueGreen", "LINE1:out_avg#$FullGreen:Written", 'GPRINT:out_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:out_max:MAX:%5.1lf%s Max,', 'GPRINT:out_avg:LAST:%5.1lf%s Last', 'GPRINT:out_avg_sum:LAST:(ca. %5.1lf%sB Total)\l', "LINE1:inc_avg#$FullBlue:Read ", 'GPRINT:inc_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:inc_max:MAX:%5.1lf%s Max,', 'GPRINT:inc_avg:LAST:%5.1lf%s Last', 'GPRINT:inc_avg_sum:LAST:(ca. %5.1lf%sB Total)\l'); $GraphDefs['disk_merged'] = array( '-v', 'Merged Ops/s', '--units=si', 'DEF:out_min={file}:write:MIN', 'DEF:out_avg={file}:write:AVERAGE', 'DEF:out_max={file}:write:MAX', 'DEF:inc_min={file}:read:MIN', 'DEF:inc_avg={file}:read:AVERAGE', 'DEF:inc_max={file}:read:MAX', 'CDEF:overlap=out_avg,inc_avg,GT,inc_avg,out_avg,IF', "AREA:out_avg#$HalfGreen", "AREA:inc_avg#$HalfBlue", "AREA:overlap#$HalfBlueGreen", "LINE1:out_avg#$FullGreen:Written", 'GPRINT:out_avg:AVERAGE:%6.2lf Avg,', 'GPRINT:out_max:MAX:%6.2lf Max,', 'GPRINT:out_avg:LAST:%6.2lf Last\l', "LINE1:inc_avg#$FullBlue:Read ", 'GPRINT:inc_avg:AVERAGE:%6.2lf Avg,', 'GPRINT:inc_max:MAX:%6.2lf Max,', 'GPRINT:inc_avg:LAST:%6.2lf Last\l'); $GraphDefs['disk_ops'] = array( '-v', 'Ops/s', '--units=si', 'DEF:out_min={file}:write:MIN', 'DEF:out_avg={file}:write:AVERAGE', 'DEF:out_max={file}:write:MAX', 'DEF:inc_min={file}:read:MIN', 'DEF:inc_avg={file}:read:AVERAGE', 'DEF:inc_max={file}:read:MAX', 'CDEF:overlap=out_avg,inc_avg,GT,inc_avg,out_avg,IF', "AREA:out_avg#$HalfGreen", "AREA:inc_avg#$HalfBlue", "AREA:overlap#$HalfBlueGreen", "LINE1:out_avg#$FullGreen:Written", 'GPRINT:out_avg:AVERAGE:%6.2lf Avg,', 'GPRINT:out_max:MAX:%6.2lf Max,', 'GPRINT:out_avg:LAST:%6.2lf Last\l', "LINE1:inc_avg#$FullBlue:Read ", 'GPRINT:inc_avg:AVERAGE:%6.2lf Avg,', 'GPRINT:inc_max:MAX:%6.2lf Max,', 'GPRINT:inc_avg:LAST:%6.2lf Last\l'); $GraphDefs['disk_time'] = array( '-v', 'Seconds/s', 'DEF:out_min_raw={file}:write:MIN', 'DEF:out_avg_raw={file}:write:AVERAGE', 'DEF:out_max_raw={file}:write:MAX', 'DEF:inc_min_raw={file}:read:MIN', 'DEF:inc_avg_raw={file}:read:AVERAGE', 'DEF:inc_max_raw={file}:read:MAX', 'CDEF:out_min=out_min_raw,1000,/', 'CDEF:out_avg=out_avg_raw,1000,/', 'CDEF:out_max=out_max_raw,1000,/', 'CDEF:inc_min=inc_min_raw,1000,/', 'CDEF:inc_avg=inc_avg_raw,1000,/', 'CDEF:inc_max=inc_max_raw,1000,/', 'CDEF:overlap=out_avg,inc_avg,GT,inc_avg,out_avg,IF', "AREA:out_avg#$HalfGreen", "AREA:inc_avg#$HalfBlue", "AREA:overlap#$HalfBlueGreen", "LINE1:out_avg#$FullGreen:Written", 'GPRINT:out_avg:AVERAGE:%5.1lf%ss Avg,', 'GPRINT:out_max:MAX:%5.1lf%ss Max,', 'GPRINT:out_avg:LAST:%5.1lf%ss Last\l', "LINE1:inc_avg#$FullBlue:Read ", 'GPRINT:inc_avg:AVERAGE:%5.1lf%ss Avg,', 'GPRINT:inc_max:MAX:%5.1lf%ss Max,', 'GPRINT:inc_avg:LAST:%5.1lf%ss Last\l'); $GraphDefs['dns_traffic'] = array( 'DEF:rsp_min_raw={file}:responses:MIN', 'DEF:rsp_avg_raw={file}:responses:AVERAGE', 'DEF:rsp_max_raw={file}:responses:MAX', 'DEF:qry_min_raw={file}:queries:MIN', 'DEF:qry_avg_raw={file}:queries:AVERAGE', 'DEF:qry_max_raw={file}:queries:MAX', 'CDEF:rsp_min=rsp_min_raw,8,*', 'CDEF:rsp_avg=rsp_avg_raw,8,*', 'CDEF:rsp_max=rsp_max_raw,8,*', 'CDEF:qry_min=qry_min_raw,8,*', 'CDEF:qry_avg=qry_avg_raw,8,*', 'CDEF:qry_max=qry_max_raw,8,*', 'CDEF:overlap=rsp_avg,qry_avg,GT,qry_avg,rsp_avg,IF', 'CDEF:mytime=rsp_avg_raw,TIME,TIME,IF', 'CDEF:sample_len_raw=mytime,PREV(mytime),-', 'CDEF:sample_len=sample_len_raw,UN,0,sample_len_raw,IF', 'CDEF:rsp_avg_sample=rsp_avg_raw,UN,0,rsp_avg_raw,IF,sample_len,*', 'CDEF:rsp_avg_sum=PREV,UN,0,PREV,IF,rsp_avg_sample,+', 'CDEF:qry_avg_sample=qry_avg_raw,UN,0,qry_avg_raw,IF,sample_len,*', 'CDEF:qry_avg_sum=PREV,UN,0,PREV,IF,qry_avg_sample,+', "AREA:rsp_avg#$HalfGreen", "AREA:qry_avg#$HalfBlue", "AREA:overlap#$HalfBlueGreen", "LINE1:rsp_avg#$FullGreen:Responses", 'GPRINT:rsp_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:rsp_max:MAX:%5.1lf%s Max,', 'GPRINT:rsp_avg:LAST:%5.1lf%s Last', 'GPRINT:rsp_avg_sum:LAST:(ca. %5.1lf%sB Total)\l', "LINE1:qry_avg#$FullBlue:Queries ", // 'GPRINT:qry_min:MIN:%5.1lf %s Min,', 'GPRINT:qry_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:qry_max:MAX:%5.1lf%s Max,', 'GPRINT:qry_avg:LAST:%5.1lf%s Last', 'GPRINT:qry_avg_sum:LAST:(ca. %5.1lf%sB Total)\l'); $GraphDefs['email_count'] = array( '-v', 'Mails', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfMagenta", "AREA:min#$Canvas", "LINE1:avg#$FullMagenta:Count ", 'GPRINT:min:MIN:%4.1lf Min,', 'GPRINT:avg:AVERAGE:%4.1lf Avg,', 'GPRINT:max:MAX:%4.1lf Max,', 'GPRINT:avg:LAST:%4.1lf Last\l'); $GraphDefs['files'] = $GraphDefs['email_count']; $GraphDefs['email_size'] = array( '-v', 'Bytes', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfMagenta", "AREA:min#$Canvas", "LINE1:avg#$FullMagenta:Count ", 'GPRINT:min:MIN:%4.1lf Min,', 'GPRINT:avg:AVERAGE:%4.1lf Avg,', 'GPRINT:max:MAX:%4.1lf Max,', 'GPRINT:avg:LAST:%4.1lf Last\l'); $GraphDefs['bytes'] = $GraphDefs['email_size']; $GraphDefs['spam_score'] = array( '-v', 'Score', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Score ", 'GPRINT:min:MIN:%4.1lf Min,', 'GPRINT:avg:AVERAGE:%4.1lf Avg,', 'GPRINT:max:MAX:%4.1lf Max,', 'GPRINT:avg:LAST:%4.1lf Last\l'); $GraphDefs['spam_check'] = array( 'DEF:avg={file}:hits:AVERAGE', 'DEF:min={file}:hits:MIN', 'DEF:max={file}:hits:MAX', "AREA:max#$HalfMagenta", "AREA:min#$Canvas", "LINE1:avg#$FullMagenta:Count ", 'GPRINT:min:MIN:%4.1lf Min,', 'GPRINT:avg:AVERAGE:%4.1lf Avg,', 'GPRINT:max:MAX:%4.1lf Max,', 'GPRINT:avg:LAST:%4.1lf Last\l'); $GraphDefs['conntrack'] = array( '-v', 'Entries', 'DEF:avg={file}:entropy:AVERAGE', 'DEF:min={file}:entropy:MIN', 'DEF:max={file}:entropy:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Count", 'GPRINT:min:MIN:%4.0lf Min,', 'GPRINT:avg:AVERAGE:%4.0lf Avg,', 'GPRINT:max:MAX:%4.0lf Max,', 'GPRINT:avg:LAST:%4.0lf Last\l'); $GraphDefs['entropy'] = array( '-v', 'Bits', 'DEF:avg={file}:entropy:AVERAGE', 'DEF:min={file}:entropy:MIN', 'DEF:max={file}:entropy:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Bits", 'GPRINT:min:MIN:%4.0lfbit Min,', 'GPRINT:avg:AVERAGE:%4.0lfbit Avg,', 'GPRINT:max:MAX:%4.0lfbit Max,', 'GPRINT:avg:LAST:%4.0lfbit Last\l'); $GraphDefs['fanspeed'] = array( '-v', 'RPM', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfMagenta", "AREA:min#$Canvas", "LINE1:avg#$FullMagenta:RPM", 'GPRINT:min:MIN:%4.1lf Min,', 'GPRINT:avg:AVERAGE:%4.1lf Avg,', 'GPRINT:max:MAX:%4.1lf Max,', 'GPRINT:avg:LAST:%4.1lf Last\l'); $GraphDefs['frequency'] = array( '-v', 'Hertz', 'DEF:avg={file}:frequency:AVERAGE', 'DEF:min={file}:frequency:MIN', 'DEF:max={file}:frequency:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Frequency [Hz]", 'GPRINT:min:MIN:%4.1lf Min,', 'GPRINT:avg:AVERAGE:%4.1lf Avg,', 'GPRINT:max:MAX:%4.1lf Max,', 'GPRINT:avg:LAST:%4.1lf Last\l'); $GraphDefs['frequency_offset'] = array( // NTPd 'DEF:ppm_avg={file}:ppm:AVERAGE', 'DEF:ppm_min={file}:ppm:MIN', 'DEF:ppm_max={file}:ppm:MAX', "AREA:ppm_max#$HalfBlue", "AREA:ppm_min#$Canvas", "LINE1:ppm_avg#$FullBlue:{inst}", 'GPRINT:ppm_min:MIN:%5.2lf Min,', 'GPRINT:ppm_avg:AVERAGE:%5.2lf Avg,', 'GPRINT:ppm_max:MAX:%5.2lf Max,', 'GPRINT:ppm_avg:LAST:%5.2lf Last'); $GraphDefs['gauge'] = array( '-v', 'Exec value', 'DEF:temp_avg={file}:value:AVERAGE', 'DEF:temp_min={file}:value:MIN', 'DEF:temp_max={file}:value:MAX', "AREA:temp_max#$HalfBlue", "AREA:temp_min#$Canvas", "LINE1:temp_avg#$FullBlue:Exec value", 'GPRINT:temp_min:MIN:%6.2lf Min,', 'GPRINT:temp_avg:AVERAGE:%6.2lf Avg,', 'GPRINT:temp_max:MAX:%6.2lf Max,', 'GPRINT:temp_avg:LAST:%6.2lf Last\l'); $GraphDefs['hddtemp'] = array( '-v', '°C', 'DEF:temp_avg={file}:value:AVERAGE', 'DEF:temp_min={file}:value:MIN', 'DEF:temp_max={file}:value:MAX', "AREA:temp_max#$HalfRed", "AREA:temp_min#$Canvas", "LINE1:temp_avg#$FullRed:Temperature", 'GPRINT:temp_min:MIN:%4.1lf Min,', 'GPRINT:temp_avg:AVERAGE:%4.1lf Avg,', 'GPRINT:temp_max:MAX:%4.1lf Max,', 'GPRINT:temp_avg:LAST:%4.1lf Last\l'); $GraphDefs['humidity'] = array( '-v', 'Percent', 'DEF:temp_avg={file}:value:AVERAGE', 'DEF:temp_min={file}:value:MIN', 'DEF:temp_max={file}:value:MAX', "AREA:temp_max#$HalfGreen", "AREA:temp_min#$Canvas", "LINE1:temp_avg#$FullGreen:Temperature", 'GPRINT:temp_min:MIN:%4.1lf%% Min,', 'GPRINT:temp_avg:AVERAGE:%4.1lf%% Avg,', 'GPRINT:temp_max:MAX:%4.1lf%% Max,', 'GPRINT:temp_avg:LAST:%4.1lf%% Last\l'); $GraphDefs['if_errors'] = array( '-v', 'Errors/s', '--units=si', 'DEF:tx_min={file}:tx:MIN', 'DEF:tx_avg={file}:tx:AVERAGE', 'DEF:tx_max={file}:tx:MAX', 'DEF:rx_min={file}:rx:MIN', 'DEF:rx_avg={file}:rx:AVERAGE', 'DEF:rx_max={file}:rx:MAX', 'CDEF:overlap=tx_avg,rx_avg,GT,rx_avg,tx_avg,IF', 'CDEF:mytime=tx_avg,TIME,TIME,IF', 'CDEF:sample_len_raw=mytime,PREV(mytime),-', 'CDEF:sample_len=sample_len_raw,UN,0,sample_len_raw,IF', 'CDEF:tx_avg_sample=tx_avg,UN,0,tx_avg,IF,sample_len,*', 'CDEF:tx_avg_sum=PREV,UN,0,PREV,IF,tx_avg_sample,+', 'CDEF:rx_avg_sample=rx_avg,UN,0,rx_avg,IF,sample_len,*', 'CDEF:rx_avg_sum=PREV,UN,0,PREV,IF,rx_avg_sample,+', "AREA:tx_avg#$HalfGreen", "AREA:rx_avg#$HalfBlue", "AREA:overlap#$HalfBlueGreen", "LINE1:tx_avg#$FullGreen:TX", 'GPRINT:tx_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:tx_max:MAX:%5.1lf%s Max,', 'GPRINT:tx_avg:LAST:%5.1lf%s Last', 'GPRINT:tx_avg_sum:LAST:(ca. %4.0lf%s Total)\l', "LINE1:rx_avg#$FullBlue:RX", // 'GPRINT:rx_min:MIN:%5.1lf %s Min,', 'GPRINT:rx_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:rx_max:MAX:%5.1lf%s Max,', 'GPRINT:rx_avg:LAST:%5.1lf%s Last', 'GPRINT:rx_avg_sum:LAST:(ca. %4.0lf%s Total)\l'); $GraphDefs['if_collisions'] = array( '-v', 'Collisions/s', '--units=si', 'DEF:min_raw={file}:value:MIN', 'DEF:avg_raw={file}:value:AVERAGE', 'DEF:max_raw={file}:value:MAX', 'CDEF:min=min_raw,8,*', 'CDEF:avg=avg_raw,8,*', 'CDEF:max=max_raw,8,*', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Collisions/s", 'GPRINT:min:MIN:%5.1lf %s Min,', 'GPRINT:avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:max:MAX:%5.1lf%s Max,', 'GPRINT:avg:LAST:%5.1lf%s Last\l'); $GraphDefs['if_dropped'] = array( '-v', 'Packets/s', '--units=si', 'DEF:tx_min={file}:tx:MIN', 'DEF:tx_avg={file}:tx:AVERAGE', 'DEF:tx_max={file}:tx:MAX', 'DEF:rx_min={file}:rx:MIN', 'DEF:rx_avg={file}:rx:AVERAGE', 'DEF:rx_max={file}:rx:MAX', 'CDEF:overlap=tx_avg,rx_avg,GT,rx_avg,tx_avg,IF', 'CDEF:mytime=tx_avg,TIME,TIME,IF', 'CDEF:sample_len_raw=mytime,PREV(mytime),-', 'CDEF:sample_len=sample_len_raw,UN,0,sample_len_raw,IF', 'CDEF:tx_avg_sample=tx_avg,UN,0,tx_avg,IF,sample_len,*', 'CDEF:tx_avg_sum=PREV,UN,0,PREV,IF,tx_avg_sample,+', 'CDEF:rx_avg_sample=rx_avg,UN,0,rx_avg,IF,sample_len,*', 'CDEF:rx_avg_sum=PREV,UN,0,PREV,IF,rx_avg_sample,+', "AREA:tx_avg#$HalfGreen", "AREA:rx_avg#$HalfBlue", "AREA:overlap#$HalfBlueGreen", "LINE1:tx_avg#$FullGreen:TX", 'GPRINT:tx_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:tx_max:MAX:%5.1lf%s Max,', 'GPRINT:tx_avg:LAST:%5.1lf%s Last', 'GPRINT:tx_avg_sum:LAST:(ca. %4.0lf%s Total)\l', "LINE1:rx_avg#$FullBlue:RX", // 'GPRINT:rx_min:MIN:%5.1lf %s Min,', 'GPRINT:rx_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:rx_max:MAX:%5.1lf%s Max,', 'GPRINT:rx_avg:LAST:%5.1lf%s Last', 'GPRINT:rx_avg_sum:LAST:(ca. %4.0lf%s Total)\l'); $GraphDefs['if_packets'] = array( '-v', 'Packets/s', '--units=si', 'DEF:tx_min={file}:tx:MIN', 'DEF:tx_avg={file}:tx:AVERAGE', 'DEF:tx_max={file}:tx:MAX', 'DEF:rx_min={file}:rx:MIN', 'DEF:rx_avg={file}:rx:AVERAGE', 'DEF:rx_max={file}:rx:MAX', 'CDEF:overlap=tx_avg,rx_avg,GT,rx_avg,tx_avg,IF', 'CDEF:mytime=tx_avg,TIME,TIME,IF', 'CDEF:sample_len_raw=mytime,PREV(mytime),-', 'CDEF:sample_len=sample_len_raw,UN,0,sample_len_raw,IF', 'CDEF:tx_avg_sample=tx_avg,UN,0,tx_avg,IF,sample_len,*', 'CDEF:tx_avg_sum=PREV,UN,0,PREV,IF,tx_avg_sample,+', 'CDEF:rx_avg_sample=rx_avg,UN,0,rx_avg,IF,sample_len,*', 'CDEF:rx_avg_sum=PREV,UN,0,PREV,IF,rx_avg_sample,+', "AREA:tx_avg#$HalfGreen", "AREA:rx_avg#$HalfBlue", "AREA:overlap#$HalfBlueGreen", "LINE1:tx_avg#$FullGreen:TX", 'GPRINT:tx_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:tx_max:MAX:%5.1lf%s Max,', 'GPRINT:tx_avg:LAST:%5.1lf%s Last', 'GPRINT:tx_avg_sum:LAST:(ca. %4.0lf%s Total)\l', "LINE1:rx_avg#$FullBlue:RX", // 'GPRINT:rx_min:MIN:%5.1lf %s Min,', 'GPRINT:rx_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:rx_max:MAX:%5.1lf%s Max,', 'GPRINT:rx_avg:LAST:%5.1lf%s Last', 'GPRINT:rx_avg_sum:LAST:(ca. %4.0lf%s Total)\l'); $GraphDefs['if_rx_errors'] = array( '-v', 'Errors/s', '--units=si', 'DEF:min={file}:value:MIN', 'DEF:avg={file}:value:AVERAGE', 'DEF:max={file}:value:MAX', 'CDEF:mytime=avg,TIME,TIME,IF', 'CDEF:sample_len_raw=mytime,PREV(mytime),-', 'CDEF:sample_len=sample_len_raw,UN,0,sample_len_raw,IF', 'CDEF:avg_sample=avg,UN,0,avg,IF,sample_len,*', 'CDEF:avg_sum=PREV,UN,0,PREV,IF,avg_sample,+', "AREA:avg#$HalfBlue", "LINE1:avg#$FullBlue:Errors/s", 'GPRINT:avg:AVERAGE:%3.1lf%s Avg,', 'GPRINT:max:MAX:%3.1lf%s Max,', 'GPRINT:avg:LAST:%3.1lf%s Last', 'GPRINT:avg_sum:LAST:(ca. %2.0lf%s Total)\l'); $GraphDefs['ipt_bytes'] = array( '-v', 'Bits/s', 'DEF:min_raw={file}:value:MIN', 'DEF:avg_raw={file}:value:AVERAGE', 'DEF:max_raw={file}:value:MAX', 'CDEF:min=min_raw,8,*', 'CDEF:avg=avg_raw,8,*', 'CDEF:max=max_raw,8,*', 'CDEF:mytime=avg_raw,TIME,TIME,IF', 'CDEF:sample_len_raw=mytime,PREV(mytime),-', 'CDEF:sample_len=sample_len_raw,UN,0,sample_len_raw,IF', 'CDEF:avg_sample=avg_raw,UN,0,avg_raw,IF,sample_len,*', 'CDEF:avg_sum=PREV,UN,0,PREV,IF,avg_sample,+', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Bits/s", // 'GPRINT:min:MIN:%5.1lf %s Min,', 'GPRINT:avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:max:MAX:%5.1lf%s Max,', 'GPRINT:avg:LAST:%5.1lf%s Last', 'GPRINT:avg_sum:LAST:(ca. %5.1lf%sB Total)\l'); $GraphDefs['ipt_packets'] = array( '-v', 'Packets/s', 'DEF:min_raw={file}:value:MIN', 'DEF:avg_raw={file}:value:AVERAGE', 'DEF:max_raw={file}:value:MAX', 'CDEF:min=min_raw,8,*', 'CDEF:avg=avg_raw,8,*', 'CDEF:max=max_raw,8,*', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Packets/s", 'GPRINT:min:MIN:%5.1lf %s Min,', 'GPRINT:avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:max:MAX:%5.1lf%s Max,', 'GPRINT:avg:LAST:%5.1lf%s Last\l'); $GraphDefs['irq'] = array( '-v', 'Issues/s', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Issues/s", 'GPRINT:min:MIN:%6.2lf Min,', 'GPRINT:avg:AVERAGE:%6.2lf Avg,', 'GPRINT:max:MAX:%6.2lf Max,', 'GPRINT:avg:LAST:%6.2lf Last\l'); $GraphDefs['load'] = array( '-v', 'System load', 'DEF:s_avg={file}:shortterm:AVERAGE', 'DEF:s_min={file}:shortterm:MIN', 'DEF:s_max={file}:shortterm:MAX', 'DEF:m_avg={file}:midterm:AVERAGE', 'DEF:m_min={file}:midterm:MIN', 'DEF:m_max={file}:midterm:MAX', 'DEF:l_avg={file}:longterm:AVERAGE', 'DEF:l_min={file}:longterm:MIN', 'DEF:l_max={file}:longterm:MAX', "AREA:s_max#$HalfGreen", "AREA:s_min#$Canvas", "LINE1:s_avg#$FullGreen: 1m average", 'GPRINT:s_min:MIN:%4.2lf Min,', 'GPRINT:s_avg:AVERAGE:%4.2lf Avg,', 'GPRINT:s_max:MAX:%4.2lf Max,', 'GPRINT:s_avg:LAST:%4.2lf Last\n', "LINE1:m_avg#$FullBlue: 5m average", 'GPRINT:m_min:MIN:%4.2lf Min,', 'GPRINT:m_avg:AVERAGE:%4.2lf Avg,', 'GPRINT:m_max:MAX:%4.2lf Max,', 'GPRINT:m_avg:LAST:%4.2lf Last\n', "LINE1:l_avg#$FullRed:15m average", 'GPRINT:l_min:MIN:%4.2lf Min,', 'GPRINT:l_avg:AVERAGE:%4.2lf Avg,', 'GPRINT:l_max:MAX:%4.2lf Max,', 'GPRINT:l_avg:LAST:%4.2lf Last'); $GraphDefs['load_percent'] = array( 'DEF:avg={file}:percent:AVERAGE', 'DEF:min={file}:percent:MIN', 'DEF:max={file}:percent:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Load", 'GPRINT:min:MIN:%5.1lf%s%% Min,', 'GPRINT:avg:AVERAGE:%5.1lf%s%% Avg,', 'GPRINT:max:MAX:%5.1lf%s%% Max,', 'GPRINT:avg:LAST:%5.1lf%s%% Last\l'); $GraphDefs['mails'] = array( 'DEF:rawgood={file}:good:AVERAGE', 'DEF:rawspam={file}:spam:AVERAGE', 'CDEF:good=rawgood,UN,0,rawgood,IF', 'CDEF:spam=rawspam,UN,0,rawspam,IF', 'CDEF:negspam=spam,-1,*', "AREA:good#$HalfGreen", "LINE1:good#$FullGreen:Good mails", 'GPRINT:good:AVERAGE:%4.1lf Avg,', 'GPRINT:good:MAX:%4.1lf Max,', 'GPRINT:good:LAST:%4.1lf Last\n', "AREA:negspam#$HalfRed", "LINE1:negspam#$FullRed:Spam mails", 'GPRINT:spam:AVERAGE:%4.1lf Avg,', 'GPRINT:spam:MAX:%4.1lf Max,', 'GPRINT:spam:LAST:%4.1lf Last', 'HRULE:0#000000'); $GraphDefs['memory'] = array( '-b', '1024', '-v', 'Bytes', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Memory", 'GPRINT:min:MIN:%5.1lf%sbyte Min,', 'GPRINT:avg:AVERAGE:%5.1lf%sbyte Avg,', 'GPRINT:max:MAX:%5.1lf%sbyte Max,', 'GPRINT:avg:LAST:%5.1lf%sbyte Last\l'); $GraphDefs['old_memory'] = array( 'DEF:used_avg={file}:used:AVERAGE', 'DEF:free_avg={file}:free:AVERAGE', 'DEF:buffers_avg={file}:buffers:AVERAGE', 'DEF:cached_avg={file}:cached:AVERAGE', 'DEF:used_min={file}:used:MIN', 'DEF:free_min={file}:free:MIN', 'DEF:buffers_min={file}:buffers:MIN', 'DEF:cached_min={file}:cached:MIN', 'DEF:used_max={file}:used:MAX', 'DEF:free_max={file}:free:MAX', 'DEF:buffers_max={file}:buffers:MAX', 'DEF:cached_max={file}:cached:MAX', 'CDEF:cached_avg_nn=cached_avg,UN,0,cached_avg,IF', 'CDEF:buffers_avg_nn=buffers_avg,UN,0,buffers_avg,IF', 'CDEF:free_cached_buffers_used=free_avg,cached_avg_nn,+,buffers_avg_nn,+,used_avg,+', 'CDEF:cached_buffers_used=cached_avg,buffers_avg_nn,+,used_avg,+', 'CDEF:buffers_used=buffers_avg,used_avg,+', "AREA:free_cached_buffers_used#$HalfGreen", "AREA:cached_buffers_used#$HalfBlue", "AREA:buffers_used#$HalfYellow", "AREA:used_avg#$HalfRed", "LINE1:free_cached_buffers_used#$FullGreen:Free ", 'GPRINT:free_min:MIN:%5.1lf%s Min,', 'GPRINT:free_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:free_max:MAX:%5.1lf%s Max,', 'GPRINT:free_avg:LAST:%5.1lf%s Last\n', "LINE1:cached_buffers_used#$FullBlue:Page cache ", 'GPRINT:cached_min:MIN:%5.1lf%s Min,', 'GPRINT:cached_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:cached_max:MAX:%5.1lf%s Max,', 'GPRINT:cached_avg:LAST:%5.1lf%s Last\n', "LINE1:buffers_used#$FullYellow:Buffer cache", 'GPRINT:buffers_min:MIN:%5.1lf%s Min,', 'GPRINT:buffers_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:buffers_max:MAX:%5.1lf%s Max,', 'GPRINT:buffers_avg:LAST:%5.1lf%s Last\n', "LINE1:used_avg#$FullRed:Used ", 'GPRINT:used_min:MIN:%5.1lf%s Min,', 'GPRINT:used_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:used_max:MAX:%5.1lf%s Max,', 'GPRINT:used_avg:LAST:%5.1lf%s Last'); $GraphDefs['mysql_commands'] = array( '-v', 'Issues/s', "DEF:val_avg={file}:value:AVERAGE", "DEF:val_min={file}:value:MIN", "DEF:val_max={file}:value:MAX", "AREA:val_max#$HalfBlue", "AREA:val_min#$Canvas", "LINE1:val_avg#$FullBlue:Issues/s", 'GPRINT:val_min:MIN:%5.2lf Min,', 'GPRINT:val_avg:AVERAGE:%5.2lf Avg,', 'GPRINT:val_max:MAX:%5.2lf Max,', 'GPRINT:val_avg:LAST:%5.2lf Last'); $GraphDefs['mysql_handler'] = array( '-v', 'Issues/s', "DEF:val_avg={file}:value:AVERAGE", "DEF:val_min={file}:value:MIN", "DEF:val_max={file}:value:MAX", "AREA:val_max#$HalfBlue", "AREA:val_min#$Canvas", "LINE1:val_avg#$FullBlue:Issues/s", 'GPRINT:val_min:MIN:%5.2lf Min,', 'GPRINT:val_avg:AVERAGE:%5.2lf Avg,', 'GPRINT:val_max:MAX:%5.2lf Max,', 'GPRINT:val_avg:LAST:%5.2lf Last'); $GraphDefs['mysql_octets'] = array( '-v', 'Bits/s', 'DEF:out_min={file}:tx:MIN', 'DEF:out_avg={file}:tx:AVERAGE', 'DEF:out_max={file}:tx:MAX', 'DEF:inc_min={file}:rx:MIN', 'DEF:inc_avg={file}:rx:AVERAGE', 'DEF:inc_max={file}:rx:MAX', 'CDEF:mytime=out_avg,TIME,TIME,IF', 'CDEF:sample_len_raw=mytime,PREV(mytime),-', 'CDEF:sample_len=sample_len_raw,UN,0,sample_len_raw,IF', 'CDEF:out_avg_sample=out_avg,UN,0,out_avg,IF,sample_len,*', 'CDEF:out_avg_sum=PREV,UN,0,PREV,IF,out_avg_sample,+', 'CDEF:inc_avg_sample=inc_avg,UN,0,inc_avg,IF,sample_len,*', 'CDEF:inc_avg_sum=PREV,UN,0,PREV,IF,inc_avg_sample,+', 'CDEF:out_bit_min=out_min,8,*', 'CDEF:out_bit_avg=out_avg,8,*', 'CDEF:out_bit_max=out_max,8,*', 'CDEF:inc_bit_min=inc_min,8,*', 'CDEF:inc_bit_avg=inc_avg,8,*', 'CDEF:inc_bit_max=inc_max,8,*', 'CDEF:overlap=out_bit_avg,inc_bit_avg,GT,inc_bit_avg,out_bit_avg,IF', "AREA:out_bit_avg#$HalfGreen", "AREA:inc_bit_avg#$HalfBlue", "AREA:overlap#$HalfBlueGreen", "LINE1:out_bit_avg#$FullGreen:Written", 'GPRINT:out_bit_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:out_bit_max:MAX:%5.1lf%s Max,', 'GPRINT:out_bit_avg:LAST:%5.1lf%s Last', 'GPRINT:out_avg_sum:LAST:(ca. %5.1lf%sB Total)\l', "LINE1:inc_bit_avg#$FullBlue:Read ", 'GPRINT:inc_bit_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:inc_bit_max:MAX:%5.1lf%s Max,', 'GPRINT:inc_bit_avg:LAST:%5.1lf%s Last', 'GPRINT:inc_avg_sum:LAST:(ca. %5.1lf%sB Total)\l'); $GraphDefs['mysql_qcache'] = array( '-v', 'Queries/s', "DEF:hits_min={file}:hits:MIN", "DEF:hits_avg={file}:hits:AVERAGE", "DEF:hits_max={file}:hits:MAX", "DEF:inserts_min={file}:inserts:MIN", "DEF:inserts_avg={file}:inserts:AVERAGE", "DEF:inserts_max={file}:inserts:MAX", "DEF:not_cached_min={file}:not_cached:MIN", "DEF:not_cached_avg={file}:not_cached:AVERAGE", "DEF:not_cached_max={file}:not_cached:MAX", "DEF:lowmem_prunes_min={file}:lowmem_prunes:MIN", "DEF:lowmem_prunes_avg={file}:lowmem_prunes:AVERAGE", "DEF:lowmem_prunes_max={file}:lowmem_prunes:MAX", "DEF:queries_min={file}:queries_in_cache:MIN", "DEF:queries_avg={file}:queries_in_cache:AVERAGE", "DEF:queries_max={file}:queries_in_cache:MAX", "CDEF:unknown=queries_avg,UNKN,+", "CDEF:not_cached_agg=hits_avg,inserts_avg,+,not_cached_avg,+", "CDEF:inserts_agg=hits_avg,inserts_avg,+", "CDEF:hits_agg=hits_avg", "AREA:not_cached_agg#$HalfYellow", "AREA:inserts_agg#$HalfBlue", "AREA:hits_agg#$HalfGreen", "LINE1:not_cached_agg#$FullYellow:Not Cached ", 'GPRINT:not_cached_min:MIN:%5.2lf Min,', 'GPRINT:not_cached_avg:AVERAGE:%5.2lf Avg,', 'GPRINT:not_cached_max:MAX:%5.2lf Max,', 'GPRINT:not_cached_avg:LAST:%5.2lf Last\l', "LINE1:inserts_agg#$FullBlue:Inserts ", 'GPRINT:inserts_min:MIN:%5.2lf Min,', 'GPRINT:inserts_avg:AVERAGE:%5.2lf Avg,', 'GPRINT:inserts_max:MAX:%5.2lf Max,', 'GPRINT:inserts_avg:LAST:%5.2lf Last\l', "LINE1:hits_agg#$FullGreen:Hits ", 'GPRINT:hits_min:MIN:%5.2lf Min,', 'GPRINT:hits_avg:AVERAGE:%5.2lf Avg,', 'GPRINT:hits_max:MAX:%5.2lf Max,', 'GPRINT:hits_avg:LAST:%5.2lf Last\l', "LINE1:lowmem_prunes_avg#$FullRed:Lowmem Prunes ", 'GPRINT:lowmem_prunes_min:MIN:%5.2lf Min,', 'GPRINT:lowmem_prunes_avg:AVERAGE:%5.2lf Avg,', 'GPRINT:lowmem_prunes_max:MAX:%5.2lf Max,', 'GPRINT:lowmem_prunes_avg:LAST:%5.2lf Last\l', "LINE1:unknown#$Canvas:Queries in cache", 'GPRINT:queries_min:MIN:%5.0lf Min,', 'GPRINT:queries_avg:AVERAGE:%5.0lf Avg,', 'GPRINT:queries_max:MAX:%5.0lf Max,', 'GPRINT:queries_avg:LAST:%5.0lf Last\l'); $GraphDefs['mysql_threads'] = array( '-v', 'Threads', "DEF:running_min={file}:running:MIN", "DEF:running_avg={file}:running:AVERAGE", "DEF:running_max={file}:running:MAX", "DEF:connected_min={file}:connected:MIN", "DEF:connected_avg={file}:connected:AVERAGE", "DEF:connected_max={file}:connected:MAX", "DEF:cached_min={file}:cached:MIN", "DEF:cached_avg={file}:cached:AVERAGE", "DEF:cached_max={file}:cached:MAX", "DEF:created_min={file}:created:MIN", "DEF:created_avg={file}:created:AVERAGE", "DEF:created_max={file}:created:MAX", "CDEF:unknown=created_avg,UNKN,+", "CDEF:cached_agg=connected_avg,cached_avg,+", "AREA:cached_agg#$HalfGreen", "AREA:connected_avg#$HalfBlue", "AREA:running_avg#$HalfRed", "LINE1:cached_agg#$FullGreen:Cached ", 'GPRINT:cached_min:MIN:%5.1lf Min,', 'GPRINT:cached_avg:AVERAGE:%5.1lf Avg,', 'GPRINT:cached_max:MAX:%5.1lf Max,', 'GPRINT:cached_avg:LAST:%5.1lf Last\l', "LINE1:connected_avg#$FullBlue:Connected", 'GPRINT:connected_min:MIN:%5.1lf Min,', 'GPRINT:connected_avg:AVERAGE:%5.1lf Avg,', 'GPRINT:connected_max:MAX:%5.1lf Max,', 'GPRINT:connected_avg:LAST:%5.1lf Last\l', "LINE1:running_avg#$FullRed:Running ", 'GPRINT:running_min:MIN:%5.1lf Min,', 'GPRINT:running_avg:AVERAGE:%5.1lf Avg,', 'GPRINT:running_max:MAX:%5.1lf Max,', 'GPRINT:running_avg:LAST:%5.1lf Last\l', "LINE1:unknown#$Canvas:Created ", 'GPRINT:created_min:MIN:%5.0lf Min,', 'GPRINT:created_avg:AVERAGE:%5.0lf Avg,', 'GPRINT:created_max:MAX:%5.0lf Max,', 'GPRINT:created_avg:LAST:%5.0lf Last\l'); $GraphDefs['nfs_procedure'] = array( '-v', 'Issues/s', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Issues/s", 'GPRINT:min:MIN:%6.2lf Min,', 'GPRINT:avg:AVERAGE:%6.2lf Avg,', 'GPRINT:max:MAX:%6.2lf Max,', 'GPRINT:avg:LAST:%6.2lf Last\l'); $GraphDefs['nfs3_procedures'] = array( "DEF:null_avg={file}:null:AVERAGE", "DEF:getattr_avg={file}:getattr:AVERAGE", "DEF:setattr_avg={file}:setattr:AVERAGE", "DEF:lookup_avg={file}:lookup:AVERAGE", "DEF:access_avg={file}:access:AVERAGE", "DEF:readlink_avg={file}:readlink:AVERAGE", "DEF:read_avg={file}:read:AVERAGE", "DEF:write_avg={file}:write:AVERAGE", "DEF:create_avg={file}:create:AVERAGE", "DEF:mkdir_avg={file}:mkdir:AVERAGE", "DEF:symlink_avg={file}:symlink:AVERAGE", "DEF:mknod_avg={file}:mknod:AVERAGE", "DEF:remove_avg={file}:remove:AVERAGE", "DEF:rmdir_avg={file}:rmdir:AVERAGE", "DEF:rename_avg={file}:rename:AVERAGE", "DEF:link_avg={file}:link:AVERAGE", "DEF:readdir_avg={file}:readdir:AVERAGE", "DEF:readdirplus_avg={file}:readdirplus:AVERAGE", "DEF:fsstat_avg={file}:fsstat:AVERAGE", "DEF:fsinfo_avg={file}:fsinfo:AVERAGE", "DEF:pathconf_avg={file}:pathconf:AVERAGE", "DEF:commit_avg={file}:commit:AVERAGE", "DEF:null_max={file}:null:MAX", "DEF:getattr_max={file}:getattr:MAX", "DEF:setattr_max={file}:setattr:MAX", "DEF:lookup_max={file}:lookup:MAX", "DEF:access_max={file}:access:MAX", "DEF:readlink_max={file}:readlink:MAX", "DEF:read_max={file}:read:MAX", "DEF:write_max={file}:write:MAX", "DEF:create_max={file}:create:MAX", "DEF:mkdir_max={file}:mkdir:MAX", "DEF:symlink_max={file}:symlink:MAX", "DEF:mknod_max={file}:mknod:MAX", "DEF:remove_max={file}:remove:MAX", "DEF:rmdir_max={file}:rmdir:MAX", "DEF:rename_max={file}:rename:MAX", "DEF:link_max={file}:link:MAX", "DEF:readdir_max={file}:readdir:MAX", "DEF:readdirplus_max={file}:readdirplus:MAX", "DEF:fsstat_max={file}:fsstat:MAX", "DEF:fsinfo_max={file}:fsinfo:MAX", "DEF:pathconf_max={file}:pathconf:MAX", "DEF:commit_max={file}:commit:MAX", "CDEF:other_avg=null_avg,readlink_avg,create_avg,mkdir_avg,symlink_avg,mknod_avg,remove_avg,rmdir_avg,rename_avg,link_avg,readdir_avg,readdirplus_avg,fsstat_avg,fsinfo_avg,pathconf_avg,+,+,+,+,+,+,+,+,+,+,+,+,+,+", "CDEF:other_max=null_max,readlink_max,create_max,mkdir_max,symlink_max,mknod_max,remove_max,rmdir_max,rename_max,link_max,readdir_max,readdirplus_max,fsstat_max,fsinfo_max,pathconf_max,+,+,+,+,+,+,+,+,+,+,+,+,+,+", "CDEF:stack_read=read_avg", "CDEF:stack_getattr=stack_read,getattr_avg,+", "CDEF:stack_access=stack_getattr,access_avg,+", "CDEF:stack_lookup=stack_access,lookup_avg,+", "CDEF:stack_write=stack_lookup,write_avg,+", "CDEF:stack_commit=stack_write,commit_avg,+", "CDEF:stack_setattr=stack_commit,setattr_avg,+", "CDEF:stack_other=stack_setattr,other_avg,+", "AREA:stack_other#$HalfRed", "AREA:stack_setattr#$HalfGreen", "AREA:stack_commit#$HalfYellow", "AREA:stack_write#$HalfGreen", "AREA:stack_lookup#$HalfBlue", "AREA:stack_access#$HalfMagenta", "AREA:stack_getattr#$HalfCyan", "AREA:stack_read#$HalfBlue", "LINE1:stack_other#$FullRed:Other ", 'GPRINT:other_max:MAX:%5.1lf Max,', 'GPRINT:other_avg:AVERAGE:%5.1lf Avg,', 'GPRINT:other_avg:LAST:%5.1lf Last\l', "LINE1:stack_setattr#$FullGreen:setattr", 'GPRINT:setattr_max:MAX:%5.1lf Max,', 'GPRINT:setattr_avg:AVERAGE:%5.1lf Avg,', 'GPRINT:setattr_avg:LAST:%5.1lf Last\l', "LINE1:stack_commit#$FullYellow:commit ", 'GPRINT:commit_max:MAX:%5.1lf Max,', 'GPRINT:commit_avg:AVERAGE:%5.1lf Avg,', 'GPRINT:commit_avg:LAST:%5.1lf Last\l', "LINE1:stack_write#$FullGreen:write ", 'GPRINT:write_max:MAX:%5.1lf Max,', 'GPRINT:write_avg:AVERAGE:%5.1lf Avg,', 'GPRINT:write_avg:LAST:%5.1lf Last\l', "LINE1:stack_lookup#$FullBlue:lookup ", 'GPRINT:lookup_max:MAX:%5.1lf Max,', 'GPRINT:lookup_avg:AVERAGE:%5.1lf Avg,', 'GPRINT:lookup_avg:LAST:%5.1lf Last\l', "LINE1:stack_access#$FullMagenta:access ", 'GPRINT:access_max:MAX:%5.1lf Max,', 'GPRINT:access_avg:AVERAGE:%5.1lf Avg,', 'GPRINT:access_avg:LAST:%5.1lf Last\l', "LINE1:stack_getattr#$FullCyan:getattr", 'GPRINT:getattr_max:MAX:%5.1lf Max,', 'GPRINT:getattr_avg:AVERAGE:%5.1lf Avg,', 'GPRINT:getattr_avg:LAST:%5.1lf Last\l', "LINE1:stack_read#$FullBlue:read ", 'GPRINT:read_max:MAX:%5.1lf Max,', 'GPRINT:read_avg:AVERAGE:%5.1lf Avg,', 'GPRINT:read_avg:LAST:%5.1lf Last\l'); $GraphDefs['opcode'] = array( 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Queries/s", 'GPRINT:min:MIN:%9.3lf Min,', 'GPRINT:avg:AVERAGE:%9.3lf Average,', 'GPRINT:max:MAX:%9.3lf Max,', 'GPRINT:avg:LAST:%9.3lf Last\l'); $GraphDefs['partition'] = array( "DEF:rbyte_avg={file}:rbytes:AVERAGE", "DEF:rbyte_min={file}:rbytes:MIN", "DEF:rbyte_max={file}:rbytes:MAX", "DEF:wbyte_avg={file}:wbytes:AVERAGE", "DEF:wbyte_min={file}:wbytes:MIN", "DEF:wbyte_max={file}:wbytes:MAX", 'CDEF:overlap=wbyte_avg,rbyte_avg,GT,rbyte_avg,wbyte_avg,IF', "AREA:wbyte_avg#$HalfGreen", "AREA:rbyte_avg#$HalfBlue", "AREA:overlap#$HalfBlueGreen", "LINE1:wbyte_avg#$FullGreen:Write", 'GPRINT:wbyte_min:MIN:%5.1lf%s Min,', 'GPRINT:wbyte_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:wbyte_max:MAX:%5.1lf%s Max,', 'GPRINT:wbyte_avg:LAST:%5.1lf%s Last\l', "LINE1:rbyte_avg#$FullBlue:Read ", 'GPRINT:rbyte_min:MIN:%5.1lf%s Min,', 'GPRINT:rbyte_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:rbyte_max:MAX:%5.1lf%s Max,', 'GPRINT:rbyte_avg:LAST:%5.1lf%s Last\l'); $GraphDefs['percent'] = array( '-v', 'Percent', 'DEF:avg={file}:percent:AVERAGE', 'DEF:min={file}:percent:MIN', 'DEF:max={file}:percent:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Percent", 'GPRINT:min:MIN:%5.1lf%% Min,', 'GPRINT:avg:AVERAGE:%5.1lf%% Avg,', 'GPRINT:max:MAX:%5.1lf%% Max,', 'GPRINT:avg:LAST:%5.1lf%% Last\l'); $GraphDefs['ping'] = array( 'DEF:ping_avg={file}:ping:AVERAGE', 'DEF:ping_min={file}:ping:MIN', 'DEF:ping_max={file}:ping:MAX', "AREA:ping_max#$HalfBlue", "AREA:ping_min#$Canvas", "LINE1:ping_avg#$FullBlue:Ping", 'GPRINT:ping_min:MIN:%4.1lf ms Min,', 'GPRINT:ping_avg:AVERAGE:%4.1lf ms Avg,', 'GPRINT:ping_max:MAX:%4.1lf ms Max,', 'GPRINT:ping_avg:LAST:%4.1lf ms Last'); $GraphDefs['power'] = array( '-v', 'Watt', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Watt", 'GPRINT:min:MIN:%5.1lf%sW Min,', 'GPRINT:avg:AVERAGE:%5.1lf%sW Avg,', 'GPRINT:max:MAX:%5.1lf%sW Max,', 'GPRINT:avg:LAST:%5.1lf%sW Last\l'); $GraphDefs['processes'] = array( "DEF:running_avg={file}:running:AVERAGE", "DEF:running_min={file}:running:MIN", "DEF:running_max={file}:running:MAX", "DEF:sleeping_avg={file}:sleeping:AVERAGE", "DEF:sleeping_min={file}:sleeping:MIN", "DEF:sleeping_max={file}:sleeping:MAX", "DEF:zombies_avg={file}:zombies:AVERAGE", "DEF:zombies_min={file}:zombies:MIN", "DEF:zombies_max={file}:zombies:MAX", "DEF:stopped_avg={file}:stopped:AVERAGE", "DEF:stopped_min={file}:stopped:MIN", "DEF:stopped_max={file}:stopped:MAX", "DEF:paging_avg={file}:paging:AVERAGE", "DEF:paging_min={file}:paging:MIN", "DEF:paging_max={file}:paging:MAX", "DEF:blocked_avg={file}:blocked:AVERAGE", "DEF:blocked_min={file}:blocked:MIN", "DEF:blocked_max={file}:blocked:MAX", 'CDEF:paging_acc=sleeping_avg,running_avg,stopped_avg,zombies_avg,blocked_avg,paging_avg,+,+,+,+,+', 'CDEF:blocked_acc=sleeping_avg,running_avg,stopped_avg,zombies_avg,blocked_avg,+,+,+,+', 'CDEF:zombies_acc=sleeping_avg,running_avg,stopped_avg,zombies_avg,+,+,+', 'CDEF:stopped_acc=sleeping_avg,running_avg,stopped_avg,+,+', 'CDEF:running_acc=sleeping_avg,running_avg,+', 'CDEF:sleeping_acc=sleeping_avg', "AREA:paging_acc#$HalfYellow", "AREA:blocked_acc#$HalfCyan", "AREA:zombies_acc#$HalfRed", "AREA:stopped_acc#$HalfMagenta", "AREA:running_acc#$HalfGreen", "AREA:sleeping_acc#$HalfBlue", "LINE1:paging_acc#$FullYellow:Paging ", 'GPRINT:paging_min:MIN:%5.1lf Min,', 'GPRINT:paging_avg:AVERAGE:%5.1lf Average,', 'GPRINT:paging_max:MAX:%5.1lf Max,', 'GPRINT:paging_avg:LAST:%5.1lf Last\l', "LINE1:blocked_acc#$FullCyan:Blocked ", 'GPRINT:blocked_min:MIN:%5.1lf Min,', 'GPRINT:blocked_avg:AVERAGE:%5.1lf Average,', 'GPRINT:blocked_max:MAX:%5.1lf Max,', 'GPRINT:blocked_avg:LAST:%5.1lf Last\l', "LINE1:zombies_acc#$FullRed:Zombies ", 'GPRINT:zombies_min:MIN:%5.1lf Min,', 'GPRINT:zombies_avg:AVERAGE:%5.1lf Average,', 'GPRINT:zombies_max:MAX:%5.1lf Max,', 'GPRINT:zombies_avg:LAST:%5.1lf Last\l', "LINE1:stopped_acc#$FullMagenta:Stopped ", 'GPRINT:stopped_min:MIN:%5.1lf Min,', 'GPRINT:stopped_avg:AVERAGE:%5.1lf Average,', 'GPRINT:stopped_max:MAX:%5.1lf Max,', 'GPRINT:stopped_avg:LAST:%5.1lf Last\l', "LINE1:running_acc#$FullGreen:Running ", 'GPRINT:running_min:MIN:%5.1lf Min,', 'GPRINT:running_avg:AVERAGE:%5.1lf Average,', 'GPRINT:running_max:MAX:%5.1lf Max,', 'GPRINT:running_avg:LAST:%5.1lf Last\l', "LINE1:sleeping_acc#$FullBlue:Sleeping", 'GPRINT:sleeping_min:MIN:%5.1lf Min,', 'GPRINT:sleeping_avg:AVERAGE:%5.1lf Average,', 'GPRINT:sleeping_max:MAX:%5.1lf Max,', 'GPRINT:sleeping_avg:LAST:%5.1lf Last\l'); $GraphDefs['ps_count'] = array( '-v', 'Processes', 'DEF:procs_avg={file}:processes:AVERAGE', 'DEF:procs_min={file}:processes:MIN', 'DEF:procs_max={file}:processes:MAX', 'DEF:thrds_avg={file}:threads:AVERAGE', 'DEF:thrds_min={file}:threads:MIN', 'DEF:thrds_max={file}:threads:MAX', "AREA:thrds_avg#$HalfBlue", "AREA:procs_avg#$HalfRed", "LINE1:thrds_avg#$FullBlue:Threads ", 'GPRINT:thrds_min:MIN:%5.1lf Min,', 'GPRINT:thrds_avg:AVERAGE:%5.1lf Avg,', 'GPRINT:thrds_max:MAX:%5.1lf Max,', 'GPRINT:thrds_avg:LAST:%5.1lf Last\l', "LINE1:procs_avg#$FullRed:Processes", 'GPRINT:procs_min:MIN:%5.1lf Min,', 'GPRINT:procs_avg:AVERAGE:%5.1lf Avg,', 'GPRINT:procs_max:MAX:%5.1lf Max,', 'GPRINT:procs_avg:LAST:%5.1lf Last\l'); $GraphDefs['ps_cputime'] = array( '-v', 'Jiffies', 'DEF:user_avg_raw={file}:user:AVERAGE', 'DEF:user_min_raw={file}:user:MIN', 'DEF:user_max_raw={file}:user:MAX', 'DEF:syst_avg_raw={file}:syst:AVERAGE', 'DEF:syst_min_raw={file}:syst:MIN', 'DEF:syst_max_raw={file}:syst:MAX', 'CDEF:user_avg=user_avg_raw,1000000,/', 'CDEF:user_min=user_min_raw,1000000,/', 'CDEF:user_max=user_max_raw,1000000,/', 'CDEF:syst_avg=syst_avg_raw,1000000,/', 'CDEF:syst_min=syst_min_raw,1000000,/', 'CDEF:syst_max=syst_max_raw,1000000,/', 'CDEF:user_syst=syst_avg,UN,0,syst_avg,IF,user_avg,+', "AREA:user_syst#$HalfBlue", "AREA:syst_avg#$HalfRed", "LINE1:user_syst#$FullBlue:User ", 'GPRINT:user_min:MIN:%5.1lf%s Min,', 'GPRINT:user_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:user_max:MAX:%5.1lf%s Max,', 'GPRINT:user_avg:LAST:%5.1lf%s Last\l', "LINE1:syst_avg#$FullRed:System", 'GPRINT:syst_min:MIN:%5.1lf%s Min,', 'GPRINT:syst_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:syst_max:MAX:%5.1lf%s Max,', 'GPRINT:syst_avg:LAST:%5.1lf%s Last\l'); $GraphDefs['ps_pagefaults'] = array( '-v', 'Pagefaults/s', 'DEF:minor_avg={file}:minflt:AVERAGE', 'DEF:minor_min={file}:minflt:MIN', 'DEF:minor_max={file}:minflt:MAX', 'DEF:major_avg={file}:majflt:AVERAGE', 'DEF:major_min={file}:majflt:MIN', 'DEF:major_max={file}:majflt:MAX', 'CDEF:minor_major=major_avg,UN,0,major_avg,IF,minor_avg,+', "AREA:minor_major#$HalfBlue", "AREA:major_avg#$HalfRed", "LINE1:minor_major#$FullBlue:Minor", 'GPRINT:minor_min:MIN:%5.1lf%s Min,', 'GPRINT:minor_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:minor_max:MAX:%5.1lf%s Max,', 'GPRINT:minor_avg:LAST:%5.1lf%s Last\l', "LINE1:major_avg#$FullRed:Major", 'GPRINT:major_min:MIN:%5.1lf%s Min,', 'GPRINT:major_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:major_max:MAX:%5.1lf%s Max,', 'GPRINT:major_avg:LAST:%5.1lf%s Last\l'); $GraphDefs['ps_rss'] = array( '-v', 'Bytes', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:avg#$HalfBlue", "LINE1:avg#$FullBlue:RSS", 'GPRINT:min:MIN:%5.1lf%s Min,', 'GPRINT:avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:max:MAX:%5.1lf%s Max,', 'GPRINT:avg:LAST:%5.1lf%s Last\l'); $GraphDefs['ps_state'] = array( '-v', 'Processes', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Processes", 'GPRINT:min:MIN:%6.2lf Min,', 'GPRINT:avg:AVERAGE:%6.2lf Avg,', 'GPRINT:max:MAX:%6.2lf Max,', 'GPRINT:avg:LAST:%6.2lf Last\l'); $GraphDefs['qtype'] = array( 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Queries/s", 'GPRINT:min:MIN:%9.3lf Min,', 'GPRINT:avg:AVERAGE:%9.3lf Average,', 'GPRINT:max:MAX:%9.3lf Max,', 'GPRINT:avg:LAST:%9.3lf Last\l'); $GraphDefs['rcode'] = array( 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Queries/s", 'GPRINT:min:MIN:%9.3lf Min,', 'GPRINT:avg:AVERAGE:%9.3lf Average,', 'GPRINT:max:MAX:%9.3lf Max,', 'GPRINT:avg:LAST:%9.3lf Last\l'); $GraphDefs['swap'] = array( '-v', 'Bytes', '-b', '1024', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Bytes", 'GPRINT:min:MIN:%6.2lf%sByte Min,', 'GPRINT:avg:AVERAGE:%6.2lf%sByte Avg,', 'GPRINT:max:MAX:%6.2lf%sByte Max,', 'GPRINT:avg:LAST:%6.2lf%sByte Last\l'); $GraphDefs['old_swap'] = array( 'DEF:used_avg={file}:used:AVERAGE', 'DEF:used_min={file}:used:MIN', 'DEF:used_max={file}:used:MAX', 'DEF:free_avg={file}:free:AVERAGE', 'DEF:free_min={file}:free:MIN', 'DEF:free_max={file}:free:MAX', 'DEF:cach_avg={file}:cached:AVERAGE', 'DEF:cach_min={file}:cached:MIN', 'DEF:cach_max={file}:cached:MAX', 'DEF:resv_avg={file}:resv:AVERAGE', 'DEF:resv_min={file}:resv:MIN', 'DEF:resv_max={file}:resv:MAX', 'CDEF:cach_avg_notnull=cach_avg,UN,0,cach_avg,IF', 'CDEF:resv_avg_notnull=resv_avg,UN,0,resv_avg,IF', 'CDEF:used_acc=used_avg', 'CDEF:resv_acc=used_acc,resv_avg_notnull,+', 'CDEF:cach_acc=resv_acc,cach_avg_notnull,+', 'CDEF:free_acc=cach_acc,free_avg,+', "AREA:free_acc#$HalfGreen", "AREA:cach_acc#$HalfBlue", "AREA:resv_acc#$HalfYellow", "AREA:used_acc#$HalfRed", "LINE1:free_acc#$FullGreen:Free ", 'GPRINT:free_min:MIN:%5.1lf%s Min,', 'GPRINT:free_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:free_max:MAX:%5.1lf%s Max,', 'GPRINT:free_avg:LAST:%5.1lf%s Last\n', "LINE1:cach_acc#$FullBlue:Cached ", 'GPRINT:cach_min:MIN:%5.1lf%s Min,', 'GPRINT:cach_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:cach_max:MAX:%5.1lf%s Max,', 'GPRINT:cach_avg:LAST:%5.1lf%s Last\l', "LINE1:resv_acc#$FullYellow:Reserved", 'GPRINT:resv_min:MIN:%5.1lf%s Min,', 'GPRINT:resv_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:resv_max:MAX:%5.1lf%s Max,', 'GPRINT:resv_avg:LAST:%5.1lf%s Last\n', "LINE1:used_acc#$FullRed:Used ", 'GPRINT:used_min:MIN:%5.1lf%s Min,', 'GPRINT:used_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:used_max:MAX:%5.1lf%s Max,', 'GPRINT:used_avg:LAST:%5.1lf%s Last\l'); $GraphDefs['tcp_connections'] = array( '-v', 'Connections', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Connections", 'GPRINT:min:MIN:%4.1lf Min,', 'GPRINT:avg:AVERAGE:%4.1lf Avg,', 'GPRINT:max:MAX:%4.1lf Max,', 'GPRINT:avg:LAST:%4.1lf Last\l'); $GraphDefs['temperature'] = array( '-v', 'Celsius', 'DEF:temp_avg={file}:value:AVERAGE', 'DEF:temp_min={file}:value:MIN', 'DEF:temp_max={file}:value:MAX', 'CDEF:average=temp_avg,0.2,*,PREV,UN,temp_avg,PREV,IF,0.8,*,+', "AREA:temp_max#$HalfRed", "AREA:temp_min#$Canvas", "LINE1:temp_avg#$FullRed:Temperature", 'GPRINT:temp_min:MIN:%4.1lf Min,', 'GPRINT:temp_avg:AVERAGE:%4.1lf Avg,', 'GPRINT:temp_max:MAX:%4.1lf Max,', 'GPRINT:temp_avg:LAST:%4.1lf Last\l'); $GraphDefs['timeleft'] = array( '-v', 'Minutes', 'DEF:avg={file}:timeleft:AVERAGE', 'DEF:min={file}:timeleft:MIN', 'DEF:max={file}:timeleft:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Time left [min]", 'GPRINT:min:MIN:%5.1lf%s Min,', 'GPRINT:avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:max:MAX:%5.1lf%s Max,', 'GPRINT:avg:LAST:%5.1lf%s Last\l'); $GraphDefs['time_offset'] = array( # NTPd 'DEF:s_avg={file}:seconds:AVERAGE', 'DEF:s_min={file}:seconds:MIN', 'DEF:s_max={file}:seconds:MAX', "AREA:s_max#$HalfBlue", "AREA:s_min#$Canvas", "LINE1:s_avg#$FullBlue:{inst}", 'GPRINT:s_min:MIN:%7.3lf%s Min,', 'GPRINT:s_avg:AVERAGE:%7.3lf%s Avg,', 'GPRINT:s_max:MAX:%7.3lf%s Max,', 'GPRINT:s_avg:LAST:%7.3lf%s Last'); $GraphDefs['if_octets'] = array( '-v', 'Bits/s', '--units=si', 'DEF:out_min_raw={file}:tx:MIN', 'DEF:out_avg_raw={file}:tx:AVERAGE', 'DEF:out_max_raw={file}:tx:MAX', 'DEF:inc_min_raw={file}:rx:MIN', 'DEF:inc_avg_raw={file}:rx:AVERAGE', 'DEF:inc_max_raw={file}:rx:MAX', 'CDEF:out_min=out_min_raw,8,*', 'CDEF:out_avg=out_avg_raw,8,*', 'CDEF:out_max=out_max_raw,8,*', 'CDEF:inc_min=inc_min_raw,8,*', 'CDEF:inc_avg=inc_avg_raw,8,*', 'CDEF:inc_max=inc_max_raw,8,*', 'CDEF:overlap=out_avg,inc_avg,GT,inc_avg,out_avg,IF', 'CDEF:mytime=out_avg_raw,TIME,TIME,IF', 'CDEF:sample_len_raw=mytime,PREV(mytime),-', 'CDEF:sample_len=sample_len_raw,UN,0,sample_len_raw,IF', 'CDEF:out_avg_sample=out_avg_raw,UN,0,out_avg_raw,IF,sample_len,*', 'CDEF:out_avg_sum=PREV,UN,0,PREV,IF,out_avg_sample,+', 'CDEF:inc_avg_sample=inc_avg_raw,UN,0,inc_avg_raw,IF,sample_len,*', 'CDEF:inc_avg_sum=PREV,UN,0,PREV,IF,inc_avg_sample,+', "AREA:out_avg#$HalfGreen", "AREA:inc_avg#$HalfBlue", "AREA:overlap#$HalfBlueGreen", "LINE1:out_avg#$FullGreen:Outgoing", 'GPRINT:out_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:out_max:MAX:%5.1lf%s Max,', 'GPRINT:out_avg:LAST:%5.1lf%s Last', 'GPRINT:out_avg_sum:LAST:(ca. %5.1lf%sB Total)\l', "LINE1:inc_avg#$FullBlue:Incoming", // 'GPRINT:inc_min:MIN:%5.1lf %s Min,', 'GPRINT:inc_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:inc_max:MAX:%5.1lf%s Max,', 'GPRINT:inc_avg:LAST:%5.1lf%s Last', 'GPRINT:inc_avg_sum:LAST:(ca. %5.1lf%sB Total)\l'); $GraphDefs['cpufreq'] = array( 'DEF:cpufreq_avg={file}:value:AVERAGE', 'DEF:cpufreq_min={file}:value:MIN', 'DEF:cpufreq_max={file}:value:MAX', "AREA:cpufreq_max#$HalfBlue", "AREA:cpufreq_min#$Canvas", "LINE1:cpufreq_avg#$FullBlue:Frequency", 'GPRINT:cpufreq_min:MIN:%5.1lf%s Min,', 'GPRINT:cpufreq_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:cpufreq_max:MAX:%5.1lf%s Max,', 'GPRINT:cpufreq_avg:LAST:%5.1lf%s Last\l'); $GraphDefs['multimeter'] = array( 'DEF:multimeter_avg={file}:value:AVERAGE', 'DEF:multimeter_min={file}:value:MIN', 'DEF:multimeter_max={file}:value:MAX', "AREA:multimeter_max#$HalfBlue", "AREA:multimeter_min#$Canvas", "LINE1:multimeter_avg#$FullBlue:Multimeter", 'GPRINT:multimeter_min:MIN:%4.1lf Min,', 'GPRINT:multimeter_avg:AVERAGE:%4.1lf Average,', 'GPRINT:multimeter_max:MAX:%4.1lf Max,', 'GPRINT:multimeter_avg:LAST:%4.1lf Last\l'); $GraphDefs['users'] = array( '-v', 'Users', 'DEF:users_avg={file}:users:AVERAGE', 'DEF:users_min={file}:users:MIN', 'DEF:users_max={file}:users:MAX', "AREA:users_max#$HalfBlue", "AREA:users_min#$Canvas", "LINE1:users_avg#$FullBlue:Users", 'GPRINT:users_min:MIN:%4.1lf Min,', 'GPRINT:users_avg:AVERAGE:%4.1lf Average,', 'GPRINT:users_max:MAX:%4.1lf Max,', 'GPRINT:users_avg:LAST:%4.1lf Last\l'); $GraphDefs['voltage'] = array( '-v', 'Voltage', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Voltage", 'GPRINT:min:MIN:%5.1lf%sV Min,', 'GPRINT:avg:AVERAGE:%5.1lf%sV Avg,', 'GPRINT:max:MAX:%5.1lf%sV Max,', 'GPRINT:avg:LAST:%5.1lf%sV Last\l'); $GraphDefs['vmpage_action'] = array( '-v', 'Actions', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Action", 'GPRINT:min:MIN:%5.1lf%sV Min,', 'GPRINT:avg:AVERAGE:%5.1lf%sV Avg,', 'GPRINT:max:MAX:%5.1lf%sV Max,', 'GPRINT:avg:LAST:%5.1lf%sV Last\l'); $GraphDefs['vmpage_faults'] = $GraphDefs['ps_pagefaults']; $GraphDefs['vmpage_io'] = array( '-v', 'Bytes/s', 'DEF:out_min={file}:out:MIN', 'DEF:out_avg={file}:out:AVERAGE', 'DEF:out_max={file}:out:MAX', 'DEF:inc_min={file}:in:MIN', 'DEF:inc_avg={file}:in:AVERAGE', 'DEF:inc_max={file}:in:MAX', 'CDEF:overlap=out_avg,inc_avg,GT,inc_avg,out_avg,IF', 'CDEF:mytime=out_avg,TIME,TIME,IF', 'CDEF:sample_len_raw=mytime,PREV(mytime),-', 'CDEF:sample_len=sample_len_raw,UN,0,sample_len_raw,IF', 'CDEF:out_avg_sample=out_avg,UN,0,out_avg,IF,sample_len,*', 'CDEF:out_avg_sum=PREV,UN,0,PREV,IF,out_avg_sample,+', 'CDEF:inc_avg_sample=inc_avg,UN,0,inc_avg,IF,sample_len,*', 'CDEF:inc_avg_sum=PREV,UN,0,PREV,IF,inc_avg_sample,+', "AREA:out_avg#$HalfGreen", "AREA:inc_avg#$HalfBlue", "AREA:overlap#$HalfBlueGreen", "LINE1:out_avg#$FullGreen:Written", 'GPRINT:out_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:out_max:MAX:%5.1lf%s Max,', 'GPRINT:out_avg:LAST:%5.1lf%s Last', 'GPRINT:out_avg_sum:LAST:(ca. %5.1lf%sB Total)\l', "LINE1:inc_avg#$FullBlue:Read ", 'GPRINT:inc_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:inc_max:MAX:%5.1lf%s Max,', 'GPRINT:inc_avg:LAST:%5.1lf%s Last', 'GPRINT:inc_avg_sum:LAST:(ca. %5.1lf%sB Total)\l'); $GraphDefs['vmpage_number'] = array( '-v', 'Count', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:avg#$HalfBlue", "LINE1:avg#$FullBlue:Count", 'GPRINT:min:MIN:%5.1lf%s Min,', 'GPRINT:avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:max:MAX:%5.1lf%s Max,', 'GPRINT:avg:LAST:%5.1lf%s Last\l'); $GraphDefs['vs_threads'] = array( "DEF:total_avg={file}:total:AVERAGE", "DEF:total_min={file}:total:MIN", "DEF:total_max={file}:total:MAX", "DEF:running_avg={file}:running:AVERAGE", "DEF:running_min={file}:running:MIN", "DEF:running_max={file}:running:MAX", "DEF:uninterruptible_avg={file}:uninterruptible:AVERAGE", "DEF:uninterruptible_min={file}:uninterruptible:MIN", "DEF:uninterruptible_max={file}:uninterruptible:MAX", "DEF:onhold_avg={file}:onhold:AVERAGE", "DEF:onhold_min={file}:onhold:MIN", "DEF:onhold_max={file}:onhold:MAX", "LINE1:total_avg#$FullYellow:Total ", 'GPRINT:total_min:MIN:%5.1lf Min,', 'GPRINT:total_avg:AVERAGE:%5.1lf Avg.,', 'GPRINT:total_max:MAX:%5.1lf Max,', 'GPRINT:total_avg:LAST:%5.1lf Last\l', "LINE1:running_avg#$FullRed:Running ", 'GPRINT:running_min:MIN:%5.1lf Min,', 'GPRINT:running_avg:AVERAGE:%5.1lf Avg.,', 'GPRINT:running_max:MAX:%5.1lf Max,', 'GPRINT:running_avg:LAST:%5.1lf Last\l', "LINE1:uninterruptible_avg#$FullGreen:Unintr ", 'GPRINT:uninterruptible_min:MIN:%5.1lf Min,', 'GPRINT:uninterruptible_avg:AVERAGE:%5.1lf Avg.,', 'GPRINT:uninterruptible_max:MAX:%5.1lf Max,', 'GPRINT:uninterruptible_avg:LAST:%5.1lf Last\l', "LINE1:onhold_avg#$FullBlue:Onhold ", 'GPRINT:onhold_min:MIN:%5.1lf Min,', 'GPRINT:onhold_avg:AVERAGE:%5.1lf Avg.,', 'GPRINT:onhold_max:MAX:%5.1lf Max,', 'GPRINT:onhold_avg:LAST:%5.1lf Last\l'); $GraphDefs['vs_memory'] = array( 'DEF:vm_avg={file}:vm:AVERAGE', 'DEF:vm_min={file}:vm:MIN', 'DEF:vm_max={file}:vm:MAX', 'DEF:vml_avg={file}:vml:AVERAGE', 'DEF:vml_min={file}:vml:MIN', 'DEF:vml_max={file}:vml:MAX', 'DEF:rss_avg={file}:rss:AVERAGE', 'DEF:rss_min={file}:rss:MIN', 'DEF:rss_max={file}:rss:MAX', 'DEF:anon_avg={file}:anon:AVERAGE', 'DEF:anon_min={file}:anon:MIN', 'DEF:anon_max={file}:anon:MAX', "LINE1:vm_avg#$FullYellow:VM ", 'GPRINT:vm_min:MIN:%5.1lf%s Min,', 'GPRINT:vm_avg:AVERAGE:%5.1lf%s Avg.,', 'GPRINT:vm_max:MAX:%5.1lf%s Avg.,', 'GPRINT:vm_avg:LAST:%5.1lf%s Last\l', "LINE1:vml_avg#$FullRed:Locked ", 'GPRINT:vml_min:MIN:%5.1lf%s Min,', 'GPRINT:vml_avg:AVERAGE:%5.1lf%s Avg.,', 'GPRINT:vml_max:MAX:%5.1lf%s Avg.,', 'GPRINT:vml_avg:LAST:%5.1lf%s Last\l', "LINE1:rss_avg#$FullGreen:RSS ", 'GPRINT:rss_min:MIN:%5.1lf%s Min,', 'GPRINT:rss_avg:AVERAGE:%5.1lf%s Avg.,', 'GPRINT:rss_max:MAX:%5.1lf%s Avg.,', 'GPRINT:rss_avg:LAST:%5.1lf%s Last\l', "LINE1:anon_avg#$FullBlue:Anon. ", 'GPRINT:anon_min:MIN:%5.1lf%s Min,', 'GPRINT:anon_avg:AVERAGE:%5.1lf%s Avg.,', 'GPRINT:anon_max:MAX:%5.1lf%s Avg.,', 'GPRINT:anon_avg:LAST:%5.1lf%s Last\l'); $GraphDefs['vs_processes'] = array( '-v', 'Processes', 'DEF:proc_avg={file}:value:AVERAGE', 'DEF:proc_min={file}:value:MIN', 'DEF:proc_max={file}:value:MAX', "AREA:proc_max#$HalfBlue", "AREA:proc_min#$Canvas", "LINE1:proc_avg#$FullBlue:Processes", 'GPRINT:proc_min:MIN:%4.1lf Min,', 'GPRINT:proc_avg:AVERAGE:%4.1lf Avg.,', 'GPRINT:proc_max:MAX:%4.1lf Max,', 'GPRINT:proc_avg:LAST:%4.1lf Last\l'); $GraphDefs['if_multicast'] = $GraphDefs['ipt_packets']; $GraphDefs['if_tx_errors'] = $GraphDefs['if_rx_errors']; $MetaGraphDefs['files_count'] = 'meta_graph_files_count'; $MetaGraphDefs['files_size'] = 'meta_graph_files_size'; $MetaGraphDefs['cpu'] = 'meta_graph_cpu'; $MetaGraphDefs['if_rx_errors'] = 'meta_graph_if_rx_errors'; $MetaGraphDefs['if_tx_errors'] = 'meta_graph_if_rx_errors'; $MetaGraphDefs['memory'] = 'meta_graph_memory'; $MetaGraphDefs['vs_memory'] = 'meta_graph_vs_memory'; $MetaGraphDefs['vs_threads'] = 'meta_graph_vs_threads'; $MetaGraphDefs['nfs_procedure'] = 'meta_graph_nfs_procedure'; $MetaGraphDefs['ps_state'] = 'meta_graph_ps_state'; $MetaGraphDefs['swap'] = 'meta_graph_swap'; $MetaGraphDefs['apache_scoreboard'] = 'meta_graph_apache_scoreboard'; $MetaGraphDefs['mysql_commands'] = 'meta_graph_mysql_commands'; $MetaGraphDefs['mysql_handler'] = 'meta_graph_mysql_commands'; $MetaGraphDefs['tcp_connections'] = 'meta_graph_tcp_connections'; $MetaGraphDefs['dns_opcode'] = 'meta_graph_dns_event'; $MetaGraphDefs['dns_qtype'] = 'meta_graph_dns_event'; $MetaGraphDefs['dns_qtype_cached'] = 'meta_graph_dns_event'; $MetaGraphDefs['dns_rcode'] = 'meta_graph_dns_event'; $MetaGraphDefs['dns_request'] = 'meta_graph_dns_event'; $MetaGraphDefs['dns_resolver'] = 'meta_graph_dns_event'; $MetaGraphDefs['dns_update'] = 'meta_graph_dns_event'; $MetaGraphDefs['dns_zops'] = 'meta_graph_dns_event'; $MetaGraphDefs['dns_response'] = 'meta_graph_dns_event'; $MetaGraphDefs['dns_query'] = 'meta_graph_dns_event'; $MetaGraphDefs['dns_reject'] = 'meta_graph_dns_event'; $MetaGraphDefs['dns_notify'] = 'meta_graph_dns_event'; $MetaGraphDefs['dns_transfer'] = 'meta_graph_dns_event'; if (function_exists('load_graph_definitions_local')) load_graph_definitions_local($logarithmic, $tinylegend); if ($logarithmic) foreach ($GraphDefs as &$GraphDef) array_unshift($GraphDef, '-o'); if ($tinylegend) foreach ($GraphDefs as &$GraphDef) for ($i = count($GraphDef)-1; $i >=0; $i--) if (strncmp('GPRINT:', $GraphDef[$i], 7) == 0) unset($GraphDef[$i]); } function meta_graph_files_count($host, $plugin, $plugin_instance, $type, $type_instances, $opts = array()) { global $config; $sources = array(); $title = "$host/$plugin".(!is_null($plugin_instance) ? "-$plugin_instance" : '')."/$type"; if (!isset($opts['title'])) $opts['title'] = $title; $opts['rrd_opts'] = array('-v', 'Mails'); $files = array(); $opts['colors'] = array( 'incoming' => '00e000', 'active' => 'a0e000', 'deferred' => 'a00050' ); $type_instances = array('incoming', 'active', 'deferred'); while (list($k, $inst) = each($type_instances)) { $file = ''; foreach ($config['datadirs'] as $datadir) if (is_file($datadir.'/'.$title.'-'.$inst.'.rrd')) { $file = $datadir.'/'.$title.'-'.$inst.'.rrd'; break; } if ($file == '') continue; $sources[] = array('name'=>$inst, 'file'=>$file); } return collectd_draw_meta_stack($opts, $sources); } function meta_graph_files_size($host, $plugin, $plugin_instance, $type, $type_instances, $opts = array()) { global $config; $sources = array(); $title = "$host/$plugin".(!is_null($plugin_instance) ? "-$plugin_instance" : '')."/$type"; if (!isset($opts['title'])) $opts['title'] = $title; $opts['rrd_opts'] = array('-v', 'Bytes'); $files = array(); $opts['colors'] = array( 'incoming' => '00e000', 'active' => 'a0e000', 'deferred' => 'a00050' ); $type_instances = array('incoming', 'active', 'deferred'); while (list($k, $inst) = each($type_instances)) { $file = ''; foreach ($config['datadirs'] as $datadir) if (is_file($datadir.'/'.$title.'-'.$inst.'.rrd')) { $file = $datadir.'/'.$title.'-'.$inst.'.rrd'; break; } if ($file == '') continue; $sources[] = array('name'=>$inst, 'file'=>$file); } return collectd_draw_meta_stack($opts, $sources); } function meta_graph_cpu($host, $plugin, $plugin_instance, $type, $type_instances, $opts = array()) { global $config; $sources = array(); $title = "$host/$plugin".(!is_null($plugin_instance) ? "-$plugin_instance" : '')."/$type"; if (!isset($opts['title'])) $opts['title'] = $title; $opts['rrd_opts'] = array('-v', 'Percent', '-r', '-u', '100'); $files = array(); $opts['colors'] = array( 'idle' => 'ffffff', 'nice' => '00e000', 'user' => '0000ff', 'wait' => 'ffb000', 'system' => 'ff0000', 'softirq' => 'ff00ff', 'interrupt' => 'a000a0', 'steal' => '000000' ); $type_instances = array('idle', 'wait', 'nice', 'user', 'system', 'softirq', 'interrupt', 'steal'); while (list($k, $inst) = each($type_instances)) { $file = ''; foreach ($config['datadirs'] as $datadir) if (is_file($datadir.'/'.$title.'-'.$inst.'.rrd')) { $file = $datadir.'/'.$title.'-'.$inst.'.rrd'; break; } if ($file == '') continue; $sources[] = array('name'=>$inst, 'file'=>$file); } return collectd_draw_meta_stack($opts, $sources); } function meta_graph_memory($host, $plugin, $plugin_instance, $type, $type_instances, $opts = array()) { global $config; $sources = array(); $title = "$host/$plugin".(!is_null($plugin_instance) ? "-$plugin_instance" : '')."/$type"; if (!isset($opts['title'])) $opts['title'] = $title; $opts['number_format'] = '%5.1lf%s'; $opts['rrd_opts'] = array('-b', '1024', '-v', 'Bytes'); $files = array(); $opts['colors'] = array( // Linux - System memoery 'free' => '00e000', 'cached' => '0000ff', 'buffered' => 'ffb000', 'used' => 'ff0000', // Bind - Server memory 'TotalUse' => '00e000', 'InUse' => 'ff0000', 'BlockSize' => '8888dd', 'ContextSize' => '444499', 'Lost' => '222222' ); $type_instances = array('free', 'cached', 'buffered', 'used', 'TotalUse', 'InUse', 'BlockSize', 'ContextSize', 'Lost'); while (list($k, $inst) = each($type_instances)) { $file = ''; foreach ($config['datadirs'] as $datadir) if (is_file($datadir.'/'.$title.'-'.$inst.'.rrd')) { $file = $datadir.'/'.$title.'-'.$inst.'.rrd'; break; } if ($file == '') continue; $sources[] = array('name'=>$inst, 'file'=>$file); } if ($plugin == 'bind') return collectd_draw_meta_line($opts, $sources); else return collectd_draw_meta_stack($opts, $sources); } function meta_graph_vs_threads($host, $plugin, $plugin_instance, $type, $type_instances, $opts = array()) { global $config; $sources = array(); $title = "$host/$plugin".(!is_null($plugin_instance) ? "-$plugin_instance" : '')."/$type"; if (!isset($opts['title'])) $opts['title'] = $title; $opts['number_format'] = '%5.1lf%s'; $opts['rrd_opts'] = array('-v', 'Threads'); $files = array(); $opts['colors'] = array( 'total' => 'F0A000', 'running' => 'FF0000', 'onhold' => '00E000', 'uninterruptable' => '0000FF' ); $type_instances = array('total', 'running', 'onhold', 'uninterruptable'); while (list($k, $inst) = each($type_instances)) { $file = ''; foreach ($config['datadirs'] as $datadir) if (is_file($datadir.'/'.$title.'-'.$inst.'.rrd')) { $file = $datadir.'/'.$title.'-'.$inst.'.rrd'; break; } if ($file == '') continue; $sources[] = array('name'=>$inst, 'file'=>$file); } return collectd_draw_meta_line($opts, $sources); } function meta_graph_vs_memory($host, $plugin, $plugin_instance, $type, $type_instances, $opts = array()) { global $config; $sources = array(); $title = "$host/$plugin".(!is_null($plugin_instance) ? "-$plugin_instance" : '')."/$type"; if (!isset($opts['title'])) $opts['title'] = $title; $opts['number_format'] = '%5.1lf%s'; $opts['rrd_opts'] = array('-b', '1024', '-v', 'Bytes'); $files = array(); $opts['colors'] = array( 'vm' => 'F0A000', 'vml' => 'FF0000', 'rss' => '00E000', 'anon' => '0000FF' ); $type_instances = array('anon', 'rss', 'vml', 'vm'); while (list($k, $inst) = each($type_instances)) { $file = ''; foreach ($config['datadirs'] as $datadir) if (is_file($datadir.'/'.$title.'-'.$inst.'.rrd')) { $file = $datadir.'/'.$title.'-'.$inst.'.rrd'; break; } if ($file == '') continue; $sources[] = array('name'=>$inst, 'file'=>$file); } return collectd_draw_meta_line($opts, $sources); } function meta_graph_if_rx_errors($host, $plugin, $plugin_instance, $type, $type_instances, $opts = array()) { global $config; $sources = array(); $title = "$host/$plugin".(!is_null($plugin_instance) ? "-$plugin_instance" : '')."/$type"; if (!isset($opts['title'])) $opts['title'] = $title; $opts['number_format'] = '%5.2lf'; $opts['rrd_opts'] = array('-v', 'Errors/s'); $files = array(); while (list($k, $inst) = each($type_instances)) { $file = ''; foreach ($config['datadirs'] as $datadir) if (is_file($datadir.'/'.$title.'-'.$inst.'.rrd')) { $file = $datadir.'/'.$title.'-'.$inst.'.rrd'; break; } if ($file == '') continue; $sources[] = array('name'=>$inst, 'file'=>$file); } return collectd_draw_meta_stack($opts, $sources); } function meta_graph_mysql_commands($host, $plugin, $plugin_instance, $type, $type_instances, $opts = array()) { global $config; $sources = array(); $title = "$host/$plugin".(!is_null($plugin_instance) ? "-$plugin_instance" : '')."/$type"; if (!isset($opts['title'])) $opts['title'] = $title; $opts['rrd_opts'] = array('-v', 'Issues/s'); $opts['number_format'] = '%5.2lf'; $files = array(); while (list($k, $inst) = each($type_instances)) { $file = ''; foreach ($config['datadirs'] as $datadir) if (is_file($datadir.'/'.$title.'-'.$inst.'.rrd')) { $file = $datadir.'/'.$title.'-'.$inst.'.rrd'; break; } if ($file == '') continue; $sources[] = array('name'=>$inst, 'file'=>$file); } return collectd_draw_meta_stack($opts, $sources); } function meta_graph_nfs_procedure($host, $plugin, $plugin_instance, $type, $type_instances, $opts = array()) { global $config; $sources = array(); $title = "$host/$plugin".(!is_null($plugin_instance) ? "-$plugin_instance" : '')."/$type"; if (!isset($opts['title'])) $opts['title'] = $title; $opts['number_format'] = '%5.1lf%s'; $opts['rrd_opts'] = array('-v', 'Ops/s'); $files = array(); while (list($k, $inst) = each($type_instances)) { $file = ''; foreach ($config['datadirs'] as $datadir) if (is_file($datadir.'/'.$title.'-'.$inst.'.rrd')) { $file = $datadir.'/'.$title.'-'.$inst.'.rrd'; break; } if ($file == '') continue; $sources[] = array('name'=>$inst, 'file'=>$file); } return collectd_draw_meta_stack($opts, $sources); } function meta_graph_ps_state($host, $plugin, $plugin_instance, $type, $type_instances, $opts = array()) { global $config; $sources = array(); $title = "$host/$plugin".(!is_null($plugin_instance) ? "-$plugin_instance" : '')."/$type"; if (!isset($opts['title'])) $opts['title'] = $title; $opts['rrd_opts'] = array('-v', 'Processes'); $files = array(); $opts['colors'] = array( 'running' => '00e000', 'sleeping' => '0000ff', 'paging' => 'ffb000', 'zombies' => 'ff0000', 'blocked' => 'ff00ff', 'stopped' => 'a000a0' ); $type_instances = array('paging', 'blocked', 'zombies', 'stopped', 'running', 'sleeping'); while (list($k, $inst) = each($type_instances)) { $file = ''; foreach ($config['datadirs'] as $datadir) if (is_file($datadir.'/'.$title.'-'.$inst.'.rrd')) { $file = $datadir.'/'.$title.'-'.$inst.'.rrd'; break; } if ($file == '') continue; $sources[] = array('name'=>$inst, 'file'=>$file); } return collectd_draw_meta_stack($opts, $sources); } function meta_graph_swap($host, $plugin, $plugin_instance, $type, $type_instances, $opts = array()) { global $config; $sources = array(); $title = "$host/$plugin".(!is_null($plugin_instance) ? "-$plugin_instance" : '')."/$type"; if (!isset($opts['title'])) $opts['title'] = $title; $opts['number_format'] = '%5.1lf%s'; $opts['rrd_opts'] = array('-b', '1024', '-v', 'Bytes'); $files = array(); $opts['colors'] = array( 'free' => '00e000', 'cached' => '0000ff', 'used' => 'ff0000' ); $type_instances = array('free', 'cached', 'used'); while (list($k, $inst) = each($type_instances)) { $file = ''; foreach ($config['datadirs'] as $datadir) if (is_file($datadir.'/'.$title.'-'.$inst.'.rrd')) { $file = $datadir.'/'.$title.'-'.$inst.'.rrd'; break; } if ($file == '') continue; $sources[] = array('name'=>$inst, 'file'=>$file); } return collectd_draw_meta_stack($opts, $sources); } function meta_graph_apache_scoreboard($host, $plugin, $plugin_instance, $type, $type_instances, $opts = array()) { global $config; $sources = array(); $title = "$host/$plugin".(!is_null($plugin_instance) ? "-$plugin_instance" : '')."/$type"; if (!isset($opts['title'])) $opts['title'] = $title; $opts['number_format'] = '%6.2lf%s'; $opts['rrd_opts'] = array('-v', 'Processes'); $files = array(); $opts['colors'] = array( 'open' => '00e000', 'waiting' => '0000ff', 'starting' => 'a00000', 'reading' => 'ff0000', 'sending' => '00ff00', 'keepalive' => 'f000f0', 'dnslookup' => '00a000', 'logging' => '008080', 'closing' => 'a000a0', 'finishing' => '000080', 'idle_cleanup' => '000000', ); $type_instances = array(/* 'open',*/ 'waiting', 'starting', 'reading', 'sending', 'keepalive', 'dnslookup', 'logging', 'closing', 'finishing', 'idle_cleanup'); while (list($k, $inst) = each($type_instances)) { $file = ''; foreach ($config['datadirs'] as $datadir) if (is_file($datadir.'/'.$title.'-'.$inst.'.rrd')) { $file = $datadir.'/'.$title.'-'.$inst.'.rrd'; break; } if ($file == '') continue; $sources[] = array('name'=>$inst, 'file'=>$file, 'ds'=>'value'); } return collectd_draw_meta_stack($opts, $sources); } function meta_graph_tcp_connections($host, $plugin, $plugin_instance, $type, $type_instances, $opts = array()) { global $config; $sources = array(); $title = "$host/$plugin".(!is_null($plugin_instance) ? "-$plugin_instance" : '')."/$type"; if (!isset($opts['title'])) $opts['title'] = $title; $opts['number_format'] = '%6.2lf%s'; $opts['rrd_opts'] = array('-v', 'Connections'); $files = array(); $opts['colors'] = array( 'ESTABLISHED' => '00e000', 'SYN_SENT' => '00e0ff', 'SYN_RECV' => '00e0a0', 'FIN_WAIT1' => 'f000f0', 'FIN_WAIT2' => 'f000a0', 'TIME_WAIT' => 'ffb000', 'CLOSE' => '0000f0', 'CLOSE_WAIT' => '0000a0', 'LAST_ACK' => '000080', 'LISTEN' => 'ff0000', 'CLOSING' => '000000' ); $type_instances = array('ESTABLISHED', 'SYN_SENT', 'SYN_RECV', 'FIN_WAIT1', 'FIN_WAIT2', 'TIME_WAIT', 'CLOSE', 'CLOSE_WAIT', 'LAST_ACK', 'CLOSING', 'LISTEN'); while (list($k, $inst) = each($type_instances)) { $file = ''; foreach ($config['datadirs'] as $datadir) if (is_file($datadir.'/'.$title.'-'.$inst.'.rrd')) { $file = $datadir.'/'.$title.'-'.$inst.'.rrd'; break; } if ($file == '') continue; $sources[] = array('name'=>$inst, 'file'=>$file, 'ds'=>'value'); } return collectd_draw_meta_stack($opts, $sources); } function meta_graph_dns_event($host, $plugin, $plugin_instance, $type, $type_instances, $opts = array()) { global $config; $sources = array(); $title = "$host/$plugin".(!is_null($plugin_instance) ? "-$plugin_instance" : '')."/$type"; if (!isset($opts['title'])) $opts['title'] = $title; $opts['rrd_opts'] = array('-v', 'Events', '-r', '-l', '0'); $files = array(); // $opts['colors'] = array( // ); // $type_instances = array('IQUERY', 'NOTIFY'); while (list($k, $inst) = each($type_instances)) { $file = ''; $title = $opts['title']; foreach ($config['datadirs'] as $datadir) if (is_file($datadir.'/'.$title.'-'.$inst.'.rrd')) { $file = $datadir.'/'.$title.'-'.$inst.'.rrd'; break; } if ($file == '') continue; $sources[] = array('name'=>$inst, 'file'=>$file); } return collectd_draw_meta_stack($opts, $sources); } ?> collectd-5.4.0/contrib/php-collection/PaxHeaders.11991/graph.php0000644037772200116100000000013212204120331022535 xustar000000000000000030 mtime=1376821465.057973183 30 atime=1376821477.202167674 30 ctime=1376821742.446407696 collectd-5.4.0/contrib/php-collection/graph.php0000644037772200116100000001771712204120331021316 0ustar00octoeng00000000000000 * * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. */ error_reporting(E_ALL | E_NOTICE | E_WARNING); require('config.php'); require('functions.php'); require('definitions.php'); function makeTextBlock($text, $fontfile, $fontsize, $width) { // TODO: handle explicit line-break! $words = explode(' ', $text); $lines = array($words[0]); $currentLine = 0; foreach ($words as $word) { $lineSize = imagettfbbox($fontsize, 0, $fontfile, $lines[$currentLine] . ' ' . $word); if($lineSize[2] - $lineSize[0] < $width) { $lines[$currentLine] .= ' ' . $word; } else { $currentLine++; $lines[$currentLine] = $word; } } error_log(sprintf('Handles message "%s", %d words => %d/%d lines', $text, count($words), $currentLine, count($lines))); return implode("\n", $lines); } /** * No RRD files found that could match request * @code HTTP error code * @code_msg Short text description of HTTP error code * @title Title for fake RRD graph * @msg Complete error message to display in place of graph content */ function error($code, $code_msg, $title, $msg) { global $config; header(sprintf("HTTP/1.0 %d %s", $code, $code_msg)); header("Pragma: no-cache"); header("Expires: Mon, 01 Jan 2008 00:00:00 CET"); header("Content-Type: image/png"); $w = $config['rrd_width']+81; $h = $config['rrd_height']+79; $png = imagecreate($w, $h); $c_bkgnd = imagecolorallocate($png, 240, 240, 240); $c_fgnd = imagecolorallocate($png, 255, 255, 255); $c_blt = imagecolorallocate($png, 208, 208, 208); $c_brb = imagecolorallocate($png, 160, 160, 160); $c_grln = imagecolorallocate($png, 114, 114, 114); $c_grarr = imagecolorallocate($png, 128, 32, 32); $c_txt = imagecolorallocate($png, 0, 0, 0); $c_etxt = imagecolorallocate($png, 64, 0, 0); if (function_exists('imageantialias')) imageantialias($png, true); imagefilledrectangle($png, 0, 0, $w, $h, $c_bkgnd); imagefilledrectangle($png, 51, 33, $w-31, $h-47, $c_fgnd); imageline($png, 51, 30, 51, $h-43, $c_grln); imageline($png, 48, $h-46, $w-28, $h-46, $c_grln); imagefilledpolygon($png, array(49, 30, 51, 26, 53, 30), 3, $c_grarr); imagefilledpolygon($png, array($w-28, $h-48, $w-24, $h-46, $w-28, $h-44), 3, $c_grarr); imageline($png, 0, 0, $w, 0, $c_blt); imageline($png, 0, 1, $w, 1, $c_blt); imageline($png, 0, 0, 0, $h, $c_blt); imageline($png, 1, 0, 1, $h, $c_blt); imageline($png, $w-1, 0, $w-1, $h, $c_brb); imageline($png, $w-2, 1, $w-2, $h, $c_brb); imageline($png, 1, $h-2, $w, $h-2, $c_brb); imageline($png, 0, $h-1, $w, $h-1, $c_brb); imagestring($png, 4, ceil(($w-strlen($title)*imagefontwidth(4)) / 2), 10, $title, $c_txt); imagestring($png, 5, 60, 35, sprintf('%s [%d]', $code_msg, $code), $c_etxt); if (function_exists('imagettfbbox') && is_file($config['error_font'])) { // Detailled error message $fmt_msg = makeTextBlock($msg, $errorfont, 10, $w-86); $fmtbox = imagettfbbox(12, 0, $errorfont, $fmt_msg); imagettftext($png, 10, 0, 55, 35+3+imagefontwidth(5)-$fmtbox[7]+$fmtbox[1], $c_txt, $errorfont, $fmt_msg); } else { imagestring($png, 4, 53, 35+6+imagefontwidth(5), $msg, $c_txt); } imagepng($png); imagedestroy($png); } /** * No RRD files found that could match request */ function error404($title, $msg) { return error(404, "Not found", $title, $msg); } /** * Incomplete / invalid request */ function error400($title, $msg) { return error(400, "Bad request", $title, $msg); } /** * Incomplete / invalid request */ function error500($title, $msg) { return error(500, "Internal error", $title, $msg); } // Process input arguments $host = read_var('host', $_GET, null); if (is_null($host)) return error400("?/?-?/?", "Missing host name"); else if (!is_string($host)) return error400("?/?-?/?", "Expecting exactly 1 host name"); else if (strlen($host) == 0) return error400("?/?-?/?", "Host name may not be blank"); $plugin = read_var('plugin', $_GET, null); if (is_null($plugin)) return error400($host.'/?-?/?', "Missing plugin name"); else if (!is_string($plugin)) return error400($host.'/?-?/?', "Plugin name must be a string"); else if (strlen($plugin) == 0) return error400($host.'/?-?/?', "Plugin name may not be blank"); $pinst = read_var('plugin_instance', $_GET, ''); if (!is_string($pinst)) return error400($host.'/'.$plugin.'-?/?', "Plugin instance name must be a string"); $type = read_var('type', $_GET, ''); if (is_null($type)) return error400($host.'/'.$plugin.(strlen($pinst) ? '-'.$pinst : '').'/?', "Missing type name"); else if (!is_string($type)) return error400($host.'/'.$plugin.(strlen($pinst) ? '-'.$pinst : '').'/?', "Type name must be a string"); else if (strlen($type) == 0) return error400($host.'/'.$plugin.(strlen($pinst) ? '-'.$pinst : '').'/?', "Type name may not be blank"); $tinst = read_var('type_instance', $_GET, ''); $graph_identifier = $host.'/'.$plugin.(strlen($pinst) ? '-'.$pinst : '').'/'.$type.(strlen($tinst) ? '-'.$tinst : '-*'); $timespan = read_var('timespan', $_GET, $config['timespan'][0]['name']); $timespan_ok = false; foreach ($config['timespan'] as &$ts) if ($ts['name'] == $timespan) $timespan_ok = true; if (!$timespan_ok) return error400($graph_identifier, "Unknown timespan requested"); $logscale = (boolean)read_var('logarithmic', $_GET, false); $tinylegend = (boolean)read_var('tinylegend', $_GET, false); // Check that at least 1 RRD exists for the specified request $all_tinst = collectd_list_types($host, $plugin, $pinst, $type); if (count($all_tinst) == 0) return error404($graph_identifier, "No rrd file found for graphing"); // Now that we are read, do the bulk work load_graph_definitions($logscale, $tinylegend); $pinst = strlen($pinst) == 0 ? null : $pinst; $tinst = strlen($tinst) == 0 ? null : $tinst; $opts = array(); $opts['timespan'] = $timespan; if ($logscale) $opts['logarithmic'] = 1; if ($tinylegend) $opts['tinylegend'] = 1; $rrd_cmd = false; if ((is_null($tinst) || $tinst == '@merge') && isset($MetaGraphDefs[$type])) { $identifiers = array(); foreach ($all_tinst as &$atinst) $identifiers[] = collectd_identifier($host, $plugin, is_null($pinst) ? '' : $pinst, $type, $atinst); collectd_flush($identifiers); $rrd_cmd = $MetaGraphDefs[$type]($host, $plugin, $pinst, $type, $all_tinst, $opts); } else { if (!in_array(is_null($tinst) ? '' : $tinst, $all_tinst)) return error404($host.'/'.$plugin.(!is_null($pinst) ? '-'.$pinst : '').'/'.$type.(!is_null($tinst) ? '-'.$tinst : ''), "No rrd file found for graphing"); collectd_flush(collectd_identifier($host, $plugin, is_null($pinst) ? '' : $pinst, $type, is_null($tinst) ? '' : $tinst)); if (isset($GraphDefs[$type])) $rrd_cmd = collectd_draw_generic($timespan, $host, $plugin, $pinst, $type, $tinst); else $rrd_cmd = collectd_draw_rrd($host, $plugin, $pinst, $type, $tinst); } if (isset($_GET['debug'])) { header('Content-Type: text/plain; charset=utf-8'); printf("Would have executed:\n%s\n", $rrd_cmd); return 0; } else if ($rrd_cmd) { header('Content-Type: image/png'); header('Cache-Control: max-age=60'); $rt = 0; passthru($rrd_cmd, $rt); if ($rt != 0) return error500($graph_identifier, "RRD failed to generate the graph: ".$rt); return $rt; } else { return error500($graph_identifier, "Failed to tell RRD how to generate the graph"); } ?> collectd-5.4.0/contrib/php-collection/PaxHeaders.11991/browser.js0000644037772200116100000000013212204120331022744 xustar000000000000000030 mtime=1376821465.053973118 30 atime=1376821477.202167674 30 ctime=1376821742.446407696 collectd-5.4.0/contrib/php-collection/browser.js0000644037772200116100000007112412204120331021515 0ustar00octoeng00000000000000/* * Copyright (C) 2009 Bruno Prémont * * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // Toggle visibility of a div function toggleDiv(divID) { var div = document.getElementById(divID); var label = document.getElementById(divID+'_sw'); var label_txt = null; if (div) { if (div.style.display == 'none') { div.style.display = 'block'; label_txt = 'Hide'; } else { div.style.display = 'none'; label_txt = 'Show'; } } if (label_txt && label) { var childCnt = label.childNodes.length; while (childCnt > 0) label.removeChild(label.childNodes[--childCnt]); label.appendChild(document.createTextNode(label_txt)); } GraphPositionToolbox(null); } var req = null; // DHTML helper code to asynchronous loading of content function loadXMLDoc(url, query) { if (window.XMLHttpRequest) { req = new XMLHttpRequest(); req.onreadystatechange = processReqChange; req.open('POST', url, true); req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); req.send(query); } else if (window.ActiveXObject) { req = new ActiveXObject("Microsoft.XMLHTTP"); if (req) { req.onreadystatechange = processReqChange; req.open('POST', url, true); req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); req.send(query); } } } // DHTML new-content dispatcher function processReqChange(evt) { if (req.readyState == 4) { if (req.status == 200) { var response = req.responseXML.documentElement; var method = response.getElementsByTagName('method')[0].firstChild.data; var result = response.getElementsByTagName('result')[0]; req = null; eval(method + '(result)'); } } } // Update contents of a HTML for (my $i = 0; $i < @hosts; $i++) { my $host = encode_entities ($hosts[$i]); my $selected = defined ($selected_hosts{$hosts[$i]}) ? ' selected="selected"' : ''; print qq(\t \n); } print "\t\n"; if (keys %selected_hosts) { my $all_plugins = _find_files_for_hosts (keys %selected_hosts); my %selected_plugins = map { $_ => 1 } (param ('plugin')); print qq(\t\n"; } # if (keys %selected_hosts) print qq(\t HTML } sub print_header { print < collection.cgi, Version 2 HEAD print_selector (); } # print_header sub print_footer { print < FOOT } # print_footer sub main { read_config (); validate_args (); if (defined ($Args->{'host'}) && defined ($Args->{'plugin'}) && defined ($Args->{'type'}) && ($Args->{'action'} eq 'show_graph')) { $| = 1; print STDOUT header (-Content_Type => 'image/png'); action_show_graph ($Args->{'host'}, $Args->{'plugin'}, $Args->{'plugin_instance'}, $Args->{'type'}, $Args->{'type_instance'}); return (0); } print_header (); if (!$Args->{'host'}) { list_hosts (); } elsif (!$Args->{'plugin'}) { action_show_host ($Args->{'host'}); } elsif (!$Args->{'type'}) { action_show_plugin ($Args->{'plugin'}, $Args->{'plugin_instance'}); } else { action_show_type ($Args->{'host'}, $Args->{'plugin'}, $Args->{'plugin_instance'}, $Args->{'type'}, $Args->{'type_instance'}); } print_footer (); return (0); } sub load_graph_definitions { my $Canvas = 'FFFFFF'; my $FullRed = 'FF0000'; my $FullGreen = '00E000'; my $FullBlue = '0000FF'; my $FullYellow = 'F0A000'; my $FullCyan = '00A0FF'; my $FullMagenta= 'A000FF'; my $HalfRed = 'F7B7B7'; my $HalfGreen = 'B7EFB7'; my $HalfBlue = 'B7B7F7'; my $HalfYellow = 'F3DFB7'; my $HalfCyan = 'B7DFF7'; my $HalfMagenta= 'DFB7F7'; my $HalfBlueGreen = '89B3C9'; $GraphDefs = { apache_bytes => ['DEF:min_raw={file}:count:MIN', 'DEF:avg_raw={file}:count:AVERAGE', 'DEF:max_raw={file}:count:MAX', 'CDEF:min=min_raw,8,*', 'CDEF:avg=avg_raw,8,*', 'CDEF:max=max_raw,8,*', 'CDEF:mytime=avg_raw,TIME,TIME,IF', 'CDEF:sample_len_raw=mytime,PREV(mytime),-', 'CDEF:sample_len=sample_len_raw,UN,0,sample_len_raw,IF', 'CDEF:avg_sample=avg_raw,UN,0,avg_raw,IF,sample_len,*', 'CDEF:avg_sum=PREV,UN,0,PREV,IF,avg_sample,+', "AREA:avg#$HalfBlue", "LINE1:avg#$FullBlue:Bit/s", 'GPRINT:min:MIN:%5.1lf%s Min,', 'GPRINT:avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:max:MAX:%5.1lf%s Max,', 'GPRINT:avg:LAST:%5.1lf%s Last', 'GPRINT:avg_sum:LAST:(ca. %5.1lf%sB Total)\l' ], apache_connections => ['DEF:min={file}:count:MIN', 'DEF:avg={file}:count:AVERAGE', 'DEF:max={file}:count:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Connections", 'GPRINT:min:MIN:%6.2lf Min,', 'GPRINT:avg:AVERAGE:%6.2lf Avg,', 'GPRINT:max:MAX:%6.2lf Max,', 'GPRINT:avg:LAST:%6.2lf Last' ], apache_idle_workers => ['DEF:min={file}:count:MIN', 'DEF:avg={file}:count:AVERAGE', 'DEF:max={file}:count:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Idle Workers", 'GPRINT:min:MIN:%6.2lf Min,', 'GPRINT:avg:AVERAGE:%6.2lf Avg,', 'GPRINT:max:MAX:%6.2lf Max,', 'GPRINT:avg:LAST:%6.2lf Last' ], apache_requests => ['DEF:min={file}:count:MIN', 'DEF:avg={file}:count:AVERAGE', 'DEF:max={file}:count:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Requests/s", 'GPRINT:min:MIN:%6.2lf Min,', 'GPRINT:avg:AVERAGE:%6.2lf Avg,', 'GPRINT:max:MAX:%6.2lf Max,', 'GPRINT:avg:LAST:%6.2lf Last' ], apache_scoreboard => ['DEF:min={file}:count:MIN', 'DEF:avg={file}:count:AVERAGE', 'DEF:max={file}:count:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Processes", 'GPRINT:min:MIN:%6.2lf Min,', 'GPRINT:avg:AVERAGE:%6.2lf Avg,', 'GPRINT:max:MAX:%6.2lf Max,', 'GPRINT:avg:LAST:%6.2lf Last' ], bitrate => ['-v', 'Bits/s', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Bits/s", 'GPRINT:min:MIN:%5.1lf%s Min,', 'GPRINT:avg:AVERAGE:%5.1lf%s Average,', 'GPRINT:max:MAX:%5.1lf%s Max,', 'GPRINT:avg:LAST:%5.1lf%s Last\l' ], charge => ['-v', 'Ah', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Charge", 'GPRINT:min:MIN:%5.1lf%sAh Min,', 'GPRINT:avg:AVERAGE:%5.1lf%sAh Avg,', 'GPRINT:max:MAX:%5.1lf%sAh Max,', 'GPRINT:avg:LAST:%5.1lf%sAh Last\l' ], connections => ['-v', 'Connections', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Connections", 'GPRINT:min:MIN:%4.1lf Min,', 'GPRINT:avg:AVERAGE:%4.1lf Avg,', 'GPRINT:max:MAX:%4.1lf Max,', 'GPRINT:avg:LAST:%4.1lf Last\l' ], cpu => ['-v', 'CPU load', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Percent", 'GPRINT:min:MIN:%6.2lf%% Min,', 'GPRINT:avg:AVERAGE:%6.2lf%% Avg,', 'GPRINT:max:MAX:%6.2lf%% Max,', 'GPRINT:avg:LAST:%6.2lf%% Last\l' ], current => ['-v', 'Ampere', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Current", 'GPRINT:min:MIN:%5.1lf%sA Min,', 'GPRINT:avg:AVERAGE:%5.1lf%sA Avg,', 'GPRINT:max:MAX:%5.1lf%sA Max,', 'GPRINT:avg:LAST:%5.1lf%sA Last\l' ], df => ['-v', 'Percent', '-l', '0', 'DEF:free_avg={file}:free:AVERAGE', 'DEF:free_min={file}:free:MIN', 'DEF:free_max={file}:free:MAX', 'DEF:used_avg={file}:used:AVERAGE', 'DEF:used_min={file}:used:MIN', 'DEF:used_max={file}:used:MAX', 'CDEF:total=free_avg,used_avg,+', 'CDEF:free_pct=100,free_avg,*,total,/', 'CDEF:used_pct=100,used_avg,*,total,/', 'CDEF:free_acc=free_pct,used_pct,+', 'CDEF:used_acc=used_pct', "AREA:free_acc#$HalfGreen", "AREA:used_acc#$HalfRed", "LINE1:free_acc#$FullGreen:Free", 'GPRINT:free_min:MIN:%5.1lf%sB Min,', 'GPRINT:free_avg:AVERAGE:%5.1lf%sB Avg,', 'GPRINT:free_max:MAX:%5.1lf%sB Max,', 'GPRINT:free_avg:LAST:%5.1lf%sB Last\l', "LINE1:used_acc#$FullRed:Used", 'GPRINT:used_min:MIN:%5.1lf%sB Min,', 'GPRINT:used_avg:AVERAGE:%5.1lf%sB Avg,', 'GPRINT:used_max:MAX:%5.1lf%sB Max,', 'GPRINT:used_avg:LAST:%5.1lf%sB Last\l' ], disk => [ 'DEF:rtime_avg={file}:rtime:AVERAGE', 'DEF:rtime_min={file}:rtime:MIN', 'DEF:rtime_max={file}:rtime:MAX', 'DEF:wtime_avg={file}:wtime:AVERAGE', 'DEF:wtime_min={file}:wtime:MIN', 'DEF:wtime_max={file}:wtime:MAX', 'CDEF:rtime_avg_ms=rtime_avg,1000,/', 'CDEF:rtime_min_ms=rtime_min,1000,/', 'CDEF:rtime_max_ms=rtime_max,1000,/', 'CDEF:wtime_avg_ms=wtime_avg,1000,/', 'CDEF:wtime_min_ms=wtime_min,1000,/', 'CDEF:wtime_max_ms=wtime_max,1000,/', 'CDEF:total_avg_ms=rtime_avg_ms,wtime_avg_ms,+', 'CDEF:total_min_ms=rtime_min_ms,wtime_min_ms,+', 'CDEF:total_max_ms=rtime_max_ms,wtime_max_ms,+', "AREA:total_max_ms#$HalfRed", "AREA:total_min_ms#$Canvas", "LINE1:wtime_avg_ms#$FullGreen:Write", 'GPRINT:wtime_min_ms:MIN:%5.1lf%s Min,', 'GPRINT:wtime_avg_ms:AVERAGE:%5.1lf%s Avg,', 'GPRINT:wtime_max_ms:MAX:%5.1lf%s Max,', 'GPRINT:wtime_avg_ms:LAST:%5.1lf%s Last\n', "LINE1:rtime_avg_ms#$FullBlue:Read ", 'GPRINT:rtime_min_ms:MIN:%5.1lf%s Min,', 'GPRINT:rtime_avg_ms:AVERAGE:%5.1lf%s Avg,', 'GPRINT:rtime_max_ms:MAX:%5.1lf%s Max,', 'GPRINT:rtime_avg_ms:LAST:%5.1lf%s Last\n', "LINE1:total_avg_ms#$FullRed:Total", 'GPRINT:total_min_ms:MIN:%5.1lf%s Min,', 'GPRINT:total_avg_ms:AVERAGE:%5.1lf%s Avg,', 'GPRINT:total_max_ms:MAX:%5.1lf%s Max,', 'GPRINT:total_avg_ms:LAST:%5.1lf%s Last' ], disk_octets => ['-v', 'Bytes/s', 'DEF:out_min={file}:write:MIN', 'DEF:out_avg={file}:write:AVERAGE', 'DEF:out_max={file}:write:MAX', 'DEF:inc_min={file}:read:MIN', 'DEF:inc_avg={file}:read:AVERAGE', 'DEF:inc_max={file}:read:MAX', 'CDEF:overlap=out_avg,inc_avg,GT,inc_avg,out_avg,IF', 'CDEF:mytime=out_avg,TIME,TIME,IF', 'CDEF:sample_len_raw=mytime,PREV(mytime),-', 'CDEF:sample_len=sample_len_raw,UN,0,sample_len_raw,IF', 'CDEF:out_avg_sample=out_avg,UN,0,out_avg,IF,sample_len,*', 'CDEF:out_avg_sum=PREV,UN,0,PREV,IF,out_avg_sample,+', 'CDEF:inc_avg_sample=inc_avg,UN,0,inc_avg,IF,sample_len,*', 'CDEF:inc_avg_sum=PREV,UN,0,PREV,IF,inc_avg_sample,+', "AREA:out_avg#$HalfGreen", "AREA:inc_avg#$HalfBlue", "AREA:overlap#$HalfBlueGreen", "LINE1:out_avg#$FullGreen:Written", 'GPRINT:out_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:out_max:MAX:%5.1lf%s Max,', 'GPRINT:out_avg:LAST:%5.1lf%s Last', 'GPRINT:out_avg_sum:LAST:(ca. %5.1lf%sB Total)\l', "LINE1:inc_avg#$FullBlue:Read ", 'GPRINT:inc_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:inc_max:MAX:%5.1lf%s Max,', 'GPRINT:inc_avg:LAST:%5.1lf%s Last', 'GPRINT:inc_avg_sum:LAST:(ca. %5.1lf%sB Total)\l' ], disk_merged => ['-v', 'Merged Ops/s', 'DEF:out_min={file}:write:MIN', 'DEF:out_avg={file}:write:AVERAGE', 'DEF:out_max={file}:write:MAX', 'DEF:inc_min={file}:read:MIN', 'DEF:inc_avg={file}:read:AVERAGE', 'DEF:inc_max={file}:read:MAX', 'CDEF:overlap=out_avg,inc_avg,GT,inc_avg,out_avg,IF', "AREA:out_avg#$HalfGreen", "AREA:inc_avg#$HalfBlue", "AREA:overlap#$HalfBlueGreen", "LINE1:out_avg#$FullGreen:Written", 'GPRINT:out_avg:AVERAGE:%6.2lf Avg,', 'GPRINT:out_max:MAX:%6.2lf Max,', 'GPRINT:out_avg:LAST:%6.2lf Last\l', "LINE1:inc_avg#$FullBlue:Read ", 'GPRINT:inc_avg:AVERAGE:%6.2lf Avg,', 'GPRINT:inc_max:MAX:%6.2lf Max,', 'GPRINT:inc_avg:LAST:%6.2lf Last\l' ], disk_ops => ['-v', 'Ops/s', 'DEF:out_min={file}:write:MIN', 'DEF:out_avg={file}:write:AVERAGE', 'DEF:out_max={file}:write:MAX', 'DEF:inc_min={file}:read:MIN', 'DEF:inc_avg={file}:read:AVERAGE', 'DEF:inc_max={file}:read:MAX', 'CDEF:overlap=out_avg,inc_avg,GT,inc_avg,out_avg,IF', "AREA:out_avg#$HalfGreen", "AREA:inc_avg#$HalfBlue", "AREA:overlap#$HalfBlueGreen", "LINE1:out_avg#$FullGreen:Written", 'GPRINT:out_avg:AVERAGE:%6.2lf Avg,', 'GPRINT:out_max:MAX:%6.2lf Max,', 'GPRINT:out_avg:LAST:%6.2lf Last\l', "LINE1:inc_avg#$FullBlue:Read ", 'GPRINT:inc_avg:AVERAGE:%6.2lf Avg,', 'GPRINT:inc_max:MAX:%6.2lf Max,', 'GPRINT:inc_avg:LAST:%6.2lf Last\l' ], disk_time => ['-v', 'Seconds/s', 'DEF:out_min_raw={file}:write:MIN', 'DEF:out_avg_raw={file}:write:AVERAGE', 'DEF:out_max_raw={file}:write:MAX', 'DEF:inc_min_raw={file}:read:MIN', 'DEF:inc_avg_raw={file}:read:AVERAGE', 'DEF:inc_max_raw={file}:read:MAX', 'CDEF:out_min=out_min_raw,1000,/', 'CDEF:out_avg=out_avg_raw,1000,/', 'CDEF:out_max=out_max_raw,1000,/', 'CDEF:inc_min=inc_min_raw,1000,/', 'CDEF:inc_avg=inc_avg_raw,1000,/', 'CDEF:inc_max=inc_max_raw,1000,/', 'CDEF:overlap=out_avg,inc_avg,GT,inc_avg,out_avg,IF', "AREA:out_avg#$HalfGreen", "AREA:inc_avg#$HalfBlue", "AREA:overlap#$HalfBlueGreen", "LINE1:out_avg#$FullGreen:Written", 'GPRINT:out_avg:AVERAGE:%5.1lf%ss Avg,', 'GPRINT:out_max:MAX:%5.1lf%ss Max,', 'GPRINT:out_avg:LAST:%5.1lf%ss Last\l', "LINE1:inc_avg#$FullBlue:Read ", 'GPRINT:inc_avg:AVERAGE:%5.1lf%ss Avg,', 'GPRINT:inc_max:MAX:%5.1lf%ss Max,', 'GPRINT:inc_avg:LAST:%5.1lf%ss Last\l' ], dns_octets => ['DEF:rsp_min_raw={file}:responses:MIN', 'DEF:rsp_avg_raw={file}:responses:AVERAGE', 'DEF:rsp_max_raw={file}:responses:MAX', 'DEF:qry_min_raw={file}:queries:MIN', 'DEF:qry_avg_raw={file}:queries:AVERAGE', 'DEF:qry_max_raw={file}:queries:MAX', 'CDEF:rsp_min=rsp_min_raw,8,*', 'CDEF:rsp_avg=rsp_avg_raw,8,*', 'CDEF:rsp_max=rsp_max_raw,8,*', 'CDEF:qry_min=qry_min_raw,8,*', 'CDEF:qry_avg=qry_avg_raw,8,*', 'CDEF:qry_max=qry_max_raw,8,*', 'CDEF:overlap=rsp_avg,qry_avg,GT,qry_avg,rsp_avg,IF', 'CDEF:mytime=rsp_avg_raw,TIME,TIME,IF', 'CDEF:sample_len_raw=mytime,PREV(mytime),-', 'CDEF:sample_len=sample_len_raw,UN,0,sample_len_raw,IF', 'CDEF:rsp_avg_sample=rsp_avg_raw,UN,0,rsp_avg_raw,IF,sample_len,*', 'CDEF:rsp_avg_sum=PREV,UN,0,PREV,IF,rsp_avg_sample,+', 'CDEF:qry_avg_sample=qry_avg_raw,UN,0,qry_avg_raw,IF,sample_len,*', 'CDEF:qry_avg_sum=PREV,UN,0,PREV,IF,qry_avg_sample,+', "AREA:rsp_avg#$HalfGreen", "AREA:qry_avg#$HalfBlue", "AREA:overlap#$HalfBlueGreen", "LINE1:rsp_avg#$FullGreen:Responses", 'GPRINT:rsp_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:rsp_max:MAX:%5.1lf%s Max,', 'GPRINT:rsp_avg:LAST:%5.1lf%s Last', 'GPRINT:rsp_avg_sum:LAST:(ca. %5.1lf%sB Total)\l', "LINE1:qry_avg#$FullBlue:Queries ", #'GPRINT:qry_min:MIN:%5.1lf %s Min,', 'GPRINT:qry_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:qry_max:MAX:%5.1lf%s Max,', 'GPRINT:qry_avg:LAST:%5.1lf%s Last', 'GPRINT:qry_avg_sum:LAST:(ca. %5.1lf%sB Total)\l' ], dns_opcode => [ 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Queries/s", 'GPRINT:min:MIN:%9.3lf Min,', 'GPRINT:avg:AVERAGE:%9.3lf Average,', 'GPRINT:max:MAX:%9.3lf Max,', 'GPRINT:avg:LAST:%9.3lf Last\l' ], email_count => ['-v', 'Mails', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfMagenta", "AREA:min#$Canvas", "LINE1:avg#$FullMagenta:Count ", 'GPRINT:min:MIN:%4.1lf Min,', 'GPRINT:avg:AVERAGE:%4.1lf Avg,', 'GPRINT:max:MAX:%4.1lf Max,', 'GPRINT:avg:LAST:%4.1lf Last\l' ], email_size => ['-v', 'Bytes', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfMagenta", "AREA:min#$Canvas", "LINE1:avg#$FullMagenta:Count ", 'GPRINT:min:MIN:%4.1lf Min,', 'GPRINT:avg:AVERAGE:%4.1lf Avg,', 'GPRINT:max:MAX:%4.1lf Max,', 'GPRINT:avg:LAST:%4.1lf Last\l' ], spam_score => ['-v', 'Score', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Score ", 'GPRINT:min:MIN:%4.1lf Min,', 'GPRINT:avg:AVERAGE:%4.1lf Avg,', 'GPRINT:max:MAX:%4.1lf Max,', 'GPRINT:avg:LAST:%4.1lf Last\l' ], spam_check => [ 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfMagenta", "AREA:min#$Canvas", "LINE1:avg#$FullMagenta:Count ", 'GPRINT:min:MIN:%4.1lf Min,', 'GPRINT:avg:AVERAGE:%4.1lf Avg,', 'GPRINT:max:MAX:%4.1lf Max,', 'GPRINT:avg:LAST:%4.1lf Last\l' ], conntrack => ['-v', 'Entries', 'DEF:avg={file}:entropy:AVERAGE', 'DEF:min={file}:entropy:MIN', 'DEF:max={file}:entropy:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Count", 'GPRINT:min:MIN:%4.0lf Min,', 'GPRINT:avg:AVERAGE:%4.0lf Avg,', 'GPRINT:max:MAX:%4.0lf Max,', 'GPRINT:avg:LAST:%4.0lf Last\l' ], entropy => ['-v', 'Bits', 'DEF:avg={file}:entropy:AVERAGE', 'DEF:min={file}:entropy:MIN', 'DEF:max={file}:entropy:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Bits", 'GPRINT:min:MIN:%4.0lfbit Min,', 'GPRINT:avg:AVERAGE:%4.0lfbit Avg,', 'GPRINT:max:MAX:%4.0lfbit Max,', 'GPRINT:avg:LAST:%4.0lfbit Last\l' ], fanspeed => ['-v', 'RPM', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfMagenta", "AREA:min#$Canvas", "LINE1:avg#$FullMagenta:RPM", 'GPRINT:min:MIN:%4.1lf Min,', 'GPRINT:avg:AVERAGE:%4.1lf Avg,', 'GPRINT:max:MAX:%4.1lf Max,', 'GPRINT:avg:LAST:%4.1lf Last\l' ], frequency => ['-v', 'Hertz', 'DEF:avg={file}:frequency:AVERAGE', 'DEF:min={file}:frequency:MIN', 'DEF:max={file}:frequency:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Frequency [Hz]", 'GPRINT:min:MIN:%4.1lf Min,', 'GPRINT:avg:AVERAGE:%4.1lf Avg,', 'GPRINT:max:MAX:%4.1lf Max,', 'GPRINT:avg:LAST:%4.1lf Last\l' ], frequency_offset => [ # NTPd 'DEF:ppm_avg={file}:ppm:AVERAGE', 'DEF:ppm_min={file}:ppm:MIN', 'DEF:ppm_max={file}:ppm:MAX', "AREA:ppm_max#$HalfBlue", "AREA:ppm_min#$Canvas", "LINE1:ppm_avg#$FullBlue:{inst}", 'GPRINT:ppm_min:MIN:%5.2lf Min,', 'GPRINT:ppm_avg:AVERAGE:%5.2lf Avg,', 'GPRINT:ppm_max:MAX:%5.2lf Max,', 'GPRINT:ppm_avg:LAST:%5.2lf Last' ], gauge => ['-v', 'Exec value', 'DEF:temp_avg={file}:value:AVERAGE', 'DEF:temp_min={file}:value:MIN', 'DEF:temp_max={file}:value:MAX', "AREA:temp_max#$HalfBlue", "AREA:temp_min#$Canvas", "LINE1:temp_avg#$FullBlue:Exec value", 'GPRINT:temp_min:MIN:%6.2lf Min,', 'GPRINT:temp_avg:AVERAGE:%6.2lf Avg,', 'GPRINT:temp_max:MAX:%6.2lf Max,', 'GPRINT:temp_avg:LAST:%6.2lf Last\l' ], hddtemp => [ 'DEF:temp_avg={file}:value:AVERAGE', 'DEF:temp_min={file}:value:MIN', 'DEF:temp_max={file}:value:MAX', "AREA:temp_max#$HalfRed", "AREA:temp_min#$Canvas", "LINE1:temp_avg#$FullRed:Temperature", 'GPRINT:temp_min:MIN:%4.1lf Min,', 'GPRINT:temp_avg:AVERAGE:%4.1lf Avg,', 'GPRINT:temp_max:MAX:%4.1lf Max,', 'GPRINT:temp_avg:LAST:%4.1lf Last\l' ], humidity => ['-v', 'Percent', 'DEF:temp_avg={file}:value:AVERAGE', 'DEF:temp_min={file}:value:MIN', 'DEF:temp_max={file}:value:MAX', "AREA:temp_max#$HalfGreen", "AREA:temp_min#$Canvas", "LINE1:temp_avg#$FullGreen:Temperature", 'GPRINT:temp_min:MIN:%4.1lf%% Min,', 'GPRINT:temp_avg:AVERAGE:%4.1lf%% Avg,', 'GPRINT:temp_max:MAX:%4.1lf%% Max,', 'GPRINT:temp_avg:LAST:%4.1lf%% Last\l' ], if_errors => ['-v', 'Errors/s', 'DEF:tx_min={file}:tx:MIN', 'DEF:tx_avg={file}:tx:AVERAGE', 'DEF:tx_max={file}:tx:MAX', 'DEF:rx_min={file}:rx:MIN', 'DEF:rx_avg={file}:rx:AVERAGE', 'DEF:rx_max={file}:rx:MAX', 'CDEF:overlap=tx_avg,rx_avg,GT,rx_avg,tx_avg,IF', 'CDEF:mytime=tx_avg,TIME,TIME,IF', 'CDEF:sample_len_raw=mytime,PREV(mytime),-', 'CDEF:sample_len=sample_len_raw,UN,0,sample_len_raw,IF', 'CDEF:tx_avg_sample=tx_avg,UN,0,tx_avg,IF,sample_len,*', 'CDEF:tx_avg_sum=PREV,UN,0,PREV,IF,tx_avg_sample,+', 'CDEF:rx_avg_sample=rx_avg,UN,0,rx_avg,IF,sample_len,*', 'CDEF:rx_avg_sum=PREV,UN,0,PREV,IF,rx_avg_sample,+', "AREA:tx_avg#$HalfGreen", "AREA:rx_avg#$HalfBlue", "AREA:overlap#$HalfBlueGreen", "LINE1:tx_avg#$FullGreen:TX", 'GPRINT:tx_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:tx_max:MAX:%5.1lf%s Max,', 'GPRINT:tx_avg:LAST:%5.1lf%s Last', 'GPRINT:tx_avg_sum:LAST:(ca. %4.0lf%s Total)\l', "LINE1:rx_avg#$FullBlue:RX", #'GPRINT:rx_min:MIN:%5.1lf %s Min,', 'GPRINT:rx_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:rx_max:MAX:%5.1lf%s Max,', 'GPRINT:rx_avg:LAST:%5.1lf%s Last', 'GPRINT:rx_avg_sum:LAST:(ca. %4.0lf%s Total)\l' ], if_collisions => ['-v', 'Collisions/s', 'DEF:min_raw={file}:value:MIN', 'DEF:avg_raw={file}:value:AVERAGE', 'DEF:max_raw={file}:value:MAX', 'CDEF:min=min_raw,8,*', 'CDEF:avg=avg_raw,8,*', 'CDEF:max=max_raw,8,*', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Collisions/s", 'GPRINT:min:MIN:%5.1lf %s Min,', 'GPRINT:avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:max:MAX:%5.1lf%s Max,', 'GPRINT:avg:LAST:%5.1lf%s Last\l' ], if_dropped => ['-v', 'Packets/s', 'DEF:tx_min={file}:tx:MIN', 'DEF:tx_avg={file}:tx:AVERAGE', 'DEF:tx_max={file}:tx:MAX', 'DEF:rx_min={file}:rx:MIN', 'DEF:rx_avg={file}:rx:AVERAGE', 'DEF:rx_max={file}:rx:MAX', 'CDEF:overlap=tx_avg,rx_avg,GT,rx_avg,tx_avg,IF', 'CDEF:mytime=tx_avg,TIME,TIME,IF', 'CDEF:sample_len_raw=mytime,PREV(mytime),-', 'CDEF:sample_len=sample_len_raw,UN,0,sample_len_raw,IF', 'CDEF:tx_avg_sample=tx_avg,UN,0,tx_avg,IF,sample_len,*', 'CDEF:tx_avg_sum=PREV,UN,0,PREV,IF,tx_avg_sample,+', 'CDEF:rx_avg_sample=rx_avg,UN,0,rx_avg,IF,sample_len,*', 'CDEF:rx_avg_sum=PREV,UN,0,PREV,IF,rx_avg_sample,+', "AREA:tx_avg#$HalfGreen", "AREA:rx_avg#$HalfBlue", "AREA:overlap#$HalfBlueGreen", "LINE1:tx_avg#$FullGreen:TX", 'GPRINT:tx_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:tx_max:MAX:%5.1lf%s Max,', 'GPRINT:tx_avg:LAST:%5.1lf%s Last', 'GPRINT:tx_avg_sum:LAST:(ca. %4.0lf%s Total)\l', "LINE1:rx_avg#$FullBlue:RX", #'GPRINT:rx_min:MIN:%5.1lf %s Min,', 'GPRINT:rx_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:rx_max:MAX:%5.1lf%s Max,', 'GPRINT:rx_avg:LAST:%5.1lf%s Last', 'GPRINT:rx_avg_sum:LAST:(ca. %4.0lf%s Total)\l' ], if_packets => ['-v', 'Packets/s', 'DEF:tx_min={file}:tx:MIN', 'DEF:tx_avg={file}:tx:AVERAGE', 'DEF:tx_max={file}:tx:MAX', 'DEF:rx_min={file}:rx:MIN', 'DEF:rx_avg={file}:rx:AVERAGE', 'DEF:rx_max={file}:rx:MAX', 'CDEF:overlap=tx_avg,rx_avg,GT,rx_avg,tx_avg,IF', 'CDEF:mytime=tx_avg,TIME,TIME,IF', 'CDEF:sample_len_raw=mytime,PREV(mytime),-', 'CDEF:sample_len=sample_len_raw,UN,0,sample_len_raw,IF', 'CDEF:tx_avg_sample=tx_avg,UN,0,tx_avg,IF,sample_len,*', 'CDEF:tx_avg_sum=PREV,UN,0,PREV,IF,tx_avg_sample,+', 'CDEF:rx_avg_sample=rx_avg,UN,0,rx_avg,IF,sample_len,*', 'CDEF:rx_avg_sum=PREV,UN,0,PREV,IF,rx_avg_sample,+', "AREA:tx_avg#$HalfGreen", "AREA:rx_avg#$HalfBlue", "AREA:overlap#$HalfBlueGreen", "LINE1:tx_avg#$FullGreen:TX", 'GPRINT:tx_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:tx_max:MAX:%5.1lf%s Max,', 'GPRINT:tx_avg:LAST:%5.1lf%s Last', 'GPRINT:tx_avg_sum:LAST:(ca. %4.0lf%s Total)\l', "LINE1:rx_avg#$FullBlue:RX", #'GPRINT:rx_min:MIN:%5.1lf %s Min,', 'GPRINT:rx_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:rx_max:MAX:%5.1lf%s Max,', 'GPRINT:rx_avg:LAST:%5.1lf%s Last', 'GPRINT:rx_avg_sum:LAST:(ca. %4.0lf%s Total)\l' ], if_rx_errors => ['-v', 'Errors/s', 'DEF:min={file}:value:MIN', 'DEF:avg={file}:value:AVERAGE', 'DEF:max={file}:value:MAX', 'CDEF:mytime=avg,TIME,TIME,IF', 'CDEF:sample_len_raw=mytime,PREV(mytime),-', 'CDEF:sample_len=sample_len_raw,UN,0,sample_len_raw,IF', 'CDEF:avg_sample=avg,UN,0,avg,IF,sample_len,*', 'CDEF:avg_sum=PREV,UN,0,PREV,IF,avg_sample,+', "AREA:avg#$HalfBlue", "LINE1:avg#$FullBlue:Errors/s", 'GPRINT:avg:AVERAGE:%3.1lf%s Avg,', 'GPRINT:max:MAX:%3.1lf%s Max,', 'GPRINT:avg:LAST:%3.1lf%s Last', 'GPRINT:avg_sum:LAST:(ca. %2.0lf%s Total)\l' ], ipt_bytes => ['-v', 'Bits/s', 'DEF:min_raw={file}:value:MIN', 'DEF:avg_raw={file}:value:AVERAGE', 'DEF:max_raw={file}:value:MAX', 'CDEF:min=min_raw,8,*', 'CDEF:avg=avg_raw,8,*', 'CDEF:max=max_raw,8,*', 'CDEF:mytime=avg_raw,TIME,TIME,IF', 'CDEF:sample_len_raw=mytime,PREV(mytime),-', 'CDEF:sample_len=sample_len_raw,UN,0,sample_len_raw,IF', 'CDEF:avg_sample=avg_raw,UN,0,avg_raw,IF,sample_len,*', 'CDEF:avg_sum=PREV,UN,0,PREV,IF,avg_sample,+', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Bits/s", #'GPRINT:min:MIN:%5.1lf %s Min,', 'GPRINT:avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:max:MAX:%5.1lf%s Max,', 'GPRINT:avg:LAST:%5.1lf%s Last', 'GPRINT:avg_sum:LAST:(ca. %5.1lf%sB Total)\l' ], ipt_packets => ['-v', 'Packets/s', 'DEF:min_raw={file}:value:MIN', 'DEF:avg_raw={file}:value:AVERAGE', 'DEF:max_raw={file}:value:MAX', 'CDEF:min=min_raw,8,*', 'CDEF:avg=avg_raw,8,*', 'CDEF:max=max_raw,8,*', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Packets/s", 'GPRINT:min:MIN:%5.1lf %s Min,', 'GPRINT:avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:max:MAX:%5.1lf%s Max,', 'GPRINT:avg:LAST:%5.1lf%s Last\l' ], irq => ['-v', 'Issues/s', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Issues/s", 'GPRINT:min:MIN:%6.2lf Min,', 'GPRINT:avg:AVERAGE:%6.2lf Avg,', 'GPRINT:max:MAX:%6.2lf Max,', 'GPRINT:avg:LAST:%6.2lf Last\l' ], load => ['-v', 'System load', 'DEF:s_avg={file}:shortterm:AVERAGE', 'DEF:s_min={file}:shortterm:MIN', 'DEF:s_max={file}:shortterm:MAX', 'DEF:m_avg={file}:midterm:AVERAGE', 'DEF:m_min={file}:midterm:MIN', 'DEF:m_max={file}:midterm:MAX', 'DEF:l_avg={file}:longterm:AVERAGE', 'DEF:l_min={file}:longterm:MIN', 'DEF:l_max={file}:longterm:MAX', "AREA:s_max#$HalfGreen", "AREA:s_min#$Canvas", "LINE1:s_avg#$FullGreen: 1m average", 'GPRINT:s_min:MIN:%4.2lf Min,', 'GPRINT:s_avg:AVERAGE:%4.2lf Avg,', 'GPRINT:s_max:MAX:%4.2lf Max,', 'GPRINT:s_avg:LAST:%4.2lf Last\n', "LINE1:m_avg#$FullBlue: 5m average", 'GPRINT:m_min:MIN:%4.2lf Min,', 'GPRINT:m_avg:AVERAGE:%4.2lf Avg,', 'GPRINT:m_max:MAX:%4.2lf Max,', 'GPRINT:m_avg:LAST:%4.2lf Last\n', "LINE1:l_avg#$FullRed:15m average", 'GPRINT:l_min:MIN:%4.2lf Min,', 'GPRINT:l_avg:AVERAGE:%4.2lf Avg,', 'GPRINT:l_max:MAX:%4.2lf Max,', 'GPRINT:l_avg:LAST:%4.2lf Last' ], load_percent => [ 'DEF:avg={file}:percent:AVERAGE', 'DEF:min={file}:percent:MIN', 'DEF:max={file}:percent:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Load", 'GPRINT:min:MIN:%5.1lf%s%% Min,', 'GPRINT:avg:AVERAGE:%5.1lf%s%% Avg,', 'GPRINT:max:MAX:%5.1lf%s%% Max,', 'GPRINT:avg:LAST:%5.1lf%s%% Last\l' ], mails => ['DEF:rawgood={file}:good:AVERAGE', 'DEF:rawspam={file}:spam:AVERAGE', 'CDEF:good=rawgood,UN,0,rawgood,IF', 'CDEF:spam=rawspam,UN,0,rawspam,IF', 'CDEF:negspam=spam,-1,*', "AREA:good#$HalfGreen", "LINE1:good#$FullGreen:Good mails", 'GPRINT:good:AVERAGE:%4.1lf Avg,', 'GPRINT:good:MAX:%4.1lf Max,', 'GPRINT:good:LAST:%4.1lf Last\n', "AREA:negspam#$HalfRed", "LINE1:negspam#$FullRed:Spam mails", 'GPRINT:spam:AVERAGE:%4.1lf Avg,', 'GPRINT:spam:MAX:%4.1lf Max,', 'GPRINT:spam:LAST:%4.1lf Last', 'HRULE:0#000000' ], memcached_command => ['-v', 'Commands', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Commands", 'GPRINT:min:MIN:%5.1lf%s Min,', 'GPRINT:avg:AVERAGE:%5.1lf Avg,', 'GPRINT:max:MAX:%5.1lf Max,', 'GPRINT:avg:LAST:%5.1lf Last\l' ], memcached_connections => ['-v', 'Connections', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Connections", 'GPRINT:min:MIN:%4.1lf Min,', 'GPRINT:avg:AVERAGE:%4.1lf Avg,', 'GPRINT:max:MAX:%4.1lf Max,', 'GPRINT:avg:LAST:%4.1lf Last\l' ], memcached_items => ['-v', 'Items', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Items", 'GPRINT:min:MIN:%4.1lf Min,', 'GPRINT:avg:AVERAGE:%4.1lf Avg,', 'GPRINT:max:MAX:%4.1lf Max,', 'GPRINT:avg:LAST:%4.1lf Last\l' ], memcached_octets => ['-v', 'Bits/s', 'DEF:out_min={file}:tx:MIN', 'DEF:out_avg={file}:tx:AVERAGE', 'DEF:out_max={file}:tx:MAX', 'DEF:inc_min={file}:rx:MIN', 'DEF:inc_avg={file}:rx:AVERAGE', 'DEF:inc_max={file}:rx:MAX', 'CDEF:mytime=out_avg,TIME,TIME,IF', 'CDEF:sample_len_raw=mytime,PREV(mytime),-', 'CDEF:sample_len=sample_len_raw,UN,0,sample_len_raw,IF', 'CDEF:out_avg_sample=out_avg,UN,0,out_avg,IF,sample_len,*', 'CDEF:out_avg_sum=PREV,UN,0,PREV,IF,out_avg_sample,+', 'CDEF:inc_avg_sample=inc_avg,UN,0,inc_avg,IF,sample_len,*', 'CDEF:inc_avg_sum=PREV,UN,0,PREV,IF,inc_avg_sample,+', 'CDEF:out_bit_min=out_min,8,*', 'CDEF:out_bit_avg=out_avg,8,*', 'CDEF:out_bit_max=out_max,8,*', 'CDEF:inc_bit_min=inc_min,8,*', 'CDEF:inc_bit_avg=inc_avg,8,*', 'CDEF:inc_bit_max=inc_max,8,*', 'CDEF:overlap=out_bit_avg,inc_bit_avg,GT,inc_bit_avg,out_bit_avg,IF', "AREA:out_bit_avg#$HalfGreen", "AREA:inc_bit_avg#$HalfBlue", "AREA:overlap#$HalfBlueGreen", "LINE1:out_bit_avg#$FullGreen:Written", 'GPRINT:out_bit_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:out_bit_max:MAX:%5.1lf%s Max,', 'GPRINT:out_bit_avg:LAST:%5.1lf%s Last', 'GPRINT:out_avg_sum:LAST:(ca. %5.1lf%sB Total)\l', "LINE1:inc_bit_avg#$FullBlue:Read ", 'GPRINT:inc_bit_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:inc_bit_max:MAX:%5.1lf%s Max,', 'GPRINT:inc_bit_avg:LAST:%5.1lf%s Last', 'GPRINT:inc_avg_sum:LAST:(ca. %5.1lf%sB Total)\l' ], memcached_ops => ['-v', 'Ops', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Ops", 'GPRINT:min:MIN:%4.1lf Min,', 'GPRINT:avg:AVERAGE:%4.1lf Avg,', 'GPRINT:max:MAX:%4.1lf Max,', 'GPRINT:avg:LAST:%4.1lf Last\l' ], memory => ['-b', '1024', '-v', 'Bytes', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Memory", 'GPRINT:min:MIN:%5.1lf%sbyte Min,', 'GPRINT:avg:AVERAGE:%5.1lf%sbyte Avg,', 'GPRINT:max:MAX:%5.1lf%sbyte Max,', 'GPRINT:avg:LAST:%5.1lf%sbyte Last\l' ], old_memory => [ 'DEF:used_avg={file}:used:AVERAGE', 'DEF:free_avg={file}:free:AVERAGE', 'DEF:buffers_avg={file}:buffers:AVERAGE', 'DEF:cached_avg={file}:cached:AVERAGE', 'DEF:used_min={file}:used:MIN', 'DEF:free_min={file}:free:MIN', 'DEF:buffers_min={file}:buffers:MIN', 'DEF:cached_min={file}:cached:MIN', 'DEF:used_max={file}:used:MAX', 'DEF:free_max={file}:free:MAX', 'DEF:buffers_max={file}:buffers:MAX', 'DEF:cached_max={file}:cached:MAX', 'CDEF:cached_avg_nn=cached_avg,UN,0,cached_avg,IF', 'CDEF:buffers_avg_nn=buffers_avg,UN,0,buffers_avg,IF', 'CDEF:free_cached_buffers_used=free_avg,cached_avg_nn,+,buffers_avg_nn,+,used_avg,+', 'CDEF:cached_buffers_used=cached_avg,buffers_avg_nn,+,used_avg,+', 'CDEF:buffers_used=buffers_avg,used_avg,+', "AREA:free_cached_buffers_used#$HalfGreen", "AREA:cached_buffers_used#$HalfBlue", "AREA:buffers_used#$HalfYellow", "AREA:used_avg#$HalfRed", "LINE1:free_cached_buffers_used#$FullGreen:Free ", 'GPRINT:free_min:MIN:%5.1lf%s Min,', 'GPRINT:free_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:free_max:MAX:%5.1lf%s Max,', 'GPRINT:free_avg:LAST:%5.1lf%s Last\n', "LINE1:cached_buffers_used#$FullBlue:Page cache ", 'GPRINT:cached_min:MIN:%5.1lf%s Min,', 'GPRINT:cached_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:cached_max:MAX:%5.1lf%s Max,', 'GPRINT:cached_avg:LAST:%5.1lf%s Last\n', "LINE1:buffers_used#$FullYellow:Buffer cache", 'GPRINT:buffers_min:MIN:%5.1lf%s Min,', 'GPRINT:buffers_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:buffers_max:MAX:%5.1lf%s Max,', 'GPRINT:buffers_avg:LAST:%5.1lf%s Last\n', "LINE1:used_avg#$FullRed:Used ", 'GPRINT:used_min:MIN:%5.1lf%s Min,', 'GPRINT:used_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:used_max:MAX:%5.1lf%s Max,', 'GPRINT:used_avg:LAST:%5.1lf%s Last' ], mysql_commands => ['-v', 'Issues/s', "DEF:val_avg={file}:value:AVERAGE", "DEF:val_min={file}:value:MIN", "DEF:val_max={file}:value:MAX", "AREA:val_max#$HalfBlue", "AREA:val_min#$Canvas", "LINE1:val_avg#$FullBlue:Issues/s", 'GPRINT:val_min:MIN:%5.2lf Min,', 'GPRINT:val_avg:AVERAGE:%5.2lf Avg,', 'GPRINT:val_max:MAX:%5.2lf Max,', 'GPRINT:val_avg:LAST:%5.2lf Last' ], mysql_handler => ['-v', 'Issues/s', "DEF:val_avg={file}:value:AVERAGE", "DEF:val_min={file}:value:MIN", "DEF:val_max={file}:value:MAX", "AREA:val_max#$HalfBlue", "AREA:val_min#$Canvas", "LINE1:val_avg#$FullBlue:Issues/s", 'GPRINT:val_min:MIN:%5.2lf Min,', 'GPRINT:val_avg:AVERAGE:%5.2lf Avg,', 'GPRINT:val_max:MAX:%5.2lf Max,', 'GPRINT:val_avg:LAST:%5.2lf Last' ], mysql_octets => ['-v', 'Bits/s', 'DEF:out_min={file}:tx:MIN', 'DEF:out_avg={file}:tx:AVERAGE', 'DEF:out_max={file}:tx:MAX', 'DEF:inc_min={file}:rx:MIN', 'DEF:inc_avg={file}:rx:AVERAGE', 'DEF:inc_max={file}:rx:MAX', 'CDEF:mytime=out_avg,TIME,TIME,IF', 'CDEF:sample_len_raw=mytime,PREV(mytime),-', 'CDEF:sample_len=sample_len_raw,UN,0,sample_len_raw,IF', 'CDEF:out_avg_sample=out_avg,UN,0,out_avg,IF,sample_len,*', 'CDEF:out_avg_sum=PREV,UN,0,PREV,IF,out_avg_sample,+', 'CDEF:inc_avg_sample=inc_avg,UN,0,inc_avg,IF,sample_len,*', 'CDEF:inc_avg_sum=PREV,UN,0,PREV,IF,inc_avg_sample,+', 'CDEF:out_bit_min=out_min,8,*', 'CDEF:out_bit_avg=out_avg,8,*', 'CDEF:out_bit_max=out_max,8,*', 'CDEF:inc_bit_min=inc_min,8,*', 'CDEF:inc_bit_avg=inc_avg,8,*', 'CDEF:inc_bit_max=inc_max,8,*', 'CDEF:overlap=out_bit_avg,inc_bit_avg,GT,inc_bit_avg,out_bit_avg,IF', "AREA:out_bit_avg#$HalfGreen", "AREA:inc_bit_avg#$HalfBlue", "AREA:overlap#$HalfBlueGreen", "LINE1:out_bit_avg#$FullGreen:Written", 'GPRINT:out_bit_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:out_bit_max:MAX:%5.1lf%s Max,', 'GPRINT:out_bit_avg:LAST:%5.1lf%s Last', 'GPRINT:out_avg_sum:LAST:(ca. %5.1lf%sB Total)\l', "LINE1:inc_bit_avg#$FullBlue:Read ", 'GPRINT:inc_bit_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:inc_bit_max:MAX:%5.1lf%s Max,', 'GPRINT:inc_bit_avg:LAST:%5.1lf%s Last', 'GPRINT:inc_avg_sum:LAST:(ca. %5.1lf%sB Total)\l' ], mysql_qcache => ['-v', 'Queries/s', "DEF:hits_min={file}:hits:MIN", "DEF:hits_avg={file}:hits:AVERAGE", "DEF:hits_max={file}:hits:MAX", "DEF:inserts_min={file}:inserts:MIN", "DEF:inserts_avg={file}:inserts:AVERAGE", "DEF:inserts_max={file}:inserts:MAX", "DEF:not_cached_min={file}:not_cached:MIN", "DEF:not_cached_avg={file}:not_cached:AVERAGE", "DEF:not_cached_max={file}:not_cached:MAX", "DEF:lowmem_prunes_min={file}:lowmem_prunes:MIN", "DEF:lowmem_prunes_avg={file}:lowmem_prunes:AVERAGE", "DEF:lowmem_prunes_max={file}:lowmem_prunes:MAX", "DEF:queries_min={file}:queries_in_cache:MIN", "DEF:queries_avg={file}:queries_in_cache:AVERAGE", "DEF:queries_max={file}:queries_in_cache:MAX", "CDEF:unknown=queries_avg,UNKN,+", "CDEF:not_cached_agg=hits_avg,inserts_avg,+,not_cached_avg,+", "CDEF:inserts_agg=hits_avg,inserts_avg,+", "CDEF:hits_agg=hits_avg", "AREA:not_cached_agg#$HalfYellow", "AREA:inserts_agg#$HalfBlue", "AREA:hits_agg#$HalfGreen", "LINE1:not_cached_agg#$FullYellow:Not Cached ", 'GPRINT:not_cached_min:MIN:%5.2lf Min,', 'GPRINT:not_cached_avg:AVERAGE:%5.2lf Avg,', 'GPRINT:not_cached_max:MAX:%5.2lf Max,', 'GPRINT:not_cached_avg:LAST:%5.2lf Last\l', "LINE1:inserts_agg#$FullBlue:Inserts ", 'GPRINT:inserts_min:MIN:%5.2lf Min,', 'GPRINT:inserts_avg:AVERAGE:%5.2lf Avg,', 'GPRINT:inserts_max:MAX:%5.2lf Max,', 'GPRINT:inserts_avg:LAST:%5.2lf Last\l', "LINE1:hits_agg#$FullGreen:Hits ", 'GPRINT:hits_min:MIN:%5.2lf Min,', 'GPRINT:hits_avg:AVERAGE:%5.2lf Avg,', 'GPRINT:hits_max:MAX:%5.2lf Max,', 'GPRINT:hits_avg:LAST:%5.2lf Last\l', "LINE1:lowmem_prunes_avg#$FullRed:Lowmem Prunes ", 'GPRINT:lowmem_prunes_min:MIN:%5.2lf Min,', 'GPRINT:lowmem_prunes_avg:AVERAGE:%5.2lf Avg,', 'GPRINT:lowmem_prunes_max:MAX:%5.2lf Max,', 'GPRINT:lowmem_prunes_avg:LAST:%5.2lf Last\l', "LINE1:unknown#$Canvas:Queries in cache", 'GPRINT:queries_min:MIN:%5.0lf Min,', 'GPRINT:queries_avg:AVERAGE:%5.0lf Avg,', 'GPRINT:queries_max:MAX:%5.0lf Max,', 'GPRINT:queries_avg:LAST:%5.0lf Last\l' ], mysql_threads => ['-v', 'Threads', "DEF:running_min={file}:running:MIN", "DEF:running_avg={file}:running:AVERAGE", "DEF:running_max={file}:running:MAX", "DEF:connected_min={file}:connected:MIN", "DEF:connected_avg={file}:connected:AVERAGE", "DEF:connected_max={file}:connected:MAX", "DEF:cached_min={file}:cached:MIN", "DEF:cached_avg={file}:cached:AVERAGE", "DEF:cached_max={file}:cached:MAX", "DEF:created_min={file}:created:MIN", "DEF:created_avg={file}:created:AVERAGE", "DEF:created_max={file}:created:MAX", "CDEF:unknown=created_avg,UNKN,+", "CDEF:cached_agg=connected_avg,cached_avg,+", "AREA:cached_agg#$HalfGreen", "AREA:connected_avg#$HalfBlue", "AREA:running_avg#$HalfRed", "LINE1:cached_agg#$FullGreen:Cached ", 'GPRINT:cached_min:MIN:%5.1lf Min,', 'GPRINT:cached_avg:AVERAGE:%5.1lf Avg,', 'GPRINT:cached_max:MAX:%5.1lf Max,', 'GPRINT:cached_avg:LAST:%5.1lf Last\l', "LINE1:connected_avg#$FullBlue:Connected", 'GPRINT:connected_min:MIN:%5.1lf Min,', 'GPRINT:connected_avg:AVERAGE:%5.1lf Avg,', 'GPRINT:connected_max:MAX:%5.1lf Max,', 'GPRINT:connected_avg:LAST:%5.1lf Last\l', "LINE1:running_avg#$FullRed:Running ", 'GPRINT:running_min:MIN:%5.1lf Min,', 'GPRINT:running_avg:AVERAGE:%5.1lf Avg,', 'GPRINT:running_max:MAX:%5.1lf Max,', 'GPRINT:running_avg:LAST:%5.1lf Last\l', "LINE1:unknown#$Canvas:Created ", 'GPRINT:created_min:MIN:%5.0lf Min,', 'GPRINT:created_avg:AVERAGE:%5.0lf Avg,', 'GPRINT:created_max:MAX:%5.0lf Max,', 'GPRINT:created_avg:LAST:%5.0lf Last\l' ], nfs_procedure => ['-v', 'Issues/s', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Issues/s", 'GPRINT:min:MIN:%6.2lf Min,', 'GPRINT:avg:AVERAGE:%6.2lf Avg,', 'GPRINT:max:MAX:%6.2lf Max,', 'GPRINT:avg:LAST:%6.2lf Last\l' ], nfs3_procedures => [ "DEF:null_avg={file}:null:AVERAGE", "DEF:getattr_avg={file}:getattr:AVERAGE", "DEF:setattr_avg={file}:setattr:AVERAGE", "DEF:lookup_avg={file}:lookup:AVERAGE", "DEF:access_avg={file}:access:AVERAGE", "DEF:readlink_avg={file}:readlink:AVERAGE", "DEF:read_avg={file}:read:AVERAGE", "DEF:write_avg={file}:write:AVERAGE", "DEF:create_avg={file}:create:AVERAGE", "DEF:mkdir_avg={file}:mkdir:AVERAGE", "DEF:symlink_avg={file}:symlink:AVERAGE", "DEF:mknod_avg={file}:mknod:AVERAGE", "DEF:remove_avg={file}:remove:AVERAGE", "DEF:rmdir_avg={file}:rmdir:AVERAGE", "DEF:rename_avg={file}:rename:AVERAGE", "DEF:link_avg={file}:link:AVERAGE", "DEF:readdir_avg={file}:readdir:AVERAGE", "DEF:readdirplus_avg={file}:readdirplus:AVERAGE", "DEF:fsstat_avg={file}:fsstat:AVERAGE", "DEF:fsinfo_avg={file}:fsinfo:AVERAGE", "DEF:pathconf_avg={file}:pathconf:AVERAGE", "DEF:commit_avg={file}:commit:AVERAGE", "DEF:null_max={file}:null:MAX", "DEF:getattr_max={file}:getattr:MAX", "DEF:setattr_max={file}:setattr:MAX", "DEF:lookup_max={file}:lookup:MAX", "DEF:access_max={file}:access:MAX", "DEF:readlink_max={file}:readlink:MAX", "DEF:read_max={file}:read:MAX", "DEF:write_max={file}:write:MAX", "DEF:create_max={file}:create:MAX", "DEF:mkdir_max={file}:mkdir:MAX", "DEF:symlink_max={file}:symlink:MAX", "DEF:mknod_max={file}:mknod:MAX", "DEF:remove_max={file}:remove:MAX", "DEF:rmdir_max={file}:rmdir:MAX", "DEF:rename_max={file}:rename:MAX", "DEF:link_max={file}:link:MAX", "DEF:readdir_max={file}:readdir:MAX", "DEF:readdirplus_max={file}:readdirplus:MAX", "DEF:fsstat_max={file}:fsstat:MAX", "DEF:fsinfo_max={file}:fsinfo:MAX", "DEF:pathconf_max={file}:pathconf:MAX", "DEF:commit_max={file}:commit:MAX", "CDEF:other_avg=null_avg,readlink_avg,create_avg,mkdir_avg,symlink_avg,mknod_avg,remove_avg,rmdir_avg,rename_avg,link_avg,readdir_avg,readdirplus_avg,fsstat_avg,fsinfo_avg,pathconf_avg,+,+,+,+,+,+,+,+,+,+,+,+,+,+", "CDEF:other_max=null_max,readlink_max,create_max,mkdir_max,symlink_max,mknod_max,remove_max,rmdir_max,rename_max,link_max,readdir_max,readdirplus_max,fsstat_max,fsinfo_max,pathconf_max,+,+,+,+,+,+,+,+,+,+,+,+,+,+", "CDEF:stack_read=read_avg", "CDEF:stack_getattr=stack_read,getattr_avg,+", "CDEF:stack_access=stack_getattr,access_avg,+", "CDEF:stack_lookup=stack_access,lookup_avg,+", "CDEF:stack_write=stack_lookup,write_avg,+", "CDEF:stack_commit=stack_write,commit_avg,+", "CDEF:stack_setattr=stack_commit,setattr_avg,+", "CDEF:stack_other=stack_setattr,other_avg,+", "AREA:stack_other#$HalfRed", "AREA:stack_setattr#$HalfGreen", "AREA:stack_commit#$HalfYellow", "AREA:stack_write#$HalfGreen", "AREA:stack_lookup#$HalfBlue", "AREA:stack_access#$HalfMagenta", "AREA:stack_getattr#$HalfCyan", "AREA:stack_read#$HalfBlue", "LINE1:stack_other#$FullRed:Other ", 'GPRINT:other_max:MAX:%5.1lf Max,', 'GPRINT:other_avg:AVERAGE:%5.1lf Avg,', 'GPRINT:other_avg:LAST:%5.1lf Last\l', "LINE1:stack_setattr#$FullGreen:setattr", 'GPRINT:setattr_max:MAX:%5.1lf Max,', 'GPRINT:setattr_avg:AVERAGE:%5.1lf Avg,', 'GPRINT:setattr_avg:LAST:%5.1lf Last\l', "LINE1:stack_commit#$FullYellow:commit ", 'GPRINT:commit_max:MAX:%5.1lf Max,', 'GPRINT:commit_avg:AVERAGE:%5.1lf Avg,', 'GPRINT:commit_avg:LAST:%5.1lf Last\l', "LINE1:stack_write#$FullGreen:write ", 'GPRINT:write_max:MAX:%5.1lf Max,', 'GPRINT:write_avg:AVERAGE:%5.1lf Avg,', 'GPRINT:write_avg:LAST:%5.1lf Last\l', "LINE1:stack_lookup#$FullBlue:lookup ", 'GPRINT:lookup_max:MAX:%5.1lf Max,', 'GPRINT:lookup_avg:AVERAGE:%5.1lf Avg,', 'GPRINT:lookup_avg:LAST:%5.1lf Last\l', "LINE1:stack_access#$FullMagenta:access ", 'GPRINT:access_max:MAX:%5.1lf Max,', 'GPRINT:access_avg:AVERAGE:%5.1lf Avg,', 'GPRINT:access_avg:LAST:%5.1lf Last\l', "LINE1:stack_getattr#$FullCyan:getattr", 'GPRINT:getattr_max:MAX:%5.1lf Max,', 'GPRINT:getattr_avg:AVERAGE:%5.1lf Avg,', 'GPRINT:getattr_avg:LAST:%5.1lf Last\l', "LINE1:stack_read#$FullBlue:read ", 'GPRINT:read_max:MAX:%5.1lf Max,', 'GPRINT:read_avg:AVERAGE:%5.1lf Avg,', 'GPRINT:read_avg:LAST:%5.1lf Last\l' ], partition => [ "DEF:rbyte_avg={file}:rbytes:AVERAGE", "DEF:rbyte_min={file}:rbytes:MIN", "DEF:rbyte_max={file}:rbytes:MAX", "DEF:wbyte_avg={file}:wbytes:AVERAGE", "DEF:wbyte_min={file}:wbytes:MIN", "DEF:wbyte_max={file}:wbytes:MAX", 'CDEF:overlap=wbyte_avg,rbyte_avg,GT,rbyte_avg,wbyte_avg,IF', "AREA:wbyte_avg#$HalfGreen", "AREA:rbyte_avg#$HalfBlue", "AREA:overlap#$HalfBlueGreen", "LINE1:wbyte_avg#$FullGreen:Write", 'GPRINT:wbyte_min:MIN:%5.1lf%s Min,', 'GPRINT:wbyte_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:wbyte_max:MAX:%5.1lf%s Max,', 'GPRINT:wbyte_avg:LAST:%5.1lf%s Last\l', "LINE1:rbyte_avg#$FullBlue:Read ", 'GPRINT:rbyte_min:MIN:%5.1lf%s Min,', 'GPRINT:rbyte_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:rbyte_max:MAX:%5.1lf%s Max,', 'GPRINT:rbyte_avg:LAST:%5.1lf%s Last\l' ], percent => ['-v', 'Percent', 'DEF:avg={file}:percent:AVERAGE', 'DEF:min={file}:percent:MIN', 'DEF:max={file}:percent:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Percent", 'GPRINT:min:MIN:%5.1lf%% Min,', 'GPRINT:avg:AVERAGE:%5.1lf%% Avg,', 'GPRINT:max:MAX:%5.1lf%% Max,', 'GPRINT:avg:LAST:%5.1lf%% Last\l' ], ping => ['DEF:ping_avg={file}:ping:AVERAGE', 'DEF:ping_min={file}:ping:MIN', 'DEF:ping_max={file}:ping:MAX', "AREA:ping_max#$HalfBlue", "AREA:ping_min#$Canvas", "LINE1:ping_avg#$FullBlue:Ping", 'GPRINT:ping_min:MIN:%4.1lf ms Min,', 'GPRINT:ping_avg:AVERAGE:%4.1lf ms Avg,', 'GPRINT:ping_max:MAX:%4.1lf ms Max,', 'GPRINT:ping_avg:LAST:%4.1lf ms Last'], pg_blks => ['DEF:pg_blks_avg={file}:value:AVERAGE', 'DEF:pg_blks_min={file}:value:MIN', 'DEF:pg_blks_max={file}:value:MAX', "AREA:pg_blks_max#$HalfBlue", "AREA:pg_blks_min#$Canvas", "LINE1:pg_blks_avg#$FullBlue:Blocks", 'GPRINT:pg_blks_min:MIN:%4.1lf%s Min,', 'GPRINT:pg_blks_avg:AVERAGE:%4.1lf%s Avg,', 'GPRINT:pg_blks_max:MAX:%4.1lf%s Max,', 'GPRINT:pg_blks_avg:LAST:%4.1lf%s Last'], pg_db_size => ['DEF:pg_db_size_avg={file}:value:AVERAGE', 'DEF:pg_db_size_min={file}:value:MIN', 'DEF:pg_db_size_max={file}:value:MAX', "AREA:pg_db_size_max#$HalfBlue", "AREA:pg_db_size_min#$Canvas", "LINE1:pg_db_size_avg#$FullBlue:Bytes", 'GPRINT:pg_db_size_min:MIN:%4.1lf%s Min,', 'GPRINT:pg_db_size_avg:AVERAGE:%4.1lf%s Avg,', 'GPRINT:pg_db_size_max:MAX:%4.1lf%s Max,', 'GPRINT:pg_db_size_avg:LAST:%4.1lf%s Last'], pg_n_tup_c => ['DEF:pg_n_tup_avg={file}:value:AVERAGE', 'DEF:pg_n_tup_min={file}:value:MIN', 'DEF:pg_n_tup_max={file}:value:MAX', "AREA:pg_n_tup_max#$HalfBlue", "AREA:pg_n_tup_min#$Canvas", "LINE1:pg_n_tup_avg#$FullBlue:Tuples", 'GPRINT:pg_n_tup_min:MIN:%4.1lf%s Min,', 'GPRINT:pg_n_tup_avg:AVERAGE:%4.1lf%s Avg,', 'GPRINT:pg_n_tup_max:MAX:%4.1lf%s Max,', 'GPRINT:pg_n_tup_avg:LAST:%4.1lf%s Last'], pg_n_tup_g => ['DEF:pg_n_tup_avg={file}:value:AVERAGE', 'DEF:pg_n_tup_min={file}:value:MIN', 'DEF:pg_n_tup_max={file}:value:MAX', "AREA:pg_n_tup_max#$HalfBlue", "AREA:pg_n_tup_min#$Canvas", "LINE1:pg_n_tup_avg#$FullBlue:Tuples", 'GPRINT:pg_n_tup_min:MIN:%4.1lf%s Min,', 'GPRINT:pg_n_tup_avg:AVERAGE:%4.1lf%s Avg,', 'GPRINT:pg_n_tup_max:MAX:%4.1lf%s Max,', 'GPRINT:pg_n_tup_avg:LAST:%4.1lf%s Last'], pg_numbackends => ['DEF:pg_numbackends_avg={file}:value:AVERAGE', 'DEF:pg_numbackends_min={file}:value:MIN', 'DEF:pg_numbackends_max={file}:value:MAX', "AREA:pg_numbackends_max#$HalfBlue", "AREA:pg_numbackends_min#$Canvas", "LINE1:pg_numbackends_avg#$FullBlue:Backends", 'GPRINT:pg_numbackends_min:MIN:%4.1lf%s Min,', 'GPRINT:pg_numbackends_avg:AVERAGE:%4.1lf%s Avg,', 'GPRINT:pg_numbackends_max:MAX:%4.1lf%s Max,', 'GPRINT:pg_numbackends_avg:LAST:%4.1lf%s Last'], pg_scan => ['DEF:pg_scan_avg={file}:value:AVERAGE', 'DEF:pg_scan_min={file}:value:MIN', 'DEF:pg_scan_max={file}:value:MAX', "AREA:pg_scan_max#$HalfBlue", "AREA:pg_scan_min#$Canvas", "LINE1:pg_scan_avg#$FullBlue:Scans", 'GPRINT:pg_scan_min:MIN:%4.1lf%s Min,', 'GPRINT:pg_scan_avg:AVERAGE:%4.1lf%s Avg,', 'GPRINT:pg_scan_max:MAX:%4.1lf%s Max,', 'GPRINT:pg_scan_avg:LAST:%4.1lf%s Last'], pg_xact => ['DEF:pg_xact_avg={file}:value:AVERAGE', 'DEF:pg_xact_min={file}:value:MIN', 'DEF:pg_xact_max={file}:value:MAX', "AREA:pg_xact_max#$HalfBlue", "AREA:pg_xact_min#$Canvas", "LINE1:pg_xact_avg#$FullBlue:Transactions", 'GPRINT:pg_xact_min:MIN:%4.1lf%s Min,', 'GPRINT:pg_xact_avg:AVERAGE:%4.1lf%s Avg,', 'GPRINT:pg_xact_max:MAX:%4.1lf%s Max,', 'GPRINT:pg_xact_avg:LAST:%4.1lf%s Last'], power => ['-v', 'Watt', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Watt", 'GPRINT:min:MIN:%5.1lf%sW Min,', 'GPRINT:avg:AVERAGE:%5.1lf%sW Avg,', 'GPRINT:max:MAX:%5.1lf%sW Max,', 'GPRINT:avg:LAST:%5.1lf%sW Last\l' ], processes => [ "DEF:running_avg={file}:running:AVERAGE", "DEF:running_min={file}:running:MIN", "DEF:running_max={file}:running:MAX", "DEF:sleeping_avg={file}:sleeping:AVERAGE", "DEF:sleeping_min={file}:sleeping:MIN", "DEF:sleeping_max={file}:sleeping:MAX", "DEF:zombies_avg={file}:zombies:AVERAGE", "DEF:zombies_min={file}:zombies:MIN", "DEF:zombies_max={file}:zombies:MAX", "DEF:stopped_avg={file}:stopped:AVERAGE", "DEF:stopped_min={file}:stopped:MIN", "DEF:stopped_max={file}:stopped:MAX", "DEF:paging_avg={file}:paging:AVERAGE", "DEF:paging_min={file}:paging:MIN", "DEF:paging_max={file}:paging:MAX", "DEF:blocked_avg={file}:blocked:AVERAGE", "DEF:blocked_min={file}:blocked:MIN", "DEF:blocked_max={file}:blocked:MAX", 'CDEF:paging_acc=sleeping_avg,running_avg,stopped_avg,zombies_avg,blocked_avg,paging_avg,+,+,+,+,+', 'CDEF:blocked_acc=sleeping_avg,running_avg,stopped_avg,zombies_avg,blocked_avg,+,+,+,+', 'CDEF:zombies_acc=sleeping_avg,running_avg,stopped_avg,zombies_avg,+,+,+', 'CDEF:stopped_acc=sleeping_avg,running_avg,stopped_avg,+,+', 'CDEF:running_acc=sleeping_avg,running_avg,+', 'CDEF:sleeping_acc=sleeping_avg', "AREA:paging_acc#$HalfYellow", "AREA:blocked_acc#$HalfCyan", "AREA:zombies_acc#$HalfRed", "AREA:stopped_acc#$HalfMagenta", "AREA:running_acc#$HalfGreen", "AREA:sleeping_acc#$HalfBlue", "LINE1:paging_acc#$FullYellow:Paging ", 'GPRINT:paging_min:MIN:%5.1lf Min,', 'GPRINT:paging_avg:AVERAGE:%5.1lf Average,', 'GPRINT:paging_max:MAX:%5.1lf Max,', 'GPRINT:paging_avg:LAST:%5.1lf Last\l', "LINE1:blocked_acc#$FullCyan:Blocked ", 'GPRINT:blocked_min:MIN:%5.1lf Min,', 'GPRINT:blocked_avg:AVERAGE:%5.1lf Average,', 'GPRINT:blocked_max:MAX:%5.1lf Max,', 'GPRINT:blocked_avg:LAST:%5.1lf Last\l', "LINE1:zombies_acc#$FullRed:Zombies ", 'GPRINT:zombies_min:MIN:%5.1lf Min,', 'GPRINT:zombies_avg:AVERAGE:%5.1lf Average,', 'GPRINT:zombies_max:MAX:%5.1lf Max,', 'GPRINT:zombies_avg:LAST:%5.1lf Last\l', "LINE1:stopped_acc#$FullMagenta:Stopped ", 'GPRINT:stopped_min:MIN:%5.1lf Min,', 'GPRINT:stopped_avg:AVERAGE:%5.1lf Average,', 'GPRINT:stopped_max:MAX:%5.1lf Max,', 'GPRINT:stopped_avg:LAST:%5.1lf Last\l', "LINE1:running_acc#$FullGreen:Running ", 'GPRINT:running_min:MIN:%5.1lf Min,', 'GPRINT:running_avg:AVERAGE:%5.1lf Average,', 'GPRINT:running_max:MAX:%5.1lf Max,', 'GPRINT:running_avg:LAST:%5.1lf Last\l', "LINE1:sleeping_acc#$FullBlue:Sleeping", 'GPRINT:sleeping_min:MIN:%5.1lf Min,', 'GPRINT:sleeping_avg:AVERAGE:%5.1lf Average,', 'GPRINT:sleeping_max:MAX:%5.1lf Max,', 'GPRINT:sleeping_avg:LAST:%5.1lf Last\l' ], ps_count => ['-v', 'Processes', 'DEF:procs_avg={file}:processes:AVERAGE', 'DEF:procs_min={file}:processes:MIN', 'DEF:procs_max={file}:processes:MAX', 'DEF:thrds_avg={file}:threads:AVERAGE', 'DEF:thrds_min={file}:threads:MIN', 'DEF:thrds_max={file}:threads:MAX', "AREA:thrds_avg#$HalfBlue", "AREA:procs_avg#$HalfRed", "LINE1:thrds_avg#$FullBlue:Threads ", 'GPRINT:thrds_min:MIN:%5.1lf Min,', 'GPRINT:thrds_avg:AVERAGE:%5.1lf Avg,', 'GPRINT:thrds_max:MAX:%5.1lf Max,', 'GPRINT:thrds_avg:LAST:%5.1lf Last\l', "LINE1:procs_avg#$FullRed:Processes", 'GPRINT:procs_min:MIN:%5.1lf Min,', 'GPRINT:procs_avg:AVERAGE:%5.1lf Avg,', 'GPRINT:procs_max:MAX:%5.1lf Max,', 'GPRINT:procs_avg:LAST:%5.1lf Last\l' ], ps_cputime => ['-v', 'Jiffies', 'DEF:user_avg_raw={file}:user:AVERAGE', 'DEF:user_min_raw={file}:user:MIN', 'DEF:user_max_raw={file}:user:MAX', 'DEF:syst_avg_raw={file}:syst:AVERAGE', 'DEF:syst_min_raw={file}:syst:MIN', 'DEF:syst_max_raw={file}:syst:MAX', 'CDEF:user_avg=user_avg_raw,1000000,/', 'CDEF:user_min=user_min_raw,1000000,/', 'CDEF:user_max=user_max_raw,1000000,/', 'CDEF:syst_avg=syst_avg_raw,1000000,/', 'CDEF:syst_min=syst_min_raw,1000000,/', 'CDEF:syst_max=syst_max_raw,1000000,/', 'CDEF:user_syst=syst_avg,UN,0,syst_avg,IF,user_avg,+', "AREA:user_syst#$HalfBlue", "AREA:syst_avg#$HalfRed", "LINE1:user_syst#$FullBlue:User ", 'GPRINT:user_min:MIN:%5.1lf%s Min,', 'GPRINT:user_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:user_max:MAX:%5.1lf%s Max,', 'GPRINT:user_avg:LAST:%5.1lf%s Last\l', "LINE1:syst_avg#$FullRed:System", 'GPRINT:syst_min:MIN:%5.1lf%s Min,', 'GPRINT:syst_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:syst_max:MAX:%5.1lf%s Max,', 'GPRINT:syst_avg:LAST:%5.1lf%s Last\l' ], ps_pagefaults => ['-v', 'Pagefaults/s', 'DEF:minor_avg={file}:minflt:AVERAGE', 'DEF:minor_min={file}:minflt:MIN', 'DEF:minor_max={file}:minflt:MAX', 'DEF:major_avg={file}:majflt:AVERAGE', 'DEF:major_min={file}:majflt:MIN', 'DEF:major_max={file}:majflt:MAX', 'CDEF:minor_major=major_avg,UN,0,major_avg,IF,minor_avg,+', "AREA:minor_major#$HalfBlue", "AREA:major_avg#$HalfRed", "LINE1:minor_major#$FullBlue:Minor", 'GPRINT:minor_min:MIN:%5.1lf%s Min,', 'GPRINT:minor_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:minor_max:MAX:%5.1lf%s Max,', 'GPRINT:minor_avg:LAST:%5.1lf%s Last\l', "LINE1:major_avg#$FullRed:Major", 'GPRINT:major_min:MIN:%5.1lf%s Min,', 'GPRINT:major_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:major_max:MAX:%5.1lf%s Max,', 'GPRINT:major_avg:LAST:%5.1lf%s Last\l' ], ps_rss => ['-v', 'Bytes', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:avg#$HalfBlue", "LINE1:avg#$FullBlue:RSS", 'GPRINT:min:MIN:%5.1lf%s Min,', 'GPRINT:avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:max:MAX:%5.1lf%s Max,', 'GPRINT:avg:LAST:%5.1lf%s Last\l' ], ps_state => ['-v', 'Processes', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Processes", 'GPRINT:min:MIN:%6.2lf Min,', 'GPRINT:avg:AVERAGE:%6.2lf Avg,', 'GPRINT:max:MAX:%6.2lf Max,', 'GPRINT:avg:LAST:%6.2lf Last\l' ], signal_noise => ['-v', 'dBm', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Noise", 'GPRINT:min:MIN:%5.1lf%sdBm Min,', 'GPRINT:avg:AVERAGE:%5.1lf%sdBm Avg,', 'GPRINT:max:MAX:%5.1lf%sdBm Max,', 'GPRINT:avg:LAST:%5.1lf%sdBm Last\l' ], signal_power => ['-v', 'dBm', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Power", 'GPRINT:min:MIN:%5.1lf%sdBm Min,', 'GPRINT:avg:AVERAGE:%5.1lf%sdBm Avg,', 'GPRINT:max:MAX:%5.1lf%sdBm Max,', 'GPRINT:avg:LAST:%5.1lf%sdBm Last\l' ], signal_quality => ['-v', '%', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Quality", 'GPRINT:min:MIN:%5.1lf%s%% Min,', 'GPRINT:avg:AVERAGE:%5.1lf%s%% Avg,', 'GPRINT:max:MAX:%5.1lf%s%% Max,', 'GPRINT:avg:LAST:%5.1lf%s%% Last\l' ], swap => ['-v', 'Bytes', '-b', '1024', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Bytes", 'GPRINT:min:MIN:%6.2lf%sByte Min,', 'GPRINT:avg:AVERAGE:%6.2lf%sByte Avg,', 'GPRINT:max:MAX:%6.2lf%sByte Max,', 'GPRINT:avg:LAST:%6.2lf%sByte Last\l' ], old_swap => [ 'DEF:used_avg={file}:used:AVERAGE', 'DEF:used_min={file}:used:MIN', 'DEF:used_max={file}:used:MAX', 'DEF:free_avg={file}:free:AVERAGE', 'DEF:free_min={file}:free:MIN', 'DEF:free_max={file}:free:MAX', 'DEF:cach_avg={file}:cached:AVERAGE', 'DEF:cach_min={file}:cached:MIN', 'DEF:cach_max={file}:cached:MAX', 'DEF:resv_avg={file}:resv:AVERAGE', 'DEF:resv_min={file}:resv:MIN', 'DEF:resv_max={file}:resv:MAX', 'CDEF:cach_avg_notnull=cach_avg,UN,0,cach_avg,IF', 'CDEF:resv_avg_notnull=resv_avg,UN,0,resv_avg,IF', 'CDEF:used_acc=used_avg', 'CDEF:resv_acc=used_acc,resv_avg_notnull,+', 'CDEF:cach_acc=resv_acc,cach_avg_notnull,+', 'CDEF:free_acc=cach_acc,free_avg,+', "AREA:free_acc#$HalfGreen", "AREA:cach_acc#$HalfBlue", "AREA:resv_acc#$HalfYellow", "AREA:used_acc#$HalfRed", "LINE1:free_acc#$FullGreen:Free ", 'GPRINT:free_min:MIN:%5.1lf%s Min,', 'GPRINT:free_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:free_max:MAX:%5.1lf%s Max,', 'GPRINT:free_avg:LAST:%5.1lf%s Last\n', "LINE1:cach_acc#$FullBlue:Cached ", 'GPRINT:cach_min:MIN:%5.1lf%s Min,', 'GPRINT:cach_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:cach_max:MAX:%5.1lf%s Max,', 'GPRINT:cach_avg:LAST:%5.1lf%s Last\l', "LINE1:resv_acc#$FullYellow:Reserved", 'GPRINT:resv_min:MIN:%5.1lf%s Min,', 'GPRINT:resv_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:resv_max:MAX:%5.1lf%s Max,', 'GPRINT:resv_avg:LAST:%5.1lf%s Last\n', "LINE1:used_acc#$FullRed:Used ", 'GPRINT:used_min:MIN:%5.1lf%s Min,', 'GPRINT:used_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:used_max:MAX:%5.1lf%s Max,', 'GPRINT:used_avg:LAST:%5.1lf%s Last\l' ], tcp_connections => ['-v', 'Connections', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Connections", 'GPRINT:min:MIN:%4.1lf Min,', 'GPRINT:avg:AVERAGE:%4.1lf Avg,', 'GPRINT:max:MAX:%4.1lf Max,', 'GPRINT:avg:LAST:%4.1lf Last\l' ], temperature => ['-v', 'Celsius', 'DEF:temp_avg={file}:value:AVERAGE', 'DEF:temp_min={file}:value:MIN', 'DEF:temp_max={file}:value:MAX', 'CDEF:average=temp_avg,0.2,*,PREV,UN,temp_avg,PREV,IF,0.8,*,+', "AREA:temp_max#$HalfRed", "AREA:temp_min#$Canvas", "LINE1:temp_avg#$FullRed:Temperature", 'GPRINT:temp_min:MIN:%4.1lf Min,', 'GPRINT:temp_avg:AVERAGE:%4.1lf Avg,', 'GPRINT:temp_max:MAX:%4.1lf Max,', 'GPRINT:temp_avg:LAST:%4.1lf Last\l' ], timeleft => ['-v', 'Minutes', 'DEF:avg={file}:timeleft:AVERAGE', 'DEF:min={file}:timeleft:MIN', 'DEF:max={file}:timeleft:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Time left [min]", 'GPRINT:min:MIN:%5.1lf%s Min,', 'GPRINT:avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:max:MAX:%5.1lf%s Max,', 'GPRINT:avg:LAST:%5.1lf%s Last\l' ], time_offset => [ # NTPd 'DEF:s_avg={file}:seconds:AVERAGE', 'DEF:s_min={file}:seconds:MIN', 'DEF:s_max={file}:seconds:MAX', "AREA:s_max#$HalfBlue", "AREA:s_min#$Canvas", "LINE1:s_avg#$FullBlue:{inst}", 'GPRINT:s_min:MIN:%7.3lf%s Min,', 'GPRINT:s_avg:AVERAGE:%7.3lf%s Avg,', 'GPRINT:s_max:MAX:%7.3lf%s Max,', 'GPRINT:s_avg:LAST:%7.3lf%s Last' ], if_octets => ['-v', 'Bits/s', '-l', '0', 'DEF:out_min_raw={file}:tx:MIN', 'DEF:out_avg_raw={file}:tx:AVERAGE', 'DEF:out_max_raw={file}:tx:MAX', 'DEF:inc_min_raw={file}:rx:MIN', 'DEF:inc_avg_raw={file}:rx:AVERAGE', 'DEF:inc_max_raw={file}:rx:MAX', 'CDEF:out_min=out_min_raw,8,*', 'CDEF:out_avg=out_avg_raw,8,*', 'CDEF:out_max=out_max_raw,8,*', 'CDEF:inc_min=inc_min_raw,8,*', 'CDEF:inc_avg=inc_avg_raw,8,*', 'CDEF:inc_max=inc_max_raw,8,*', 'CDEF:overlap=out_avg,inc_avg,GT,inc_avg,out_avg,IF', 'CDEF:mytime=out_avg_raw,TIME,TIME,IF', 'CDEF:sample_len_raw=mytime,PREV(mytime),-', 'CDEF:sample_len=sample_len_raw,UN,0,sample_len_raw,IF', 'CDEF:out_avg_sample=out_avg_raw,UN,0,out_avg_raw,IF,sample_len,*', 'CDEF:out_avg_sum=PREV,UN,0,PREV,IF,out_avg_sample,+', 'CDEF:inc_avg_sample=inc_avg_raw,UN,0,inc_avg_raw,IF,sample_len,*', 'CDEF:inc_avg_sum=PREV,UN,0,PREV,IF,inc_avg_sample,+', "AREA:out_avg#$HalfGreen", "AREA:inc_avg#$HalfBlue", "AREA:overlap#$HalfBlueGreen", "LINE1:out_avg#$FullGreen:Outgoing", 'GPRINT:out_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:out_max:MAX:%5.1lf%s Max,', 'GPRINT:out_avg:LAST:%5.1lf%s Last', 'GPRINT:out_avg_sum:LAST:(ca. %5.1lf%sB Total)\l', "LINE1:inc_avg#$FullBlue:Incoming", #'GPRINT:inc_min:MIN:%5.1lf %s Min,', 'GPRINT:inc_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:inc_max:MAX:%5.1lf%s Max,', 'GPRINT:inc_avg:LAST:%5.1lf%s Last', 'GPRINT:inc_avg_sum:LAST:(ca. %5.1lf%sB Total)\l' ], cpufreq => [ 'DEF:cpufreq_avg={file}:value:AVERAGE', 'DEF:cpufreq_min={file}:value:MIN', 'DEF:cpufreq_max={file}:value:MAX', "AREA:cpufreq_max#$HalfBlue", "AREA:cpufreq_min#$Canvas", "LINE1:cpufreq_avg#$FullBlue:Frequency", 'GPRINT:cpufreq_min:MIN:%5.1lf%s Min,', 'GPRINT:cpufreq_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:cpufreq_max:MAX:%5.1lf%s Max,', 'GPRINT:cpufreq_avg:LAST:%5.1lf%s Last\l' ], multimeter => [ 'DEF:multimeter_avg={file}:value:AVERAGE', 'DEF:multimeter_min={file}:value:MIN', 'DEF:multimeter_max={file}:value:MAX', "AREA:multimeter_max#$HalfBlue", "AREA:multimeter_min#$Canvas", "LINE1:multimeter_avg#$FullBlue:Multimeter", 'GPRINT:multimeter_min:MIN:%4.1lf Min,', 'GPRINT:multimeter_avg:AVERAGE:%4.1lf Average,', 'GPRINT:multimeter_max:MAX:%4.1lf Max,', 'GPRINT:multimeter_avg:LAST:%4.1lf Last\l' ], users => ['-v', 'Users', 'DEF:users_avg={file}:users:AVERAGE', 'DEF:users_min={file}:users:MIN', 'DEF:users_max={file}:users:MAX', "AREA:users_max#$HalfBlue", "AREA:users_min#$Canvas", "LINE1:users_avg#$FullBlue:Users", 'GPRINT:users_min:MIN:%4.1lf Min,', 'GPRINT:users_avg:AVERAGE:%4.1lf Average,', 'GPRINT:users_max:MAX:%4.1lf Max,', 'GPRINT:users_avg:LAST:%4.1lf Last\l' ], voltage => ['-v', 'Voltage', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Voltage", 'GPRINT:min:MIN:%5.1lf%sV Min,', 'GPRINT:avg:AVERAGE:%5.1lf%sV Avg,', 'GPRINT:max:MAX:%5.1lf%sV Max,', 'GPRINT:avg:LAST:%5.1lf%sV Last\l' ], vs_threads => [ "DEF:avg={file}:value:AVERAGE", "DEF:min={file}:value:MIN", "DEF:max={file}:value:MAX", "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Threads", 'GPRINT:min:MIN:%5.1lf Min,', 'GPRINT:avg:AVERAGE:%5.1lf Avg.,', 'GPRINT:max:MAX:%5.1lf Max,', 'GPRINT:avg:LAST:%5.1lf Last\l', ], vs_memory => ['-b', '1024', '-v', 'Bytes', "DEF:avg={file}:value:AVERAGE", "DEF:min={file}:value:MIN", "DEF:max={file}:value:MAX", "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:", 'GPRINT:min:MIN:%5.1lf%sbytes Min,', 'GPRINT:avg:AVERAGE:%5.1lf%sbytes Avg.,', 'GPRINT:max:MAX:%5.1lf%sbytes Max,', 'GPRINT:avg:LAST:%5.1lf%sbytes Last\l', ], vs_processes => [ "DEF:avg={file}:value:AVERAGE", "DEF:min={file}:value:MIN", "DEF:max={file}:value:MAX", "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Processes", 'GPRINT:min:MIN:%5.1lf Min,', 'GPRINT:avg:AVERAGE:%5.1lf Avg.,', 'GPRINT:max:MAX:%5.1lf Max,', 'GPRINT:avg:LAST:%5.1lf Last\l', ], vmpage_number => ['-v', 'Pages', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Number", 'GPRINT:min:MIN:%4.1lf Min,', 'GPRINT:avg:AVERAGE:%4.1lf Avg,', 'GPRINT:max:MAX:%4.1lf Max,', 'GPRINT:avg:LAST:%4.1lf Last\l' ], vmpage_faults => [ "DEF:minf_avg={file}:minflt:AVERAGE", "DEF:minf_min={file}:minflt:MIN", "DEF:minf_max={file}:minflt:MAX", "DEF:majf_avg={file}:majflt:AVERAGE", "DEF:majf_min={file}:majflt:MIN", "DEF:majf_max={file}:majflt:MAX", 'CDEF:overlap=majf_avg,minf_avg,GT,minf_avg,majf_avg,IF', "AREA:majf_avg#$HalfGreen", "AREA:minf_avg#$HalfBlue", "AREA:overlap#$HalfBlueGreen", "LINE1:majf_avg#$FullGreen:Major", 'GPRINT:majf_min:MIN:%5.1lf%s Min,', 'GPRINT:majf_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:majf_max:MAX:%5.1lf%s Max,', 'GPRINT:majf_avg:LAST:%5.1lf%s Last\l', "LINE1:minf_avg#$FullBlue:Minor", 'GPRINT:minf_min:MIN:%5.1lf%s Min,', 'GPRINT:minf_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:minf_max:MAX:%5.1lf%s Max,', 'GPRINT:minf_avg:LAST:%5.1lf%s Last\l' ], vmpage_io => [ "DEF:rpag_avg={file}:in:AVERAGE", "DEF:rpag_min={file}:in:MIN", "DEF:rpag_max={file}:in:MAX", "DEF:wpag_avg={file}:out:AVERAGE", "DEF:wpag_min={file}:out:MIN", "DEF:wpag_max={file}:out:MAX", 'CDEF:overlap=wpag_avg,rpag_avg,GT,rpag_avg,wpag_avg,IF', "AREA:wpag_avg#$HalfGreen", "AREA:rpag_avg#$HalfBlue", "AREA:overlap#$HalfBlueGreen", "LINE1:wpag_avg#$FullGreen:OUT", 'GPRINT:wpag_min:MIN:%5.1lf%s Min,', 'GPRINT:wpag_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:wpag_max:MAX:%5.1lf%s Max,', 'GPRINT:wpag_avg:LAST:%5.1lf%s Last\l', "LINE1:rpag_avg#$FullBlue:IN ", 'GPRINT:rpag_min:MIN:%5.1lf%s Min,', 'GPRINT:rpag_avg:AVERAGE:%5.1lf%s Avg,', 'GPRINT:rpag_max:MAX:%5.1lf%s Max,', 'GPRINT:rpag_avg:LAST:%5.1lf%s Last\l' ], vmpage_action => ['-v', 'Pages', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', 'DEF:max={file}:value:MAX', "AREA:max#$HalfBlue", "AREA:min#$Canvas", "LINE1:avg#$FullBlue:Number", 'GPRINT:min:MIN:%4.1lf Min,', 'GPRINT:avg:AVERAGE:%4.1lf Avg,', 'GPRINT:max:MAX:%4.1lf Max,', 'GPRINT:avg:LAST:%4.1lf Last\l' ], virt_cpu_total => ['-v', 'Milliseconds', 'DEF:avg_raw={file}:ns:AVERAGE', 'DEF:min_raw={file}:ns:MIN', 'DEF:max_raw={file}:ns:MAX', 'CDEF:avg=avg_raw,1000000,/', 'CDEF:min=min_raw,1000000,/', 'CDEF:max=max_raw,1000000,/', "AREA:avg#$HalfBlue", "LINE1:avg#$FullBlue:CPU time", 'GPRINT:min:MIN:%4.1lf Min,', 'GPRINT:avg:AVERAGE:%4.1lf Avg,', 'GPRINT:max:MAX:%4.1lf Max,', 'GPRINT:avg:LAST:%4.1lf Last\l' ], }; $GraphDefs->{'if_multicast'} = $GraphDefs->{'ipt_packets'}; $GraphDefs->{'if_tx_errors'} = $GraphDefs->{'if_rx_errors'}; $GraphDefs->{'dns_qtype'} = $GraphDefs->{'dns_opcode'}; $GraphDefs->{'dns_rcode'} = $GraphDefs->{'dns_opcode'}; $GraphDefs->{'vmpage_io-memory'} = $GraphDefs->{'vmpage_io'}; $GraphDefs->{'vmpage_io-swap'} = $GraphDefs->{'vmpage_io'}; $GraphDefs->{'virt_cpu_total'} = $GraphDefs->{'virt_cpu_total'}; $MetaGraphDefs->{'cpu'} = \&meta_graph_cpu; $MetaGraphDefs->{'dns_qtype'} = \&meta_graph_dns; $MetaGraphDefs->{'dns_rcode'} = \&meta_graph_dns; $MetaGraphDefs->{'if_rx_errors'} = \&meta_graph_if_rx_errors; $MetaGraphDefs->{'if_tx_errors'} = \&meta_graph_if_rx_errors; $MetaGraphDefs->{'memory'} = \&meta_graph_memory; $MetaGraphDefs->{'nfs_procedure'} = \&meta_graph_nfs_procedure; $MetaGraphDefs->{'ps_state'} = \&meta_graph_ps_state; $MetaGraphDefs->{'swap'} = \&meta_graph_swap; $MetaGraphDefs->{'mysql_commands'} = \&meta_graph_mysql_commands; $MetaGraphDefs->{'mysql_handler'} = \&meta_graph_mysql_commands; $MetaGraphDefs->{'tcp_connections'} = \&meta_graph_tcp_connections; $MetaGraphDefs->{'vmpage_number'} = \&meta_graph_vmpage_number; $MetaGraphDefs->{'vmpage_action'} = \&meta_graph_vmpage_action; } # load_graph_definitions sub meta_graph_generic_stack { confess ("Wrong number of arguments") if (@_ != 2); my $opts = shift; my $sources = shift; my $i; my $timespan_str = _get_param_timespan (); my $timespan_int = (-1) * $ValidTimespan->{$timespan_str}; $opts->{'title'} ||= 'Unknown title'; $opts->{'rrd_opts'} ||= []; $opts->{'colors'} ||= {}; my @cmd = ('-', '-a', 'PNG', '-s', $timespan_int, '-t', $opts->{'title'} || 'Unknown title', @RRDDefaultArgs, @{$opts->{'rrd_opts'}}); my $max_inst_name = 0; my @vnames = (); for ($i = 0; $i < @$sources; $i++) { my $tmp = $sources->[$i]->{'name'}; $tmp =~ tr/A-Za-z0-9\-_/_/c; $vnames[$i] = $i . $tmp; } for ($i = 0; $i < @$sources; $i++) { my $inst_data = $sources->[$i]; my $inst_name = $inst_data->{'name'} || confess; my $file = $inst_data->{'file'} || confess; my $vname = $vnames[$i]; if (length ($inst_name) > $max_inst_name) { $max_inst_name = length ($inst_name); } confess ("No such file: $file") if (!-e $file); push (@cmd, qq#DEF:${vname}_min=$file:value:MIN#, qq#DEF:${vname}_avg=$file:value:AVERAGE#, qq#DEF:${vname}_max=$file:value:MAX#, qq#CDEF:${vname}_nnl=${vname}_avg,UN,0,${vname}_avg,IF#); } { my $vname = $vnames[@vnames - 1]; push (@cmd, qq#CDEF:${vname}_stk=${vname}_nnl#); } for (my $i = 1; $i < @$sources; $i++) { my $vname0 = $vnames[@vnames - ($i + 1)]; my $vname1 = $vnames[@vnames - $i]; push (@cmd, qq#CDEF:${vname0}_stk=${vname0}_nnl,${vname1}_stk,+#); } for (my $i = 0; $i < @$sources; $i++) { my $inst_data = $sources->[$i]; my $inst_name = $inst_data->{'name'}; my $vname = $vnames[$i]; my $legend = sprintf ('%-*s', $max_inst_name, $inst_name); my $line_color; my $area_color; my $number_format = $opts->{'number_format'} || '%6.1lf'; if (exists ($opts->{'colors'}{$inst_name})) { $line_color = $opts->{'colors'}{$inst_name}; $area_color = _string_to_color ($line_color); } else { $area_color = _get_random_color (); $line_color = _color_to_string ($area_color); } $area_color = _color_to_string (_get_faded_color ($area_color)); push (@cmd, qq(AREA:${vname}_stk#$area_color), qq(LINE1:${vname}_stk#$line_color:$legend), qq(GPRINT:${vname}_min:MIN:$number_format Min,), qq(GPRINT:${vname}_avg:AVERAGE:$number_format Avg,), qq(GPRINT:${vname}_max:MAX:$number_format Max,), qq(GPRINT:${vname}_avg:LAST:$number_format Last\\l), ); } RRDs::graph (@cmd); if (my $errmsg = RRDs::error ()) { confess ("RRDs::graph: $errmsg"); } } # meta_graph_generic_stack sub meta_graph_cpu { confess ("Wrong number of arguments") if (@_ != 5); my $host = shift; my $plugin = shift; my $plugin_instance = shift; my $type = shift; my $type_instances = shift; my $opts = {}; my $sources = []; $opts->{'title'} = "$host/$plugin" . (defined ($plugin_instance) ? "-$plugin_instance" : '') . "/$type"; $opts->{'rrd_opts'} = ['-v', 'Percent']; my @files = (); $opts->{'colors'} = { 'idle' => 'ffffff', 'nice' => '00e000', 'user' => '0000ff', 'wait' => 'ffb000', 'system' => 'ff0000', 'softirq' => 'ff00ff', 'interrupt' => 'a000a0', 'steal' => '000000' }; _custom_sort_arrayref ($type_instances, [qw(idle nice user wait system softirq interrupt steal)]); for (@$type_instances) { my $inst = $_; my $file = ''; my $title = $opts->{'title'}; for (@DataDirs) { if (-e "$_/$title-$inst.rrd") { $file = "$_/$title-$inst.rrd"; last; } } confess ("No file found for $title") if ($file eq ''); push (@$sources, { name => $inst, file => $file } ); } # for (@$type_instances) return (meta_graph_generic_stack ($opts, $sources)); } # meta_graph_cpu sub meta_graph_dns { confess ("Wrong number of arguments") if (@_ != 5); my $host = shift; my $plugin = shift; my $plugin_instance = shift; my $type = shift; my $type_instances = shift; my $opts = {}; my $sources = []; $opts->{'title'} = "$host/$plugin" . (defined ($plugin_instance) ? "-$plugin_instance" : '') . "/$type"; $opts->{'rrd_opts'} = ['-v', 'Queries/s']; my @files = (); @$type_instances = sort @$type_instances; $opts->{'colors'} = _get_n_colors ($type_instances); for (@$type_instances) { my $inst = $_; my $file = ''; my $title = $opts->{'title'}; for (@DataDirs) { if (-e "$_/$title-$inst.rrd") { $file = "$_/$title-$inst.rrd"; last; } } confess ("No file found for $title") if ($file eq ''); push (@$sources, { name => $inst, file => $file } ); } # for (@$type_instances) return (meta_graph_generic_stack ($opts, $sources)); } # meta_graph_dns sub meta_graph_memory { confess ("Wrong number of arguments") if (@_ != 5); my $host = shift; my $plugin = shift; my $plugin_instance = shift; my $type = shift; my $type_instances = shift; my $opts = {}; my $sources = []; $opts->{'title'} = "$host/$plugin" . (defined ($plugin_instance) ? "-$plugin_instance" : '') . "/$type"; $opts->{'number_format'} = '%5.1lf%s'; $opts->{'rrd_opts'} = ['-b', '1024', '-v', 'Bytes']; my @files = (); $opts->{'colors'} = { 'free' => '00e000', 'cached' => '0000ff', 'buffered' => 'ffb000', 'used' => 'ff0000' }; _custom_sort_arrayref ($type_instances, [qw(free cached buffered used)]); for (@$type_instances) { my $inst = $_; my $file = ''; my $title = $opts->{'title'}; for (@DataDirs) { if (-e "$_/$title-$inst.rrd") { $file = "$_/$title-$inst.rrd"; last; } } confess ("No file found for $title") if ($file eq ''); push (@$sources, { name => $inst, file => $file } ); } # for (@$type_instances) return (meta_graph_generic_stack ($opts, $sources)); } # meta_graph_memory sub meta_graph_if_rx_errors { confess ("Wrong number of arguments") if (@_ != 5); my $host = shift; my $plugin = shift; my $plugin_instance = shift; my $type = shift; my $type_instances = shift; my $opts = {}; my $sources = []; $opts->{'title'} = "$host/$plugin" . (defined ($plugin_instance) ? "-$plugin_instance" : '') . "/$type"; $opts->{'number_format'} = '%5.2lf'; $opts->{'rrd_opts'} = ['-v', 'Errors/s']; my @files = (); for (sort @$type_instances) { my $inst = $_; my $file = ''; my $title = $opts->{'title'}; for (@DataDirs) { if (-e "$_/$title-$inst.rrd") { $file = "$_/$title-$inst.rrd"; last; } } confess ("No file found for $title") if ($file eq ''); push (@$sources, { name => $inst, file => $file } ); } # for (@$type_instances) return (meta_graph_generic_stack ($opts, $sources)); } # meta_graph_if_rx_errors sub meta_graph_mysql_commands { confess ("Wrong number of arguments") if (@_ != 5); my $host = shift; my $plugin = shift; my $plugin_instance = shift; my $type = shift; my $type_instances = shift; my $opts = {}; my $sources = []; $opts->{'title'} = "$host/$plugin" . (defined ($plugin_instance) ? "-$plugin_instance" : '') . "/$type"; $opts->{'number_format'} = '%5.2lf'; my @files = (); for (sort @$type_instances) { my $inst = $_; my $file = ''; my $title = $opts->{'title'}; for (@DataDirs) { if (-e "$_/$title-$inst.rrd") { $file = "$_/$title-$inst.rrd"; last; } } confess ("No file found for $title") if ($file eq ''); push (@$sources, { name => $inst, file => $file } ); } # for (@$type_instances) return (meta_graph_generic_stack ($opts, $sources)); } # meta_graph_mysql_commands sub meta_graph_nfs_procedure { confess ("Wrong number of arguments") if (@_ != 5); my $host = shift; my $plugin = shift; my $plugin_instance = shift; my $type = shift; my $type_instances = shift; my $opts = {}; my $sources = []; $opts->{'title'} = "$host/$plugin" . (defined ($plugin_instance) ? "-$plugin_instance" : '') . "/$type"; $opts->{'number_format'} = '%5.1lf%s'; my @files = (); for (sort @$type_instances) { my $inst = $_; my $file = ''; my $title = $opts->{'title'}; for (@DataDirs) { if (-e "$_/$title-$inst.rrd") { $file = "$_/$title-$inst.rrd"; last; } } confess ("No file found for $title") if ($file eq ''); push (@$sources, { name => $inst, file => $file } ); } # for (@$type_instances) return (meta_graph_generic_stack ($opts, $sources)); } # meta_graph_nfs_procedure sub meta_graph_ps_state { confess ("Wrong number of arguments") if (@_ != 5); my $host = shift; my $plugin = shift; my $plugin_instance = shift; my $type = shift; my $type_instances = shift; my $opts = {}; my $sources = []; $opts->{'title'} = "$host/$plugin" . (defined ($plugin_instance) ? "-$plugin_instance" : '') . "/$type"; $opts->{'rrd_opts'} = ['-v', 'Processes']; my @files = (); $opts->{'colors'} = { 'Running' => '00e000', 'Sleeping' => '0000ff', 'Paging' => 'ffb000', 'Zombies' => 'ff0000', 'Blocked' => 'ff00ff', 'Stopped' => 'a000a0' }; _custom_sort_arrayref ($type_instances, [qw(paging blocked zombies stopped running sleeping)]); for (@$type_instances) { my $inst = $_; my $file = ''; my $title = $opts->{'title'}; for (@DataDirs) { if (-e "$_/$title-$inst.rrd") { $file = "$_/$title-$inst.rrd"; last; } } confess ("No file found for $title") if ($file eq ''); push (@$sources, { name => ucfirst ($inst), file => $file } ); } # for (@$type_instances) return (meta_graph_generic_stack ($opts, $sources)); } # meta_graph_ps_state sub meta_graph_swap { confess ("Wrong number of arguments") if (@_ != 5); my $host = shift; my $plugin = shift; my $plugin_instance = shift; my $type = shift; my $type_instances = shift; my $opts = {}; my $sources = []; $opts->{'title'} = "$host/$plugin" . (defined ($plugin_instance) ? "-$plugin_instance" : '') . "/$type"; $opts->{'number_format'} = '%5.1lf%s'; $opts->{'rrd_opts'} = ['-v', 'Bytes']; my @files = (); $opts->{'colors'} = { 'Free' => '00e000', 'Cached' => '0000ff', 'Reserved' => 'ffb000', 'Used' => 'ff0000' }; _custom_sort_arrayref ($type_instances, [qw(free cached reserved used)]); for (@$type_instances) { my $inst = $_; my $file = ''; my $title = $opts->{'title'}; for (@DataDirs) { if (-e "$_/$title-$inst.rrd") { $file = "$_/$title-$inst.rrd"; last; } } confess ("No file found for $title") if ($file eq ''); push (@$sources, { name => ucfirst ($inst), file => $file } ); } # for (@$type_instances) return (meta_graph_generic_stack ($opts, $sources)); } # meta_graph_swap sub meta_graph_tcp_connections { confess ("Wrong number of arguments") if (@_ != 5); my $host = shift; my $plugin = shift; my $plugin_instance = shift; my $type = shift; my $type_instances = shift; my $opts = {}; my $sources = []; $opts->{'title'} = "$host/$plugin" . (defined ($plugin_instance) ? "-$plugin_instance" : '') . "/$type"; $opts->{'number_format'} = '%6.2lf'; $opts->{'rrd_opts'} = ['-v', 'Connections']; my @files = (); $opts->{'colors'} = { ESTABLISHED => '00e000', SYN_SENT => '00e0ff', SYN_RECV => '00e0a0', FIN_WAIT1 => 'f000f0', FIN_WAIT2 => 'f000a0', TIME_WAIT => 'ffb000', CLOSE => '0000f0', CLOSE_WAIT => '0000a0', LAST_ACK => '000080', LISTEN => 'ff0000', CLOSING => '000000' }; _custom_sort_arrayref ($type_instances, [reverse qw(ESTABLISHED SYN_SENT SYN_RECV FIN_WAIT1 FIN_WAIT2 TIME_WAIT CLOSE CLOSE_WAIT LAST_ACK CLOSING LISTEN)]); for (@$type_instances) { my $inst = $_; my $file = ''; my $title = $opts->{'title'}; for (@DataDirs) { if (-e "$_/$title-$inst.rrd") { $file = "$_/$title-$inst.rrd"; last; } } confess ("No file found for $title") if ($file eq ''); push (@$sources, { name => $inst, file => $file } ); } # for (@$type_instances) return (meta_graph_generic_stack ($opts, $sources)); } # meta_graph_tcp_connections sub meta_graph_vmpage_number { confess ("Wrong number of arguments") if (@_ != 5); my $host = shift; my $plugin = shift; my $plugin_instance = shift; my $type = shift; my $type_instances = shift; my $opts = {}; my $sources = []; $opts->{'title'} = "$host/$plugin" . (defined ($plugin_instance) ? "-$plugin_instance" : '') . "/$type"; $opts->{'number_format'} = '%6.2lf'; $opts->{'rrd_opts'} = ['-v', 'Pages']; my @files = (); $opts->{'colors'} = { anon_pages => '00e000', bounce => '00e0ff', dirty => '00e0a0', file_pages => 'f000f0', mapped => 'f000a0', page_table_pages => 'ffb000', slab => '0000f0', unstable => '0000a0', writeback => 'ff0000', }; _custom_sort_arrayref ($type_instances, [reverse qw(anon_pages bounce dirty file_pages mapped page_table_pages slab unstable writeback)]); for (@$type_instances) { my $inst = $_; my $file = ''; my $title = $opts->{'title'}; for (@DataDirs) { if (-e "$_/$title-$inst.rrd") { $file = "$_/$title-$inst.rrd"; last; } } confess ("No file found for $title") if ($file eq ''); push (@$sources, { name => $inst, file => $file } ); } # for (@$type_instances) return (meta_graph_generic_stack ($opts, $sources)); } # meta_graph_vmpage_number sub meta_graph_vmpage_action { confess ("Wrong number of arguments") if (@_ != 5); my $host = shift; my $plugin = shift; my $plugin_instance = shift; my $type = shift; my $type_instances = shift; my $opts = {}; my $sources = []; $opts->{'title'} = "$host/$plugin" . (defined ($plugin_instance) ? "-$plugin_instance" : '') . "/$type"; $opts->{'number_format'} = '%6.2lf'; $opts->{'rrd_opts'} = ['-v', 'Pages']; my @files = (); $opts->{'colors'} = { activate => '00e000', deactivate => '00e0ff', free => '00e0a0', alloc => 'f000f0', refill => 'f000a0', scan_direct => 'ffb000', scan_kswapd => '0000f0', steal => '0000a0', }; _custom_sort_arrayref ($type_instances, [reverse qw(activate deactivate alloc free refill scan_direct scan_kswapd steal)]); for (@$type_instances) { my $inst = $_; my $file = ''; my $title = $opts->{'title'}; for (@DataDirs) { if (-e "$_/$title-$inst.rrd") { $file = "$_/$title-$inst.rrd"; last; } } confess ("No file found for $title") if ($file eq ''); push (@$sources, { name => $inst, file => $file } ); } # for (@$type_instances) return (meta_graph_generic_stack ($opts, $sources)); } # meta_graph_vmpage_action # vim: shiftwidth=2:softtabstop=2:tabstop=8 collectd-5.4.0/contrib/PaxHeaders.11991/exec-ksm.sh0000644037772200116100000000013212204120331020053 xustar000000000000000030 mtime=1376821465.053973118 30 atime=1376821477.202167674 30 ctime=1376821742.458407887 collectd-5.4.0/contrib/exec-ksm.sh0000754037772200116100000000360012204120331016620 0ustar00octoeng00000000000000#!/bin/bash # collectd - contrib/exec-ksm.sh # Copyright (C) 2011 Florian Forster # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. # # Authors: # Florian Forster HOSTNAME="${COLLECTD_HOSTNAME:-$(hostname -f)}" INTERVAL="${COLLECTD_INTERVAL:-60}" function read_file() { local type="$1" local type_instance="$2" local file_name="/sys/kernel/mm/ksm/$3" local ident="$HOSTNAME/exec-ksm/vmpage_number-${type_instance}" echo "PUTVAL \"$ident\" interval=$INTERVAL N:$(< $file_name)" } if [[ 0 -eq $(< /sys/kernel/mm/ksm/run) ]]; then echo "$0: KSM not active." >&2 exit 1 fi while sleep "$INTERVAL" do read_file vmpage_number shared pages_shared read_file vmpage_number saved pages_sharing read_file vmpage_number unshared pages_unshared read_file vmpage_number volatile pages_volatile read_file total_operations scan full_scans done exit 0 collectd-5.4.0/contrib/PaxHeaders.11991/migrate-4-5.px0000644037772200116100000000013112204120331020306 xustar000000000000000030 mtime=1376821465.053973118 30 atime=1376821477.202167674 29 ctime=1376821742.46240795 collectd-5.4.0/contrib/migrate-4-5.px0000754037772200116100000001561212204120331017062 0ustar00octoeng00000000000000#!/usr/bin/perl # collectd - contrib/migrate-4-5.px # Copyright (C) 2010 Florian Forster # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. # # Authors: # Florian Forster use strict; use warnings; use Getopt::Long ('GetOptions'); use Data::Dumper (); use File::Basename ('dirname'); our $InDir = '/var/lib/collectd'; our $RRDtool = 'rrdtool'; our $RRDFilter = 'rrd_filter.px'; our %TypesCounterToDerive = # {{{ ( apache_bytes => ["count"], apache_requests => ["count"], arc_counts => ["demand_data", "demand_metadata", "prefetch_data", "prefetch_metadata"], arc_l2_bytes => ["read", "write"], ath_stat => ["value"], compression => ["uncompressed", "compressed"], connections => ["value"], cpu => ["value"], current => ["value"], disk_merged => ["read", "write"], disk_octets => ["read", "write"], disk_ops => ["read", "write"], disk_ops_complex => ["value"], disk_time => ["read", "write"], dns_answer => ["value"], dns_notify => ["value"], dns_octets => ["queries", "responses"], dns_opcode => ["value"], dns_qtype => ["value"], dns_query => ["value"], dns_question => ["value"], dns_rcode => ["value"], dns_reject => ["value"], dns_request => ["value"], dns_resolver => ["value"], dns_response => ["value"], dns_transfer => ["value"], dns_update => ["value"], dns_zops => ["value"], fscache_stat => ["value"], fork_rate => ["value"], http_request_methods => ["count"], http_requests => ["count"], http_response_codes => ["count"], if_collisions => ["value"], if_dropped => ["rx", "tx"], if_errors => ["rx", "tx"], if_multicast => ["value"], if_octets => ["rx", "tx"], if_packets => ["rx", "tx"], if_rx_errors => ["value"], if_tx_errors => ["value"], io_octets => ["rx", "tx"], io_packets => ["rx", "tx"], ipt_bytes => ["value"], ipt_packets => ["value"], irq => ["value"], memcached_command => ["value"], memcached_octets => ["rx", "tx"], memcached_ops => ["value"], mysql_commands => ["value"], mysql_handler => ["value"], mysql_locks => ["value"], mysql_log_position => ["value"], mysql_octets => ["rx", "tx"], nfs_procedure => ["value"], nginx_requests => ["value"], node_octets => ["rx", "tx"], node_stat => ["value"], operations => ["value"], pg_blks => ["value"], pg_n_tup_c => ["value"], pg_scan => ["value"], pg_xact => ["value"], protocol_counter => ["value"], ps_cputime => ["user", "syst"], ps_pagefaults => ["minflt", "majflt"], ps_code => ["value"], ps_data => ["value"], serial_octets => ["rx", "tx"], swap_io => ["value"], virt_cpu_total => ["ns"], virt_vcpu => ["ns"], vmpage_action => ["value"], vmpage_faults => ["minflt", "majflt"], vmpage_io => ["in", "out"], ); # }}} %TypesCounterToDerive our %TypesRenameDataSource = # {{{ ( absolute => "count", apache_bytes => "count", apache_connections => "count", apache_idle_workers => "count", apache_requests => "count", apache_scoreboard => "count", conntrack => "entropy", contextswitch => "contextswitches", delay => "seconds", entropy => "entropy", file_size => "bytes", frequency => "frequency", frequency_offset => "ppm", http_request_methods => "count", http_requests => "count", http_response_codes => "count", percent => "percent", ping => "ping", records => "count", time_dispersion => "seconds", timeleft => "timeleft", time_offset => "seconds", users => "users", virt_cpu_total => "ns", virt_vcpu => "ns", ); # }}} %TypesRenameDataSource sub handle_file # {{{ { my @path = @_; my $path = join ('/', @path); if (!($path =~ m/\.rrd$/)) { return; } my $tmp = pop (@path); $tmp =~ s/\.rrd$//; my ($type, $type_inst) = split (m/-/, $tmp, 2); $type_inst ||= ''; $tmp = pop (@path); my ($plugin, $plugin_inst) = split (m/-/, $tmp, 2); $plugin_inst ||= ''; if ($TypesRenameDataSource{$type}) { my $old_ds = $TypesRenameDataSource{$type}; print "$RRDtool tune \"$path\" --data-source-rename ${old_ds}:value\n"; } if ($TypesCounterToDerive{$type}) { my $ds_names = $TypesCounterToDerive{$type}; for (@$ds_names) { my $name = $_; print "$RRDtool tune \"$path\" --data-source-type ${name}:DERIVE --minimum ${name}:0 --maximum ${name}:U\n"; } } if ((($plugin eq 'df') || ($plugin eq 'interface')) && (!$plugin_inst) && ($type_inst)) { my $dir = join ('/', @path); print "mkdir -p \"$dir/$plugin-$type_inst\"\n"; if (($plugin eq 'df') and ($type eq 'df')) { print "$RRDFilter --infile=\"$path\" --outfile=\"$dir/$plugin-$type_inst/df_complex-free.rrd\" --map free:value\n"; print "$RRDFilter --infile=\"$path\" --outfile=\"$dir/$plugin-$type_inst/df_complex-used.rrd\" --map used:value\n"; } else { print "mv \"$path\" \"$dir/$plugin-$type_inst/$type.rrd\"\n"; } } } # }}} sub handle_file sub scan_dir # {{{ { my @dir_parts = @_; my $dir_str = join ('/', @dir_parts); my $dh; opendir ($dh, $dir_str) || die; while (my $entry = readdir ($dh)) { my $entry_path = "$dir_str/$entry"; if ($entry =~ m/^\./) { next; } if (-d $entry_path) { scan_dir (@dir_parts, $entry); } elsif (-f $entry_path) { handle_file (@dir_parts, $entry); } } closedir ($dh); } # }}} sub scan_dir sub exit_usage # {{{ { print STDERR < Source directory Default: $InDir --rrdtool Path to the RRDtool binary Default: $RRDtool --rrdfilter Path to the rrd_filter.px script Default: $RRDFilter EOF exit (1); } # }}} sub exit_usage GetOptions ("indir|i=s" => \$InDir, "rrdtool=s" => \$RRDtool, "rrdfilter=s" => \$RRDFilter, "help|h" => \&exit_usage) or exit_usage (); print "#!/bin/bash\n\n"; scan_dir ($InDir); # vim: set sw=2 sts=2 et fdm=marker : collectd-5.4.0/contrib/PaxHeaders.11991/exec-nagios.conf0000644037772200116100000000013112204120331021053 xustar000000000000000030 mtime=1376821465.053973118 30 atime=1376821477.202167674 29 ctime=1376821742.46240795 collectd-5.4.0/contrib/exec-nagios.conf0000644037772200116100000000041212204120331017615 0ustar00octoeng00000000000000# Run `perldoc exec-nagios.px' for details on this config file. NRPEConfig /etc/nrpe.cfg Interval 300 collectd-5.4.0/contrib/PaxHeaders.11991/README0000644037772200116100000000013112204120331016662 xustar000000000000000030 mtime=1376821465.049973054 29 atime=1376821477.19816761 30 ctime=1376821742.466408014 collectd-5.4.0/contrib/README0000644037772200116100000001061212204120331015427 0ustar00octoeng00000000000000The files in this directory may be used to perform common tasks that aren't exactly `collectd's job. They may or may not require in-depth knowledge of RRD files and/or `collectd's inner workings. Use at your own risk. add_rra.sh ---------- Before version 3.9.0 collectd used to create a different set of RRAs. The most detailed of these old RRAs had a one minute resolution. This script can be used to add three more RRAs: minimum, maximum and average with a ten second resolution and 2200 rows (~6 hours). This will make hourly statistics much more interesting. Please note that no sanity- checking whatsoever is performed. You can seriously fuck up your RRD files if you don't know what you're doing. collectd-network.py ------------------- This Python module by Adrian Perez implements the collectd network protocol in pure Python. It currently supports to receive data and notifications from collectd. collectd-unixsock.py -------------------- This Python module by Clay Loveless provides an interface to collect's unixsock plugin. collectd2html.pl ---------------- This script by Vincent Stehlé will search for RRD files in `/var/lib/collectd/' and generate an HTML file and a directory containing several PNG files which are graphs of the RRD files found. collection.cgi -------------- Sample CGI script that creates graphs on the fly. The Perl modules `RRDs' (Debian package `librrds-perl'), `URI:Escape' (package liburi-perl), `HTML::Entities' (package libhtml-parser-perl) and a CGI capable web server (e.g. apache2 or boa) are needed. Simply install the script to a place where the webserver will treat it as a CGI script (/usr/lib/cgi-bin/ by default) and visit that page in a browser (http://localhost/cgi-bin/collection.cgi by default). Please refer to your webserver's documentation for more details. Starting with version 4, collection.cgi requires a small config file, which should look something like this: datadir: "/var/lib/collectd/rrd/" libdir: "/usr/lib/collectd/" exec-munin.px ------------- Script to be used with the exec-plugin (see collectd-exec(5) for details) which executes munin plugins, parses the output and translates it to a format the exec-plugin understands. The features are limited - changing the munin plugins to use the output format understood by the exec-plugin is recommended. See the embedded POD documentation for more details: $ perldoc contrib/exec-munin.px exec-smartctl ------------- Sample script for the exec plugin. Please refer to the documentation in the file - you will have to adapt it to your needs anyway. extractDS.px ------------ Creates a new RRD-file with only one data-source (DS) of the source-RRD- file. That is very handy when you realise that you have bundled up DSes in one RRD-file that should have been in multiple RRD-files instead. Is is used by `migrate-3-4.px' to split up the cpu-, nfs-, swap-files and possibly others. fedora/ ------- Init-script and Spec-file that can be used when creating RPM-packages for Fedora. GenericJMX.conf --------------- Example configuration file for the ‘GenericJMX’ Java plugin. Please read the documentation at the beginning of the file for more details. migrate-3-4.px -------------- Migration-script to ease the switch from version 3 to version 4. Many RRD-files are expected in a different place, some have been changed (DSes have been renamed) and others have bee split up into multiple files. This script prints a bash-script to STDOUT which should do most of the work for you. You may still need to do some things by hand, read `README.migration' for more details. redhat/ ------- Spec-file and affiliated files to build an RedHat RPM package of collectd. snmp-data.conf -------------- Sample configuration for the SNMP plugin. This config includes a few standard definitions that you can include in your own config using the `Include' statement (available since version 4.2.0). The config includes some data that is defined in the IF-MIB, e. g. octet or packet counters, UPS-MIB and whatever people have send in. If you have some more definitions please send them in, so others can profit from it. solaris-smf ----------- Manifest file for the Solaris SMF system and detailed information on how to register collectd as a service with this system. collectd.service ---------------- Service file for systemd. Please ship this file as /lib/systemd/system/collectd.service in any linux package of collectd. collectd-5.4.0/contrib/PaxHeaders.11991/snmp-data.conf0000644037772200116100000000013212204120331020536 xustar000000000000000030 mtime=1376821465.057973183 30 atime=1376821477.206167738 30 ctime=1376821742.466408014 collectd-5.4.0/contrib/snmp-data.conf0000644037772200116100000003073712204120331017314 0ustar00octoeng00000000000000 # # IF-MIB # Interface statistics using the IF-MIB # Type "if_octets" Table true Instance "IF-MIB::ifDescr" Values "IF-MIB::ifInOctets" "IF-MIB::ifOutOctets" Type "if_octets" Table true Instance "IF-MIB::ifName" Values "IF-MIB::ifHCInOctets" "IF-MIB::ifHCOutOctets" Type "if_packets" Table true Instance "IF-MIB::ifDescr" Values "IF-MIB::ifInUcastPkts" "IF-MIB::ifOutUcastPkts" Type "if_packets" Table true Instance "IF-MIB::ifName" Values "IF-MIB::ifHCInUcastPkts" "IF-MIB::ifHCOutUcastPkts" Type "if_errors" Table true Instance "IF-MIB::ifDescr" Values "IF-MIB::ifInErrors" "IF-MIB::ifOutErrors" Type "if_errors" Table true Instance "IF-MIB::ifName" Values "IF-MIB::ifHCInErrors" "IF-MIB::ifHCOutErrors" # # UPS-MIB # Statistics about your UPS using the UPS-MIB from the RFC1628. # # Battery branch Type "timeleft" Table false Instance "battery" Values ".1.3.6.1.2.1.33.1.2.3.0" Type "percent" Table false Instance "charge-battery" Values ".1.3.6.1.2.1.33.1.2.4.0" Type "voltage" Table false Instance "battery" Values ".1.3.6.1.2.1.33.1.2.5.0" Scale 0.1 Type "current" Table false Instance "battery" Values ".1.3.6.1.2.1.33.1.2.6.0" Scale 0.1 Type "temperature" Table false Instance "battery" Values ".1.3.6.1.2.1.33.1.2.7.0" # Input branch Type "frequency" Table true InstancePrefix "input" Values ".1.3.6.1.2.1.33.1.3.3.1.2" Scale 0.1 Type "voltage" Table true InstancePrefix "input" Values ".1.3.6.1.2.1.33.1.3.3.1.3" Type "current" Table true InstancePrefix "input" Values ".1.3.6.1.2.1.33.1.3.3.1.4" Scale 0.1 Type "power" Table true InstancePrefix "input" Values ".1.3.6.1.2.1.33.1.3.3.1.5" # Output branch Type "frequency" Table false Instance "output" Values ".1.3.6.1.2.1.33.1.4.2.0" Scale 0.1 Type "voltage" Table true InstancePrefix "output" Values ".1.3.6.1.2.1.33.1.4.4.1.2" Type "current" Table true InstancePrefix "output" Values ".1.3.6.1.2.1.33.1.4.4.1.3" Scale 0.1 Type "power" Table true InstancePrefix "output" Values ".1.3.6.1.2.1.33.1.4.4.1.4" Type "percent" Table true InstancePrefix "load-output" Values ".1.3.6.1.2.1.33.1.4.4.1.5" # Bypass branch Type "frequency" Table false Instance "output" Values ".1.3.6.1.2.1.33.1.5.1.0" Scale 0.1 Type "voltage" Table true InstancePrefix "bypass" Values ".1.3.6.1.2.1.33.1.5.3.1.2" Type "current" Table true InstancePrefix "bypass" Values ".1.3.6.1.2.1.33.1.5.3.1.3" Scale 0.1 Type "power" Table true InstancePrefix "bypass" Values ".1.3.6.1.2.1.33.1.5.3.1.4" # Special definitions for broken UPSes Type "voltage" Table false Instance "battery" Values ".1.3.6.1.2.1.33.1.2.5.0" Type "current" Table true InstancePrefix "input" Values ".1.3.6.1.2.1.33.1.3.3.1.4" Type "current" Table true InstancePrefix "output" Values ".1.3.6.1.2.1.33.1.4.4.1.3" # # Riello UPS # Temperatures for UPSes by Riello, # Type "temperature" Table false Instance "system" Values ".1.3.6.1.4.1.5491.1.51.1.5.4.0" Type "temperature" Table false Instance "rectifier" Values ".1.3.6.1.4.1.5491.1.51.1.5.5.0" Type "temperature" Table false Instance "inverter" Values ".1.3.6.1.4.1.5491.1.51.1.5.6.0" # # PowerPlus UPS, manufactured by Gamatronic, , # distributed in Germany by AdPoS, # # Global inputs Type "voltage" Table true InstancePrefix "input" Values ".1.3.6.1.4.1.6050.5.4.1.1.2" Type "current" Table true InstancePrefix "input" Values ".1.3.6.1.4.1.6050.5.4.1.1.3" Type "power" Table true InstancePrefix "apparent-input" Values ".1.3.6.1.4.1.6050.5.4.1.1.4" Scale 100.0 Type "power" Table true InstancePrefix "active-input" Values ".1.3.6.1.4.1.6050.5.4.1.1.5" Scale 100.0 Type "percent" Table true InstancePrefix "performance_factor-input" Values ".1.3.6.1.4.1.6050.5.4.1.1.6" # Global outputs Type "voltage" Table true InstancePrefix "output" Values ".1.3.6.1.4.1.6050.5.5.1.1.2" Type "current" Table true InstancePrefix "output" Values ".1.3.6.1.4.1.6050.5.5.1.1.3" Type "power" Table true InstancePrefix "apparent-output" Values ".1.3.6.1.4.1.6050.5.5.1.1.4" Scale 100.0 Type "power" Table true InstancePrefix "active-output" Values ".1.3.6.1.4.1.6050.5.5.1.1.5" Scale 100.0 Type "percent" Table true InstancePrefix "load_level-output" Values ".1.3.6.1.4.1.6050.5.5.1.1.6" Type "percent" Table true InstancePrefix "active_load_level-output" Values ".1.3.6.1.4.1.6050.5.5.1.1.7" Type "percent" Table true InstancePrefix "performance_factor-output" Values ".1.3.6.1.4.1.6050.5.5.1.1.8" # Global DC Type "voltage" Table false Instance "dc_positive-global" Values ".1.3.6.1.4.1.6050.5.6.1.0" Type "voltage" Table false Instance "dc_negative-global" Values ".1.3.6.1.4.1.6050.5.6.2.0" Type "voltage" Table false Instance "dc_total-global" Values ".1.3.6.1.4.1.6050.5.6.3.0" # # NetApp # Some simple statistics of storage systems by NetApp. # Type "cpu" Table false Instance "system" Values ".1.3.6.1.4.1.789.1.2.1.2.0" Type "cpu" Table false Instance "idle" Values ".1.3.6.1.4.1.789.1.2.1.4.0" Type "if_octets" Table false Instance "net" Values ".1.3.6.1.4.1.789.1.2.2.12.0" ".1.3.6.1.4.1.789.1.2.2.14.0" # # Juniper SSL # Some stats of an SSL-appliance by Juniper. # Type "users" Table false Instance "web" Values ".1.3.6.1.4.1.12532.2.0" Type "users" Table false Instance "mail" Values ".1.3.6.1.4.1.12532.3.0" Type "percent" Table false Instance "logfull" Values ".1.3.6.1.4.1.12532.1.0" Type "percent" Table false Instance "diskfull" Values ".1.3.6.1.4.1.12532.25.0" # # WuT # Some thermometers and digital IO devices from WuT # # Type "temperature" Table true Instance ".1.3.6.1.4.1.5040.1.2.6.3.2.1.1.2" Values ".1.3.6.1.4.1.5040.1.2.6.1.4.1.1" Scale 0.1 Type "temperature" Table true Instance ".1.3.6.1.4.1.5040.1.2.7.3.2.1.1.2" Values ".1.3.6.1.4.1.5040.1.2.7.1.4.1.1" Scale 0.1 Type "temperature" Table true Instance ".1.3.6.1.4.1.5040.1.2.8.3.2.1.1.2" Values ".1.3.6.1.4.1.5040.1.2.8.1.4.1.1" Scale 0.1 Type "temperature" Table true Instance ".1.3.6.1.4.1.5040.1.2.1.3.2.1.1.2" Values ".1.3.6.1.4.1.5040.1.2.1.1.4.1.1" Scale 0.1 Type "temperature" Table true Instance ".1.3.6.1.4.1.5040.1.2.2.3.2.1.1.2" Values ".1.3.6.1.4.1.5040.1.2.2.1.4.1.1" Scale 0.1 Type "temperature" Table true Instance ".1.3.6.1.4.1.5040.1.2.3.3.2.1.1.2" Values ".1.3.6.1.4.1.5040.1.2.3.1.4.1.1" Scale 0.1 # # Infratec # Rack monitoring devices by Infratec, # # Model H2-17 Type "temperature" Table true Instance ".1.3.6.1.4.1.4519.10.4.1.1.2" Values ".1.3.6.1.4.1.4519.10.4.1.1.3" Type "humidity" Table true Instance ".1.3.6.1.4.1.4519.10.5.1.1.2" Values ".1.3.6.1.4.1.4519.10.5.1.1.3" Type "voltage" Table true InstancePrefix "input" Values ".1.3.6.1.4.1.4519.10.6.1.1.3" # Model H2-30 Type "temperature" Table true Instance ".1.3.6.1.4.1.1909.10.4.1.1.2" Values ".1.3.6.1.4.1.1909.10.4.1.1.3" Type "humidity" Table true Instance ".1.3.6.1.4.1.1909.10.5.1.1.2" Values ".1.3.6.1.4.1.1909.10.5.1.1.3" Type "voltage" Table true InstancePrefix "input" Values ".1.3.6.1.4.1.1909.10.6.1.1.3" # # Mikrotik RouterBoards # # Wireless statistics: station mode tYPE "Bitrate" Table true InstancePrefix "st-tx-" Instance ".1.3.6.1.4.1.14988.1.1.1.1.1.5" Values ".1.3.6.1.4.1.14988.1.1.1.1.1.2" Type "bitrate" Table true InstancePrefix "st-rx-" Instance ".1.3.6.1.4.1.14988.1.1.1.1.1.5" Values ".1.3.6.1.4.1.14988.1.1.1.1.1.3" Type "signal_power" Table true InstancePrefix "st-" Instance ".1.3.6.1.4.1.14988.1.1.1.1.1.5" Values ".1.3.6.1.4.1.14988.1.1.1.1.1.4" # Wireless statistics: AP mode / registration table Type "signal_power" Table true InstancePrefix "ap-" Instance ".1.3.6.1.4.1.14988.1.1.1.2.1.1" Values ".1.3.6.1.4.1.14988.1.1.1.2.1.3" Type "if_octets" Table true InstancePrefix "ap-" Instance ".1.3.6.1.4.1.14988.1.1.1.2.1.1" Values ".1.3.6.1.4.1.14988.1.1.1.2.1.5" ".1.3.6.1.4.1.14988.1.1.1.2.1.4" Type "if_packets" Table true InstancePrefix "ap-" Instance ".1.3.6.1.4.1.14988.1.1.1.2.1.1" Values ".1.3.6.1.4.1.14988.1.1.1.2.1.7" ".1.3.6.1.4.1.14988.1.1.1.2.1.6" Type "bitrate" Table true InstancePrefix "ap-tx-" Instance ".1.3.6.1.4.1.14988.1.1.1.2.1.1" Values ".1.3.6.1.4.1.14988.1.1.1.2.1.8" Type "bitrate" Table true InstancePrefix "ap-rx-" Instance ".1.3.6.1.4.1.14988.1.1.1.2.1.1" Values ".1.3.6.1.4.1.14988.1.1.1.2.1.9" collectd-5.4.0/contrib/PaxHeaders.11991/collectd_unixsock.py0000644037772200116100000000013112204120331022070 xustar000000000000000030 mtime=1376821465.049973054 29 atime=1376821477.19816761 30 ctime=1376821742.470408078 collectd-5.4.0/contrib/collectd_unixsock.py0000644037772200116100000001760312204120331020644 0ustar00octoeng00000000000000#-*- coding: ISO-8859-1 -*- # collect.py: the python collectd-unixsock module. # # Requires collectd to be configured with the unixsock plugin, like so: # # LoadPlugin unixsock # # SocketFile "/var/run/collectd-unixsock" # SocketPerms "0775" # # # Copyright (C) 2008 Clay Loveless # # This software is provided 'as-is', without any express or implied # warranty. In no event will the author be held liable for any damages # arising from the use of this software. # # Permission is granted to anyone to use this software for any purpose, # including commercial applications, and to alter it and redistribute it # freely, subject to the following restrictions: # # 1. The origin of this software must not be misrepresented; you must not # claim that you wrote the original software. If you use this software # in a product, an acknowledgment in the product documentation would be # appreciated but is not required. # 2. Altered source versions must be plainly marked as such, and must not be # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. import socket import sys class Collectd(): def __init__(self, path='/var/run/collectd-unixsock', noisy=False): self.noisy = noisy self.path = path self._sock = self._connect() def flush(self, timeout=None, plugins=[], identifiers=[]): """Send a FLUSH command. Full documentation: http://collectd.org/wiki/index.php/Plain_text_protocol#FLUSH """ # have to pass at least one plugin or identifier if not plugins and not identifiers: return None args = [] if timeout: args.append("timeout=%s" % timeout) if plugins: plugin_args = map(lambda x: "plugin=%s" % x, plugins) args.extend(plugin_args) if identifiers: identifier_args = map(lambda x: "identifier=%s" % x, identifiers) args.extend(identifier_args) return self._cmd('FLUSH %s' % ' '.join(args)) def getthreshold(self, identifier): """Send a GETTHRESHOLD command. Full documentation: http://collectd.org/wiki/index.php/Plain_text_protocol#GETTHRESHOLD """ numvalues = self._cmd('GETTHRESHOLD "%s"' % identifier) lines = [] if not numvalues or numvalues < 0: raise KeyError("Identifier '%s' not found" % identifier) lines = self._readlines(numvalues) return lines def getval(self, identifier, flush_after=True): """Send a GETVAL command. Also flushes the identifier if flush_after is True. Full documentation: http://collectd.org/wiki/index.php/Plain_text_protocol#GETVAL """ numvalues = self._cmd('GETVAL "%s"' % identifier) lines = [] if not numvalues or numvalues < 0: raise KeyError("Identifier '%s' not found" % identifier) lines = self._readlines(numvalues) if flush_after: self.flush(identifiers=[identifier]) return lines def listval(self): """Send a LISTVAL command. Full documentation: http://collectd.org/wiki/index.php/Plain_text_protocol#LISTVAL """ numvalues = self._cmd('LISTVAL') lines = [] if numvalues: lines = self._readlines(numvalues) return lines def putnotif(self, message, options={}): """Send a PUTNOTIF command. Options must be passed as a Python dictionary. Example: options={'severity': 'failure', 'host': 'example.com'} Full documentation: http://collectd.org/wiki/index.php/Plain_text_protocol#PUTNOTIF """ args = [] if options: options_args = map(lambda x: "%s=%s" % (x, options[x]), options) args.extend(options_args) args.append('message="%s"' % message) return self._cmd('PUTNOTIF %s' % ' '.join(args)) def putval(self, identifier, values, options={}): """Send a PUTVAL command. Options must be passed as a Python dictionary. Example: options={'interval': 10} Full documentation: http://collectd.org/wiki/index.php/Plain_text_protocol#PUTVAL """ args = [] args.append('"%s"' % identifier) if options: options_args = map(lambda x: "%s=%s" % (x, options[x]), options) args.extend(options_args) values = map(str, values) args.append(':'.join(values)) return self._cmd('PUTVAL %s' % ' '.join(args)) def _cmd(self, c): try: return self._cmdattempt(c) except socket.error, (errno, errstr): sys.stderr.write("[error] Sending to socket failed: [%d] %s\n" % (errno, errstr)) self._sock = self._connect() return self._cmdattempt(c) def _cmdattempt(self, c): if self.noisy: print "[send] %s" % c if not self._sock: sys.stderr.write("[error] Socket unavailable. Can not send.") return False self._sock.send(c + "\n") status_message = self._readline() if self.noisy: print "[receive] %s" % status_message if not status_message: return None code, message = status_message.split(' ', 1) if int(code): return int(code) return False def _connect(self): try: sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) sock.connect(self.path) if self.noisy: print "[socket] connected to %s" % self.path return sock except socket.error, (errno, errstr): sys.stderr.write("[error] Connecting to socket failed: [%d] %s" % (errno, errstr)) return None def _readline(self): """Read single line from socket""" if not self._sock: sys.stderr.write("[error] Socket unavailable. Can not read.") return None try: data = '' buf = [] recv = self._sock.recv while data != "\n": data = recv(1) if not data: break if data != "\n": buf.append(data) return ''.join(buf) except socket.error, (errno, errstr): sys.stderr.write("[error] Reading from socket failed: [%d] %s" % (errno, errstr)) self._sock = self._connect() return None def _readlines(self, sizehint=0): """Read multiple lines from socket""" total = 0 list = [] while True: line = self._readline() if not line: break list.append(line) total = len(list) if sizehint and total >= sizehint: break return list def __del__(self): if not self._sock: return try: self._sock.close() except socket.error, (errno, errstr): sys.stderr.write("[error] Closing socket failed: [%d] %s" % (errno, errstr)) if __name__ == '__main__': """Collect values from socket and dump to STDOUT""" c = Collectd('/var/run/collectd-unixsock', noisy=True) list = c.listval() for val in list: stamp, identifier = val.split() print "\n%s" % identifier print "\tUpdate time: %s" % stamp values = c.getval(identifier) print "\tValue list: %s" % ', '.join(values) # don't fetch thresholds by default because collectd will crash # if there is no treshold for the given identifier #thresholds = c.getthreshold(identifier) #print "\tThresholds: %s" % ', '.join(thresholds) collectd-5.4.0/contrib/PaxHeaders.11991/examples0000644037772200116100000000013212204120331017544 xustar000000000000000030 mtime=1376821465.053973118 30 atime=1376821742.470408078 30 ctime=1376821742.470408078 collectd-5.4.0/contrib/examples/0000755037772200116100000000000012204120331016365 5ustar00octoeng00000000000000collectd-5.4.0/contrib/examples/PaxHeaders.11991/myplugin.c0000644037772200116100000000013212204120331021631 xustar000000000000000030 mtime=1376821465.053973118 30 atime=1376821477.202167674 30 ctime=1376821742.474408142 collectd-5.4.0/contrib/examples/myplugin.c0000644037772200116100000001330612204120331020400 0ustar00octoeng00000000000000/* * /usr/share/doc/collectd/examples/myplugin.c * * A plugin template for collectd. * * Written by Sebastian Harl * * This 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. */ /* * Notes: * - plugins are executed in parallel, thus, thread-safe * functions need to be used * - each of the functions below (except module_register) * is optional */ #if ! HAVE_CONFIG_H #include #include #ifndef __USE_ISOC99 /* required for NAN */ # define DISABLE_ISOC99 1 # define __USE_ISOC99 1 #endif /* !defined(__USE_ISOC99) */ #include #if DISABLE_ISOC99 # undef DISABLE_ISOC99 # undef __USE_ISOC99 #endif /* DISABLE_ISOC99 */ #include #endif /* ! HAVE_CONFIG */ #include #include #include /* * data source definition: * - name of the data source * - type of the data source (DS_TYPE_GAUGE, DS_TYPE_COUNTER) * - minimum allowed value * - maximum allowed value */ static data_source_t dsrc[1] = { { "my_ds", DS_TYPE_GAUGE, 0, NAN } }; /* * data set definition: * - name of the data set * - number of data sources * - list of data sources * * NOTE: If you're defining a custom data-set, you have to make that known to * any servers as well. Else, the server is not able to store values using the * type defined by that data-set. * It is strongly recommended to use one of the types and data-sets * pre-defined in the types.db file. */ static data_set_t ds = { "myplugin", STATIC_ARRAY_SIZE (dsrc), dsrc }; /* * This function is called once upon startup to initialize the plugin. */ static int my_init (void) { /* open sockets, initialize data structures, ... */ /* A return value != 0 indicates an error and causes the plugin to be disabled. */ return 0; } /* static int my_init (void) */ /* * This function is called in regular intervalls to collect the data. */ static int my_read (void) { value_t values[1]; /* the size of this list should equal the number of data sources */ value_list_t vl = VALUE_LIST_INIT; /* do the magic to read the data */ values[0].gauge = random (); vl.values = values; vl.values_len = 1; vl.time = time (NULL); sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "myplugin", sizeof (vl.plugin)); /* optionally set vl.plugin_instance and vl.type_instance to reasonable * values (default: "") */ /* dispatch the values to collectd which passes them on to all registered * write functions - the first argument is used to lookup the data set * definition (it is strongly recommended to use a type defined in the * types.db file) */ plugin_dispatch_values ("myplugin", &vl); /* A return value != 0 indicates an error and the plugin will be skipped * for an increasing amount of time. */ return 0; } /* static int my_read (void) */ /* * This function is called after values have been dispatched to collectd. */ static int my_write (const data_set_t *ds, const value_list_t *vl) { char name[1024] = ""; int i = 0; if (ds->ds_num != vl->values_len) { plugin_log (LOG_WARNING, "DS number does not match values length"); return -1; } /* get the default base filename for the output file - depending on the * provided values this will be something like * /[-]/[-] */ if (0 != format_name (name, 1024, vl->host, vl->plugin, vl->plugin_instance, ds->type, vl->type_instance)) return -1; for (i = 0; i < ds->ds_num; ++i) { /* do the magic to output the data */ printf ("%s (%s) at %i: ", name, (ds->ds->type == DS_TYPE_GAUGE) ? "GAUGE" : "COUNTER", (int)vl->time); if (ds->ds->type == DS_TYPE_GAUGE) printf ("%f\n", vl->values[i].gauge); else printf ("%lld\n", vl->values[i].counter); } return 0; } /* static int my_write (data_set_t *, value_list_t *) */ /* * This function is called when plugin_log () has been used. */ static void my_log (int severity, const char *msg) { printf ("LOG: %i - %s\n", severity, msg); return; } /* static void my_log (int, const char *) */ /* * This function is called when plugin_dispatch_notification () has been used. */ static int my_notify (const notification_t *notif) { char time_str[32] = ""; struct tm *tm = NULL; int n = 0; if (NULL == (tm = localtime (¬if->time))) time_str[0] = '\0'; n = strftime (time_str, 32, "%F %T", tm); if (n >= 32) n = 31; time_str[n] = '\0'; printf ("NOTIF (%s): %i - ", time_str, notif->severity); if ('\0' != *notif->host) printf ("%s: ", notif->host); if ('\0' != *notif->plugin) printf ("%s: ", notif->plugin); if ('\0' != *notif->plugin_instance) printf ("%s: ", notif->plugin_instance); if ('\0' != *notif->type) printf ("%s: ", notif->type); if ('\0' != *notif->type_instance) printf ("%s: ", notif->type_instance); printf ("%s\n", notif->message); return 0; } /* static int my_notify (notification_t *) */ /* * This function is called before shutting down collectd. */ static int my_shutdown (void) { /* close sockets, free data structures, ... */ return 0; } /* static int my_shutdown (void) */ /* * This function is called after loading the plugin to register it with * collectd. */ void module_register (void) { plugin_register_log ("myplugin", my_log); plugin_register_notification ("myplugin", my_notify); plugin_register_data_set (&ds); plugin_register_read ("myplugin", my_read); plugin_register_init ("myplugin", my_init); plugin_register_write ("myplugin", my_write); plugin_register_shutdown ("myplugin", my_shutdown); return; } /* void module_register (void) */ collectd-5.4.0/contrib/examples/PaxHeaders.11991/MyPlugin.pm0000644037772200116100000000013212204120331021723 xustar000000000000000030 mtime=1376821465.053973118 30 atime=1376821477.202167674 30 ctime=1376821742.474408142 collectd-5.4.0/contrib/examples/MyPlugin.pm0000644037772200116100000001050512204120331020470 0ustar00octoeng00000000000000# /usr/share/doc/collectd/examples/MyPlugin.pm # # A Perl plugin template for collectd. # # Written by Sebastian Harl # # This 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. # Notes: # - each of the functions below (and the corresponding plugin_register call) # is optional package Collectd::Plugin::MyPlugin; use strict; use warnings; use Collectd qw( :all ); # data set definition: # see section "DATA TYPES" in collectd-perl(5) for details # # NOTE: If you're defining a custom data-set, you have to make that known to # any servers as well. Else, the server is not able to store values using the # type defined by that data-set. # It is strongly recommended to use one of the types and data-sets pre-defined # in the types.db file. my $dataset = [ { name => 'my_ds', type => DS_TYPE_GAUGE, min => 0, max => 65535, }, ]; # This code is executed after loading the plugin to register it with collectd. plugin_register (TYPE_LOG, 'myplugin', 'my_log'); plugin_register (TYPE_NOTIF, 'myplugin', 'my_notify'); plugin_register (TYPE_DATASET, 'mytype', $dataset); plugin_register (TYPE_INIT, 'myplugin', 'my_init'); plugin_register (TYPE_READ, 'myplugin', 'my_read'); plugin_register (TYPE_WRITE, 'myplugin', 'my_write'); plugin_register (TYPE_SHUTDOWN, 'myplugin', 'my_shutdown'); # For each of the functions below see collectd-perl(5) for details about # arguments and the like. # This function is called once upon startup to initialize the plugin. sub my_init { # open sockets, initialize data structures, ... # A false return value indicates an error and causes the plugin to be # disabled. return 1; } # my_init () # This function is called in regular intervals to collectd the data. sub my_read { # value list to dispatch to collectd: # see section "DATA TYPES" in collectd-perl(5) for details my $vl = {}; # do the magic to read the data: # the number of values has to match the number of data sources defined in # the registered data set. The type used here (in this example: # "mytype") must be defined in the types.db, see types.db(5) for # details, or registered as "TYPE_DATASET". $vl->{'values'} = [ rand(65535) ]; $vl->{'plugin'} = 'myplugin'; $vl->{'type'} = 'mytype'; # any other elements are optional # dispatch the values to collectd which passes them on to all registered # write functions plugin_dispatch_values ($vl); # A false return value indicates an error and the plugin will be skipped # for an increasing amount of time. return 1; } # my_read () # This function is called after values have been dispatched to collectd. sub my_write { my $type = shift; my $ds = shift; my $vl = shift; if (scalar (@$ds) != scalar (@{$vl->{'values'}})) { plugin_log (LOG_WARNING, "DS number does not match values length"); return; } for (my $i = 0; $i < scalar (@$ds); ++$i) { # do the magic to output the data print "$vl->{'host'}: $vl->{'plugin'}: "; if (defined $vl->{'plugin_instance'}) { print "$vl->{'plugin_instance'}: "; } print "$type: "; if (defined $vl->{'type_instance'}) { print "$vl->{'type_instance'}: "; } print "$vl->{'values'}->[$i]\n"; } return 1; } # my_write() # This function is called before shutting down collectd. sub my_shutdown { # close sockets, ... return 1; } # my_shutdown () # This function is called when plugin_log () has been used. sub my_log { my $level = shift; my $msg = shift; print "LOG: $level - $msg\n"; return 1; } # my_log () # This function is called when plugin_dispatch_notification () has been used sub my_notify { my $notif = shift; my ($sec, $min, $hour, $mday, $mon, $year) = localtime ($notif->{'time'}); printf "NOTIF (%04d-%02d-%02d %02d:%02d:%02d): %d - ", $year + 1900, $mon + 1, $mday, $hour, $min, $sec, $notif->{'severity'}; if (defined $notif->{'host'}) { print "$notif->{'host'}: "; } if (defined $notif->{'plugin'}) { print "$notif->{'plugin'}: "; } if (defined $notif->{'plugin_instance'}) { print "$notif->{'plugin_instance'}: "; } if (defined $notif->{'type'}) { print "$notif->{'type'}: "; } if (defined $notif->{'type_instance'}) { print "$notif->{'type_instance'}: "; } print "$notif->{'message'}\n"; return 1; } # my_notify () collectd-5.4.0/contrib/PaxHeaders.11991/exec-nagios.px0000644037772200116100000000013212204120331020556 xustar000000000000000030 mtime=1376821465.053973118 30 atime=1376821477.202167674 30 ctime=1376821742.478408205 collectd-5.4.0/contrib/exec-nagios.px0000754037772200116100000002607112204120331017332 0ustar00octoeng00000000000000#!/usr/bin/perl use strict; use warnings; =head1 NAME exec-nagios.px =head1 DESCRIPTION This script allows you to use plugins that were written for Nagios with collectd's C. If the plugin checks some kind of threshold, please consider configuring the threshold using collectd's own facilities instead of using this transition layer. =cut use Sys::Hostname ('hostname'); use File::Basename ('basename'); use Config::General ('ParseConfig'); use Regexp::Common ('number'); our $ConfigFile = '/etc/exec-nagios.conf'; our $TypeMap = {}; our $NRPEMap = {}; our $Scripts = []; our $Interval = defined ($ENV{'COLLECTD_INTERVAL'}) ? (0 + $ENV{'COLLECTD_INTERVAL'}) : 300; our $Hostname = defined ($ENV{'COLLECTD_HOSTNAME'}) ? $ENV{'COLLECTD_HOSTNAME'} : ''; main (); exit (0); # Configuration # {{{ =head1 CONFIGURATION This script reads it's configuration from F. The configuration is read using C which understands a Apache-like config syntax, so it's very similar to the F syntax, too. Here's a short sample config: NRPEConfig "/etc/nrpe.cfg" Interval 300 The options have the following semantic (i.Ee. meaning): =over 4 =item B I Read the NRPE config and add the command definitions to an alias table. After reading the file you can use the NRPE command name rather than the script's filename within B HTML $html_started = 1; } sub end_html { print < HTML $html_started = 0; } sub contains_invalid_chars { my $str = shift; for (split (m//, $str)) { my $n = ord ($_); # Whitespace is allowed. if (($n >= 9) && ($n <= 13)) { next; } elsif ($n < 32) { return (1); } } return; } sub show_selector { my $timespan_selection = get_timespan_selection (); my $host_selection = get_host_selection (); my $plugin_selection = get_plugin_selection (); print <
Data selection HTML for (sort (keys %$plugin_selection)) { next if contains_invalid_chars ($_); my $plugin = encode_entities ($_); my $selected = $plugin_selection->{$_} ? ' selected="selected"' : ''; print qq# \n#; } print <
HTML } # show_selector sub action_list_hosts { start_html (); show_selector (); my @hosts = get_all_hosts (); print "
    \n"; for (sort @hosts) { my $url = encode_entities (script_name () . "?action=show_selection;hostname=$_"); next if contains_invalid_chars ($_); my $name = encode_entities ($_); print qq#
  • $name
  • \n#; } print "
\n"; end_html (); } # action_list_hosts =head1 MODULE LOADING This script makes use of the various B modules. If a file like C is encountered it tries to load the B module and, if that fails, falls back to the B base class. If you want to create a specialized graph for a certain type, you have to create a new module which inherits from the B base class. A description of provided (and used) methods can be found in the inline documentation of the B module. There are other, more specialized, "abstract" classes that possibly better fit your need. Unfortunately they are not yet documented. =over 4 =item B Specialized class that groups files by their plugin instance and stacks them on top of each other. Example types that inherit from this class are B and B. =item B Specialized class for input/output graphs. This class can only handle files with exactly two data sources, input and output. Example types that inherit from this class are B and B. =back =cut sub action_show_selection { start_html (); show_selector (); my $all_files; my $timespan; my $types = {}; my $id_counter = 0; $all_files = get_selected_files (); $timespan = get_timespan_selection (); if (param ('debug')) { print "
", Data::Dumper->Dump ([$all_files], ['all_files']), "
\n"; } # Send FLUSH command to the daemon if necessary and possible. flush_files ($all_files, begin => time () - $timespan, end => time (), addr => gc_get_scalar ('UnixSockAddr', undef), interval => gc_get_scalar ('Interval', 10)); for (@$all_files) { my $file = $_; my $type = ucfirst (lc ($file->{'type'})); $type =~ s/[^A-Za-z0-9_]//g; $type =~ s/_([A-Za-z0-9])/\U$1\E/g; if (!defined ($types->{$type})) { $types->{$type} = tl_load_type ($file->{'type'}); if (!$types->{$type}) { warn ("tl_load_type (" . $file->{'type'} . ") failed"); next; } } $types->{$type}->addFiles ($file); } #print STDOUT Data::Dumper->Dump ([$types], ['types']); print qq# \n#; for (sort (keys %$types)) { my $type = $_; if (!defined ($types->{$type})) { next; } my $graphs_num = $types->{$type}->getGraphsNum (); for (my $i = 0; $i < $graphs_num; $i++) { my $args = $types->{$type}->getGraphArgs ($i); my $url = encode_entities ("graph.cgi?$args;begin=-$timespan"); my $id = sprintf ("graph%04i", $id_counter++); print " \n"; print " \n" if ($i == 0); print <
A graph
-
+
H
D
W
M
Y
!
EOF # print qq#
\n#; print " \n"; } } print "
$type
\n"; end_html (); } main (); =head1 SEE ALSO L =head1 AUTHOR AND LICENSE Copyright (c) 2008 by Florian Forster EoctoEatEverplant.orgE. Licensed under the terms of the GNU General Public License, VersionE2 (GPLv2). =cut # vim: set shiftwidth=2 softtabstop=2 tabstop=8 : collectd-5.4.0/contrib/collection3/bin/PaxHeaders.11991/.htaccess0000644037772200116100000000013112204120331022566 xustar000000000000000030 mtime=1376821465.049973054 29 atime=1376821477.19816761 30 ctime=1376821742.542409228 collectd-5.4.0/contrib/collection3/bin/.htaccess0000644037772200116100000000005412204120331021332 0ustar00octoeng00000000000000Options +ExecCGI AddHandler cgi-script .cgi collectd-5.4.0/contrib/collection3/bin/PaxHeaders.11991/json.cgi0000644037772200116100000000013112204120331022425 xustar000000000000000030 mtime=1376821465.049973054 29 atime=1376821477.19816761 30 ctime=1376821742.546409292 collectd-5.4.0/contrib/collection3/bin/json.cgi0000754037772200116100000000547112204120331021203 0ustar00octoeng00000000000000#!/usr/bin/perl # Copyright (C) 2008 Florian octo 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. use strict; use warnings; use lib ('../lib'); use utf8; use FindBin ('$RealBin'); use CGI (':cgi'); use CGI::Carp ('fatalsToBrowser'); use URI::Escape ('uri_escape'); use JSON ('objToJson'); use Data::Dumper; use Collectd::Graph::Config (qw(gc_read_config)); use Collectd::Graph::TypeLoader (qw(tl_load_type)); use Collectd::Graph::Common (qw(get_all_hosts get_files_for_host type_to_module_name)); use Collectd::Graph::Type (); our $Debug = param ('debug') ? 1 : 0; our $ServerName = 'collect.noris.net'; gc_read_config ("$RealBin/../etc/collection.conf"); if ($Debug) { print "Content-Type: text/plain; charset=utf-8\n\n"; } else { print "Content-Type: application/json; charset=utf-8\n\n"; } my $obj = {}; my @hosts = get_all_hosts (); for (my $i = 0; $i < @hosts; $i++) { my $host_obj = {}; my $host = $hosts[$i]; my $files = get_files_for_host ($host); my %graphs = (); my @graphs = (); # Group files by graphs for (@$files) { my $file = $_; my $type = $file->{'type'}; # Create a new graph object if this is the first of this type. if (!defined ($graphs{$type})) { $graphs{$type} = tl_load_type ($file->{'type'}); if (!$graphs{$type}) { cluck ("tl_load_type (" . $file->{'type'} . ") failed"); next; } } $graphs{$type}->addFiles ($file); } # for (@$files) #print qq( ") . objToJson ({ foo => 123 }) . qq(":\n {\n); @graphs = keys %graphs; for (my $j = 0; $j < @graphs; $j++) { my $type = $graphs[$j]; my $graphs_num = $graphs{$type}->getGraphsNum (); if (!defined ($host_obj->{$type})) { $host_obj->{$type} = []; } for (my $k = 0; $k < $graphs_num; $k++) { my $args = $graphs{$type}->getGraphArgs ($k); my $url = "http://$ServerName/cgi-bin/collection3/bin/graph.cgi?" . $args; push (@{$host_obj->{$type}}, $url); } } # for (keys %graphs) $obj->{$host} = $host_obj; } # for (my $i = 0; $i < @hosts; $i++) print STDOUT objToJson ($obj, { pretty => 1, indent => 2 }); exit (0); # vim: set shiftwidth=2 softtabstop=2 tabstop=8 : collectd-5.4.0/contrib/PaxHeaders.11991/snmp-probe-host.px0000644037772200116100000000013212204120331021411 xustar000000000000000030 mtime=1376821465.057973183 30 atime=1376821477.206167738 30 ctime=1376821742.546409292 collectd-5.4.0/contrib/snmp-probe-host.px0000754037772200116100000002220412204120331020157 0ustar00octoeng00000000000000#!/usr/bin/perl # # collectd - snmp-probe-host.px # Copyright (C) 2008,2009 Florian octo Forster # Copyright (C) 2009 noris network AG # # 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 # # Author: # Florian octo Forster # use strict; use warnings; use SNMP; use Config::General ('ParseConfig'); use Getopt::Long ('GetOptions'); use Socket6; our %ExcludeOptions = ( 'IF-MIB64' => qr/^\.?1\.3\.6\.1\.2\.1\.31/, 'IF-MIB32' => qr/^\.?1\.3\.6\.1\.2\.1\.2/ ); sub get_config { my %conf; my $file = shift; %conf = ParseConfig (-ConfigFile => $file, -LowerCaseNames => 1, -UseApacheInclude => 1, -IncludeDirectories => 1, ($Config::General::VERSION >= 2.38) ? (-IncludeAgain => 0) : (), -MergeDuplicateBlocks => 1, -CComments => 0); if (!%conf) { return; } return (\%conf); } # get_config sub probe_one { my $sess = shift; my $conf = shift; my $excludes = @_ ? shift : []; my @oids; my $cmd = 'GET'; my $vl; if (!$conf->{'table'} || !$conf->{'values'}) { warn "No 'table' or 'values' setting"; return; } @oids = split (/"\s*"/, $conf->{'values'}); if ($conf->{'table'} =~ m/^(true|yes|on)$/i) { $cmd = 'GETNEXT'; if (defined ($conf->{'instance'})) { push (@oids, $conf->{'instance'}); } } require Data::Dumper; #print "probe_one: \@oids = (" . join (', ', @oids) . ");\n"; for (@oids) { my $oid_orig = $_; my $vb; my $status; if ($oid_orig =~ m/[^0-9\.]/) { my $tmp = SNMP::translateObj ($oid_orig); if (!defined ($tmp)) { warn ("Cannot translate OID $oid_orig"); return; } $oid_orig = $tmp; } for (@$excludes) { if ($oid_orig =~ $_) { return; } } $vb = SNMP::Varbind->new ([$oid_orig]); if ($cmd eq 'GET') { $status = $sess->get ($vb); if ($sess->{'ErrorNum'} != 0) { return; } if (!defined ($status)) { return; } if ("$status" eq 'NOSUCHOBJECT') { return; } } else { my $oid_copy; $status = $sess->getnext ($vb); if ($sess->{'ErrorNum'} != 0) { return; } $oid_copy = $vb->[0]; if ($oid_copy =~ m/[^0-9\.]/) { my $tmp = SNMP::translateObj ($oid_copy); if (!defined ($tmp)) { warn ("Cannot translate OID $oid_copy"); return; } $oid_copy = $tmp; } #print "$oid_orig > $oid_copy ?\n"; if (substr ($oid_copy, 0, length ($oid_orig)) ne $oid_orig) { return; } } #print STDOUT Data::Dumper->Dump ([$oid_orig, $status], [qw(oid_orig status)]); } # for (@oids) return (1); } # probe_one sub probe_all { my $host = shift; my $community = shift; my $data = shift; my $excludes = @_ ? shift : []; my $version = 2; my @valid_data = (); my $begin; my $address; { my @status; @status = getaddrinfo ($host, 'snmp'); while (@status >= 5) { my $family = shift (@status); my $socktype = shift (@status); my $proto = shift (@status); my $saddr = shift (@status); my $canonname = shift (@status); my $host; my $port; ($host, $port) = getnameinfo ($saddr, NI_NUMERICHOST); if (defined ($port)) { $address = $host; } else { warn ("getnameinfo failed: $host"); } } } if (!$address) { return; } while ($version > 0) { my $sess; $sess = new SNMP::Session (DestHost => $host, Community => $community, Version => $version, Timeout => 1000000, UseNumeric => 1); if (!$sess) { $version--; next; } $begin = time (); for (keys %$data) { my $name = $_; if (probe_one ($sess, $data->{$name}, $excludes)) { push (@valid_data, $name); } if ((@valid_data == 0) && ((time () - $begin) > 10)) { # break for loop last; } } if (@valid_data) { # break while loop last; } $version--; } # while ($version > 0) print < Address "$address" Version $version Community "$community" EOF for (sort (@valid_data)) { print " Collect \"$_\"\n"; } if (!@valid_data) { print < EOF } # probe_all sub exit_usage { print < [options] Options are: -H | --host Hostname of the device to probe. -C | --config Path to config file holding the SNMP data blocks. -c | --community SNMP community to use. Default: `public'. -h | --help Print this information and exit. -x | --exclude Exclude a specific MIB. Call with "help" for more information. USAGE exit (1); } sub exit_usage_exclude { print "Available exclude MIBs:\n\n"; for (sort (keys %ExcludeOptions)) { print " $_\n"; } print "\n"; exit (1); } =head1 NAME snmp-probe-host.px - Find out what information an SNMP device provides. =head1 SYNOPSIS ./snmp-probe-host.px --host switch01.mycompany.com --community ei2Acoum =head1 DESCRIPTION The C script can be used to automatically generate SNMP configuration snippets for collectd's snmp plugin (see L). This script parses the collectd configuration and detecs all "data" blocks that are defined for the SNMP plugin. It then queries the device specified on the command line for all OIDs and registeres which OIDs could be answered correctly and which resulted in an error. With that information the script figures out which "data" blocks can be used with this hosts and prints an appropriate "host" block to standard output. The script first tries to contact the device via SNMPv2. If after ten seconds no working "data" block has been found, it will try to downgrade to SNMPv1. This is a bit a hack, but works for now. =cut my $host; my $file = '/etc/collectd/collectd.conf'; my $community = 'public'; my $conf; my $working_data; my @excludes = (); =head1 OPTIONS The following command line options are accepted: =over 4 =item B<--host> I Hostname of the device. This B be a fully qualified domain name (FQDN), but anything the system can resolve to an IP address will word. B. =item B<--config> I Sets the name of the collectd config file which defined the SNMP "data" blocks. Due to limitations of the config parser used in this script (C), C statements cannot be parsed correctly. Defaults to F. =item B<--community> I SNMP community to use. Should be pretty straight forward. =item B<--exclude> I This option can be used to exclude specific data from being enabled in the generated config. Currently the following MIBs are understood: =over 4 =item B Exclude interface information, such as I and I. =back =back =cut GetOptions ('H|host|hostname=s' => \$host, 'C|conf|config=s' => \$file, 'c|community=s' => \$community, 'x|exclude=s' => \@excludes, 'h|help' => \&exit_usage) or die; if (!$host) { print STDERR "No hostname given. Please use `--host'.\n"; exit (1); } if (@excludes) { my $tmp = join (',', @excludes); my @tmp = split (/\s*,\s*/, $tmp); @excludes = (); for (@tmp) { my $mib = uc ($_); if ($mib eq 'HELP') { exit_usage_exclude (); } elsif (!exists ($ExcludeOptions{$mib})) { print STDERR "No such MIB: $mib\n"; exit_usage_exclude (); } push (@excludes, $ExcludeOptions{$mib}); } } $conf = get_config ($file) or die ("Cannot read config"); if (!defined ($conf->{'plugin'}) || !defined ($conf->{'plugin'}{'snmp'}) || !defined ($conf->{'plugin'}{'snmp'}{'data'})) { print STDERR "Error: No , , or block found.\n"; exit (1); } probe_all ($host, $community, $conf->{'plugin'}{'snmp'}{'data'}, \@excludes); exit (0); =head1 BUGS =over 4 =item C statements in the config file are not handled correctly. =item SNMPv2 / SNMPv1 detection is a hack. =back =head1 AUTHOR Copyright (c) 2008 by Florian octo Forster EoctoEatEnoris.netE. Licensed under the terms of the GPLv2. Written for the norisEnetworkEAG L. =cut # vim: set sw=2 sts=2 ts=8 et : collectd-5.4.0/contrib/PaxHeaders.11991/oracle0000644037772200116100000000013212204120331017173 xustar000000000000000030 mtime=1376821465.053973118 30 atime=1376821742.550409356 30 ctime=1376821742.550409356 collectd-5.4.0/contrib/oracle/0000755037772200116100000000000012204120331016014 5ustar00octoeng00000000000000collectd-5.4.0/contrib/oracle/PaxHeaders.11991/db_systat.sql0000644037772200116100000000013212204120331021765 xustar000000000000000030 mtime=1376821465.053973118 30 atime=1376821477.202167674 30 ctime=1376821742.550409356 collectd-5.4.0/contrib/oracle/db_systat.sql0000644037772200116100000000277612204120331020545 0ustar00octoeng00000000000000-- Table sizes SELECT owner, TABLE_NAME, bytes FROM collectdu.c_tbl_size; -- Tablespace sizes SELECT tablespace_name, bytes_free, bytes_used FROM collectdu.c_tbs_usage; -- IO per Tablespace SELECT SUM(vf.phyblkrd) *8192 AS phy_blk_r, SUM(vf.phyblkwrt) *8192 AS phy_blk_w, 'tablespace' AS i_prefix, dt.tablespace_name FROM((dba_data_files dd JOIN v$filestat vf ON dd.file_id = vf.file#) JOIN dba_tablespaces dt ON dd.tablespace_name = dt.tablespace_name) GROUP BY dt.tablespace_name; -- Buffer Pool Hit Ratio: SELECT DISTINCT 100 *ROUND(1 -((MAX(decode(name, 'physical reads cache', VALUE))) /(MAX(decode(name, 'db block gets from cache', VALUE)) + MAX(decode(name, 'consistent gets from cache', VALUE)))), 4) AS VALUE, 'BUFFER_CACHE_HIT_RATIO' AS buffer_cache_hit_ratio FROM v$sysstat; -- Shared Pool Hit Ratio: SELECT 100.0 * sum(PINHITS) / sum(pins) as VALUE, 'SHAREDPOOL_HIT_RATIO' AS SHAREDPOOL_HIT_RATIO FROM V$LIBRARYCACHE; -- PGA Hit Ratio: SELECT VALUE, 'PGA_HIT_RATIO' AS pga_hit_ratio FROM v$pgastat WHERE name = 'cache hit percentage'; -- DB Efficiency SELECT ROUND(SUM(decode(metric_name, 'Database Wait Time Ratio', VALUE)), 2) AS database_wait_time_ratio, ROUND(SUM(decode(metric_name, 'Database CPU Time Ratio', VALUE)), 2) AS database_cpu_time_ratio, 'DB_EFFICIENCY' AS db_efficiency FROM sys.v_$sysmetric WHERE metric_name IN('Database CPU Time Ratio', 'Database Wait Time Ratio') AND intsize_csec = (SELECT MAX(intsize_csec) FROM sys.v_$sysmetric); collectd-5.4.0/contrib/oracle/PaxHeaders.11991/create_schema.ddl0000644037772200116100000000013212204120331022520 xustar000000000000000030 mtime=1376821465.053973118 30 atime=1376821477.202167674 30 ctime=1376821742.554409419 collectd-5.4.0/contrib/oracle/create_schema.ddl0000644037772200116100000001774612204120331021303 0ustar00octoeng00000000000000-- collectd - contrib/oracle/create_schema.ddl -- Copyright (C) 2008,2009 Roman Klesel -- -- 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: -- Roman Klesel -- Description -------------- -- This will create a schema to provide collectd with the required permissions -- and space for statistic data. -- The idea is to store the output of some expensive queries in static tables -- and fill these tables with dbms_scheduler jobs as often as necessary. -- collectd will then just read from the static tables. This will reduces the -- chance that your system will be killed by excessive monitoring queries and -- gives the dba control on the interval the information provided to collectd -- will be refreshed. You have to create a dbms_scheduler job for each of the -- schemas you what to monitor for object-space-usage. See the example below. -- -- Requirements --------------- -- make sure you have: -- write permission in $PWD -- you have GID of oracle software owner -- set $ORACLE_HOME -- set $ORACLE_SID -- DB is up an running in RW mode -- execute like this: -- sqlplus /nolog @ create_collectd-schema.dll spool create_collectd-schema.log connect / as sysdba -- Create user, tablespace and permissions CREATE TABLESPACE "COLLECTD-TBS" DATAFILE SIZE 30M AUTOEXTEND ON NEXT 10M MAXSIZE 300M LOGGING EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO DEFAULT NOCOMPRESS; CREATE ROLE "CREATE_COLLECTD_SCHEMA" NOT IDENTIFIED; GRANT CREATE JOB TO "CREATE_COLLECTD_SCHEMA"; GRANT CREATE SEQUENCE TO "CREATE_COLLECTD_SCHEMA"; GRANT CREATE SYNONYM TO "CREATE_COLLECTD_SCHEMA"; GRANT CREATE TABLE TO "CREATE_COLLECTD_SCHEMA"; GRANT CREATE VIEW TO "CREATE_COLLECTD_SCHEMA"; GRANT CREATE PROCEDURE TO "CREATE_COLLECTD_SCHEMA"; CREATE USER "COLLECTDU" PROFILE "DEFAULT" IDENTIFIED BY "Change_me-1st" PASSWORD EXPIRE DEFAULT TABLESPACE "COLLECTD-TBS" TEMPORARY TABLESPACE "TEMP" QUOTA UNLIMITED ON "COLLECTD-TBS" ACCOUNT UNLOCK; GRANT "CONNECT" TO "COLLECTDU"; GRANT "SELECT_CATALOG_ROLE" TO "COLLECTDU"; GRANT "CREATE_COLLECTD_SCHEMA" TO "COLLECTDU"; GRANT analyze any TO "COLLECTDU"; GRANT select on dba_tables TO "COLLECTDU"; GRANT select on dba_lobs TO "COLLECTDU"; GRANT select on dba_indexes TO "COLLECTDU"; GRANT select on dba_segments TO "COLLECTDU"; GRANT select on dba_tab_columns TO "COLLECTDU"; GRANT select on dba_free_space TO "COLLECTDU"; GRANT select on dba_data_files TO "COLLECTDU"; -- Create tables and indexes alter session set current_schema=collectdu; create table c_tbs_usage ( tablespace_name varchar2(30), bytes_free number, bytes_used number, CONSTRAINT "C_TBS_USAGE_UK1" UNIQUE ("TABLESPACE_NAME") USING INDEX TABLESPACE "COLLECTD-TBS" ENABLE) TABLESPACE "COLLECTD-TBS"; CREATE TABLE "COLLECTDU"."C_TBL_SIZE" ( "OWNER" VARCHAR2(30 BYTE), "TABLE_NAME" VARCHAR2(30 BYTE), "BYTES" NUMBER, CONSTRAINT "C_TBL_SIZE_UK1" UNIQUE ("OWNER", "TABLE_NAME") USING INDEX TABLESPACE "COLLECTD-TBS" ENABLE) TABLESPACE "COLLECTD-TBS" ; create or replace PROCEDURE get_object_size(owner IN VARCHAR2) AS v_owner VARCHAR2(30) := owner; l_free_blks NUMBER; l_total_blocks NUMBER; l_total_bytes NUMBER; l_unused_blocks NUMBER; l_unused_bytes NUMBER; l_lastusedextfileid NUMBER; l_lastusedextblockid NUMBER; l_last_used_block NUMBER; CURSOR cur_tbl IS SELECT owner, TABLE_NAME FROM dba_tables WHERE owner = v_owner; CURSOR cur_idx IS SELECT owner, index_name, TABLE_NAME FROM dba_indexes WHERE owner = v_owner; CURSOR cur_lob IS SELECT owner, segment_name, TABLE_NAME FROM dba_lobs WHERE owner = v_owner; BEGIN DELETE FROM c_tbl_size WHERE owner = v_owner; COMMIT; FOR r_tbl IN cur_tbl LOOP BEGIN dbms_space.unused_space(segment_owner => r_tbl.owner, segment_name => r_tbl.TABLE_NAME, segment_type => 'TABLE', total_blocks => l_total_blocks, total_bytes => l_total_bytes, unused_blocks => l_unused_blocks, unused_bytes => l_unused_bytes, last_used_extent_file_id => l_lastusedextfileid, last_used_extent_block_id => l_lastusedextblockid, last_used_block => l_last_used_block); EXCEPTION WHEN others THEN DBMS_OUTPUT.PUT_LINE('tbl_name: ' || r_tbl.TABLE_NAME); END; INSERT INTO c_tbl_size VALUES(r_tbl.owner, r_tbl.TABLE_NAME, l_total_bytes -l_unused_bytes); END LOOP; COMMIT; FOR r_idx IN cur_idx LOOP BEGIN dbms_space.unused_space(segment_owner => r_idx.owner, segment_name => r_idx.index_name, segment_type => 'INDEX', total_blocks => l_total_blocks, total_bytes => l_total_bytes, unused_blocks => l_unused_blocks, unused_bytes => l_unused_bytes, last_used_extent_file_id => l_lastusedextfileid, last_used_extent_block_id => l_lastusedextblockid, last_used_block => l_last_used_block); EXCEPTION WHEN others THEN DBMS_OUTPUT.PUT_LINE('idx_name: ' || r_idx.index_name); END; UPDATE c_tbl_size SET bytes = bytes + l_total_bytes -l_unused_bytes WHERE owner = r_idx.owner AND TABLE_NAME = r_idx.TABLE_NAME; END LOOP; COMMIT; FOR r_lob IN cur_lob LOOP BEGIN dbms_space.unused_space(segment_owner => r_lob.owner, segment_name => r_lob.segment_name, segment_type => 'LOB', total_blocks => l_total_blocks, total_bytes => l_total_bytes, unused_blocks => l_unused_blocks, unused_bytes => l_unused_bytes, last_used_extent_file_id => l_lastusedextfileid, last_used_extent_block_id => l_lastusedextblockid, last_used_block => l_last_used_block); EXCEPTION WHEN others THEN DBMS_OUTPUT.PUT_LINE('lob_name: ' || r_lob.segment_name); END; UPDATE c_tbl_size SET bytes = bytes + l_total_bytes -l_unused_bytes WHERE owner = r_lob.owner AND TABLE_NAME = r_lob.TABLE_NAME; END LOOP; COMMIT; END get_object_size; / create or replace PROCEDURE get_tbs_size AS BEGIN execute immediate 'truncate table c_tbs_usage'; insert into c_tbs_usage ( select df.tablespace_name as tablespace_name, decode(df.maxbytes, 0, sum(fs.bytes), (df.maxbytes-(df.bytes-sum(fs.bytes)))) as bytes_free, decode(df.maxbytes, 0, round((df.bytes-sum(fs.bytes))), round(df.maxbytes-(df.maxbytes-(df.bytes-sum(fs.bytes))))) as bytes_used from dba_free_space fs inner join (select tablespace_name, sum(bytes) bytes, sum(decode(maxbytes,0,bytes,maxbytes)) maxbytes from dba_data_files group by tablespace_name ) df on fs.tablespace_name = df.tablespace_name group by df.tablespace_name,df.maxbytes,df.bytes); COMMIT; END get_tbs_size; / BEGIN sys.dbms_scheduler.create_job( job_name => '"COLLECTDU"."C_TBSSIZE_JOB"', job_type => 'PLSQL_BLOCK', job_action => 'begin get_tbs_size(); end;', repeat_interval => 'FREQ=MINUTELY;INTERVAL=5', start_date => systimestamp at time zone 'Europe/Berlin', job_class => '"DEFAULT_JOB_CLASS"', auto_drop => FALSE, enabled => TRUE); END; / BEGIN sys.dbms_scheduler.create_job( job_name => '"COLLECTDU"."C_TBLSIZE_COLLECTDU_JOB"', job_type => 'PLSQL_BLOCK', job_action => 'begin get_object_size( owner => ''COLLECTDU'' ); end;', repeat_interval => 'FREQ=HOURLY;INTERVAL=12', start_date => systimestamp at time zone 'Europe/Berlin', job_class => '"DEFAULT_JOB_CLASS"', auto_drop => FALSE, enabled => TRUE); END; / spool off quit -- vim: set syntax=sql : collectd-5.4.0/contrib/PaxHeaders.11991/collectd_network.py0000644037772200116100000000013112204120331021716 xustar000000000000000030 mtime=1376821465.049973054 29 atime=1376821477.19816761 30 ctime=1376821742.554409419 collectd-5.4.0/contrib/collectd_network.py0000644037772200116100000002265212204120331020472 0ustar00octoeng00000000000000#! /usr/bin/env python # -*- coding: utf-8 -*- # vim: fileencoding=utf-8 # # Copyright © 2009 Adrian Perez # # Distributed under terms of the GPLv2 license or newer. # # Frank Marien (frank@apsu.be) 6 Sep 2012 # - quick fixes for 5.1 binary protocol # - updated to python 3 # - fixed for larger packet sizes (possible on lo interface) # - fixed comment typo (decode_network_string decodes a string) """ Collectd network protocol implementation. """ import socket,struct,sys import platform if platform.python_version() < '2.8.0': # Python 2.7 and below io.StringIO does not like unicode from StringIO import StringIO else: try: from io import StringIO except ImportError: from cStringIO import StringIO from datetime import datetime from copy import deepcopy DEFAULT_PORT = 25826 """Default port""" DEFAULT_IPv4_GROUP = "239.192.74.66" """Default IPv4 multicast group""" DEFAULT_IPv6_GROUP = "ff18::efc0:4a42" """Default IPv6 multicast group""" HR_TIME_DIV = (2.0**30) # Message kinds TYPE_HOST = 0x0000 TYPE_TIME = 0x0001 TYPE_TIME_HR = 0x0008 TYPE_PLUGIN = 0x0002 TYPE_PLUGIN_INSTANCE = 0x0003 TYPE_TYPE = 0x0004 TYPE_TYPE_INSTANCE = 0x0005 TYPE_VALUES = 0x0006 TYPE_INTERVAL = 0x0007 TYPE_INTERVAL_HR = 0x0009 # For notifications TYPE_MESSAGE = 0x0100 TYPE_SEVERITY = 0x0101 # DS kinds DS_TYPE_COUNTER = 0 DS_TYPE_GAUGE = 1 DS_TYPE_DERIVE = 2 DS_TYPE_ABSOLUTE = 3 header = struct.Struct("!2H") number = struct.Struct("!Q") short = struct.Struct("!H") double = struct.Struct(" blen - off: raise ValueError("Packet longer than amount of data in buffer") if ptype not in _decoders: raise ValueError("Message type %i not recognized" % ptype) yield ptype, _decoders[ptype](ptype, plen, buf[off:]) off += plen class Data(object): time = 0 host = None plugin = None plugininstance = None type = None typeinstance = None def __init__(self, **kw): [setattr(self, k, v) for k, v in kw.items()] @property def datetime(self): return datetime.fromtimestamp(self.time) @property def source(self): buf = StringIO() if self.host: buf.write(str(self.host)) if self.plugin: buf.write("/") buf.write(str(self.plugin)) if self.plugininstance: buf.write("/") buf.write(str(self.plugininstance)) if self.type: buf.write("/") buf.write(str(self.type)) if self.typeinstance: buf.write("/") buf.write(str(self.typeinstance)) return buf.getvalue() def __str__(self): return "[%i] %s" % (self.time, self.source) class Notification(Data): FAILURE = 1 WARNING = 2 OKAY = 4 SEVERITY = { FAILURE: "FAILURE", WARNING: "WARNING", OKAY : "OKAY", } __severity = 0 message = "" def __set_severity(self, value): if value in (self.FAILURE, self.WARNING, self.OKAY): self.__severity = value severity = property(lambda self: self.__severity, __set_severity) @property def severitystring(self): return self.SEVERITY.get(self.severity, "UNKNOWN") def __str__(self): return "%s [%s] %s" % ( super(Notification, self).__str__(), self.severitystring, self.message) class Values(Data, list): def __str__(self): return "%s %s" % (Data.__str__(self), list.__str__(self)) def interpret_opcodes(iterable): vl = Values() nt = Notification() for kind, data in iterable: if kind == TYPE_TIME: vl.time = nt.time = data elif kind == TYPE_TIME_HR: vl.time = nt.time = data / HR_TIME_DIV elif kind == TYPE_INTERVAL: vl.interval = data elif kind == TYPE_INTERVAL_HR: vl.interval = data / HR_TIME_DIV elif kind == TYPE_HOST: vl.host = nt.host = data elif kind == TYPE_PLUGIN: vl.plugin = nt.plugin = data elif kind == TYPE_PLUGIN_INSTANCE: vl.plugininstance = nt.plugininstance = data elif kind == TYPE_TYPE: vl.type = nt.type = data elif kind == TYPE_TYPE_INSTANCE: vl.typeinstance = nt.typeinstance = data elif kind == TYPE_SEVERITY: nt.severity = data elif kind == TYPE_MESSAGE: nt.message = data yield deepcopy(nt) elif kind == TYPE_VALUES: vl[:] = data yield deepcopy(vl) class Reader(object): """Network reader for collectd data. Listens on the network in a given address, which can be a multicast group address, and handles reading data when it arrives. """ addr = None host = None port = DEFAULT_PORT BUFFER_SIZE = 16384 def __init__(self, host=None, port=DEFAULT_PORT, multicast=False): if host is None: multicast = True host = DEFAULT_IPv4_GROUP self.host, self.port = host, port self.ipv6 = ":" in self.host family, socktype, proto, canonname, sockaddr = socket.getaddrinfo( None if multicast else self.host, self.port, socket.AF_INET6 if self.ipv6 else socket.AF_UNSPEC, socket.SOCK_DGRAM, 0, socket.AI_PASSIVE)[0] self._sock = socket.socket(family, socktype, proto) self._sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self._sock.bind(sockaddr) if multicast: if hasattr(socket, "SO_REUSEPORT"): self._sock.setsockopt( socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) val = None if family == socket.AF_INET: assert "." in self.host val = struct.pack("4sl", socket.inet_aton(self.host), socket.INADDR_ANY) elif family == socket.AF_INET6: raise NotImplementedError("IPv6 support not ready yet") else: raise ValueError("Unsupported network address family") self._sock.setsockopt( socket.IPPROTO_IPV6 if self.ipv6 else socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, val) self._sock.setsockopt( socket.IPPROTO_IPV6 if self.ipv6 else socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 0) def receive(self): """Receives a single raw collect network packet. """ return self._sock.recv(self.BUFFER_SIZE) def decode(self, buf=None): """Decodes a given buffer or the next received packet. """ if buf is None: buf = self.receive() return decode_network_packet(buf) def interpret(self, iterable=None): """Interprets a sequence """ if iterable is None: iterable = self.decode() if isinstance(iterable, str): iterable = self.decode(iterable) return interpret_opcodes(iterable) collectd-5.4.0/contrib/PaxHeaders.11991/fedora0000644037772200116100000000013212204120331017166 xustar000000000000000030 mtime=1376821465.053973118 30 atime=1376821742.558409482 30 ctime=1376821742.554409419 collectd-5.4.0/contrib/fedora/0000755037772200116100000000000012204120331016007 5ustar00octoeng00000000000000collectd-5.4.0/contrib/fedora/PaxHeaders.11991/init.d-collectd0000644037772200116100000000013212204120331022142 xustar000000000000000030 mtime=1376821465.053973118 30 atime=1376821477.202167674 30 ctime=1376821742.558409482 collectd-5.4.0/contrib/fedora/init.d-collectd0000644037772200116100000000221412204120331020705 0ustar00octoeng00000000000000#!/bin/bash # # collectd Startup script for the Collectd statistics gathering daemon # chkconfig: - 86 15 # description: Collectd is a statistics gathering daemon used to collect \ # system information ie. cpu, memory, disk, network # processname: collectd # config: /etc/collectd.conf # config: /etc/sysconfig/collectd # pidfile: /var/run/collectd.pid # Source function library. . /etc/init.d/functions RETVAL=0 ARGS="" prog="collectd" CONFIG=/etc/collectd.conf if [ -r /etc/default/$prog ]; then . /etc/default/$prog fi start () { echo -n $"Starting $prog: " if [ -r "$CONFIG" ] then daemon /usr/sbin/collectd -C "$CONFIG" RETVAL=$? echo [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog fi } stop () { echo -n $"Stopping $prog: " killproc $prog RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$prog } # See how we were called. case "$1" in start) start ;; stop) stop ;; status) status $prog ;; restart|reload) stop start ;; condrestart) [ -f /var/lock/subsys/$prog ] && stop && start || : ;; *) echo $"Usage: $0 {start|stop|status|restart|reload|condrestart}" exit 1 esac exit $? # vim:syntax=sh collectd-5.4.0/contrib/fedora/PaxHeaders.11991/collectd.spec0000644037772200116100000000013212204120331021710 xustar000000000000000030 mtime=1376821465.053973118 30 atime=1376821477.202167674 30 ctime=1376821742.558409482 collectd-5.4.0/contrib/fedora/collectd.spec0000644037772200116100000003005112204120331020453 0ustar00octoeng00000000000000Summary: Statistics collection daemon for filling RRD files. Name: collectd Version: 4.2.0 Release: 1.fc6 Source: http://collectd.org/files/%{name}-%{version}.tar.gz License: GPL Group: System Environment/Daemons BuildRoot: %{_tmppath}/%{name}-%{version}-root BuildPrereq: lm_sensors-devel BuildPrereq: mysql-devel BuildPrereq: rrdtool-devel BuildPrereq: net-snmp-devel Requires: rrdtool Requires: perl-Regexp-Common Packager: Florian octo Forster Vendor: Florian octo Forster %description collectd is a small daemon written in C for performance. It reads various system statistics and updates RRD files, creating them if neccessary. Since the daemon doesn't need to startup every time it wants to update the files it's very fast and easy on the system. Also, the statistics are very fine grained since the files are updated every 10 seconds. %package apache Summary: apache-plugin for collectd. Group: System Environment/Daemons Requires: collectd = %{version}, curl %description apache This plugin collectd data provided by Apache's `mod_status'. %package email Summary: email-plugin for collectd. Group: System Environment/Daemons Requires: collectd = %{version}, spamassassin %description email This plugin collectd data provided by spamassassin. %package mysql Summary: mysql-module for collectd. Group: System Environment/Daemons Requires: collectd = %{version}, mysql %description mysql MySQL querying plugin. This plugins provides data of issued commands, called handlers and database traffic. %package sensors Summary: libsensors-module for collectd. Group: System Environment/Daemons Requires: collectd = %{version}, lm_sensors %description sensors This plugin for collectd provides querying of sensors supported by lm_sensors. %prep rm -rf $RPM_BUILD_ROOT %setup %build ./configure --prefix=%{_prefix} --sbindir=%{_sbindir} --mandir=%{_mandir} --libdir=%{_libdir} --sysconfdir=%{_sysconfdir} make %install make install DESTDIR=$RPM_BUILD_ROOT mkdir -p $RPM_BUILD_ROOT/etc/rc.d/init.d mkdir -p $RPM_BUILD_ROOT/var/www/cgi-bin cp src/collectd.conf $RPM_BUILD_ROOT/etc/collectd.conf cp contrib/fedora/init.d-collectd $RPM_BUILD_ROOT/etc/rc.d/init.d/collectd cp contrib/collection.cgi $RPM_BUILD_ROOT/var/www/cgi-bin cp contrib/collection.conf $RPM_BUILD_ROOT/etc/collection.conf mkdir -p $RPM_BUILD_ROOT/var/lib/collectd %clean rm -rf $RPM_BUILD_ROOT %post /sbin/chkconfig --add collectd /sbin/chkconfig collectd on %preun if [ "$1" = 0 ]; then /sbin/chkconfig collectd off /etc/init.d/collectd stop /sbin/chkconfig --del collectd fi exit 0 %postun if [ "$1" -ge 1 ]; then /etc/init.d/collectd restart fi exit 0 %files %defattr(-,root,root) %doc AUTHORS COPYING ChangeLog INSTALL NEWS README %attr(0644,root,root) %config(noreplace) /etc/collectd.conf %attr(0644,root,root) %config(noreplace) /etc/collection.conf %attr(0755,root,root) /etc/rc.d/init.d/collectd %attr(0755,root,root) /var/www/cgi-bin/collection.cgi %attr(0755,root,root) %{_sbindir}/collectd %attr(0755,root,root) %{_bindir}/collectd-nagios %attr(0644,root,root) %{_mandir}/man1/* %attr(0644,root,root) %{_mandir}/man5/* %attr(0644,root,root) /usr/lib/perl5/5.8.8/i386-linux-thread-multi/perllocal.pod %attr(0644,root,root) /usr/lib/perl5/site_perl/5.8.8/Collectd.pm %attr(0644,root,root) /usr/lib/perl5/site_perl/5.8.8/Collectd/Unixsock.pm %attr(0644,root,root) /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi/auto/Collectd/.packlist %attr(0644,root,root) %{_mandir}/man3/Collectd::Unixsock.3pm.gz %attr(0644,root,root) %{_libdir}/%{name}/apcups.so* %attr(0644,root,root) %{_libdir}/%{name}/apcups.la # FIXME!!! #%attr(0644,root,root) %{_libdir}/%{name}/apple_sensors.so* #%attr(0644,root,root) %{_libdir}/%{name}/apple_sensors.la %attr(0644,root,root) %{_libdir}/%{name}/battery.so* %attr(0644,root,root) %{_libdir}/%{name}/battery.la %attr(0644,root,root) %{_libdir}/%{name}/conntrack.so* %attr(0644,root,root) %{_libdir}/%{name}/conntrack.la %attr(0644,root,root) %{_libdir}/%{name}/cpufreq.so* %attr(0644,root,root) %{_libdir}/%{name}/cpufreq.la %attr(0644,root,root) %{_libdir}/%{name}/cpu.so* %attr(0644,root,root) %{_libdir}/%{name}/cpu.la %attr(0644,root,root) %{_libdir}/%{name}/csv.so* %attr(0644,root,root) %{_libdir}/%{name}/csv.la %attr(0644,root,root) %{_libdir}/%{name}/df.so* %attr(0644,root,root) %{_libdir}/%{name}/df.la %attr(0644,root,root) %{_libdir}/%{name}/disk.so* %attr(0644,root,root) %{_libdir}/%{name}/disk.la %attr(0644,root,root) %{_libdir}/%{name}/dns.so* %attr(0644,root,root) %{_libdir}/%{name}/dns.la %attr(0644,root,root) %{_libdir}/%{name}/entropy.so* %attr(0644,root,root) %{_libdir}/%{name}/entropy.la %attr(0644,root,root) %{_libdir}/%{name}/exec.so* %attr(0644,root,root) %{_libdir}/%{name}/exec.la %attr(0644,root,root) %{_libdir}/%{name}/hddtemp.so* %attr(0644,root,root) %{_libdir}/%{name}/hddtemp.la %attr(0644,root,root) %{_libdir}/%{name}/interface.so* %attr(0644,root,root) %{_libdir}/%{name}/interface.la %attr(0644,root,root) %{_libdir}/%{name}/iptables.so* %attr(0644,root,root) %{_libdir}/%{name}/iptables.la %attr(0644,root,root) %{_libdir}/%{name}/irq.so* %attr(0644,root,root) %{_libdir}/%{name}/irq.la %attr(0644,root,root) %{_libdir}/%{name}/load.so* %attr(0644,root,root) %{_libdir}/%{name}/load.la %attr(0644,root,root) %{_libdir}/%{name}/logfile.so* %attr(0644,root,root) %{_libdir}/%{name}/logfile.la %attr(0644,root,root) %{_libdir}/%{name}/mbmon.so* %attr(0644,root,root) %{_libdir}/%{name}/mbmon.la %attr(0644,root,root) %{_libdir}/%{name}/memcached.so* %attr(0644,root,root) %{_libdir}/%{name}/memcached.la %attr(0644,root,root) %{_libdir}/%{name}/memory.so* %attr(0644,root,root) %{_libdir}/%{name}/memory.la %attr(0644,root,root) %{_libdir}/%{name}/multimeter.so* %attr(0644,root,root) %{_libdir}/%{name}/multimeter.la %attr(0644,root,root) %{_libdir}/%{name}/network.so* %attr(0644,root,root) %{_libdir}/%{name}/network.la %attr(0644,root,root) %{_libdir}/%{name}/nfs.so* %attr(0644,root,root) %{_libdir}/%{name}/nfs.la %attr(0644,root,root) %{_libdir}/%{name}/nginx.so* %attr(0644,root,root) %{_libdir}/%{name}/nginx.la %attr(0644,root,root) %{_libdir}/%{name}/ntpd.so* %attr(0644,root,root) %{_libdir}/%{name}/ntpd.la # FIXME!!! #%attr(0644,root,root) %{_libdir}/%{name}/nut.so* #%attr(0644,root,root) %{_libdir}/%{name}/nut.la %attr(0644,root,root) %{_libdir}/%{name}/perl.so* %attr(0644,root,root) %{_libdir}/%{name}/perl.la %attr(0644,root,root) %{_libdir}/%{name}/ping.so* %attr(0644,root,root) %{_libdir}/%{name}/ping.la %attr(0644,root,root) %{_libdir}/%{name}/processes.so* %attr(0644,root,root) %{_libdir}/%{name}/processes.la %attr(0644,root,root) %{_libdir}/%{name}/rrdtool.so* %attr(0644,root,root) %{_libdir}/%{name}/rrdtool.la %attr(0644,root,root) %{_libdir}/%{name}/serial.so* %attr(0644,root,root) %{_libdir}/%{name}/serial.la %attr(0644,root,root) %{_libdir}/%{name}/swap.so* %attr(0644,root,root) %{_libdir}/%{name}/swap.la %attr(0644,root,root) %{_libdir}/%{name}/snmp.so* %attr(0644,root,root) %{_libdir}/%{name}/snmp.la %attr(0644,root,root) %{_libdir}/%{name}/syslog.so* %attr(0644,root,root) %{_libdir}/%{name}/syslog.la # FIXME!!! #%attr(0644,root,root) %{_libdir}/%{name}/tape.so* #%attr(0644,root,root) %{_libdir}/%{name}/tape.la %attr(0644,root,root) %{_libdir}/%{name}/tcpconns.so* %attr(0644,root,root) %{_libdir}/%{name}/tcpconns.la %attr(0644,root,root) %{_libdir}/%{name}/unixsock.so* %attr(0644,root,root) %{_libdir}/%{name}/unixsock.la %attr(0644,root,root) %{_libdir}/%{name}/users.so* %attr(0644,root,root) %{_libdir}/%{name}/users.la %attr(0644,root,root) %{_libdir}/%{name}/vserver.so* %attr(0644,root,root) %{_libdir}/%{name}/vserver.la %attr(0644,root,root) %{_libdir}/%{name}/wireless.so* %attr(0644,root,root) %{_libdir}/%{name}/wireless.la %attr(0644,root,root) %{_datadir}/%{name}/types.db %dir /var/lib/collectd %files apache %attr(0644,root,root) %{_libdir}/%{name}/apache.so* %attr(0644,root,root) %{_libdir}/%{name}/apache.la %files email %attr(0644,root,root) %{_libdir}/%{name}/email.so* %attr(0644,root,root) %{_libdir}/%{name}/email.la %files mysql %attr(0644,root,root) %{_libdir}/%{name}/mysql.so* %attr(0644,root,root) %{_libdir}/%{name}/mysql.la %files sensors %attr(0644,root,root) %{_libdir}/%{name}/sensors.so* %attr(0644,root,root) %{_libdir}/%{name}/sensors.la %changelog * Wed Oct 31 2007 Iain Lea 4.2.0 - New major release - Changes to support 4.2.0 (ie. contrib/collection.conf) * Mon Aug 06 2007 Kjell Randa 4.0.6 - New upstream version * Wed Jul 25 2007 Kjell Randa 4.0.5 - New major release - Changes to support 4.0.5 * Wed Jan 11 2007 Iain Lea 3.11.0-0 - fixed spec file to build correctly on fedora core - added improved init.d script to work with chkconfig - added %post and %postun to call chkconfig automatically * Sun Jul 09 2006 Florian octo Forster 3.10.0-1 - New upstream version * Tue Jun 25 2006 Florian octo Forster 3.9.4-1 - New upstream version * Tue Jun 01 2006 Florian octo Forster 3.9.3-1 - New upstream version * Tue May 09 2006 Florian octo Forster 3.9.2-1 - New upstream version * Tue May 09 2006 Florian octo Forster 3.8.5-1 - New upstream version * Fri Apr 21 2006 Florian octo Forster 3.9.1-1 - New upstream version * Fri Apr 14 2006 Florian octo Forster 3.9.0-1 - New upstream version - Added the `apache' package. * Thu Mar 14 2006 Florian octo Forster 3.8.2-1 - New upstream version * Thu Mar 13 2006 Florian octo Forster 3.8.1-1 - New upstream version * Thu Mar 09 2006 Florian octo Forster 3.8.0-1 - New upstream version * Sat Feb 18 2006 Florian octo Forster 3.7.2-1 - Include `tape.so' so the build doesn't terminate because of missing files.. - New upstream version * Sat Feb 04 2006 Florian octo Forster 3.7.1-1 - New upstream version * Mon Jan 30 2006 Florian octo Forster 3.7.0-1 - New upstream version - Removed the extra `hddtemp' package * Tue Jan 24 2006 Florian octo Forster 3.6.2-1 - New upstream version * Fri Jan 20 2006 Florian octo Forster 3.6.1-1 - New upstream version * Fri Jan 20 2006 Florian octo Forster 3.6.0-1 - New upstream version - Added config file, `collectd.conf(5)', `df.so' - Added package `collectd-mysql', dependency on `mysqlclient10 | mysql' * Wed Dec 07 2005 Florian octo Forster 3.5.0-1 - New upstream version * Sat Nov 26 2005 Florian octo Forster 3.4.0-1 - New upstream version * Sat Nov 05 2005 Florian octo Forster 3.3.0-1 - New upstream version * Tue Oct 26 2005 Florian octo Forster 3.2.0-1 - New upstream version - Added statement to remove the `*.la' files. This fixes a problem when `Unpackaged files terminate build' is in effect. - Added `processes.so*' to the main package * Fri Oct 14 2005 Florian octo Forster 3.1.0-1 - New upstream version - Added package `collectd-hddtemp' * Fri Sep 30 2005 Florian octo Forster 3.0.0-1 - New upstream version - Split the package into `collectd' and `collectd-sensors' * Fri Sep 16 2005 Florian octo Forster 2.1.0-1 - New upstream version * Mon Sep 10 2005 Florian octo Forster 2.0.0-1 - New upstream version * Mon Aug 29 2005 Florian octo Forster 1.8.0-1 - New upstream version * Sun Aug 25 2005 Florian octo Forster 1.7.0-1 - New upstream version * Sun Aug 21 2005 Florian octo Forster 1.6.0-1 - New upstream version * Sun Jul 17 2005 Florian octo Forster 1.5.1-1 - New upstream version * Sun Jul 17 2005 Florian octo Forster 1.5-1 - New upstream version * Mon Jul 11 2005 Florian octo Forster 1.4.2-1 - New upstream version * Sat Jul 09 2005 Florian octo Forster 1.4-1 - Built on RedHat 7.3 collectd-5.4.0/contrib/PaxHeaders.11991/python0000644037772200116100000000013212204120331017247 xustar000000000000000030 mtime=1376821465.057973183 30 atime=1376821742.562409546 30 ctime=1376821742.562409546 collectd-5.4.0/contrib/python/0000755037772200116100000000000012204120331016070 5ustar00octoeng00000000000000collectd-5.4.0/contrib/python/PaxHeaders.11991/getsigchld.py0000644037772200116100000000013212204120331022013 xustar000000000000000030 mtime=1376821465.057973183 30 atime=1376821477.202167674 30 ctime=1376821742.562409546 collectd-5.4.0/contrib/python/getsigchld.py0000644037772200116100000000177412204120331020570 0ustar00octoeng00000000000000#!/usr/bin/python ############################################################################### # WARNING! Importing this script will break the exec plugin! # ############################################################################### # Use this if you want to create new processes from your python scripts. # # Normally you will get a OSError exception when the new process terminates # # because collectd will ignore the SIGCHLD python is waiting for. # # This script will restore the default SIGCHLD behavior so python scripts can # # create new processes without errors. # ############################################################################### # WARNING! Importing this script will break the exec plugin! # ############################################################################### import signal import collectd def init(): signal.signal(signal.SIGCHLD, signal.SIG_DFL) collectd.register_init(init) collectd-5.4.0/PaxHeaders.11991/version-gen.sh0000644037772200116100000000013112204120331017132 xustar000000000000000030 mtime=1376821465.093973759 30 atime=1376821477.230168122 29 ctime=1376821742.56640961 collectd-5.4.0/version-gen.sh0000754037772200116100000000036412204120331015704 0ustar00octoeng00000000000000#!/usr/bin/env bash DEFAULT_VERSION="5.4.0.git" VERSION="`git describe 2> /dev/null | sed -e 's/^collectd-//'`" if test -z "$VERSION"; then VERSION="$DEFAULT_VERSION" fi VERSION="`echo \"$VERSION\" | sed -e 's/-/./g'`" echo -n "$VERSION" collectd-5.4.0/PaxHeaders.11991/bindings0000644037772200116100000000013012204120755016073 xustar000000000000000030 mtime=1376821741.794397291 29 atime=1376821742.56640961 29 ctime=1376821742.56640961 collectd-5.4.0/bindings/0000755037772200116100000000000012204120755014716 5ustar00octoeng00000000000000collectd-5.4.0/bindings/PaxHeaders.11991/Makefile.am0000644037772200116100000000013212204120331020174 xustar000000000000000030 mtime=1376821465.045972991 30 atime=1376821477.194167546 30 ctime=1376821742.570409674 collectd-5.4.0/bindings/Makefile.am0000644037772200116100000000360112204120331016740 0ustar00octoeng00000000000000SUBDIRS = if BUILD_WITH_JAVA SUBDIRS += java endif EXTRA_DIST = perl/Makefile.PL \ perl/uninstall_mod.pl \ perl/lib/Collectd.pm \ perl/lib/Collectd/Unixsock.pm \ perl/lib/Collectd/Plugins/Monitorus.pm \ perl/lib/Collectd/Plugins/OpenVZ.pm CLEANFILES = \ buildperl/Collectd.pm \ buildperl/Collectd/Plugins/OpenVZ.pm \ buildperl/Collectd/Unixsock.pm \ buildperl/Makefile.PL \ .perl-directory-stamp DISTCLEANFILES = \ buildperl/Collectd.pm \ buildperl/Collectd/Plugins/OpenVZ.pm \ buildperl/Collectd/Unixsock.pm \ buildperl/Makefile.PL \ .perl-directory-stamp all-local: @PERL_BINDINGS@ install-exec-local: [ ! -f buildperl/Makefile ] || ( cd buildperl && $(MAKE) install ) # Perl 'make uninstall' does not work as well as wanted. # So we do the work here. uninstall-local: @PERL@ -I$(DESTDIR)$(prefix) $(srcdir)/perl/uninstall_mod.pl Collectd find $(DESTDIR)$(prefix) -name "perllocal.pod" -exec rm {} \; clean-local: rm -rf buildperl perl: buildperl/Makefile cd buildperl && $(MAKE) buildperl/Makefile: .perl-directory-stamp buildperl/Makefile.PL \ $(top_builddir)/config.status @# beautify the output a bit @echo 'cd buildperl && @PERL@ Makefile.PL @PERL_BINDINGS_OPTIONS@' @cd buildperl && ( if ! @PERL@ Makefile.PL @PERL_BINDINGS_OPTIONS@; then \ echo ""; \ echo 'Check whether you have set $$PERL_MM_OPT in your environment and try using ./configure --with-perl-bindings=""'; \ echo ""; \ fi ) buildperl/Makefile.PL: .perl-directory-stamp $(top_builddir)/config.status .perl-directory-stamp: if test ! -d buildperl; then \ mkdir -p buildperl/Collectd/Plugins; \ cp $(srcdir)/perl/lib/Collectd.pm buildperl/; \ cp $(srcdir)/perl/Makefile.PL buildperl/; \ cp $(srcdir)/perl/lib/Collectd/Unixsock.pm buildperl/Collectd/; \ cp $(srcdir)/perl/lib/Collectd/Plugins/OpenVZ.pm buildperl/Collectd/Plugins/; \ fi touch $@ .PHONY: perl collectd-5.4.0/bindings/PaxHeaders.11991/Makefile.in0000644037772200116100000000013112204120372020211 xustar000000000000000029 mtime=1376821498.26250488 30 atime=1376821537.987140663 30 ctime=1376821742.570409674 collectd-5.4.0/bindings/Makefile.in0000644037772200116100000006164412204120372016771 0ustar00octoeng00000000000000# Makefile.in generated by automake 1.11.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @BUILD_WITH_JAVA_TRUE@am__append_1 = java subdir = bindings DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/src/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir ETAGS = etags CTAGS = ctags DIST_SUBDIRS = java DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ ARGZ_H = @ARGZ_H@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_WITH_LIBAQUAERO5_CFLAGS = @BUILD_WITH_LIBAQUAERO5_CFLAGS@ BUILD_WITH_LIBAQUAERO5_LDFLAGS = @BUILD_WITH_LIBAQUAERO5_LDFLAGS@ BUILD_WITH_LIBCREDIS_CPPFLAGS = @BUILD_WITH_LIBCREDIS_CPPFLAGS@ BUILD_WITH_LIBCREDIS_LDFLAGS = @BUILD_WITH_LIBCREDIS_LDFLAGS@ BUILD_WITH_LIBCURL_CFLAGS = @BUILD_WITH_LIBCURL_CFLAGS@ BUILD_WITH_LIBCURL_LIBS = @BUILD_WITH_LIBCURL_LIBS@ BUILD_WITH_LIBDBI_CPPFLAGS = @BUILD_WITH_LIBDBI_CPPFLAGS@ BUILD_WITH_LIBDBI_LDFLAGS = @BUILD_WITH_LIBDBI_LDFLAGS@ BUILD_WITH_LIBDBI_LIBS = @BUILD_WITH_LIBDBI_LIBS@ BUILD_WITH_LIBHAL_CFLAGS = @BUILD_WITH_LIBHAL_CFLAGS@ BUILD_WITH_LIBHAL_LIBS = @BUILD_WITH_LIBHAL_LIBS@ BUILD_WITH_LIBIPTC_CPPFLAGS = @BUILD_WITH_LIBIPTC_CPPFLAGS@ BUILD_WITH_LIBIPTC_LDFLAGS = @BUILD_WITH_LIBIPTC_LDFLAGS@ BUILD_WITH_LIBLVM2APP_CPPFLAGS = @BUILD_WITH_LIBLVM2APP_CPPFLAGS@ BUILD_WITH_LIBLVM2APP_LDFLAGS = @BUILD_WITH_LIBLVM2APP_LDFLAGS@ BUILD_WITH_LIBLVM2APP_LIBS = @BUILD_WITH_LIBLVM2APP_LIBS@ BUILD_WITH_LIBMEMCACHED_CPPFLAGS = @BUILD_WITH_LIBMEMCACHED_CPPFLAGS@ BUILD_WITH_LIBMEMCACHED_LDFLAGS = @BUILD_WITH_LIBMEMCACHED_LDFLAGS@ BUILD_WITH_LIBMEMCACHED_LIBS = @BUILD_WITH_LIBMEMCACHED_LIBS@ BUILD_WITH_LIBMNL_CFLAGS = @BUILD_WITH_LIBMNL_CFLAGS@ BUILD_WITH_LIBMNL_LIBS = @BUILD_WITH_LIBMNL_LIBS@ BUILD_WITH_LIBMODBUS_CFLAGS = @BUILD_WITH_LIBMODBUS_CFLAGS@ BUILD_WITH_LIBMODBUS_LIBS = @BUILD_WITH_LIBMODBUS_LIBS@ BUILD_WITH_LIBMONGOC_CPPFLAGS = @BUILD_WITH_LIBMONGOC_CPPFLAGS@ BUILD_WITH_LIBMONGOC_LDFLAGS = @BUILD_WITH_LIBMONGOC_LDFLAGS@ BUILD_WITH_LIBMYSQL_CFLAGS = @BUILD_WITH_LIBMYSQL_CFLAGS@ BUILD_WITH_LIBMYSQL_LIBS = @BUILD_WITH_LIBMYSQL_LIBS@ BUILD_WITH_LIBOPING_CPPFLAGS = @BUILD_WITH_LIBOPING_CPPFLAGS@ BUILD_WITH_LIBOPING_LDFLAGS = @BUILD_WITH_LIBOPING_LDFLAGS@ BUILD_WITH_LIBOWCAPI_CPPFLAGS = @BUILD_WITH_LIBOWCAPI_CPPFLAGS@ BUILD_WITH_LIBOWCAPI_LIBS = @BUILD_WITH_LIBOWCAPI_LIBS@ BUILD_WITH_LIBPQ_CPPFLAGS = @BUILD_WITH_LIBPQ_CPPFLAGS@ BUILD_WITH_LIBPQ_LDFLAGS = @BUILD_WITH_LIBPQ_LDFLAGS@ BUILD_WITH_LIBRABBITMQ_CPPFLAGS = @BUILD_WITH_LIBRABBITMQ_CPPFLAGS@ BUILD_WITH_LIBRABBITMQ_LDFLAGS = @BUILD_WITH_LIBRABBITMQ_LDFLAGS@ BUILD_WITH_LIBRABBITMQ_LIBS = @BUILD_WITH_LIBRABBITMQ_LIBS@ BUILD_WITH_LIBROUTEROS_CPPFLAGS = @BUILD_WITH_LIBROUTEROS_CPPFLAGS@ BUILD_WITH_LIBROUTEROS_LDFLAGS = @BUILD_WITH_LIBROUTEROS_LDFLAGS@ BUILD_WITH_LIBRRD_CFLAGS = @BUILD_WITH_LIBRRD_CFLAGS@ BUILD_WITH_LIBRRD_LDFLAGS = @BUILD_WITH_LIBRRD_LDFLAGS@ BUILD_WITH_LIBSENSORS_CFLAGS = @BUILD_WITH_LIBSENSORS_CFLAGS@ BUILD_WITH_LIBSENSORS_LDFLAGS = @BUILD_WITH_LIBSENSORS_LDFLAGS@ BUILD_WITH_LIBSIGROK_CFLAGS = @BUILD_WITH_LIBSIGROK_CFLAGS@ BUILD_WITH_LIBSIGROK_LDFLAGS = @BUILD_WITH_LIBSIGROK_LDFLAGS@ BUILD_WITH_LIBSNMP_CFLAGS = @BUILD_WITH_LIBSNMP_CFLAGS@ BUILD_WITH_LIBSNMP_LIBS = @BUILD_WITH_LIBSNMP_LIBS@ BUILD_WITH_LIBSTATGRAB_CFLAGS = @BUILD_WITH_LIBSTATGRAB_CFLAGS@ BUILD_WITH_LIBSTATGRAB_LDFLAGS = @BUILD_WITH_LIBSTATGRAB_LDFLAGS@ BUILD_WITH_LIBTOKYOTYRANT_CPPFLAGS = @BUILD_WITH_LIBTOKYOTYRANT_CPPFLAGS@ BUILD_WITH_LIBTOKYOTYRANT_LDFLAGS = @BUILD_WITH_LIBTOKYOTYRANT_LDFLAGS@ BUILD_WITH_LIBTOKYOTYRANT_LIBS = @BUILD_WITH_LIBTOKYOTYRANT_LIBS@ BUILD_WITH_LIBUPSCLIENT_CFLAGS = @BUILD_WITH_LIBUPSCLIENT_CFLAGS@ BUILD_WITH_LIBUPSCLIENT_LIBS = @BUILD_WITH_LIBUPSCLIENT_LIBS@ BUILD_WITH_LIBVARNISH_CFLAGS = @BUILD_WITH_LIBVARNISH_CFLAGS@ BUILD_WITH_LIBVARNISH_LIBS = @BUILD_WITH_LIBVARNISH_LIBS@ BUILD_WITH_LIBVIRT_CFLAGS = @BUILD_WITH_LIBVIRT_CFLAGS@ BUILD_WITH_LIBVIRT_LIBS = @BUILD_WITH_LIBVIRT_LIBS@ BUILD_WITH_LIBXML2_CFLAGS = @BUILD_WITH_LIBXML2_CFLAGS@ BUILD_WITH_LIBXML2_LIBS = @BUILD_WITH_LIBXML2_LIBS@ BUILD_WITH_LIBXMMS_CFLAGS = @BUILD_WITH_LIBXMMS_CFLAGS@ BUILD_WITH_LIBXMMS_LIBS = @BUILD_WITH_LIBXMMS_LIBS@ BUILD_WITH_LIBYAJL_CPPFLAGS = @BUILD_WITH_LIBYAJL_CPPFLAGS@ BUILD_WITH_LIBYAJL_LDFLAGS = @BUILD_WITH_LIBYAJL_LDFLAGS@ BUILD_WITH_LIBYAJL_LIBS = @BUILD_WITH_LIBYAJL_LIBS@ BUILD_WITH_MIC_CPPFLAGS = @BUILD_WITH_MIC_CPPFLAGS@ BUILD_WITH_MIC_LDADD = @BUILD_WITH_MIC_LDADD@ BUILD_WITH_MIC_LIBPATH = @BUILD_WITH_MIC_LIBPATH@ BUILD_WITH_OPENIPMI_CFLAGS = @BUILD_WITH_OPENIPMI_CFLAGS@ BUILD_WITH_OPENIPMI_LIBS = @BUILD_WITH_OPENIPMI_LIBS@ BUILD_WITH_ORACLE_CFLAGS = @BUILD_WITH_ORACLE_CFLAGS@ BUILD_WITH_ORACLE_LIBS = @BUILD_WITH_ORACLE_LIBS@ BUILD_WITH_PYTHON_CPPFLAGS = @BUILD_WITH_PYTHON_CPPFLAGS@ BUILD_WITH_PYTHON_LDFLAGS = @BUILD_WITH_PYTHON_LDFLAGS@ BUILD_WITH_PYTHON_LIBS = @BUILD_WITH_PYTHON_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFAULT_LOG_LEVEL = @DEFAULT_LOG_LEVEL@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GANGLIA_CPPFLAGS = @GANGLIA_CPPFLAGS@ GANGLIA_LDFLAGS = @GANGLIA_LDFLAGS@ GANGLIA_LIBS = @GANGLIA_LIBS@ GCRYPT_CPPFLAGS = @GCRYPT_CPPFLAGS@ GCRYPT_LDFLAGS = @GCRYPT_LDFLAGS@ GCRYPT_LIBS = @GCRYPT_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_COMPILE_RESOURCES = @GLIB_COMPILE_RESOURCES@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ GLIB_MKENUMS = @GLIB_MKENUMS@ GOBJECT_QUERY = @GOBJECT_QUERY@ GREP = @GREP@ INCLTDL = @INCLTDL@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAR = @JAR@ JAVAC = @JAVAC@ JAVA_CFLAGS = @JAVA_CFLAGS@ JAVA_CPPFLAGS = @JAVA_CPPFLAGS@ JAVA_LDFLAGS = @JAVA_LDFLAGS@ JAVA_LIBS = @JAVA_LIBS@ KERNEL_CFLAGS = @KERNEL_CFLAGS@ KERNEL_DIR = @KERNEL_DIR@ LCC_VERSION_EXTRA = @LCC_VERSION_EXTRA@ LCC_VERSION_MAJOR = @LCC_VERSION_MAJOR@ LCC_VERSION_MINOR = @LCC_VERSION_MINOR@ LCC_VERSION_PATCH = @LCC_VERSION_PATCH@ LCC_VERSION_STRING = @LCC_VERSION_STRING@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBADD_DL = @LIBADD_DL@ LIBADD_DLD_LINK = @LIBADD_DLD_LINK@ LIBADD_DLOPEN = @LIBADD_DLOPEN@ LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLTDL = @LIBLTDL@ LIBNETAPP_CPPFLAGS = @LIBNETAPP_CPPFLAGS@ LIBNETAPP_LDFLAGS = @LIBNETAPP_LDFLAGS@ LIBNETAPP_LIBS = @LIBNETAPP_LIBS@ LIBNOTIFY_CFLAGS = @LIBNOTIFY_CFLAGS@ LIBNOTIFY_LIBS = @LIBNOTIFY_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LOAD_PLUGIN_CSV = @LOAD_PLUGIN_CSV@ LOAD_PLUGIN_LOGFILE = @LOAD_PLUGIN_LOGFILE@ LOAD_PLUGIN_NETWORK = @LOAD_PLUGIN_NETWORK@ LOAD_PLUGIN_RRDTOOL = @LOAD_PLUGIN_RRDTOOL@ LOAD_PLUGIN_SYSLOG = @LOAD_PLUGIN_SYSLOG@ LTDLDEPS = @LTDLDEPS@ LTDLINCL = @LTDLINCL@ LTDLOPEN = @LTDLOPEN@ LTLIBOBJS = @LTLIBOBJS@ LT_CONFIG_H = @LT_CONFIG_H@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_BINDINGS = @PERL_BINDINGS@ PERL_BINDINGS_OPTIONS = @PERL_BINDINGS_OPTIONS@ PERL_CFLAGS = @PERL_CFLAGS@ PERL_LDFLAGS = @PERL_LDFLAGS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_protoc_c = @have_protoc_c@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ ltdl_LIBOBJS = @ltdl_LIBOBJS@ ltdl_LTLIBOBJS = @ltdl_LTLIBOBJS@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sys_symbol_underscore = @sys_symbol_underscore@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = $(am__append_1) EXTRA_DIST = perl/Makefile.PL \ perl/uninstall_mod.pl \ perl/lib/Collectd.pm \ perl/lib/Collectd/Unixsock.pm \ perl/lib/Collectd/Plugins/Monitorus.pm \ perl/lib/Collectd/Plugins/OpenVZ.pm CLEANFILES = \ buildperl/Collectd.pm \ buildperl/Collectd/Plugins/OpenVZ.pm \ buildperl/Collectd/Unixsock.pm \ buildperl/Makefile.PL \ .perl-directory-stamp DISTCLEANFILES = \ buildperl/Collectd.pm \ buildperl/Collectd/Plugins/OpenVZ.pm \ buildperl/Collectd/Unixsock.pm \ buildperl/Makefile.PL \ .perl-directory-stamp all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu bindings/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu bindings/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile all-local installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-exec-local install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-local .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am all-local check check-am clean clean-generic \ clean-libtool clean-local ctags ctags-recursive distclean \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-exec-local install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-recursive uninstall uninstall-am \ uninstall-local all-local: @PERL_BINDINGS@ install-exec-local: [ ! -f buildperl/Makefile ] || ( cd buildperl && $(MAKE) install ) # Perl 'make uninstall' does not work as well as wanted. # So we do the work here. uninstall-local: @PERL@ -I$(DESTDIR)$(prefix) $(srcdir)/perl/uninstall_mod.pl Collectd find $(DESTDIR)$(prefix) -name "perllocal.pod" -exec rm {} \; clean-local: rm -rf buildperl perl: buildperl/Makefile cd buildperl && $(MAKE) buildperl/Makefile: .perl-directory-stamp buildperl/Makefile.PL \ $(top_builddir)/config.status @# beautify the output a bit @echo 'cd buildperl && @PERL@ Makefile.PL @PERL_BINDINGS_OPTIONS@' @cd buildperl && ( if ! @PERL@ Makefile.PL @PERL_BINDINGS_OPTIONS@; then \ echo ""; \ echo 'Check whether you have set $$PERL_MM_OPT in your environment and try using ./configure --with-perl-bindings=""'; \ echo ""; \ fi ) buildperl/Makefile.PL: .perl-directory-stamp $(top_builddir)/config.status .perl-directory-stamp: if test ! -d buildperl; then \ mkdir -p buildperl/Collectd/Plugins; \ cp $(srcdir)/perl/lib/Collectd.pm buildperl/; \ cp $(srcdir)/perl/Makefile.PL buildperl/; \ cp $(srcdir)/perl/lib/Collectd/Unixsock.pm buildperl/Collectd/; \ cp $(srcdir)/perl/lib/Collectd/Plugins/OpenVZ.pm buildperl/Collectd/Plugins/; \ fi touch $@ .PHONY: perl # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: collectd-5.4.0/bindings/PaxHeaders.11991/java0000644037772200116100000000013212204120755017016 xustar000000000000000030 mtime=1376821741.850398185 30 atime=1376821742.574409737 30 ctime=1376821742.574409737 collectd-5.4.0/bindings/java/0000755037772200116100000000000012204120755015637 5ustar00octoeng00000000000000collectd-5.4.0/bindings/java/PaxHeaders.11991/org0000644037772200116100000000013212204120755017605 xustar000000000000000030 mtime=1376821741.842398057 30 atime=1376821742.574409737 30 ctime=1376821742.574409737 collectd-5.4.0/bindings/java/org/0000755037772200116100000000000012204120755016426 5ustar00octoeng00000000000000collectd-5.4.0/bindings/java/org/PaxHeaders.11991/collectd0000644037772200116100000000013212204120755021376 xustar000000000000000030 mtime=1376821741.842398057 30 atime=1376821742.578409801 30 ctime=1376821742.574409737 collectd-5.4.0/bindings/java/org/collectd/0000755037772200116100000000000012204120755020217 5ustar00octoeng00000000000000collectd-5.4.0/bindings/java/org/collectd/PaxHeaders.11991/api0000644037772200116100000000013212204120755022147 xustar000000000000000030 mtime=1376821741.902399015 30 atime=1376821742.578409801 30 ctime=1376821742.578409801 collectd-5.4.0/bindings/java/org/collectd/api/0000755037772200116100000000000012204120755020770 5ustar00octoeng00000000000000collectd-5.4.0/bindings/java/org/collectd/api/PaxHeaders.11991/CollectdNotificationInterface.java0000644037772200116100000000013212204120331030776 xustar000000000000000030 mtime=1376821465.045972991 30 atime=1376821477.194167546 30 ctime=1376821742.578409801 collectd-5.4.0/bindings/java/org/collectd/api/CollectdNotificationInterface.java0000644037772200116100000000221012204120331027535 0ustar00octoeng00000000000000/* * collectd/java - org/collectd/api/CollectdNotificationInterface.java * Copyright (C) 2009 Florian octo 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: * Florian octo Forster */ package org.collectd.api; /** * Interface for objects implementing a notification method. * * @author Florian Forster <octo at verplant.org> * @see Collectd#registerNotification */ public interface CollectdNotificationInterface { public int notification (Notification n); } collectd-5.4.0/bindings/java/org/collectd/api/PaxHeaders.11991/OConfigItem.java0000644037772200116100000000013212204120331025220 xustar000000000000000030 mtime=1376821465.045972991 30 atime=1376821477.194167546 30 ctime=1376821742.582409866 collectd-5.4.0/bindings/java/org/collectd/api/OConfigItem.java0000644037772200116100000000474612204120331023777 0ustar00octoeng00000000000000/* * collectd/java - org/collectd/api/OConfigItem.java * Copyright (C) 2009 Florian octo 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: * Florian octo Forster */ package org.collectd.api; import java.util.List; import java.util.ArrayList; /** * Java representation of collectd/src/liboconfig/oconfig.h:oconfig_item_t structure. * * @author Florian Forster <octo at verplant.org> */ public class OConfigItem { private String _key = null; private List _values = new ArrayList (); private List _children = new ArrayList (); public OConfigItem (String key) { _key = key; } /* OConfigItem (String key) */ public String getKey () { return (_key); } /* String getKey () */ public void addValue (OConfigValue cv) { _values.add (cv); } /* void addValue (OConfigValue cv) */ public void addValue (String s) { _values.add (new OConfigValue (s)); } /* void addValue (String s) */ public void addValue (Number n) { _values.add (new OConfigValue (n)); } /* void addValue (String s) */ public void addValue (boolean b) { _values.add (new OConfigValue (b)); } /* void addValue (String s) */ public List getValues () { return (_values); } /* List getValues () */ public void addChild (OConfigItem ci) { _children.add (ci); } /* void addChild (OConfigItem ci) */ public List getChildren () { return (_children); } /* List getChildren () */ public String toString () { return (new String ("{ key: " + _key + "; " + "values: " + _values.toString () + "; " + "children: " + _children.toString () + "; }")); } /* String toString () */ } /* class OConfigItem */ /* vim: set sw=2 sts=2 et fdm=marker : */ collectd-5.4.0/bindings/java/org/collectd/api/PaxHeaders.11991/DataSet.java0000644037772200116100000000013212204120331024402 xustar000000000000000030 mtime=1376821465.045972991 30 atime=1376821477.194167546 30 ctime=1376821742.582409866 collectd-5.4.0/bindings/java/org/collectd/api/DataSet.java0000644037772200116100000000624012204120331023150 0ustar00octoeng00000000000000/* * collectd/java - org/collectd/api/OConfigItem.java * Copyright (C) 2009 Florian octo 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: * Florian octo Forster */ package org.collectd.api; import java.util.List; import java.util.ArrayList; /** * Java representation of collectd/src/plugin.h:data_set_t structure. * * @author Florian Forster <octo at verplant.org> */ public class DataSet { private String _type; private List _ds; private DataSet () { this._type = null; this._ds = new ArrayList (); } public DataSet (String type) { this._type = type; this._ds = new ArrayList (); } public DataSet (String type, DataSource dsrc) { this._type = type; this._ds = new ArrayList (); this._ds.add (dsrc); } public DataSet (String type, List ds) { this._type = type; this._ds = ds; } public void setType (String type) { this._type = type; } public String getType () { return (this._type); } public void addDataSource (DataSource dsrc) { this._ds.add (dsrc); } public List getDataSources () { return (this._ds); } public String toString () { StringBuffer sb = new StringBuffer (); int i; sb.append (this._type); for (i = 0; i < this._ds.size (); i++) { if (i == 0) sb.append ("\t"); else sb.append (", "); sb.append (this._ds.get (i).toString ()); } return (sb.toString ()); } static public DataSet parseDataSet (String str) { DataSet ds = new DataSet (); String[] fields; int i; str = str.trim(); if (str.length() == 0) { return (null); } if (str.charAt(0) == '#') { return (null); } fields = str.split ("\\s+"); if (fields.length < 2) return (null); ds._type = fields[0]; for (i = 1; i < fields.length; i++) { DataSource dsrc; dsrc = DataSource.parseDataSource (fields[i]); if (dsrc == null) break; ds._ds.add (dsrc); } if (i < fields.length) return (null); return (ds); } /* DataSet parseDataSet */ } /* class DataSet */ /* vim: set sw=4 sts=4 et : */ collectd-5.4.0/bindings/java/org/collectd/api/PaxHeaders.11991/CollectdMatchFactoryInterface.java0000644037772200116100000000013112204120331030733 xustar000000000000000030 mtime=1376821465.045972991 30 atime=1376821477.194167546 29 ctime=1376821742.58640993 collectd-5.4.0/bindings/java/org/collectd/api/CollectdMatchFactoryInterface.java0000644037772200116100000000326512204120331027506 0ustar00octoeng00000000000000/* * collectd/java - org/collectd/api/CollectdMatchFactoryInterface.java * Copyright (C) 2009 Florian octo 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: * Florian octo Forster */ package org.collectd.api; /** * Interface for objects implementing a "match factory". * * Objects implementing this interface are used to create objects implementing * the CollectdMatchInterface interface. * * @author Florian Forster <octo at verplant.org> * @see CollectdMatchInterface * @see Collectd#registerMatch */ public interface CollectdMatchFactoryInterface { /** * Create a new "match" object. * * This method uses the configuration provided as argument to create a * new object which must implement the {@link CollectdMatchInterface} * interface. * * This function corresponds to the create member of the * src/filter_chain.h:match_proc_t struct. * * @return New {@link CollectdMatchInterface} object. */ public CollectdMatchInterface createMatch (OConfigItem ci); } collectd-5.4.0/bindings/java/org/collectd/api/PaxHeaders.11991/CollectdTargetInterface.java0000644037772200116100000000013112204120331027575 xustar000000000000000030 mtime=1376821465.045972991 30 atime=1376821477.194167546 29 ctime=1376821742.58640993 collectd-5.4.0/bindings/java/org/collectd/api/CollectdTargetInterface.java0000644037772200116100000000333612204120331026347 0ustar00octoeng00000000000000/* * collectd/java - org/collectd/api/CollectdTargetInterface.java * Copyright (C) 2009 Florian octo 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: * Florian octo Forster */ package org.collectd.api; /** * Interface for objects implementing a target method. * * These objects are instantiated using objects which implement the * CollectdTargetFactoryInterface interface. They are not instantiated by the * daemon directly! * * @author Florian Forster <octo at verplant.org> * @see CollectdTargetFactoryInterface * @see Collectd#registerTarget */ public interface CollectdTargetInterface { /** * Callback method for targets. * * This method is called to perform some action on the given ValueList. * What precisely is done depends entirely on the implementing class. * * @return One of: {@link Collectd#FC_TARGET_CONTINUE}, * {@link Collectd#FC_TARGET_STOP}, {@link Collectd#FC_TARGET_RETURN} * @see CollectdTargetFactoryInterface */ public int invoke (DataSet ds, ValueList vl); } /* public interface CollectdTargetInterface */ collectd-5.4.0/bindings/java/org/collectd/api/PaxHeaders.11991/CollectdConfigInterface.java0000644037772200116100000000013212204120331027555 xustar000000000000000030 mtime=1376821465.045972991 30 atime=1376821477.194167546 30 ctime=1376821742.590409994 collectd-5.4.0/bindings/java/org/collectd/api/CollectdConfigInterface.java0000644037772200116100000000221312204120331026317 0ustar00octoeng00000000000000/* * collectd/java - org/collectd/api/CollectdConfigInterface.java * Copyright (C) 2009 Florian octo 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: * Florian octo Forster */ package org.collectd.api; /** * Interface for objects implementing a config method. * * @author Florian Forster <octo at verplant.org> * @see Collectd#registerConfig(String, CollectdConfigInterface) */ public interface CollectdConfigInterface { public int config (OConfigItem ci); } collectd-5.4.0/bindings/java/org/collectd/api/PaxHeaders.11991/CollectdReadInterface.java0000644037772200116100000000013212204120331027223 xustar000000000000000030 mtime=1376821465.045972991 30 atime=1376821477.194167546 30 ctime=1376821742.590409994 collectd-5.4.0/bindings/java/org/collectd/api/CollectdReadInterface.java0000644037772200116100000000314612204120331025773 0ustar00octoeng00000000000000/* * collectd/java - org/collectd/api/CollectdReadInterface.java * Copyright (C) 2009 Florian octo 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: * Florian octo Forster */ package org.collectd.api; /** * Interface for objects implementing a read method. * * Objects implementing this interface can be registered with the daemon. Their * read method is then called periodically to acquire and submit values. * * @author Florian Forster <octo at verplant.org> * @see Collectd#registerRead */ public interface CollectdReadInterface { /** * Callback method for read plugins. * * This method is called once every few seconds (depends on the * configuration of the daemon). It is supposed to gather values in * some way and submit them to the daemon using * {@link Collectd#dispatchValues}. * * @return zero when successful, non-zero when an error occurred. * @see Collectd#dispatchValues */ public int read (); } collectd-5.4.0/bindings/java/org/collectd/api/PaxHeaders.11991/DataSource.java0000644037772200116100000000013212204120331025107 xustar000000000000000030 mtime=1376821465.045972991 30 atime=1376821477.194167546 30 ctime=1376821742.594410058 collectd-5.4.0/bindings/java/org/collectd/api/DataSource.java0000644037772200116100000000770712204120331023666 0ustar00octoeng00000000000000/* * jcollectd * Copyright (C) 2009 Hyperic, Inc. * * 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 */ package org.collectd.api; /** * Java representation of collectd/src/plugin.h:data_source_t structure. */ public class DataSource { public static final int TYPE_COUNTER = 0; public static final int TYPE_GAUGE = 1; public static final int TYPE_DERIVE = 2; public static final int TYPE_ABSOLUTE = 3; static final String COUNTER = "COUNTER"; static final String GAUGE = "GAUGE"; static final String DERIVE = "DERIVE"; static final String ABSOLUTE = "ABSOLUTE"; static final String NAN = "U"; private static final String[] TYPES = { COUNTER, GAUGE, DERIVE, ABSOLUTE }; String _name; int _type; double _min; double _max; public DataSource (String name, int type, double min, double max) { this._name = name; this._type = TYPE_GAUGE; if (type == TYPE_COUNTER) this._type = TYPE_COUNTER; else if (type == TYPE_DERIVE) this._type = TYPE_DERIVE; else if (type == TYPE_ABSOLUTE) this._type = TYPE_ABSOLUTE; this._min = min; this._max = max; } /* Needed in parseDataSource below. Other code should use the above * constructor or `parseDataSource'. */ private DataSource () { this._type = TYPE_GAUGE; } public String getName() { return _name; } public void setName(String name) { _name = name; } public int getType() { return _type; } public void setType(int type) { _type = type; } public double getMin() { return _min; } public void setMin(double min) { _min = min; } public double getMax() { return _max; } public void setMax(double max) { _max = max; } static double toDouble(String val) { if (val.equals(NAN)) { return Double.NaN; } else { return Double.parseDouble(val); } } private String asString(double val) { if (Double.isNaN(val)) { return NAN; } else { return String.valueOf(val); } } public String toString() { StringBuffer sb = new StringBuffer(); final char DLM = ':'; sb.append(_name).append(DLM); sb.append(TYPES[_type]).append(DLM); sb.append(asString(_min)).append(DLM); sb.append(asString(_max)); return sb.toString(); } static public DataSource parseDataSource (String str) { String[] fields; int str_len = str.length (); DataSource dsrc = new DataSource (); /* Ignore trailing commas. This makes it easier for parsing code. */ if (str.charAt (str_len - 1) == ',') { str = str.substring (0, str_len - 1); } fields = str.split(":"); if (fields.length != 4) return (null); dsrc._name = fields[0]; if (fields[1].equals (DataSource.GAUGE)) { dsrc._type = TYPE_GAUGE; } else { dsrc._type = TYPE_COUNTER; } dsrc._min = toDouble (fields[2]); dsrc._max = toDouble (fields[3]); return (dsrc); } /* DataSource parseDataSource */ } /* vim: set sw=4 sts=4 et : */ collectd-5.4.0/bindings/java/org/collectd/api/PaxHeaders.11991/CollectdInitInterface.java0000644037772200116100000000013212204120331027253 xustar000000000000000030 mtime=1376821465.045972991 30 atime=1376821477.194167546 30 ctime=1376821742.594410058 collectd-5.4.0/bindings/java/org/collectd/api/CollectdInitInterface.java0000644037772200116100000000212312204120331026015 0ustar00octoeng00000000000000/* * collectd/java - org/collectd/api/CollectdInitInterface.java * Copyright (C) 2009 Florian octo 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: * Florian octo Forster */ package org.collectd.api; /** * Interface for objects implementing an init method. * * @author Florian Forster <octo at verplant.org> * @see Collectd#registerInit */ public interface CollectdInitInterface { public int init (); } collectd-5.4.0/bindings/java/org/collectd/api/PaxHeaders.11991/CollectdShutdownInterface.java0000644037772200116100000000013212204120331030163 xustar000000000000000030 mtime=1376821465.045972991 30 atime=1376821477.194167546 30 ctime=1376821742.594410058 collectd-5.4.0/bindings/java/org/collectd/api/CollectdShutdownInterface.java0000644037772200116100000000214612204120331026732 0ustar00octoeng00000000000000/* * collectd/java - org/collectd/api/CollectdShutdownInterface.java * Copyright (C) 2009 Florian octo 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: * Florian octo Forster */ package org.collectd.api; /** * Interface for objects implementing a shutdown method. * * @author Florian Forster <octo at verplant.org> * @see Collectd#registerShutdown */ public interface CollectdShutdownInterface { public int shutdown (); } collectd-5.4.0/bindings/java/org/collectd/api/PaxHeaders.11991/OConfigValue.java0000644037772200116100000000013212204120331025376 xustar000000000000000030 mtime=1376821465.045972991 30 atime=1376821477.194167546 30 ctime=1376821742.598410122 collectd-5.4.0/bindings/java/org/collectd/api/OConfigValue.java0000644037772200116100000000511712204120331024146 0ustar00octoeng00000000000000/* * collectd/java - org/collectd/api/OConfigValue.java * Copyright (C) 2009 Florian octo 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: * Florian octo Forster */ package org.collectd.api; /** * Java representation of collectd/src/liboconfig/oconfig.h:oconfig_value_t structure. * * @author Florian Forster <octo at verplant.org> */ public class OConfigValue { public static final int OCONFIG_TYPE_STRING = 0; public static final int OCONFIG_TYPE_NUMBER = 1; public static final int OCONFIG_TYPE_BOOLEAN = 2; private int _type; private String _value_string; private Number _value_number; private boolean _value_boolean; public OConfigValue (String s) { _type = OCONFIG_TYPE_STRING; _value_string = s; _value_number = null; _value_boolean = false; } /* OConfigValue (String s) */ public OConfigValue (Number n) { _type = OCONFIG_TYPE_NUMBER; _value_string = null; _value_number = n; _value_boolean = false; } /* OConfigValue (String s) */ public OConfigValue (boolean b) { _type = OCONFIG_TYPE_BOOLEAN; _value_string = null; _value_number = null; _value_boolean = b; } /* OConfigValue (String s) */ public int getType () { return (_type); } /* int getType */ public String getString () { return (_value_string); } /* String getString */ public Number getNumber () { return (_value_number); } /* String getString */ public boolean getBoolean () { return (_value_boolean); } /* String getString */ public String toString () { if (_type == OCONFIG_TYPE_STRING) return (_value_string); else if (_type == OCONFIG_TYPE_NUMBER) return (_value_number.toString ()); else if (_type == OCONFIG_TYPE_BOOLEAN) return (Boolean.toString (_value_boolean)); return (null); } /* String toString () */ } /* class OConfigValue */ /* vim: set sw=2 sts=2 et fdm=marker : */ collectd-5.4.0/bindings/java/org/collectd/api/PaxHeaders.11991/Notification.java0000644037772200116100000000013212204120331025503 xustar000000000000000030 mtime=1376821465.045972991 30 atime=1376821477.194167546 30 ctime=1376821742.598410122 collectd-5.4.0/bindings/java/org/collectd/api/Notification.java0000644037772200116100000000457312204120331024260 0ustar00octoeng00000000000000/* * jcollectd * Copyright (C) 2009 Hyperic, Inc. * * 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 */ package org.collectd.api; /** * Java representation of collectd/src/plugin.h:notfication_t structure. */ public class Notification extends PluginData { public static final int FAILURE = 1; public static final int WARNING = 2; public static final int OKAY = 4; public static String[] SEVERITY = { "FAILURE", "WARNING", "OKAY", "UNKNOWN" }; private int _severity; private String _message; public Notification () { _severity = 0; _message = "Initial notification message"; } public Notification (PluginData pd) { super (pd); _severity = 0; _message = "Initial notification message"; } public void setSeverity (int severity) { if ((severity == FAILURE) || (severity == WARNING) || (severity == OKAY)) this._severity = severity; } public int getSeverity() { return _severity; } public String getSeverityString() { switch (_severity) { case FAILURE: return SEVERITY[0]; case WARNING: return SEVERITY[1]; case OKAY: return SEVERITY[2]; default: return SEVERITY[3]; } } public void setMessage (String message) { this._message = message; } public String getMessage() { return _message; } public String toString() { StringBuffer sb = new StringBuffer(super.toString()); sb.append(" [").append(getSeverityString()).append("] "); sb.append(_message); return sb.toString(); } } collectd-5.4.0/bindings/java/org/collectd/api/PaxHeaders.11991/PluginData.java0000644037772200116100000000013212204120331025105 xustar000000000000000030 mtime=1376821465.045972991 30 atime=1376821477.194167546 30 ctime=1376821742.602410185 collectd-5.4.0/bindings/java/org/collectd/api/PluginData.java0000644037772200116100000000613412204120331023655 0ustar00octoeng00000000000000/* * jcollectd * Copyright (C) 2009 Hyperic, Inc. * * 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 */ package org.collectd.api; import java.util.Date; /** * Shared members of value_list_t and notification_t structures. */ public class PluginData { protected long _time = 0; protected String _host; protected String _plugin; protected String _pluginInstance = ""; protected String _type = ""; protected String _typeInstance = ""; public PluginData() { } public PluginData(PluginData pd) { _time = pd._time; _host = pd._host; _plugin = pd._plugin; _pluginInstance = pd._pluginInstance; _type = pd._type; _typeInstance = pd._typeInstance; } public long getTime() { return _time; } public void setTime(long time) { _time = time; } public String getHost() { return _host; } public void setHost(String host) { _host = host; } public String getPlugin() { return _plugin; } public void setPlugin(String plugin) { _plugin = plugin; } public String getPluginInstance() { return _pluginInstance; } public void setPluginInstance(String pluginInstance) { _pluginInstance = pluginInstance; } public String getType() { return _type; } public void setType(String type) { _type = type; } public String getTypeInstance() { return _typeInstance; } public void setTypeInstance(String typeInstance) { _typeInstance = typeInstance; } public boolean defined(String val) { return (val != null) && (val.length() > 0); } public String getSource() { final char DLM = '/'; StringBuffer sb = new StringBuffer(); if (defined(_host)) { sb.append(_host); } if (defined(_plugin)) { sb.append(DLM).append(_plugin); } if (defined(_pluginInstance)) { sb.append(DLM).append(_pluginInstance); } if (defined(_type)) { sb.append(DLM).append(_type); } if (defined(_typeInstance)) { sb.append(DLM).append(_typeInstance); } return sb.toString(); } public String toString() { StringBuffer sb = new StringBuffer(); sb.append('[').append(new Date(_time)).append("] "); sb.append(getSource()); return sb.toString(); } } collectd-5.4.0/bindings/java/org/collectd/api/PaxHeaders.11991/Collectd.java0000644037772200116100000000013212204120331024606 xustar000000000000000030 mtime=1376821465.045972991 30 atime=1376821477.194167546 30 ctime=1376821742.602410185 collectd-5.4.0/bindings/java/org/collectd/api/Collectd.java0000644037772200116100000002015612204120331023356 0ustar00octoeng00000000000000/* * collectd/java - org/collectd/api/Collectd.java * Copyright (C) 2009 Florian octo 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: * Florian octo Forster */ package org.collectd.api; /** * Java API to internal functions of collectd. * * All functions in this class are {@code static}. You don't need to create an * object of this class (in fact, you can't). Just call these functions * directly. * * @author Florian Forster <octo at verplant.org> */ public class Collectd { /** * Constant for severity (log level) "error". * * @see CollectdLogInterface */ public static final int LOG_ERR = 3; /** * Constant for severity (log level) "warning". * * @see CollectdLogInterface */ public static final int LOG_WARNING = 4; /** * Constant for severity (log level) "notice". * * @see CollectdLogInterface */ public static final int LOG_NOTICE = 5; /** * Constant for severity (log level) "info". * * @see CollectdLogInterface */ public static final int LOG_INFO = 6; /** * Constant for severity (log level) "debug". * * @see CollectdLogInterface */ public static final int LOG_DEBUG = 7; /** * Return value of match methods: No match. * * This is one of two valid return values from match callbacks, indicating * that the passed {@link DataSet} and {@link ValueList} did not match. * * Do not use the numeric value directly, it is subject to change without * notice! * * @see CollectdMatchInterface */ public static final int FC_MATCH_NO_MATCH = 0; /** * Return value of match methods: Match. * * This is one of two valid return values from match callbacks, indicating * that the passed {@link DataSet} and {@link ValueList} did match. * * Do not use the numeric value directly, it is subject to change without * notice! * * @see CollectdMatchInterface */ public static final int FC_MATCH_MATCHES = 1; /** * Return value of target methods: Continue. * * This is one of three valid return values from target callbacks, indicating * that processing of the {@link ValueList} should continue. * * Do not use the numeric value directly, it is subject to change without * notice! * * @see CollectdTargetInterface */ public static final int FC_TARGET_CONTINUE = 0; /** * Return value of target methods: Stop. * * This is one of three valid return values from target callbacks, indicating * that processing of the {@link ValueList} should stop immediately. * * Do not use the numeric value directly, it is subject to change without * notice! * * @see CollectdTargetInterface */ public static final int FC_TARGET_STOP = 1; /** * Return value of target methods: Return. * * This is one of three valid return values from target callbacks, indicating * that processing of the current chain should be stopped and processing of * the {@link ValueList} should continue in the calling chain. * * Do not use the numeric value directly, it is subject to change without * notice! * * @see CollectdTargetInterface */ public static final int FC_TARGET_RETURN = 2; /** * Java representation of collectd/src/plugin.h:plugin_register_config * * @return Zero when successful, non-zero otherwise. * @see CollectdConfigInterface */ native public static int registerConfig (String name, CollectdConfigInterface object); /** * Java representation of collectd/src/plugin.h:plugin_register_init * * @return Zero when successful, non-zero otherwise. * @see CollectdInitInterface */ native public static int registerInit (String name, CollectdInitInterface object); /** * Java representation of collectd/src/plugin.h:plugin_register_read * * @return Zero when successful, non-zero otherwise. * @see CollectdReadInterface */ native public static int registerRead (String name, CollectdReadInterface object); /** * Java representation of collectd/src/plugin.h:plugin_register_write * * @return Zero when successful, non-zero otherwise. * @see CollectdWriteInterface */ native public static int registerWrite (String name, CollectdWriteInterface object); /** * Java representation of collectd/src/plugin.h:plugin_register_flush * * @return Zero when successful, non-zero otherwise. * @see CollectdFlushInterface */ native public static int registerFlush (String name, CollectdFlushInterface object); /** * Java representation of collectd/src/plugin.h:plugin_register_shutdown * * @return Zero when successful, non-zero otherwise. * @see CollectdShutdownInterface */ native public static int registerShutdown (String name, CollectdShutdownInterface object); /** * Java representation of collectd/src/plugin.h:plugin_register_log * * @return Zero when successful, non-zero otherwise. * @see CollectdLogInterface */ native public static int registerLog (String name, CollectdLogInterface object); /** * Java representation of collectd/src/plugin.h:plugin_register_notification * * @return Zero when successful, non-zero otherwise. * @see CollectdNotificationInterface */ native public static int registerNotification (String name, CollectdNotificationInterface object); /** * Java representation of collectd/src/filter_chain.h:fc_register_match * * @return Zero when successful, non-zero otherwise. * @see CollectdMatchFactoryInterface */ native public static int registerMatch (String name, CollectdMatchFactoryInterface object); /** * Java representation of collectd/src/filter_chain.h:fc_register_target * * @return Zero when successful, non-zero otherwise. * @see CollectdTargetFactoryInterface */ native public static int registerTarget (String name, CollectdTargetFactoryInterface object); /** * Java representation of collectd/src/plugin.h:plugin_dispatch_values * * @return Zero when successful, non-zero otherwise. */ native public static int dispatchValues (ValueList vl); /** * Java representation of collectd/src/plugin.h:plugin_dispatch_notification * * @return Zero when successful, non-zero otherwise. */ native public static int dispatchNotification (Notification n); /** * Java representation of collectd/src/plugin.h:plugin_get_ds * * @return The appropriate {@link DataSet} object or {@code null} if no such * type is registered. */ native public static DataSet getDS (String type); /** * Java representation of collectd/src/plugin.h:plugin_log */ native private static void log (int severity, String message); /** * Prints an error message. */ public static void logError (String message) { log (LOG_ERR, message); } /* void logError */ /** * Prints a warning message. */ public static void logWarning (String message) { log (LOG_WARNING, message); } /* void logWarning */ /** * Prints a notice. */ public static void logNotice (String message) { log (LOG_NOTICE, message); } /* void logNotice */ /** * Prints an info message. */ public static void logInfo (String message) { log (LOG_INFO, message); } /* void logInfo */ /** * Prints a debug message. */ public static void logDebug (String message) { log (LOG_DEBUG, message); } /* void logDebug */ } /* class Collectd */ /* vim: set sw=2 sts=2 et fdm=marker : */ collectd-5.4.0/bindings/java/org/collectd/api/PaxHeaders.11991/CollectdMatchInterface.java0000644037772200116100000000013212204120331027404 xustar000000000000000030 mtime=1376821465.045972991 30 atime=1376821477.194167546 30 ctime=1376821742.606410248 collectd-5.4.0/bindings/java/org/collectd/api/CollectdMatchInterface.java0000644037772200116100000000330012204120331026144 0ustar00octoeng00000000000000/* * collectd/java - org/collectd/api/CollectdMatchInterface.java * Copyright (C) 2009 Florian octo 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: * Florian octo Forster */ package org.collectd.api; /** * Interface for objects implementing a match method. * * These objects are instantiated using objects which implement the * CollectdMatchFactoryInterface interface. They are not instantiated by the * daemon directly! * * @author Florian Forster <octo at verplant.org> * @see CollectdMatchFactoryInterface * @see Collectd#registerMatch */ public interface CollectdMatchInterface { /** * Callback method for matches. * * This method is called to decide whether or not a given ValueList * matches or not. How this is determined is the is the main part of * this function. * * @return One of {@link Collectd#FC_MATCH_NO_MATCH} and {@link Collectd#FC_MATCH_MATCHES}. * @see CollectdMatchFactoryInterface */ public int match (DataSet ds, ValueList vl); } /* public interface CollectdMatchInterface */ collectd-5.4.0/bindings/java/org/collectd/api/PaxHeaders.11991/CollectdFlushInterface.java0000644037772200116100000000013212204120331027431 xustar000000000000000030 mtime=1376821465.045972991 30 atime=1376821477.194167546 30 ctime=1376821742.606410248 collectd-5.4.0/bindings/java/org/collectd/api/CollectdFlushInterface.java0000644037772200116100000000217012204120331026175 0ustar00octoeng00000000000000/* * collectd/java - org/collectd/api/CollectdFlushInterface.java * Copyright (C) 2009 Florian octo 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: * Florian octo Forster */ package org.collectd.api; /** * Interface for objects implementing a flush method. * * @author Florian Forster <octo at verplant.org> * @see Collectd#registerFlush */ public interface CollectdFlushInterface { public int flush (Number timeout, String identifier); } collectd-5.4.0/bindings/java/org/collectd/api/PaxHeaders.11991/CollectdWriteInterface.java0000644037772200116100000000013212204120331027442 xustar000000000000000030 mtime=1376821465.045972991 30 atime=1376821477.194167546 30 ctime=1376821742.610410312 collectd-5.4.0/bindings/java/org/collectd/api/CollectdWriteInterface.java0000644037772200116100000000214312204120331026206 0ustar00octoeng00000000000000/* * collectd/java - org/collectd/api/CollectdWriteInterface.java * Copyright (C) 2009 Florian octo 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: * Florian octo Forster */ package org.collectd.api; /** * Interface for objects implementing a write method. * * @author Florian Forster <octo at verplant.org> * @see Collectd#registerWrite */ public interface CollectdWriteInterface { public int write (ValueList vl); } collectd-5.4.0/bindings/java/org/collectd/api/PaxHeaders.11991/CollectdTargetFactoryInterface.java0000644037772200116100000000013212204120331031126 xustar000000000000000030 mtime=1376821465.045972991 30 atime=1376821477.194167546 30 ctime=1376821742.610410312 collectd-5.4.0/bindings/java/org/collectd/api/CollectdTargetFactoryInterface.java0000644037772200116100000000326712204120331027702 0ustar00octoeng00000000000000/* * collectd/java - org/collectd/api/CollectdTargetFactoryInterface.java * Copyright (C) 2009 Florian octo 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: * Florian octo Forster */ package org.collectd.api; /** * Interface for objects implementing a "target factory". * * Objects implementing this interface are used to create objects implementing * the CollectdTargetInterface interface. * * @author Florian Forster <octo at verplant.org> * @see CollectdTargetInterface * @see Collectd#registerTarget */ public interface CollectdTargetFactoryInterface { /** * Create a new "target" object. * * This method uses the configuration provided as argument to create a * new object which must implement the {@link CollectdTargetInterface} * interface. * * This function corresponds to the {@code create} member of the * {@code src/filter_chain.h:target_proc_t} struct. * * @return New {@link CollectdTargetInterface} object. */ public CollectdTargetInterface createTarget (OConfigItem ci); } collectd-5.4.0/bindings/java/org/collectd/api/PaxHeaders.11991/CollectdLogInterface.java0000644037772200116100000000013212204120331027071 xustar000000000000000030 mtime=1376821465.045972991 30 atime=1376821477.194167546 30 ctime=1376821742.614410376 collectd-5.4.0/bindings/java/org/collectd/api/CollectdLogInterface.java0000644037772200116100000000215212204120331025635 0ustar00octoeng00000000000000/* * collectd/java - org/collectd/api/CollectdLogInterface.java * Copyright (C) 2009 Florian octo 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: * Florian octo Forster */ package org.collectd.api; /** * Interface for objects implementing a log method. * * @author Florian Forster <octo at verplant.org> * @see Collectd#registerLog */ public interface CollectdLogInterface { public void log (int severity, String message); } collectd-5.4.0/bindings/java/org/collectd/api/PaxHeaders.11991/ValueList.java0000644037772200116100000000013212204120331024765 xustar000000000000000030 mtime=1376821465.045972991 30 atime=1376821477.194167546 30 ctime=1376821742.614410376 collectd-5.4.0/bindings/java/org/collectd/api/ValueList.java0000644037772200116100000000617212204120331023537 0ustar00octoeng00000000000000/* * jcollectd * Copyright (C) 2009 Hyperic, Inc. * * 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 */ package org.collectd.api; import java.util.ArrayList; import java.util.List; /** * Java representation of collectd/src/plugin.h:value_list_t structure. */ public class ValueList extends PluginData { private List _values = new ArrayList(); private DataSet _ds; private long _interval = 0; public ValueList() { } public ValueList(PluginData pd) { super(pd); } public ValueList(ValueList vl) { this((PluginData)vl); _interval = vl._interval; _values.addAll(vl.getValues()); _ds = vl._ds; } public List getValues() { return _values; } public void setValues(List values) { _values = values; } public void addValue(Number value) { _values.add(value); } /* Used by the network parsing code */ public void clearValues () { _values.clear (); } /** * @deprecated Use {@link #getDataSet()} instead. */ public List getDataSource() { if (_ds == null) return null; return _ds.getDataSources (); } public DataSet getDataSet () { return _ds; } public void setDataSet (DataSet ds) { _ds = ds; } /** * @deprecated Use {@link #setDataSet(DataSet)} instead. */ public void setDataSource(List dsrc) { _ds = new DataSet (_type, dsrc); } /** * Returns the interval (in milliseconds) of the value list. */ public long getInterval() { return _interval; } /** * Sets the interval (in milliseconds) of the value list. */ public void setInterval(long interval) { _interval = interval; } public String toString() { StringBuffer sb = new StringBuffer(super.toString()); sb.append("=["); List ds = getDataSource(); int size = _values.size(); for (int i=0; i */ package org.collectd.java; import java.util.List; import java.util.ArrayList; import java.util.Map; import java.util.TreeMap; import org.collectd.api.Collectd; import org.collectd.api.CollectdConfigInterface; import org.collectd.api.CollectdInitInterface; import org.collectd.api.CollectdReadInterface; import org.collectd.api.CollectdShutdownInterface; import org.collectd.api.OConfigValue; import org.collectd.api.OConfigItem; public class GenericJMX implements CollectdConfigInterface, CollectdReadInterface, CollectdShutdownInterface { static private Map _mbeans = new TreeMap (); private List _connections = null; public GenericJMX () { Collectd.registerConfig ("GenericJMX", this); Collectd.registerRead ("GenericJMX", this); Collectd.registerShutdown ("GenericJMX", this); this._connections = new ArrayList (); } public int config (OConfigItem ci) /* {{{ */ { List children; int i; Collectd.logDebug ("GenericJMX plugin: config: ci = " + ci + ";"); children = ci.getChildren (); for (i = 0; i < children.size (); i++) { OConfigItem child; String key; child = children.get (i); key = child.getKey (); if (key.equalsIgnoreCase ("MBean")) { try { GenericJMXConfMBean mbean = new GenericJMXConfMBean (child); putMBean (mbean); } catch (IllegalArgumentException e) { Collectd.logError ("GenericJMX plugin: " + "Evaluating `MBean' block failed: " + e); } } else if (key.equalsIgnoreCase ("Connection")) { try { GenericJMXConfConnection conn = new GenericJMXConfConnection (child); this._connections.add (conn); } catch (IllegalArgumentException e) { Collectd.logError ("GenericJMX plugin: " + "Evaluating `Connection' block failed: " + e); } } else { Collectd.logError ("GenericJMX plugin: Unknown config option: " + key); } } /* for (i = 0; i < children.size (); i++) */ return (0); } /* }}} int config */ public int read () /* {{{ */ { for (int i = 0; i < this._connections.size (); i++) { try { this._connections.get (i).query (); } catch (Exception e) { Collectd.logError ("GenericJMX: Caught unexpected exception: " + e); e.printStackTrace (); } } return (0); } /* }}} int read */ public int shutdown () /* {{{ */ { System.out.print ("org.collectd.java.GenericJMX.Shutdown ();\n"); this._connections = null; return (0); } /* }}} int shutdown */ /* * static functions */ static public GenericJMXConfMBean getMBean (String alias) { return (_mbeans.get (alias)); } static private void putMBean (GenericJMXConfMBean mbean) { Collectd.logDebug ("GenericJMX.putMBean: Adding " + mbean.getName ()); _mbeans.put (mbean.getName (), mbean); } } /* class GenericJMX */ /* vim: set sw=2 sts=2 et fdm=marker : */ collectd-5.4.0/bindings/java/org/collectd/java/PaxHeaders.11991/GenericJMXConfValue.java0000644037772200116100000000013112204120331026762 xustar000000000000000030 mtime=1376821465.049973054 30 atime=1376821477.194167546 29 ctime=1376821742.61841044 collectd-5.4.0/bindings/java/org/collectd/java/GenericJMXConfValue.java0000644037772200116100000003715712204120331025544 0ustar00octoeng00000000000000/* * collectd/java - org/collectd/java/GenericJMXConfValue.java * Copyright (C) 2009 Florian octo 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: * Florian octo Forster */ package org.collectd.java; import java.util.Arrays; import java.util.List; import java.util.Set; import java.util.Iterator; import java.util.ArrayList; import java.math.BigDecimal; import java.math.BigInteger; import javax.management.MBeanServerConnection; import javax.management.ObjectName; import javax.management.openmbean.OpenType; import javax.management.openmbean.CompositeData; import javax.management.openmbean.InvalidKeyException; import org.collectd.api.Collectd; import org.collectd.api.DataSet; import org.collectd.api.DataSource; import org.collectd.api.ValueList; import org.collectd.api.PluginData; import org.collectd.api.OConfigValue; import org.collectd.api.OConfigItem; /** * Representation of a <value /> block and query functionality. * * This class represents a <value /> block in the configuration. As * such, the constructor takes an {@link org.collectd.api.OConfigValue} to * construct an object of this class. * * The object can then be asked to query data from JMX and dispatch it to * collectd. * * @see GenericJMXConfMBean */ class GenericJMXConfValue { private String _ds_name; private DataSet _ds; private List _attributes; private String _instance_prefix; private List _instance_from; private boolean _is_table; /** * Converts a generic (OpenType) object to a number. * * Returns null if a conversion is not possible or not implemented. */ private Number genericObjectToNumber (Object obj, int ds_type) /* {{{ */ { if (obj instanceof String) { String str = (String) obj; try { if (ds_type == DataSource.TYPE_GAUGE) return (new Double (str)); else return (new Long (str)); } catch (NumberFormatException e) { return (null); } } else if (obj instanceof Byte) { return (new Byte ((Byte) obj)); } else if (obj instanceof Short) { return (new Short ((Short) obj)); } else if (obj instanceof Integer) { return (new Integer ((Integer) obj)); } else if (obj instanceof Long) { return (new Long ((Long) obj)); } else if (obj instanceof Float) { return (new Float ((Float) obj)); } else if (obj instanceof Double) { return (new Double ((Double) obj)); } else if (obj instanceof BigDecimal) { return (BigDecimal.ZERO.add ((BigDecimal) obj)); } else if (obj instanceof BigInteger) { return (BigInteger.ZERO.add ((BigInteger) obj)); } return (null); } /* }}} Number genericObjectToNumber */ /** * Converts a generic list to a list of numbers. * * Returns null if one or more objects could not be converted. */ private List genericListToNumber (List objects) /* {{{ */ { List ret = new ArrayList (); List dsrc = this._ds.getDataSources (); assert (objects.size () == dsrc.size ()); for (int i = 0; i < objects.size (); i++) { Number n; n = genericObjectToNumber (objects.get (i), dsrc.get (i).getType ()); if (n == null) return (null); ret.add (n); } return (ret); } /* }}} List genericListToNumber */ /** * Converts a list of CompositeData to a list of numbers. * * From each CompositeData the key key is received and all * those values are converted to a number. If one of the * CompositeData doesn't have the specified key or one returned * object cannot converted to a number then the function will return null. */ private List genericCompositeToNumber (List cdlist, /* {{{ */ String key) { List objects = new ArrayList (); for (int i = 0; i < cdlist.size (); i++) { CompositeData cd; Object value; cd = cdlist.get (i); try { value = cd.get (key); } catch (InvalidKeyException e) { return (null); } objects.add (value); } return (genericListToNumber (objects)); } /* }}} List genericCompositeToNumber */ private void submitTable (List objects, ValueList vl, /* {{{ */ String instancePrefix) { List cdlist; Set keySet = null; Iterator keyIter; cdlist = new ArrayList (); for (int i = 0; i < objects.size (); i++) { Object obj; obj = objects.get (i); if (obj instanceof CompositeData) { CompositeData cd; cd = (CompositeData) obj; if (i == 0) keySet = cd.getCompositeType ().keySet (); cdlist.add (cd); } else { Collectd.logError ("GenericJMXConfValue: At least one of the " + "attributes was not of type `CompositeData', as required " + "when table is set to `true'."); return; } } assert (keySet != null); keyIter = keySet.iterator (); while (keyIter.hasNext ()) { String key; List values; key = keyIter.next (); values = genericCompositeToNumber (cdlist, key); if (values == null) { Collectd.logError ("GenericJMXConfValue: Cannot build a list of " + "numbers for key " + key + ". Most likely not all attributes " + "have this key."); continue; } if (instancePrefix == null) vl.setTypeInstance (key); else vl.setTypeInstance (instancePrefix + key); vl.setValues (values); Collectd.dispatchValues (vl); } } /* }}} void submitTable */ private void submitScalar (List objects, ValueList vl, /* {{{ */ String instancePrefix) { List values; values = genericListToNumber (objects); if (values == null) { Collectd.logError ("GenericJMXConfValue: Cannot convert list of " + "objects to numbers."); return; } if (instancePrefix == null) vl.setTypeInstance (""); else vl.setTypeInstance (instancePrefix); vl.setValues (values); Collectd.dispatchValues (vl); } /* }}} void submitScalar */ private Object queryAttributeRecursive (CompositeData parent, /* {{{ */ List attrName) { String key; Object value; key = attrName.remove (0); try { value = parent.get (key); } catch (InvalidKeyException e) { return (null); } if (attrName.size () == 0) { return (value); } else { if (value instanceof CompositeData) return (queryAttributeRecursive ((CompositeData) value, attrName)); else return (null); } } /* }}} queryAttributeRecursive */ private Object queryAttribute (MBeanServerConnection conn, /* {{{ */ ObjectName objName, String attrName) { List attrNameList; String key; Object value; String[] attrNameArray; attrNameList = new ArrayList (); attrNameArray = attrName.split ("\\."); key = attrNameArray[0]; for (int i = 1; i < attrNameArray.length; i++) attrNameList.add (attrNameArray[i]); try { try { value = conn.getAttribute (objName, key); } catch (javax.management.AttributeNotFoundException e) { value = conn.invoke (objName, key, /* args = */ null, /* types = */ null); } } catch (Exception e) { Collectd.logError ("GenericJMXConfValue.query: getAttribute failed: " + e); return (null); } if (attrNameList.size () == 0) { return (value); } else { if (value instanceof CompositeData) return (queryAttributeRecursive((CompositeData) value, attrNameList)); else if (value instanceof OpenType) { OpenType ot = (OpenType) value; Collectd.logNotice ("GenericJMXConfValue: Handling of OpenType \"" + ot.getTypeName () + "\" is not yet implemented."); return (null); } else { Collectd.logError ("GenericJMXConfValue: Received object of " + "unknown class."); return (null); } } } /* }}} Object queryAttribute */ private String join (String separator, List list) /* {{{ */ { StringBuffer sb; sb = new StringBuffer (); for (int i = 0; i < list.size (); i++) { if (i > 0) sb.append ("-"); sb.append (list.get (i)); } return (sb.toString ()); } /* }}} String join */ private String getConfigString (OConfigItem ci) /* {{{ */ { List values; OConfigValue v; values = ci.getValues (); if (values.size () != 1) { Collectd.logError ("GenericJMXConfValue: The " + ci.getKey () + " configuration option needs exactly one string argument."); return (null); } v = values.get (0); if (v.getType () != OConfigValue.OCONFIG_TYPE_STRING) { Collectd.logError ("GenericJMXConfValue: The " + ci.getKey () + " configuration option needs exactly one string argument."); return (null); } return (v.getString ()); } /* }}} String getConfigString */ private Boolean getConfigBoolean (OConfigItem ci) /* {{{ */ { List values; OConfigValue v; Boolean b; values = ci.getValues (); if (values.size () != 1) { Collectd.logError ("GenericJMXConfValue: The " + ci.getKey () + " configuration option needs exactly one boolean argument."); return (null); } v = values.get (0); if (v.getType () != OConfigValue.OCONFIG_TYPE_BOOLEAN) { Collectd.logError ("GenericJMXConfValue: The " + ci.getKey () + " configuration option needs exactly one boolean argument."); return (null); } return (new Boolean (v.getBoolean ())); } /* }}} String getConfigBoolean */ /** * Constructs a new value with the configured properties. */ public GenericJMXConfValue (OConfigItem ci) /* {{{ */ throws IllegalArgumentException { List children; Iterator iter; this._ds_name = null; this._ds = null; this._attributes = new ArrayList (); this._instance_prefix = null; this._instance_from = new ArrayList (); this._is_table = false; /* * * Type "memory" * Table true|false * Attribute "HeapMemoryUsage" * Attribute "..." * : * # Type instance: * InstancePrefix "heap-" * */ children = ci.getChildren (); iter = children.iterator (); while (iter.hasNext ()) { OConfigItem child = iter.next (); if (child.getKey ().equalsIgnoreCase ("Type")) { String tmp = getConfigString (child); if (tmp != null) this._ds_name = tmp; } else if (child.getKey ().equalsIgnoreCase ("Table")) { Boolean tmp = getConfigBoolean (child); if (tmp != null) this._is_table = tmp.booleanValue (); } else if (child.getKey ().equalsIgnoreCase ("Attribute")) { String tmp = getConfigString (child); if (tmp != null) this._attributes.add (tmp); } else if (child.getKey ().equalsIgnoreCase ("InstancePrefix")) { String tmp = getConfigString (child); if (tmp != null) this._instance_prefix = tmp; } else if (child.getKey ().equalsIgnoreCase ("InstanceFrom")) { String tmp = getConfigString (child); if (tmp != null) this._instance_from.add (tmp); } else throw (new IllegalArgumentException ("Unknown option: " + child.getKey ())); } if (this._ds_name == null) throw (new IllegalArgumentException ("No data set was defined.")); else if (this._attributes.size () == 0) throw (new IllegalArgumentException ("No attribute was defined.")); } /* }}} GenericJMXConfValue (OConfigItem ci) */ /** * Query values via JMX according to the object's configuration and dispatch * them to collectd. * * @param conn Connection to the MBeanServer. * @param objName Object name of the MBean to query. * @param pd Preset naming components. The members host, plugin and * plugin instance will be used. */ public void query (MBeanServerConnection conn, ObjectName objName, /* {{{ */ PluginData pd) { ValueList vl; List dsrc; List values; List instanceList; String instancePrefix; if (this._ds == null) { this._ds = Collectd.getDS (this._ds_name); if (this._ds == null) { Collectd.logError ("GenericJMXConfValue: Unknown type: " + this._ds_name); return; } } dsrc = this._ds.getDataSources (); if (dsrc.size () != this._attributes.size ()) { Collectd.logError ("GenericJMXConfValue.query: The data set " + this._ds_name + " has " + this._ds.getDataSources ().size () + " data sources, but there were " + this._attributes.size () + " attributes configured. This doesn't match!"); this._ds = null; return; } vl = new ValueList (pd); vl.setType (this._ds_name); /* * Build the instnace prefix from the fixed string prefix and the * properties of the objName. */ instanceList = new ArrayList (); for (int i = 0; i < this._instance_from.size (); i++) { String propertyName; String propertyValue; propertyName = this._instance_from.get (i); propertyValue = objName.getKeyProperty (propertyName); if (propertyValue == null) { Collectd.logError ("GenericJMXConfMBean: " + "No such property in object name: " + propertyName); } else { instanceList.add (propertyValue); } } if (this._instance_prefix != null) instancePrefix = new String (this._instance_prefix + join ("-", instanceList)); else instancePrefix = join ("-", instanceList); /* * Build a list of `Object's which is then passed to `submitTable' and * `submitScalar'. */ values = new ArrayList (); assert (dsrc.size () == this._attributes.size ()); for (int i = 0; i < this._attributes.size (); i++) { Object v; v = queryAttribute (conn, objName, this._attributes.get (i)); if (v == null) { Collectd.logError ("GenericJMXConfValue.query: " + "Querying attribute " + this._attributes.get (i) + " failed."); return; } values.add (v); } if (this._is_table) submitTable (values, vl, instancePrefix); else submitScalar (values, vl, instancePrefix); } /* }}} void query */ } /* class GenericJMXConfValue */ /* vim: set sw=2 sts=2 et fdm=marker : */ collectd-5.4.0/bindings/java/org/collectd/java/PaxHeaders.11991/GenericJMXConfMBean.java0000644037772200116100000000013212204120331026671 xustar000000000000000030 mtime=1376821465.045972991 30 atime=1376821477.194167546 30 ctime=1376821742.622410503 collectd-5.4.0/bindings/java/org/collectd/java/GenericJMXConfMBean.java0000644037772200116100000001520712204120331025442 0ustar00octoeng00000000000000/* * collectd/java - org/collectd/java/GenericJMXConfMBean.java * Copyright (C) 2009,2010 Florian octo 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: * Florian octo Forster */ package org.collectd.java; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.ArrayList; import javax.management.MBeanServerConnection; import javax.management.ObjectName; import javax.management.MalformedObjectNameException; import org.collectd.api.Collectd; import org.collectd.api.PluginData; import org.collectd.api.OConfigValue; import org.collectd.api.OConfigItem; class GenericJMXConfMBean { private String _name; /* name by which this mapping is referenced */ private ObjectName _obj_name; private String _instance_prefix; private List _instance_from; private List _values; private String getConfigString (OConfigItem ci) /* {{{ */ { List values; OConfigValue v; values = ci.getValues (); if (values.size () != 1) { Collectd.logError ("GenericJMXConfMBean: The " + ci.getKey () + " configuration option needs exactly one string argument."); return (null); } v = values.get (0); if (v.getType () != OConfigValue.OCONFIG_TYPE_STRING) { Collectd.logError ("GenericJMXConfMBean: The " + ci.getKey () + " configuration option needs exactly one string argument."); return (null); } return (v.getString ()); } /* }}} String getConfigString */ /* * * ObjectName "object name" * InstancePrefix "foobar" * InstanceFrom "name" * * * : * */ public GenericJMXConfMBean (OConfigItem ci) /* {{{ */ throws IllegalArgumentException { List children; Iterator iter; this._name = getConfigString (ci); if (this._name == null) throw (new IllegalArgumentException ("No alias name was defined. " + "MBean blocks need exactly one string argument.")); this._obj_name = null; this._instance_prefix = null; this._instance_from = new ArrayList (); this._values = new ArrayList (); children = ci.getChildren (); iter = children.iterator (); while (iter.hasNext ()) { OConfigItem child = iter.next (); Collectd.logDebug ("GenericJMXConfMBean: child.getKey () = " + child.getKey ()); if (child.getKey ().equalsIgnoreCase ("ObjectName")) { String tmp = getConfigString (child); if (tmp == null) continue; try { this._obj_name = new ObjectName (tmp); } catch (MalformedObjectNameException e) { throw (new IllegalArgumentException ("Not a valid object name: " + tmp, e)); } } else if (child.getKey ().equalsIgnoreCase ("InstancePrefix")) { String tmp = getConfigString (child); if (tmp != null) this._instance_prefix = tmp; } else if (child.getKey ().equalsIgnoreCase ("InstanceFrom")) { String tmp = getConfigString (child); if (tmp != null) this._instance_from.add (tmp); } else if (child.getKey ().equalsIgnoreCase ("Value")) { GenericJMXConfValue cv; cv = new GenericJMXConfValue (child); this._values.add (cv); } else throw (new IllegalArgumentException ("Unknown option: " + child.getKey ())); } if (this._obj_name == null) throw (new IllegalArgumentException ("No object name was defined.")); if (this._values.size () == 0) throw (new IllegalArgumentException ("No value block was defined.")); } /* }}} GenericJMXConfMBean (OConfigItem ci) */ public String getName () /* {{{ */ { return (this._name); } /* }}} */ public int query (MBeanServerConnection conn, PluginData pd, /* {{{ */ String instance_prefix) { Set names; Iterator iter; try { names = conn.queryNames (this._obj_name, /* query = */ null); } catch (Exception e) { Collectd.logError ("GenericJMXConfMBean: queryNames failed: " + e); return (-1); } if (names.size () == 0) { Collectd.logWarning ("GenericJMXConfMBean: No MBean matched " + "the ObjectName " + this._obj_name); } iter = names.iterator (); while (iter.hasNext ()) { ObjectName objName; PluginData pd_tmp; List instanceList; StringBuffer instance; objName = iter.next (); pd_tmp = new PluginData (pd); instanceList = new ArrayList (); instance = new StringBuffer (); Collectd.logDebug ("GenericJMXConfMBean: objName = " + objName.toString ()); for (int i = 0; i < this._instance_from.size (); i++) { String propertyName; String propertyValue; propertyName = this._instance_from.get (i); propertyValue = objName.getKeyProperty (propertyName); if (propertyValue == null) { Collectd.logError ("GenericJMXConfMBean: " + "No such property in object name: " + propertyName); } else { instanceList.add (propertyValue); } } if (instance_prefix != null) instance.append (instance_prefix); if (this._instance_prefix != null) instance.append (this._instance_prefix); for (int i = 0; i < instanceList.size (); i++) { if (i > 0) instance.append ("-"); instance.append (instanceList.get (i)); } pd_tmp.setPluginInstance (instance.toString ()); Collectd.logDebug ("GenericJMXConfMBean: instance = " + instance.toString ()); for (int i = 0; i < this._values.size (); i++) this._values.get (i).query (conn, objName, pd_tmp); } return (0); } /* }}} void query */ } /* vim: set sw=2 sts=2 et fdm=marker : */ collectd-5.4.0/bindings/java/org/collectd/java/PaxHeaders.11991/GenericJMXConfConnection.java0000644037772200116100000000013212204120331030006 xustar000000000000000030 mtime=1376821465.045972991 30 atime=1376821477.194167546 30 ctime=1376821742.622410503 collectd-5.4.0/bindings/java/org/collectd/java/GenericJMXConfConnection.java0000644037772200116100000001610712204120331026557 0ustar00octoeng00000000000000/* * collectd/java - org/collectd/java/GenericJMXConfConnection.java * Copyright (C) 2009-2012 Florian octo 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: * Florian octo Forster */ package org.collectd.java; import java.util.List; import java.util.Map; import java.util.Iterator; import java.util.ArrayList; import java.util.HashMap; import java.net.InetAddress; import java.net.UnknownHostException; import javax.management.MBeanServerConnection; import javax.management.ObjectName; import javax.management.MalformedObjectNameException; import javax.management.remote.JMXServiceURL; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import org.collectd.api.Collectd; import org.collectd.api.PluginData; import org.collectd.api.OConfigValue; import org.collectd.api.OConfigItem; class GenericJMXConfConnection { private String _username = null; private String _password = null; private String _host = null; private String _instance_prefix = null; private String _service_url = null; private MBeanServerConnection _jmx_connection = null; private List _mbeans = null; /* * private methods */ private String getConfigString (OConfigItem ci) /* {{{ */ { List values; OConfigValue v; values = ci.getValues (); if (values.size () != 1) { Collectd.logError ("GenericJMXConfConnection: The " + ci.getKey () + " configuration option needs exactly one string argument."); return (null); } v = values.get (0); if (v.getType () != OConfigValue.OCONFIG_TYPE_STRING) { Collectd.logError ("GenericJMXConfConnection: The " + ci.getKey () + " configuration option needs exactly one string argument."); return (null); } return (v.getString ()); } /* }}} String getConfigString */ private String getHost () /* {{{ */ { if (this._host != null) { return (this._host); } try { InetAddress localHost = InetAddress.getLocalHost(); return (localHost.getHostName ()); } catch (UnknownHostException e) { return ("localhost"); } } /* }}} String getHost */ private void connect () /* {{{ */ { JMXServiceURL service_url; JMXConnector connector; Map environment; if (_jmx_connection != null) return; environment = null; if (this._password != null) { String[] credentials; if (this._username == null) this._username = new String ("monitorRole"); credentials = new String[] { this._username, this._password }; environment = new HashMap (); environment.put (JMXConnector.CREDENTIALS, credentials); } try { service_url = new JMXServiceURL (this._service_url); connector = JMXConnectorFactory.connect (service_url, environment); _jmx_connection = connector.getMBeanServerConnection (); } catch (Exception e) { Collectd.logError ("GenericJMXConfConnection: " + "Creating MBean server connection failed: " + e); return; } } /* }}} void connect */ /* * public methods * * * Host "tomcat0.mycompany" * ServiceURL "service:jmx:rmi:///jndi/rmi://localhost:17264/jmxrmi" * Collect "java.lang:type=GarbageCollector,name=Copy" * Collect "java.lang:type=Memory" * * */ public GenericJMXConfConnection (OConfigItem ci) /* {{{ */ throws IllegalArgumentException { List children; Iterator iter; this._mbeans = new ArrayList (); children = ci.getChildren (); iter = children.iterator (); while (iter.hasNext ()) { OConfigItem child = iter.next (); if (child.getKey ().equalsIgnoreCase ("Host")) { String tmp = getConfigString (child); if (tmp != null) this._host = tmp; } else if (child.getKey ().equalsIgnoreCase ("User")) { String tmp = getConfigString (child); if (tmp != null) this._username = tmp; } else if (child.getKey ().equalsIgnoreCase ("Password")) { String tmp = getConfigString (child); if (tmp != null) this._password = tmp; } else if (child.getKey ().equalsIgnoreCase ("ServiceURL")) { String tmp = getConfigString (child); if (tmp != null) this._service_url = tmp; } else if (child.getKey ().equalsIgnoreCase ("InstancePrefix")) { String tmp = getConfigString (child); if (tmp != null) this._instance_prefix = tmp; } else if (child.getKey ().equalsIgnoreCase ("Collect")) { String tmp = getConfigString (child); if (tmp != null) { GenericJMXConfMBean mbean; mbean = GenericJMX.getMBean (tmp); if (mbean == null) throw (new IllegalArgumentException ("No such MBean defined: " + tmp + ". Please make sure all `MBean' blocks appear " + "before (above) all `Connection' blocks.")); Collectd.logDebug ("GenericJMXConfConnection: " + this._host + ": Add " + tmp); this._mbeans.add (mbean); } } else throw (new IllegalArgumentException ("Unknown option: " + child.getKey ())); } if (this._service_url == null) throw (new IllegalArgumentException ("No service URL was defined.")); if (this._mbeans.size () == 0) throw (new IllegalArgumentException ("No valid collect statement " + "present.")); } /* }}} GenericJMXConfConnection (OConfigItem ci) */ public void query () /* {{{ */ { PluginData pd; connect (); if (this._jmx_connection == null) return; Collectd.logDebug ("GenericJMXConfConnection.query: " + "Reading " + this._mbeans.size () + " mbeans from " + ((this._host != null) ? this._host : "(null)")); pd = new PluginData (); pd.setHost (this.getHost ()); pd.setPlugin ("GenericJMX"); for (int i = 0; i < this._mbeans.size (); i++) { int status; status = this._mbeans.get (i).query (this._jmx_connection, pd, this._instance_prefix); if (status != 0) { this._jmx_connection = null; return; } } /* for */ } /* }}} void query */ public String toString () { return (new String ("host = " + this._host + "; " + "url = " + this._service_url)); } } /* vim: set sw=2 sts=2 et fdm=marker : */ collectd-5.4.0/bindings/java/org/collectd/java/PaxHeaders.11991/JMXMemory.java0000644037772200116100000000013212204120331025054 xustar000000000000000030 mtime=1376821465.049973054 30 atime=1376821477.194167546 30 ctime=1376821742.626410567 collectd-5.4.0/bindings/java/org/collectd/java/JMXMemory.java0000644037772200116100000001407612204120331023630 0ustar00octoeng00000000000000/* * collectd/java - org/collectd/java/JMXMemory.java * Copyright (C) 2009 Florian octo 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: * Florian octo Forster */ package org.collectd.java; import java.util.List; import java.util.Date; import java.lang.management.ManagementFactory; import java.lang.management.MemoryUsage; import java.lang.management.MemoryMXBean; import javax.management.MBeanServerConnection; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; import org.collectd.api.Collectd; import org.collectd.api.DataSet; import org.collectd.api.ValueList; import org.collectd.api.Notification; import org.collectd.api.OConfigItem; import org.collectd.api.CollectdConfigInterface; import org.collectd.api.CollectdInitInterface; import org.collectd.api.CollectdReadInterface; import org.collectd.api.CollectdShutdownInterface; import org.collectd.api.OConfigValue; import org.collectd.api.OConfigItem; public class JMXMemory implements CollectdConfigInterface, CollectdInitInterface, CollectdReadInterface, CollectdShutdownInterface { private String _jmx_service_url = null; private MemoryMXBean _mbean = null; public JMXMemory () { Collectd.registerConfig ("JMXMemory", this); Collectd.registerInit ("JMXMemory", this); Collectd.registerRead ("JMXMemory", this); Collectd.registerShutdown ("JMXMemory", this); } private void submit (String plugin_instance, MemoryUsage usage) /* {{{ */ { ValueList vl; long mem_init; long mem_used; long mem_committed; long mem_max; mem_init = usage.getInit (); mem_used = usage.getUsed (); mem_committed = usage.getCommitted (); mem_max = usage.getMax (); Collectd.logDebug ("JMXMemory plugin: plugin_instance = " + plugin_instance + "; " + "mem_init = " + mem_init + "; " + "mem_used = " + mem_used + "; " + "mem_committed = " + mem_committed + "; " + "mem_max = " + mem_max + ";"); vl = new ValueList (); vl.setHost ("localhost"); vl.setPlugin ("JMXMemory"); vl.setPluginInstance (plugin_instance); vl.setType ("memory"); if (mem_init >= 0) { vl.addValue (mem_init); vl.setTypeInstance ("init"); Collectd.dispatchValues (vl); vl.clearValues (); } if (mem_used >= 0) { vl.addValue (mem_used); vl.setTypeInstance ("used"); Collectd.dispatchValues (vl); vl.clearValues (); } if (mem_committed >= 0) { vl.addValue (mem_committed); vl.setTypeInstance ("committed"); Collectd.dispatchValues (vl); vl.clearValues (); } if (mem_max >= 0) { vl.addValue (mem_max); vl.setTypeInstance ("max"); Collectd.dispatchValues (vl); vl.clearValues (); } } /* }}} void submit */ private int configServiceURL (OConfigItem ci) /* {{{ */ { List values; OConfigValue cv; values = ci.getValues (); if (values.size () != 1) { Collectd.logError ("JMXMemory plugin: The JMXServiceURL option needs " + "exactly one string argument."); return (-1); } cv = values.get (0); if (cv.getType () != OConfigValue.OCONFIG_TYPE_STRING) { Collectd.logError ("JMXMemory plugin: The JMXServiceURL option needs " + "exactly one string argument."); return (-1); } _jmx_service_url = cv.getString (); return (0); } /* }}} int configServiceURL */ public int config (OConfigItem ci) /* {{{ */ { List children; int i; Collectd.logDebug ("JMXMemory plugin: config: ci = " + ci + ";"); children = ci.getChildren (); for (i = 0; i < children.size (); i++) { OConfigItem child; String key; child = children.get (i); key = child.getKey (); if (key.equalsIgnoreCase ("JMXServiceURL")) { configServiceURL (child); } else { Collectd.logError ("JMXMemory plugin: Unknown config option: " + key); } } return (0); } /* }}} int config */ public int init () /* {{{ */ { JMXServiceURL service_url; JMXConnector connector; MBeanServerConnection connection; if (_jmx_service_url == null) { Collectd.logError ("JMXMemory: _jmx_service_url == null"); return (-1); } try { service_url = new JMXServiceURL (_jmx_service_url); connector = JMXConnectorFactory.connect (service_url); connection = connector.getMBeanServerConnection (); _mbean = ManagementFactory.newPlatformMXBeanProxy (connection, ManagementFactory.MEMORY_MXBEAN_NAME, MemoryMXBean.class); } catch (Exception e) { Collectd.logError ("JMXMemory: Creating MBean failed: " + e); return (-1); } return (0); } /* }}} int init */ public int read () /* {{{ */ { if (_mbean == null) { Collectd.logError ("JMXMemory: _mbean == null"); return (-1); } submit ("heap", _mbean.getHeapMemoryUsage ()); submit ("non_heap", _mbean.getNonHeapMemoryUsage ()); return (0); } /* }}} int read */ public int shutdown () /* {{{ */ { System.out.print ("org.collectd.java.JMXMemory.Shutdown ();\n"); _jmx_service_url = null; _mbean = null; return (0); } /* }}} int shutdown */ } /* class JMXMemory */ /* vim: set sw=2 sts=2 et fdm=marker : */ collectd-5.4.0/bindings/java/PaxHeaders.11991/Makefile.am0000644037772200116100000000013212204120331021115 xustar000000000000000030 mtime=1376821465.045972991 30 atime=1376821477.194167546 30 ctime=1376821742.626410567 collectd-5.4.0/bindings/java/Makefile.am0000644037772200116100000000362412204120331017666 0ustar00octoeng00000000000000EXTRA_DIST = org/collectd/api/CollectdConfigInterface.java \ org/collectd/api/CollectdFlushInterface.java \ org/collectd/api/CollectdInitInterface.java \ org/collectd/api/Collectd.java \ org/collectd/api/CollectdLogInterface.java \ org/collectd/api/CollectdMatchFactoryInterface.java \ org/collectd/api/CollectdMatchInterface.java \ org/collectd/api/CollectdNotificationInterface.java \ org/collectd/api/CollectdReadInterface.java \ org/collectd/api/CollectdShutdownInterface.java \ org/collectd/api/CollectdTargetFactoryInterface.java \ org/collectd/api/CollectdTargetInterface.java \ org/collectd/api/CollectdWriteInterface.java \ org/collectd/api/DataSet.java \ org/collectd/api/DataSource.java \ org/collectd/api/Notification.java \ org/collectd/api/OConfigItem.java \ org/collectd/api/OConfigValue.java \ org/collectd/api/PluginData.java \ org/collectd/api/ValueList.java \ org/collectd/java/GenericJMXConfConnection.java \ org/collectd/java/GenericJMXConfMBean.java \ org/collectd/java/GenericJMXConfValue.java \ org/collectd/java/GenericJMX.java \ org/collectd/java/JMXMemory.java java-build-stamp: org/collectd/api/*.java org/collectd/java/*.java $(JAVAC) -d "." "$(srcdir)/org/collectd/api"/*.java $(JAVAC) -d "." "$(srcdir)/org/collectd/java"/*.java mkdir -p .libs $(JAR) cf .libs/collectd-api.jar "org/collectd/api"/*.class $(JAR) cf .libs/generic-jmx.jar "org/collectd/java"/*.class touch "$@" all-local: java-build-stamp install-exec-local: java-build-stamp mkdir -p "$(DESTDIR)$(pkgdatadir)/java" $(INSTALL) -m 644 .libs/collectd-api.jar \ "$(DESTDIR)$(pkgdatadir)/java" $(INSTALL) -m 644 .libs/generic-jmx.jar \ "$(DESTDIR)$(pkgdatadir)/java" clean-local: rm -f "org/collectd/api"/*.class rm -f "org/collectd/java"/*.class rm -f .libs rm -f "java-build-stamp" collectd-5.4.0/bindings/java/PaxHeaders.11991/Makefile.in0000644037772200116100000000013212204120372021133 xustar000000000000000030 mtime=1376821498.498508659 30 atime=1376821538.023141239 30 ctime=1376821742.630410632 collectd-5.4.0/bindings/java/Makefile.in0000644037772200116100000004334712204120372017712 0ustar00octoeng00000000000000# Makefile.in generated by automake 1.11.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = bindings/java DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/src/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ ARGZ_H = @ARGZ_H@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BUILD_WITH_LIBAQUAERO5_CFLAGS = @BUILD_WITH_LIBAQUAERO5_CFLAGS@ BUILD_WITH_LIBAQUAERO5_LDFLAGS = @BUILD_WITH_LIBAQUAERO5_LDFLAGS@ BUILD_WITH_LIBCREDIS_CPPFLAGS = @BUILD_WITH_LIBCREDIS_CPPFLAGS@ BUILD_WITH_LIBCREDIS_LDFLAGS = @BUILD_WITH_LIBCREDIS_LDFLAGS@ BUILD_WITH_LIBCURL_CFLAGS = @BUILD_WITH_LIBCURL_CFLAGS@ BUILD_WITH_LIBCURL_LIBS = @BUILD_WITH_LIBCURL_LIBS@ BUILD_WITH_LIBDBI_CPPFLAGS = @BUILD_WITH_LIBDBI_CPPFLAGS@ BUILD_WITH_LIBDBI_LDFLAGS = @BUILD_WITH_LIBDBI_LDFLAGS@ BUILD_WITH_LIBDBI_LIBS = @BUILD_WITH_LIBDBI_LIBS@ BUILD_WITH_LIBHAL_CFLAGS = @BUILD_WITH_LIBHAL_CFLAGS@ BUILD_WITH_LIBHAL_LIBS = @BUILD_WITH_LIBHAL_LIBS@ BUILD_WITH_LIBIPTC_CPPFLAGS = @BUILD_WITH_LIBIPTC_CPPFLAGS@ BUILD_WITH_LIBIPTC_LDFLAGS = @BUILD_WITH_LIBIPTC_LDFLAGS@ BUILD_WITH_LIBLVM2APP_CPPFLAGS = @BUILD_WITH_LIBLVM2APP_CPPFLAGS@ BUILD_WITH_LIBLVM2APP_LDFLAGS = @BUILD_WITH_LIBLVM2APP_LDFLAGS@ BUILD_WITH_LIBLVM2APP_LIBS = @BUILD_WITH_LIBLVM2APP_LIBS@ BUILD_WITH_LIBMEMCACHED_CPPFLAGS = @BUILD_WITH_LIBMEMCACHED_CPPFLAGS@ BUILD_WITH_LIBMEMCACHED_LDFLAGS = @BUILD_WITH_LIBMEMCACHED_LDFLAGS@ BUILD_WITH_LIBMEMCACHED_LIBS = @BUILD_WITH_LIBMEMCACHED_LIBS@ BUILD_WITH_LIBMNL_CFLAGS = @BUILD_WITH_LIBMNL_CFLAGS@ BUILD_WITH_LIBMNL_LIBS = @BUILD_WITH_LIBMNL_LIBS@ BUILD_WITH_LIBMODBUS_CFLAGS = @BUILD_WITH_LIBMODBUS_CFLAGS@ BUILD_WITH_LIBMODBUS_LIBS = @BUILD_WITH_LIBMODBUS_LIBS@ BUILD_WITH_LIBMONGOC_CPPFLAGS = @BUILD_WITH_LIBMONGOC_CPPFLAGS@ BUILD_WITH_LIBMONGOC_LDFLAGS = @BUILD_WITH_LIBMONGOC_LDFLAGS@ BUILD_WITH_LIBMYSQL_CFLAGS = @BUILD_WITH_LIBMYSQL_CFLAGS@ BUILD_WITH_LIBMYSQL_LIBS = @BUILD_WITH_LIBMYSQL_LIBS@ BUILD_WITH_LIBOPING_CPPFLAGS = @BUILD_WITH_LIBOPING_CPPFLAGS@ BUILD_WITH_LIBOPING_LDFLAGS = @BUILD_WITH_LIBOPING_LDFLAGS@ BUILD_WITH_LIBOWCAPI_CPPFLAGS = @BUILD_WITH_LIBOWCAPI_CPPFLAGS@ BUILD_WITH_LIBOWCAPI_LIBS = @BUILD_WITH_LIBOWCAPI_LIBS@ BUILD_WITH_LIBPQ_CPPFLAGS = @BUILD_WITH_LIBPQ_CPPFLAGS@ BUILD_WITH_LIBPQ_LDFLAGS = @BUILD_WITH_LIBPQ_LDFLAGS@ BUILD_WITH_LIBRABBITMQ_CPPFLAGS = @BUILD_WITH_LIBRABBITMQ_CPPFLAGS@ BUILD_WITH_LIBRABBITMQ_LDFLAGS = @BUILD_WITH_LIBRABBITMQ_LDFLAGS@ BUILD_WITH_LIBRABBITMQ_LIBS = @BUILD_WITH_LIBRABBITMQ_LIBS@ BUILD_WITH_LIBROUTEROS_CPPFLAGS = @BUILD_WITH_LIBROUTEROS_CPPFLAGS@ BUILD_WITH_LIBROUTEROS_LDFLAGS = @BUILD_WITH_LIBROUTEROS_LDFLAGS@ BUILD_WITH_LIBRRD_CFLAGS = @BUILD_WITH_LIBRRD_CFLAGS@ BUILD_WITH_LIBRRD_LDFLAGS = @BUILD_WITH_LIBRRD_LDFLAGS@ BUILD_WITH_LIBSENSORS_CFLAGS = @BUILD_WITH_LIBSENSORS_CFLAGS@ BUILD_WITH_LIBSENSORS_LDFLAGS = @BUILD_WITH_LIBSENSORS_LDFLAGS@ BUILD_WITH_LIBSIGROK_CFLAGS = @BUILD_WITH_LIBSIGROK_CFLAGS@ BUILD_WITH_LIBSIGROK_LDFLAGS = @BUILD_WITH_LIBSIGROK_LDFLAGS@ BUILD_WITH_LIBSNMP_CFLAGS = @BUILD_WITH_LIBSNMP_CFLAGS@ BUILD_WITH_LIBSNMP_LIBS = @BUILD_WITH_LIBSNMP_LIBS@ BUILD_WITH_LIBSTATGRAB_CFLAGS = @BUILD_WITH_LIBSTATGRAB_CFLAGS@ BUILD_WITH_LIBSTATGRAB_LDFLAGS = @BUILD_WITH_LIBSTATGRAB_LDFLAGS@ BUILD_WITH_LIBTOKYOTYRANT_CPPFLAGS = @BUILD_WITH_LIBTOKYOTYRANT_CPPFLAGS@ BUILD_WITH_LIBTOKYOTYRANT_LDFLAGS = @BUILD_WITH_LIBTOKYOTYRANT_LDFLAGS@ BUILD_WITH_LIBTOKYOTYRANT_LIBS = @BUILD_WITH_LIBTOKYOTYRANT_LIBS@ BUILD_WITH_LIBUPSCLIENT_CFLAGS = @BUILD_WITH_LIBUPSCLIENT_CFLAGS@ BUILD_WITH_LIBUPSCLIENT_LIBS = @BUILD_WITH_LIBUPSCLIENT_LIBS@ BUILD_WITH_LIBVARNISH_CFLAGS = @BUILD_WITH_LIBVARNISH_CFLAGS@ BUILD_WITH_LIBVARNISH_LIBS = @BUILD_WITH_LIBVARNISH_LIBS@ BUILD_WITH_LIBVIRT_CFLAGS = @BUILD_WITH_LIBVIRT_CFLAGS@ BUILD_WITH_LIBVIRT_LIBS = @BUILD_WITH_LIBVIRT_LIBS@ BUILD_WITH_LIBXML2_CFLAGS = @BUILD_WITH_LIBXML2_CFLAGS@ BUILD_WITH_LIBXML2_LIBS = @BUILD_WITH_LIBXML2_LIBS@ BUILD_WITH_LIBXMMS_CFLAGS = @BUILD_WITH_LIBXMMS_CFLAGS@ BUILD_WITH_LIBXMMS_LIBS = @BUILD_WITH_LIBXMMS_LIBS@ BUILD_WITH_LIBYAJL_CPPFLAGS = @BUILD_WITH_LIBYAJL_CPPFLAGS@ BUILD_WITH_LIBYAJL_LDFLAGS = @BUILD_WITH_LIBYAJL_LDFLAGS@ BUILD_WITH_LIBYAJL_LIBS = @BUILD_WITH_LIBYAJL_LIBS@ BUILD_WITH_MIC_CPPFLAGS = @BUILD_WITH_MIC_CPPFLAGS@ BUILD_WITH_MIC_LDADD = @BUILD_WITH_MIC_LDADD@ BUILD_WITH_MIC_LIBPATH = @BUILD_WITH_MIC_LIBPATH@ BUILD_WITH_OPENIPMI_CFLAGS = @BUILD_WITH_OPENIPMI_CFLAGS@ BUILD_WITH_OPENIPMI_LIBS = @BUILD_WITH_OPENIPMI_LIBS@ BUILD_WITH_ORACLE_CFLAGS = @BUILD_WITH_ORACLE_CFLAGS@ BUILD_WITH_ORACLE_LIBS = @BUILD_WITH_ORACLE_LIBS@ BUILD_WITH_PYTHON_CPPFLAGS = @BUILD_WITH_PYTHON_CPPFLAGS@ BUILD_WITH_PYTHON_LDFLAGS = @BUILD_WITH_PYTHON_LDFLAGS@ BUILD_WITH_PYTHON_LIBS = @BUILD_WITH_PYTHON_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFAULT_LOG_LEVEL = @DEFAULT_LOG_LEVEL@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GANGLIA_CPPFLAGS = @GANGLIA_CPPFLAGS@ GANGLIA_LDFLAGS = @GANGLIA_LDFLAGS@ GANGLIA_LIBS = @GANGLIA_LIBS@ GCRYPT_CPPFLAGS = @GCRYPT_CPPFLAGS@ GCRYPT_LDFLAGS = @GCRYPT_LDFLAGS@ GCRYPT_LIBS = @GCRYPT_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_COMPILE_RESOURCES = @GLIB_COMPILE_RESOURCES@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ GLIB_MKENUMS = @GLIB_MKENUMS@ GOBJECT_QUERY = @GOBJECT_QUERY@ GREP = @GREP@ INCLTDL = @INCLTDL@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAR = @JAR@ JAVAC = @JAVAC@ JAVA_CFLAGS = @JAVA_CFLAGS@ JAVA_CPPFLAGS = @JAVA_CPPFLAGS@ JAVA_LDFLAGS = @JAVA_LDFLAGS@ JAVA_LIBS = @JAVA_LIBS@ KERNEL_CFLAGS = @KERNEL_CFLAGS@ KERNEL_DIR = @KERNEL_DIR@ LCC_VERSION_EXTRA = @LCC_VERSION_EXTRA@ LCC_VERSION_MAJOR = @LCC_VERSION_MAJOR@ LCC_VERSION_MINOR = @LCC_VERSION_MINOR@ LCC_VERSION_PATCH = @LCC_VERSION_PATCH@ LCC_VERSION_STRING = @LCC_VERSION_STRING@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBADD_DL = @LIBADD_DL@ LIBADD_DLD_LINK = @LIBADD_DLD_LINK@ LIBADD_DLOPEN = @LIBADD_DLOPEN@ LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLTDL = @LIBLTDL@ LIBNETAPP_CPPFLAGS = @LIBNETAPP_CPPFLAGS@ LIBNETAPP_LDFLAGS = @LIBNETAPP_LDFLAGS@ LIBNETAPP_LIBS = @LIBNETAPP_LIBS@ LIBNOTIFY_CFLAGS = @LIBNOTIFY_CFLAGS@ LIBNOTIFY_LIBS = @LIBNOTIFY_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LOAD_PLUGIN_CSV = @LOAD_PLUGIN_CSV@ LOAD_PLUGIN_LOGFILE = @LOAD_PLUGIN_LOGFILE@ LOAD_PLUGIN_NETWORK = @LOAD_PLUGIN_NETWORK@ LOAD_PLUGIN_RRDTOOL = @LOAD_PLUGIN_RRDTOOL@ LOAD_PLUGIN_SYSLOG = @LOAD_PLUGIN_SYSLOG@ LTDLDEPS = @LTDLDEPS@ LTDLINCL = @LTDLINCL@ LTDLOPEN = @LTDLOPEN@ LTLIBOBJS = @LTLIBOBJS@ LT_CONFIG_H = @LT_CONFIG_H@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_BINDINGS = @PERL_BINDINGS@ PERL_BINDINGS_OPTIONS = @PERL_BINDINGS_OPTIONS@ PERL_CFLAGS = @PERL_CFLAGS@ PERL_LDFLAGS = @PERL_LDFLAGS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ have_protoc_c = @have_protoc_c@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ ltdl_LIBOBJS = @ltdl_LIBOBJS@ ltdl_LTLIBOBJS = @ltdl_LTLIBOBJS@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgconfigdir = @pkgconfigdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sys_symbol_underscore = @sys_symbol_underscore@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = org/collectd/api/CollectdConfigInterface.java \ org/collectd/api/CollectdFlushInterface.java \ org/collectd/api/CollectdInitInterface.java \ org/collectd/api/Collectd.java \ org/collectd/api/CollectdLogInterface.java \ org/collectd/api/CollectdMatchFactoryInterface.java \ org/collectd/api/CollectdMatchInterface.java \ org/collectd/api/CollectdNotificationInterface.java \ org/collectd/api/CollectdReadInterface.java \ org/collectd/api/CollectdShutdownInterface.java \ org/collectd/api/CollectdTargetFactoryInterface.java \ org/collectd/api/CollectdTargetInterface.java \ org/collectd/api/CollectdWriteInterface.java \ org/collectd/api/DataSet.java \ org/collectd/api/DataSource.java \ org/collectd/api/Notification.java \ org/collectd/api/OConfigItem.java \ org/collectd/api/OConfigValue.java \ org/collectd/api/PluginData.java \ org/collectd/api/ValueList.java \ org/collectd/java/GenericJMXConfConnection.java \ org/collectd/java/GenericJMXConfMBean.java \ org/collectd/java/GenericJMXConfValue.java \ org/collectd/java/GenericJMX.java \ org/collectd/java/JMXMemory.java all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu bindings/java/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu bindings/java/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-exec-local install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool clean-local distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-exec-local \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am uninstall uninstall-am java-build-stamp: org/collectd/api/*.java org/collectd/java/*.java $(JAVAC) -d "." "$(srcdir)/org/collectd/api"/*.java $(JAVAC) -d "." "$(srcdir)/org/collectd/java"/*.java mkdir -p .libs $(JAR) cf .libs/collectd-api.jar "org/collectd/api"/*.class $(JAR) cf .libs/generic-jmx.jar "org/collectd/java"/*.class touch "$@" all-local: java-build-stamp install-exec-local: java-build-stamp mkdir -p "$(DESTDIR)$(pkgdatadir)/java" $(INSTALL) -m 644 .libs/collectd-api.jar \ "$(DESTDIR)$(pkgdatadir)/java" $(INSTALL) -m 644 .libs/generic-jmx.jar \ "$(DESTDIR)$(pkgdatadir)/java" clean-local: rm -f "org/collectd/api"/*.class rm -f "org/collectd/java"/*.class rm -f .libs rm -f "java-build-stamp" # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: collectd-5.4.0/bindings/PaxHeaders.11991/perl0000644037772200116100000000013212204120755017037 xustar000000000000000030 mtime=1376821741.778397036 30 atime=1376821742.630410632 30 ctime=1376821742.630410632 collectd-5.4.0/bindings/perl/0000755037772200116100000000000012204120755015660 5ustar00octoeng00000000000000collectd-5.4.0/bindings/perl/PaxHeaders.11991/Makefile.PL0000644037772200116100000000013212204120331021054 xustar000000000000000030 mtime=1376821465.049973054 30 atime=1376821477.194167546 30 ctime=1376821742.634410696 collectd-5.4.0/bindings/perl/Makefile.PL0000644037772200116100000000023512204120331017620 0ustar00octoeng00000000000000use ExtUtils::MakeMaker; WriteMakefile( 'NAME' => 'Collectd', 'AUTHOR' => 'Sebastian Harl ', ); # vim: set sw=4 ts=4 tw=78 noexpandtab : collectd-5.4.0/bindings/perl/PaxHeaders.11991/lib0000644037772200116100000000013012204120755017603 xustar000000000000000028 mtime=1376821741.7823971 30 atime=1376821742.634410696 30 ctime=1376821742.634410696 collectd-5.4.0/bindings/perl/lib/0000755037772200116100000000000012204120755016426 5ustar00octoeng00000000000000collectd-5.4.0/bindings/perl/lib/PaxHeaders.11991/Collectd0000644037772200116100000000013012204120755021334 xustar000000000000000030 mtime=1376821741.786397163 29 atime=1376821742.63841076 29 ctime=1376821742.63841076 collectd-5.4.0/bindings/perl/lib/Collectd/0000755037772200116100000000000012204120755020157 5ustar00octoeng00000000000000collectd-5.4.0/bindings/perl/lib/Collectd/PaxHeaders.11991/Plugins0000644037772200116100000000013012204120755022755 xustar000000000000000030 mtime=1376821741.790397227 29 atime=1376821742.63841076 29 ctime=1376821742.63841076 collectd-5.4.0/bindings/perl/lib/Collectd/Plugins/0000755037772200116100000000000012204120755021600 5ustar00octoeng00000000000000collectd-5.4.0/bindings/perl/lib/Collectd/Plugins/PaxHeaders.11991/Monitorus.pm0000644037772200116100000000013212204120331025357 xustar000000000000000030 mtime=1376821465.049973054 30 atime=1376821477.194167546 30 ctime=1376821742.642410824 collectd-5.4.0/bindings/perl/lib/Collectd/Plugins/Monitorus.pm0000644037772200116100000000661612204120331024134 0ustar00octoeng00000000000000# # collectd - mon.itor.us collectd plugin # Copyright (C) 2009 Jeff Green # # 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: # Jeff Green # package Collectd::Plugins::Monitorus; use strict; use warnings; use Collectd qw( :all ); use LWP; use threads::shared; use constant NUM_OF_INTERVALS => 90; my $intervalcnt :shared; $intervalcnt=NUM_OF_INTERVALS; my $prev_value :shared; $prev_value=0; plugin_register (TYPE_READ, "monitorus", "monitorus_read"); sub monitorus_read { my $vl = { plugin => 'monitorus', type => 'gauge' }; # Only retrieve a value occasionally in order to not overload mon.itor.us if (++$intervalcnt{'values'} = [ $prev_value ]; plugin_dispatch_values ($vl); return 1; } $intervalcnt=0; my $site = 'http://mon.itor.us'; my $username = 'me@example.org'; my $target = $site.'/user/api/'.$username.'/secretpassword'; my $ua = LWP::UserAgent->new; my $req = HTTP::Request->new(GET => "$target"); $req->header('Accept' => 'text/html'); #Accept HTML Page my $key; my $res = $ua->get($target); if ($res->is_success) {# Success....all content of page has been received $res->content() =~ m/\[CDATA\[(.*)\]\]/; $key = $1; } else { INFO("monitorus: Error in retrieving login page."); } $target = $site.'/test/api/'.$key.'/testNames'; my $testid; $res = $ua->get($target); if ($res->is_success) {# Success....all content of page has been received $res->content() =~ m/get($target); if ($res->is_success) {# Success....all content of page has been received $res->content() =~ m/\<\/row\>\s*(\.*?sitetest_http.*?\<\/row\>)/s; $result = $1; $result =~ s/\.*?CDATA.*?\<\/cell\>//g; $result =~ m|\([0-9]*)\<\/cell\>|; $value = $1; } else { INFO("monitorus: Error in retrieving testsLastValues page."); } $prev_value = $value; $vl->{'values'} = [ $value ]; plugin_dispatch_values ($vl); return 1; } 1; collectd-5.4.0/bindings/perl/lib/Collectd/Plugins/PaxHeaders.11991/OpenVZ.pm0000644037772200116100000000013212204120331024541 xustar000000000000000030 mtime=1376821465.049973054 30 atime=1376821477.194167546 30 ctime=1376821742.642410824 collectd-5.4.0/bindings/perl/lib/Collectd/Plugins/OpenVZ.pm0000644037772200116100000001346412204120331023315 0ustar00octoeng00000000000000# # collectd - OpenVZ collectd plugin # Copyright (C) 2009 Jonathan Kolb # # 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; either version 2 of the License, or (at your option) any later # version. # # 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 # # Author: # Jonathan Kolb # package Collectd::Plugins::OpenVZ; use strict; use warnings; use Collectd qw( :all ); my @cpu_instances = ('user', 'nice', 'system', 'idle', 'wait', 'interrupt', 'softirq', 'steal'); my @if_instances = ('if_octets', 'if_packets', 'if_errors'); my $vzctl = '/usr/sbin/vzctl'; my $vzlist = '/usr/sbin/vzlist'; my $last_stat = {}; sub openvz_read { my %v = (time => time(), interval => plugin_get_interval()); my (@veids, $veid, $name, $key, $val, $i, @lines, @parts, @counters); @veids = map { s/ //g; $_; } split(/\n/, `$vzlist -Ho veid`); foreach $veid (@veids) { ($name = `$vzlist -Ho name $veid`) =~ s/^\s*(.*?)\s*$/$1/; $name = $veid if ($name =~ /^-$/); $v{'host'} = $name; ##################################################################### # interface $v{'plugin'} = 'interface'; delete $v{'plugin_instance'}; @lines = split(/\n/, `$vzctl exec $veid cat /proc/net/dev`); foreach (@lines) { next if (!/:/); @parts = split(/:/); ($key = $parts[0]) =~ s/^\s*(.*?)\s*$/$1/; ($val = $parts[1]) =~ s/^\s*(.*?)\s*$/$1/; @counters = split(/ +/, $val); $v{'type_instance'} = $key; for ($key = 0; $key <= $#if_instances; ++$key) { $v{'type'} = $if_instances[$key]; $v{'values'} = [ $counters[$key], $counters[$key + 8] ]; plugin_dispatch_values(\%v); } } ##################################################################### # cpu $v{'plugin'} = 'cpu'; $v{'type'} = 'cpu'; $i = 0; @lines = split(/\n/, `$vzctl exec $veid cat /proc/stat`); foreach (@lines) { next if (!/^cpu[0-9]/); @counters = split(/ +/); shift(@counters); # Remove once OpenVZ bug 1376 is resolved if (48485 == $counters[3]) { $counters[3] = $last_stat->{"$veid-$i-idle"}; $counters[4] = $last_stat->{"$veid-$i-wait"}; } else { $last_stat->{"$veid-$i-idle"} = $counters[3]; $last_stat->{"$veid-$i-wait"} = $counters[4]; } $v{'plugin_instance'} = $i++; for ($key = 0; $key <= $#counters; ++$key) { $v{'type_instance'} = $cpu_instances[$key]; $v{'values'} = [ $counters[$key] ]; plugin_dispatch_values(\%v); } } ##################################################################### # df $v{'plugin'} = 'df'; delete $v{'plugin_instance'}; $v{'type'} = 'df'; $val = join(' ', map { (split)[1] } split(/\n/, `$vzctl exec $veid cat /proc/mounts`)); @lines = split(/\n/, `$vzctl exec $veid stat -tf $val`); foreach (@lines) { @parts = split(/ /); next if (0 == $parts[7]); $val = substr($parts[0], 1); $val = 'root' if ($val =~ /^$/); $val =~ s#/#-#g; $v{'type_instance'} = $val; $v{'values'} = [ $parts[5] * ($parts[6] - $parts[7]), $parts[5] * $parts[7] ]; plugin_dispatch_values(\%v); } ##################################################################### # load $v{'plugin'} = 'load'; delete $v{'plugin_instance'}; $v{'type'} = 'load'; delete $v{'type_instance'}; @parts = split(/ +/, `$vzctl exec $veid cat /proc/loadavg`); $v{'values'} = [ $parts[0], $parts[1], $parts[2] ]; plugin_dispatch_values(\%v); ##################################################################### # processes my $ps_states = { 'paging' => 0, 'blocked' => 0, 'zombies' => 0, 'stopped' => 0, 'running' => 0, 'sleeping' => 0 }; my $state_map = { 'R' => 'running', 'S' => 'sleeping', 'D' => 'blocked', 'Z' => 'zombies', 'T' => 'stopped', 'W' => 'paging' }; $v{'plugin'} = 'processes'; delete $v{'plugin_instance'}; $v{'type'} = 'ps_state'; @lines = map { (split)[2] } split(/\n/, `$vzctl exec $veid cat '/proc/[0-9]*/stat'`); foreach $key (@lines) { ++$ps_states->{$state_map->{$key}}; } foreach $key (keys %{$ps_states}) { $v{'type_instance'} = $key; $v{'values'} = [ $ps_states->{$key} ]; plugin_dispatch_values(\%v); } ##################################################################### # users $v{'plugin'} = 'users'; delete $v{'plugin_instance'}; $v{'type'} = 'users'; delete $v{'type_instance'}; @lines = split(/\n/, `$vzctl exec $veid w -h`); $v{'values'} = [ scalar(@lines) ]; plugin_dispatch_values(\%v); } return 1; } plugin_register(TYPE_READ, 'OpenVZ', 'openvz_read'); return 1; collectd-5.4.0/bindings/perl/lib/Collectd/PaxHeaders.11991/Unixsock.pm0000644037772200116100000000013212204120331023542 xustar000000000000000030 mtime=1376821465.049973054 30 atime=1376821477.194167546 30 ctime=1376821742.642410824 collectd-5.4.0/bindings/perl/lib/Collectd/Unixsock.pm0000644037772200116100000003141212204120331022307 0ustar00octoeng00000000000000# # collectd - Collectd::Unixsock # Copyright (C) 2007,2008 Florian octo 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 # # Author: # Florian octo Forster # package Collectd::Unixsock; =head1 NAME Collectd::Unixsock - Abstraction layer for accessing the functionality by collectd's unixsock plugin. =head1 SYNOPSIS use Collectd::Unixsock (); my $sock = Collectd::Unixsock->new ($path); my $value = $sock->getval (%identifier); $sock->putval (%identifier, time => time (), values => [123, 234, 345]); $sock->destroy (); =head1 DESCRIPTION collectd's unixsock plugin allows external programs to access the values it has collected or received and to submit own values. This Perl-module is simply a little abstraction layer over this interface to make it even easier for programmers to interact with the daemon. =cut use strict; use warnings; #use constant { NOTIF_FAILURE => 1, NOTIF_WARNING => 2, NOTIF_OKAY => 4 }; use Carp (qw(cluck confess)); use IO::Socket::UNIX; use Regexp::Common (qw(number)); our $Debug = 0; return (1); sub _debug { if (!$Debug) { return; } print @_; } sub _create_socket { my $path = shift; my $sock = IO::Socket::UNIX->new (Type => SOCK_STREAM, Peer => $path); if (!$sock) { cluck ("Cannot open UNIX-socket $path: $!"); return; } return ($sock); } # _create_socket =head1 VALUE IDENTIFIERS The values in the collectd are identified using an five-tuple (host, plugin, plugin-instance, type, type-instance) where only plugin-instance and type-instance may be NULL (or undefined). Many functions expect an I<%identifier> hash that has at least the members B, B, and B, possibly completed by B and B. Usually you can pass this hash as follows: $obj->method (host => $host, plugin => $plugin, type => $type, %other_args); =cut sub _create_identifier { my $args = shift; my $host; my $plugin; my $type; if (!$args->{'host'} || !$args->{'plugin'} || !$args->{'type'}) { cluck ("Need `host', `plugin' and `type'"); return; } $host = $args->{'host'}; $plugin = $args->{'plugin'}; $plugin .= '-' . $args->{'plugin_instance'} if (defined ($args->{'plugin_instance'})); $type = $args->{'type'}; $type .= '-' . $args->{'type_instance'} if (defined ($args->{'type_instance'})); return ("$host/$plugin/$type"); } # _create_identifier sub _parse_identifier { my $string = shift; my $host; my $plugin; my $plugin_instance; my $type; my $type_instance; my $ident; ($host, $plugin, $type) = split ('/', $string); ($plugin, $plugin_instance) = split ('-', $plugin, 2); ($type, $type_instance) = split ('-', $type, 2); $ident = { host => $host, plugin => $plugin, type => $type }; $ident->{'plugin_instance'} = $plugin_instance if (defined ($plugin_instance)); $ident->{'type_instance'} = $type_instance if (defined ($type_instance)); return ($ident); } # _parse_identifier sub _escape_argument { my $string = shift; if ($string =~ m/^\w+$/) { return ("$string"); } $string =~ s#\\#\\\\#g; $string =~ s#"#\\"#g; $string = "\"$string\""; return ($string); } =head1 PUBLIC METHODS =over 4 =item I<$obj> = Collectd::Unixsock->B ([I<$path>]); Creates a new connection to the daemon. The optional I<$path> argument gives the path to the UNIX socket of the C and defaults to F. Returns the newly created object on success and false on error. =cut sub new { my $pkg = shift; my $path = @_ ? shift : '/var/run/collectd-unixsock'; my $sock = _create_socket ($path) or return; my $obj = bless ( { path => $path, sock => $sock, error => 'No error' }, $pkg); return ($obj); } # new =item I<$res> = I<$obj>-EB (I<%identifier>); Requests a value-list from the daemon. On success a hash-ref is returned with the name of each data-source as the key and the according value as, well, the value. On error false is returned. =cut sub getval # {{{ { my $obj = shift; my %args = @_; my $status; my $fh = $obj->{'sock'} or confess ('object has no filehandle'); my $msg; my $identifier; my $ret = {}; $identifier = _create_identifier (\%args) or return; $msg = 'GETVAL ' . _escape_argument ($identifier) . "\n"; _debug "-> $msg"; print $fh $msg; $msg = <$fh>; chomp ($msg); _debug "<- $msg\n"; ($status, $msg) = split (' ', $msg, 2); if ($status <= 0) { $obj->{'error'} = $msg; return; } for (my $i = 0; $i < $status; $i++) { my $entry = <$fh>; chomp ($entry); _debug "<- $entry\n"; if ($entry =~ m/^(\w+)=NaN$/) { $ret->{$1} = undef; } elsif ($entry =~ m/^(\w+)=($RE{num}{real})$/) { $ret->{$1} = 0.0 + $2; } } return ($ret); } # }}} sub getval =item I<$res> = I<$obj>-EB (I<%identifier>); Requests a threshold from the daemon. On success a hash-ref is returned with the threshold data. On error false is returned. =cut sub getthreshold # {{{ { my $obj = shift; my %args = @_; my $status; my $fh = $obj->{'sock'} or confess ('object has no filehandle'); my $msg; my $identifier; my $ret = {}; $identifier = _create_identifier (\%args) or return; $msg = 'GETTHRESHOLD ' . _escape_argument ($identifier) . "\n"; _debug "-> $msg"; print $fh $msg; $msg = <$fh>; chomp ($msg); _debug "<- $msg\n"; ($status, $msg) = split (' ', $msg, 2); if ($status <= 0) { $obj->{'error'} = $msg; return; } for (my $i = 0; $i < $status; $i++) { my $entry = <$fh>; chomp ($entry); _debug "<- $entry\n"; if ($entry =~ m/^([^:]+):\s*(\S.*)$/) { my $key = $1; my $value = $2; $key =~ s/^\s+//; $key =~ s/\s+$//; $ret->{$key} = $value; } } return ($ret); } # }}} sub getthreshold =item I<$obj>-EB (I<%identifier>, B