*
* Author:
* Luke Heberling <lukeh at c-ware.com>
- * Florian Forster <octo at verplant.org>
+ * Florian Forster <octo at collectd.org>
*
* DESCRIPTION
* Queries a PowerDNS control socket for statistics
#define FUNC_ERROR(func) do { char errbuf[1024]; ERROR ("powerdns plugin: %s failed: %s", func, sstrerror (errno, errbuf, sizeof (errbuf))); } while (0)
#define SERVER_SOCKET LOCALSTATEDIR"/run/pdns.controlsocket"
-#define SERVER_COMMAND "SHOW *"
+#define SERVER_COMMAND "SHOW * \n"
#define RECURSOR_SOCKET LOCALSTATEDIR"/run/pdns_recursor.controlsocket"
#define RECURSOR_COMMAND "get noerror-answers nxdomain-answers " \
"servfail-answers sys-msec user-msec qa-latency cache-entries cache-hits " \
- "cache-misses questions"
+ "cache-misses questions\n"
struct list_item_s;
typedef struct list_item_s list_item_t;
/* Description of statistics returned by the recursor: {{{
all-outqueries counts the number of outgoing UDP queries since starting
-answers0-1 counts the number of queries answered within 1 milisecond
+answers0-1 counts the number of queries answered within 1 millisecond
answers100-1000 counts the number of queries answered within 1 second
-answers10-100 counts the number of queries answered within 100 miliseconds
-answers1-10 counts the number of queries answered within 10 miliseconds
+answers10-100 counts the number of queries answered within 100 milliseconds
+answers1-10 counts the number of queries answered within 10 milliseconds
answers-slow counts the number of queries answered after 1 second
cache-entries shows the number of entries in the cache
cache-hits counts the number of cache hits since starting
{"recursing-questions", "dns_question", "recurse"},
{"tcp-queries", "dns_question", "tcp"},
{"udp-queries", "dns_question", "udp"},
+ {"rd-queries", "dns_question", "rd"},
/* Answers */
{"recursing-answers", "dns_answer", "recurse"},
{"tcp-answers", "dns_answer", "tcp"},
{"udp-answers", "dns_answer", "udp"},
+ {"recursion-unanswered", "dns_answer", "recursion-unanswered"},
+ {"udp-answers-bytes", "total_bytes", "udp-answers-bytes"},
/* Cache stuff */
{"packetcache-hit", "cache_result", "packet-hit"},
{"packetcache-miss", "cache_result", "packet-miss"},
{"packetcache-size", "cache_size", "packet"},
+ {"key-cache-size", "cache_size", "key"},
+ {"meta-cache-size", "cache_size", "meta"},
+ {"signature-cache-size", "cache_size", "signature"},
{"query-cache-hit", "cache_result", "query-hit"},
{"query-cache-miss", "cache_result", "query-miss"},
/* Latency */
{"latency", "latency", NULL},
+ /* DNS updates */
+ {"dnsupdate-answers", "dns_answer", "dnsupdate-answer"},
+ {"dnsupdate-changes", "dns_question", "dnsupdate-changes"},
+ {"dnsupdate-queries", "dns_question", "dnsupdate-queries"},
+ {"dnsupdate-refused", "dns_answer", "dnsupdate-refused"},
+
/* Other stuff.. */
- {"corrupt-packets", "io_packets", "corrupt"},
+ {"corrupt-packets", "ipt_packets", "corrupt"},
{"deferred-cache-inserts", "counter", "cache-deferred_insert"},
{"deferred-cache-lookup", "counter", "cache-deferred_lookup"},
{"qsize-a", "cache_size", "answers"},
{"qsize-q", "cache_size", "questions"},
- {"servfail-packets", "io_packets", "servfail"},
- {"timedout-packets", "io_packets", "timeout"},
+ {"servfail-packets", "ipt_packets", "servfail"},
+ {"timedout-packets", "ipt_packets", "timeout"},
{"udp4-answers", "dns_answer", "udp4"},
{"udp4-queries", "dns_question", "queries-udp4"},
{"udp6-answers", "dns_answer", "udp6"},
{"udp6-queries", "dns_question", "queries-udp6"},
+ {"security-status", "dns_question", "security-status"},
+ {"udp-do-queries", "dns_question", "udp-do_queries"},
+ {"signatures", "counter", "signatures"},
/***********************
* Recursor statistics *
{"throttle-entries", "gauge", "entries-throttle"},
{"unauthorized-tcp", "counter", "denied-unauthorized_tcp"},
{"unauthorized-udp", "counter", "denied-unauthorized_udp"},
- {"unexpected-packets", "dns_answer", "unexpected"}
- /* {"uptime", "", ""} */
+ {"unexpected-packets", "dns_answer", "unexpected"},
+ {"uptime", "uptime", NULL}
}; /* }}} */
int lookup_table_length = STATIC_ARRAY_SIZE (lookup_table);
if (strcmp (lookup_table[i].name, pdns_type) == 0)
break;
- if (lookup_table[i].type == NULL)
- return;
-
if (i >= lookup_table_length)
{
INFO ("powerdns plugin: submit: Not found in lookup table: %s = %s;",
return;
}
+ if (lookup_table[i].type == NULL)
+ return;
+
type = lookup_table[i].type;
type_instance = lookup_table[i].type_instance;
if (ds->ds_num != 1)
{
- ERROR ("powerdns plugin: type `%s' has %i data sources, "
+ ERROR ("powerdns plugin: type `%s' has %zu data sources, "
"but I can only handle one.",
type, ds->ds_num);
return;
struct sockaddr_un sa_unix;
+ struct timeval stv_timeout;
+ cdtime_t cdt_timeout;
+
sd = socket (PF_UNIX, item->socktype, 0);
if (sd < 0)
{
break;
}
+ cdt_timeout = plugin_get_interval () * 3 / 4;
+ if (cdt_timeout < TIME_T_TO_CDTIME_T (2))
+ cdt_timeout = TIME_T_TO_CDTIME_T (2);
+
+ CDTIME_T_TO_TIMEVAL (cdt_timeout, &stv_timeout);
+
+ status = setsockopt (sd, SOL_SOCKET, SO_RCVTIMEO, &stv_timeout, sizeof (stv_timeout));
+ if (status != 0)
+ {
+ FUNC_ERROR ("setsockopt");
+ break;
+ }
+
status = connect (sd, (struct sockaddr *) &item->sockaddr,
sizeof (item->sockaddr));
if (status != 0)
return (-1);
}
+ struct timeval timeout;
+ timeout.tv_sec=5;
+ timeout.tv_usec=0;
+ status = setsockopt (sd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof (timeout));
+ if (status != 0)
+ {
+ FUNC_ERROR ("setsockopt");
+ close (sd);
+ return (-1);
+ }
+
status = connect (sd, (struct sockaddr *) &item->sockaddr,
sizeof (item->sockaddr));
if (status != 0)
buffer[buffer_size] = 0;
} /* while (42) */
close (sd);
- sd = -1;
if (status < 0)
{
int fields_num;
if (item->command == NULL)
- item->command = strdup ("SHOW *");
+ item->command = strdup (SERVER_COMMAND);
if (item->command == NULL)
{
ERROR ("powerdns plugin: strdup failed.");
else
{
sstrncpy (buffer, "get ", sizeof (buffer));
- status = strjoin (&buffer[4], sizeof (buffer) - strlen ("get "),
+ status = strjoin (&buffer[strlen("get ")], sizeof (buffer) - strlen ("get "),
li->fields, li->fields_num,
/* seperator = */ " ");
if (status < 0)
ERROR ("powerdns plugin: strjoin failed.");
return (-1);
}
+ buffer[sizeof (buffer) - 1] = 0;
+ size_t len = strlen (buffer);
+ if (len < sizeof (buffer) - 2)
+ {
+ buffer[len++] = ' ';
+ buffer[len++] = '\n';
+ buffer[len++] = '\0';
+ }
}
buffer[sizeof (buffer) - 1] = 0;
return (0);
} /* }}} int powerdns_read_recursor */
-static int powerdns_config_add_string (const char *name, /* {{{ */
- char **dest,
- oconfig_item_t *ci)
-{
- if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
- {
- WARNING ("powerdns plugin: `%s' needs exactly one string argument.",
- name);
- return (-1);
- }
-
- sfree (*dest);
- *dest = strdup (ci->values[0].value.string);
- if (*dest == NULL)
- return (-1);
-
- return (0);
-} /* }}} int powerdns_config_add_string */
-
static int powerdns_config_add_collect (list_item_t *li, /* {{{ */
oconfig_item_t *ci)
{
if (strcasecmp ("Collect", option->key) == 0)
status = powerdns_config_add_collect (item, option);
else if (strcasecmp ("Socket", option->key) == 0)
- status = powerdns_config_add_string ("Socket", &socket_temp, option);
+ status = cf_util_get_string (option, &socket_temp);
else
{
ERROR ("powerdns plugin: Option `%s' not allowed here.", option->key);
if (status != 0)
{
+ sfree (socket_temp);
sfree (item);
return (-1);
}
DEBUG ("powerdns plugin: Add server: instance = %s;", item->instance);
+ sfree (socket_temp);
return (0);
} /* }}} int powerdns_config_add_server */
powerdns_config_add_server (option);
else if (strcasecmp ("LocalSocket", option->key) == 0)
{
- char *temp = strdup (option->key);
- if (temp == NULL)
- return (1);
- sfree (local_sockpath);
- local_sockpath = temp;
+ if ((option->values_num != 1) || (option->values[0].type != OCONFIG_TYPE_STRING))
+ {
+ WARNING ("powerdns plugin: `%s' needs exactly one string argument.", option->key);
+ }
+ else
+ {
+ char *temp = strdup (option->values[0].value.string);
+ if (temp == NULL)
+ return (1);
+ sfree (local_sockpath);
+ local_sockpath = temp;
+ }
}
else
{