From 7c6a9f178e97cdde377c18c93d79158561223647 Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Wed, 23 Jan 2008 12:40:24 +0100 Subject: [PATCH] network plugin: Added support for sending and receiving notifications. Notifications are sent ``out of band'', i. e. each notification is one packet and they are not mixed with performance data values. Right now there is no configuration option to prevent listening sockets from receiving notifications nor to prevent sending sockets from sending notifications. This may be an option for the future, though. --- TODO | 1 - src/network.c | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- src/network.h | 4 ++ 3 files changed, 158 insertions(+), 10 deletions(-) diff --git a/TODO b/TODO index bb95181b..3d529a6d 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,4 @@ For version 4.3: -* Add notification stuff to the network plugin * Add notification stuff to the unixsock plugin * Add separate warning/critical thresholds. * Fix the libvirt plugin. diff --git a/src/network.c b/src/network.c index 7fb19a1c..40b21906 100644 --- a/src/network.c +++ b/src/network.c @@ -474,7 +474,8 @@ static int parse_part_string (void **ret_buffer, int *ret_buffer_len, || (h_type == TYPE_PLUGIN) || (h_type == TYPE_PLUGIN_INSTANCE) || (h_type == TYPE_TYPE) - || (h_type == TYPE_TYPE_INSTANCE)); + || (h_type == TYPE_TYPE_INSTANCE) + || (h_type == TYPE_MESSAGE)); ps.value = buffer + 4; if (ps.value[h_length - 5] != '\0') @@ -505,16 +506,18 @@ static int parse_packet (void *buffer, int buffer_len) value_list_t vl = VALUE_LIST_INIT; char type[DATA_MAX_NAME_LEN]; + notification_t n; DEBUG ("network plugin: parse_packet: buffer = %p; buffer_len = %i;", buffer, buffer_len); memset (&vl, '\0', sizeof (vl)); memset (&type, '\0', sizeof (type)); + memset (&n, '\0', sizeof (n)); status = 0; while ((status == 0) && (0 < buffer_len) - && ((unsigned int)buffer_len > sizeof (part_header_t))) + && ((unsigned int) buffer_len > sizeof (part_header_t))) { header = (part_header_t *) buffer; @@ -556,7 +559,10 @@ static int parse_packet (void *buffer, int buffer_len) uint64_t tmp = 0; status = parse_part_number (&buffer, &buffer_len, &tmp); if (status == 0) + { vl.time = (time_t) tmp; + n.time = (time_t) tmp; + } } else if (ntohs (header->type) == TYPE_INTERVAL) { @@ -569,31 +575,96 @@ static int parse_packet (void *buffer, int buffer_len) { status = parse_part_string (&buffer, &buffer_len, vl.host, sizeof (vl.host)); - DEBUG ("network plugin: parse_packet: vl.host = %s", vl.host); + strncpy (n.host, vl.host, sizeof (n.host)); + n.host[sizeof (n.host) - 1] = '\0'; + DEBUG ("network plugin: parse_packet: vl.host = %s", + vl.host); } else if (ntohs (header->type) == TYPE_PLUGIN) { status = parse_part_string (&buffer, &buffer_len, vl.plugin, sizeof (vl.plugin)); - DEBUG ("network plugin: parse_packet: vl.plugin = %s", vl.plugin); + strncpy (n.plugin, vl.plugin, sizeof (n.plugin)); + n.plugin[sizeof (n.plugin) - 1] = '\0'; + DEBUG ("network plugin: parse_packet: vl.plugin = %s", + vl.plugin); } else if (ntohs (header->type) == TYPE_PLUGIN_INSTANCE) { status = parse_part_string (&buffer, &buffer_len, - vl.plugin_instance, sizeof (vl.plugin_instance)); - DEBUG ("network plugin: parse_packet: vl.plugin_instance = %s", vl.plugin_instance); + vl.plugin_instance, + sizeof (vl.plugin_instance)); + strncpy (n.plugin_instance, vl.plugin_instance, + sizeof (n.plugin_instance)); + n.plugin_instance[sizeof (n.plugin_instance) - 1] = '\0'; + DEBUG ("network plugin: parse_packet: " + "vl.plugin_instance = %s", + vl.plugin_instance); } else if (ntohs (header->type) == TYPE_TYPE) { status = parse_part_string (&buffer, &buffer_len, type, sizeof (type)); - DEBUG ("network plugin: parse_packet: type = %s", type); + strncpy (n.type, type, sizeof (n.type)); + n.type[sizeof (n.type) - 1] = '\0'; + DEBUG ("network plugin: parse_packet: type = %s", + type); } else if (ntohs (header->type) == TYPE_TYPE_INSTANCE) { status = parse_part_string (&buffer, &buffer_len, - vl.type_instance, sizeof (vl.type_instance)); - DEBUG ("network plugin: parse_packet: vl.type_instance = %s", vl.type_instance); + vl.type_instance, + sizeof (vl.type_instance)); + strncpy (n.type_instance, vl.type_instance, + sizeof (n.type_instance)); + n.type_instance[sizeof (n.type_instance) - 1] = '\0'; + DEBUG ("network plugin: parse_packet: " + "vl.type_instance = %s", + vl.type_instance); + } + else if (ntohs (header->type) == TYPE_MESSAGE) + { + status = parse_part_string (&buffer, &buffer_len, + n.message, sizeof (n.message)); + DEBUG ("network plugin: parse_packet: n.message = %s", + n.message); + + if ((n.severity != NOTIF_FAILURE) + && (n.severity != NOTIF_WARNING) + && (n.severity != NOTIF_OKAY)) + { + INFO ("network plugin: " + "Ignoring notification with " + "unknown severity %s.", + n.severity); + } + else if (n.time <= 0) + { + INFO ("network plugin: " + "Ignoring notification with " + "time == 0."); + } + else if (strlen (n.message) <= 0) + { + INFO ("network plugin: " + "Ignoring notification with " + "an empty message."); + } + else + { + /* + * TODO: Let this do a separate thread so that + * no packets are lost if this takes too long. + */ + plugin_dispatch_notification (&n); + } + } + else if (ntohs (header->type) == TYPE_SEVERITY) + { + uint64_t tmp = 0; + status = parse_part_number (&buffer, &buffer_len, &tmp); + if (status == 0) + n.severity = (int) tmp; } else { @@ -1291,6 +1362,77 @@ static int network_config (const char *key, const char *val) return (0); } /* int network_config */ +static int network_notification (const notification_t *n) +{ + char buffer[BUFF_SIZE]; + char *buffer_ptr = buffer; + int buffer_free = sizeof (buffer); + int status; + + memset (buffer, '\0', sizeof (buffer)); + + + status = write_part_number (&buffer_ptr, &buffer_free, TYPE_TIME, + (uint64_t) n->time); + if (status != 0) + return (-1); + + status = write_part_number (&buffer_ptr, &buffer_free, TYPE_SEVERITY, + (uint64_t) n->severity); + if (status != 0) + return (-1); + + if (strlen (n->host) > 0) + { + status = write_part_string (&buffer_ptr, &buffer_free, TYPE_HOST, + n->host, strlen (n->host)); + if (status != 0) + return (-1); + } + + if (strlen (n->plugin) > 0) + { + status = write_part_string (&buffer_ptr, &buffer_free, TYPE_PLUGIN, + n->plugin, strlen (n->plugin)); + if (status != 0) + return (-1); + } + + if (strlen (n->plugin_instance) > 0) + { + status = write_part_string (&buffer_ptr, &buffer_free, + TYPE_PLUGIN_INSTANCE, + n->plugin_instance, strlen (n->plugin_instance)); + if (status != 0) + return (-1); + } + + if (strlen (n->type) > 0) + { + status = write_part_string (&buffer_ptr, &buffer_free, TYPE_TYPE, + n->type, strlen (n->type)); + if (status != 0) + return (-1); + } + + if (strlen (n->type_instance) > 0) + { + status = write_part_string (&buffer_ptr, &buffer_free, TYPE_TYPE_INSTANCE, + n->type_instance, strlen (n->type_instance)); + if (status != 0) + return (-1); + } + + status = write_part_string (&buffer_ptr, &buffer_free, TYPE_MESSAGE, + n->message, strlen (n->message)); + if (status != 0) + return (-1); + + network_send_buffer (buffer, sizeof (buffer) - buffer_free); + + return (0); +} /* int network_notification */ + static int network_shutdown (void) { listen_loop++; @@ -1343,7 +1485,10 @@ static int network_init (void) /* setup socket(s) and so on */ if (sending_sockets != NULL) + { plugin_register_write ("network", network_write); + plugin_register_notification ("network", network_notification); + } if ((listen_sockets_num != 0) && (listen_thread == 0)) { diff --git a/src/network.h b/src/network.h index 6d8e966e..25e52fa9 100644 --- a/src/network.h +++ b/src/network.h @@ -63,4 +63,8 @@ #define TYPE_VALUES 0x0006 #define TYPE_INTERVAL 0x0007 +/* Types to transmit notifications */ +#define TYPE_MESSAGE 0x0100 +#define TYPE_SEVERITY 0x0101 + #endif /* NETWORK_H */ -- 2.11.0