diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod index a12a48b64d..facb058959 100644 --- a/src/collectd.conf.pod +++ b/src/collectd.conf.pod @@ -2783,12 +2783,24 @@ 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 +=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 expecially interesting when B is disabled, but +can be configured independently from that option. Defaults to B. + =back =head2 Plugin C diff --git a/src/openvpn.c b/src/openvpn.c index 9c717dd0a6..2aca4145cd 100644 --- a/src/openvpn.c +++ b/src/openvpn.c @@ -3,6 +3,7 @@ * Copyright (C) 2008 Doug MacEachern * Copyright (C) 2009 Florian octo Forster * Copyright (C) 2009 Marco Chiappero + * Copyright (C) 2009 Fabian Schuh * * 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 @@ -21,6 +22,7 @@ * Doug MacEachern * Florian octo Forster * Marco Chiappero + * Fabian Schuh **/ #include "collectd.h" @@ -50,14 +52,19 @@ typedef struct vpn_status_s vpn_status_t; static vpn_status_t **vpn_list = NULL; static int vpn_num = 0; -static int store_compression = 1; -static int new_naming_schema = 0; +static _Bool new_naming_schema = 0; +static _Bool collect_compression = 1; +static _Bool collect_user_count = 0; +static _Bool collect_individual_users = 1; static const char *config_keys[] = { "StatusFile", - "Compression", - "ImprovedNamingSchema" + "Compression", /* old, deprecated name */ + "ImprovedNamingSchema", + "CollectCompression", + "CollectUserCount", + "CollectIndividualUsers" }; static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); @@ -85,6 +92,27 @@ static int openvpn_strsplit (char *string, char **fields, size_t size) return (i); } /* int openvpn_strsplit */ +/* dispatches number of users */ +static void numusers_submit (char *pinst, char *tinst, 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, "openvpn", sizeof (vl.plugin)); + sstrncpy (vl.type, "users", sizeof (vl.type)); + if (pinst != NULL) + sstrncpy (vl.plugin_instance, pinst, sizeof (vl.plugin_instance)); + if (tinst != NULL) + sstrncpy (vl.type_instance, tinst, sizeof (vl.type_instance)); + + plugin_dispatch_values (&vl); +} /* void numusers_submit */ + /* dispatches stats about traffic (TCP or UDP) generated by the tunnel per single endpoint */ static void iostats_submit (char *pinst, char *tinst, counter_t rx, counter_t tx) { @@ -221,7 +249,7 @@ static int single_read (char *name, FILE *fh) iostats_submit (name, "overhead", overhead_rx, overhead_tx); - if (store_compression) + if (collect_compression) { compression_submit (name, "data_in", post_decompress, pre_decompress); compression_submit (name, "data_out", pre_compress, post_compress); @@ -238,6 +266,7 @@ static int multi1_read (char *name, FILE *fh) char buffer[1024]; char *fields[10]; int fields_num, read = 0, found_header = 0; + long long sum_users = 0; /* read the file until the "ROUTING TABLE" line is found (no more info after) */ while (fgets (buffer, sizeof (buffer), fh) != NULL) @@ -261,24 +290,38 @@ static int multi1_read (char *name, FILE *fh) if (fields_num < 4) continue; - if (new_naming_schema) + if (collect_user_count) + /* If so, sum all users, ignore the individuals*/ { - iostats_submit (name, /* vpn instance */ - fields[0], /* "Common Name" */ - atoll (fields[2]), /* "Bytes Received" */ - atoll (fields[3])); /* "Bytes Sent" */ + sum_users += 1; } - else + if (collect_individual_users) { - iostats_submit (fields[0], /* "Common Name" */ - NULL, /* unused when in multimode */ - atoll (fields[2]), /* "Bytes Received" */ - atoll (fields[3])); /* "Bytes Sent" */ + if (new_naming_schema) + { + iostats_submit (name, /* vpn instance */ + fields[0], /* "Common Name" */ + atoll (fields[2]), /* "Bytes Received" */ + atoll (fields[3])); /* "Bytes Sent" */ + } + else + { + iostats_submit (fields[0], /* "Common Name" */ + NULL, /* unused when in multimode */ + atoll (fields[2]), /* "Bytes Received" */ + atoll (fields[3])); /* "Bytes Sent" */ + } } read = 1; } + if (collect_user_count) + { + numusers_submit(name, name, sum_users); + read = 1; + } + return (read); } /* int multi1_read */ @@ -289,6 +332,7 @@ static int multi2_read (char *name, FILE *fh) char *fields[10]; const int max_fields = STATIC_ARRAY_SIZE (fields); int fields_num, read = 0; + long long sum_users = 0; while (fgets (buffer, sizeof (buffer), fh) != NULL) { @@ -306,26 +350,40 @@ static int multi2_read (char *name, FILE *fh) if (strcmp (fields[0], "CLIENT_LIST") != 0) continue; - if (new_naming_schema) + if (collect_user_count) + /* If so, sum all users, ignore the individuals*/ { - /* plugin inst = file name, type inst = fields[1] */ - iostats_submit (name, /* vpn instance */ - fields[1], /* "Common Name" */ - atoll (fields[4]), /* "Bytes Received" */ - atoll (fields[5])); /* "Bytes Sent" */ + sum_users += 1; } - else + if (collect_individual_users) { - /* plugin inst = fields[1], type inst = "" */ - iostats_submit (fields[1], /* "Common Name" */ - NULL, /* unused when in multimode */ - atoll (fields[4]), /* "Bytes Received" */ - atoll (fields[5])); /* "Bytes Sent" */ + if (new_naming_schema) + { + /* plugin inst = file name, type inst = fields[1] */ + iostats_submit (name, /* vpn instance */ + fields[1], /* "Common Name" */ + atoll (fields[4]), /* "Bytes Received" */ + atoll (fields[5])); /* "Bytes Sent" */ + } + else + { + /* plugin inst = fields[1], type inst = "" */ + iostats_submit (fields[1], /* "Common Name" */ + NULL, /* unused when in multimode */ + atoll (fields[4]), /* "Bytes Received" */ + atoll (fields[5])); /* "Bytes Sent" */ + } } read = 1; } + if (collect_user_count) + { + numusers_submit(name, name, sum_users); + read = 1; + } + return (read); } /* int multi2_read */ @@ -336,6 +394,7 @@ static int multi3_read (char *name, FILE *fh) char *fields[15]; const int max_fields = STATIC_ARRAY_SIZE (fields); int fields_num, read = 0; + long long sum_users = 0; while (fgets (buffer, sizeof (buffer), fh) != NULL) { @@ -356,25 +415,40 @@ static int multi3_read (char *name, FILE *fh) if (strcmp (fields[0], "CLIENT_LIST") != 0) continue; - if (new_naming_schema) + if (collect_user_count) + /* If so, sum all users, ignore the individuals*/ { - iostats_submit (name, /* vpn instance */ - fields[1], /* "Common Name" */ - atoll (fields[4]), /* "Bytes Received" */ - atoll (fields[5])); /* "Bytes Sent" */ + sum_users += 1; } - else + + if (collect_individual_users) { - iostats_submit (fields[1], /* "Common Name" */ - NULL, /* unused when in multimode */ - atoll (fields[4]), /* "Bytes Received" */ - atoll (fields[5])); /* "Bytes Sent" */ + if (new_naming_schema) + { + iostats_submit (name, /* vpn instance */ + fields[1], /* "Common Name" */ + atoll (fields[4]), /* "Bytes Received" */ + atoll (fields[5])); /* "Bytes Sent" */ + } + else + { + iostats_submit (fields[1], /* "Common Name" */ + NULL, /* unused when in multimode */ + atoll (fields[4]), /* "Bytes Received" */ + atoll (fields[5])); /* "Bytes Sent" */ + } } read = 1; } } + if (collect_user_count) + { + numusers_submit(name, name, sum_users); + read = 1; + } + return (read); } /* int multi3_read */ @@ -394,7 +468,7 @@ static int openvpn_read (void) { char errbuf[1024]; WARNING ("openvpn plugin: fopen(%s) failed: %s", vpn_list[i]->file, - sstrerror (errno, errbuf, sizeof (errbuf))); + sstrerror (errno, errbuf, sizeof (errbuf))); continue; } @@ -506,7 +580,7 @@ static int openvpn_config (const char *key, const char *value) if (status_version == 0) { WARNING ("openvpn plugin: unable to detect status version, \ - discarding status file \"%s\".", value); + discarding status file \"%s\".", value); return (1); } @@ -515,7 +589,7 @@ static int openvpn_config (const char *key, const char *value) { char errbuf[1024]; WARNING ("openvpn plugin: sstrdup failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + sstrerror (errno, errbuf, sizeof (errbuf))); return (1); } @@ -556,7 +630,7 @@ static int openvpn_config (const char *key, const char *value) { char errbuf[1024]; ERROR ("openvpn plugin: malloc failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + sstrerror (errno, errbuf, sizeof (errbuf))); sfree (temp->file); sfree (temp); @@ -569,16 +643,14 @@ static int openvpn_config (const char *key, const char *value) DEBUG ("openvpn plugin: status file \"%s\" added", temp->file); } /* if (strcasecmp ("StatusFile", key) == 0) */ - else if (strcasecmp ("Compression", key) == 0) + else if ((strcasecmp ("CollectCompression", key) == 0) + || (strcasecmp ("Compression", key) == 0)) /* old, deprecated name */ { - if (IS_TRUE (value)) - store_compression = 1; + if (IS_FALSE (value)) + collect_compression = 0; else - { - store_compression = 0; - DEBUG ("openvpn plugin: no 'compression statistcs' collected"); - } - } /* if (strcasecmp ("Compression", key) == 0) */ + collect_compression = 1; + } /* if (strcasecmp ("CollectCompression", key) == 0) */ else if (strcasecmp ("ImprovedNamingSchema", key) == 0) { if (IS_TRUE (value)) @@ -591,6 +663,20 @@ static int openvpn_config (const char *key, const char *value) new_naming_schema = 0; } } /* if (strcasecmp ("ImprovedNamingSchema", key) == 0) */ + else if (strcasecmp("CollectUserCount", key) == 0) + { + if (IS_TRUE(value)) + collect_user_count = 1; + else + collect_user_count = 0; + } /* if (strcasecmp("CollectUserCount", key) == 0) */ + else if (strcasecmp("CollectIndividualUsers", key) == 0) + { + if (IS_FALSE (value)) + collect_individual_users = 0; + else + collect_individual_users = 1; + } /* if (strcasecmp("CollectIndividualUsers", key) == 0) */ else { return (-1); @@ -615,12 +701,29 @@ static int openvpn_shutdown (void) return (0); } /* int openvpn_shutdown */ +static int openvpn_init (void) +{ + if (!collect_individual_users + && !collect_compression + && !collect_user_count) + { + WARNING ("OpenVPN plugin: Neither `CollectIndividualUsers', " + "`CollectCompression', nor `CollectUserCount' is true. There's no " + "data left to collect."); + return (-1); + } + + plugin_register_read ("openvpn", openvpn_read); + plugin_register_shutdown ("openvpn", openvpn_shutdown); + + return (0); +} /* int openvpn_init */ + void module_register (void) { plugin_register_config ("openvpn", openvpn_config, config_keys, config_keys_num); - plugin_register_read ("openvpn", openvpn_read); - plugin_register_shutdown ("openvpn", openvpn_shutdown); + plugin_register_init ("openvpn", openvpn_init); } /* void module_register */ /* vim: set sw=2 ts=2 : */