Code

network plugin: Added support for sending and receiving notifications.
authorFlorian Forster <octo@leeloo.lan.home.verplant.org>
Wed, 23 Jan 2008 11:40:24 +0000 (12:40 +0100)
committerFlorian Forster <octo@leeloo.lan.home.verplant.org>
Wed, 23 Jan 2008 11:40:24 +0000 (12:40 +0100)
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
src/network.c
src/network.h

diff --git a/TODO b/TODO
index bb95181bfe059c17b828e1cbe6c1943d72653ca1..3d529a6db65cc7f1264723be6068ecacadf44dce 100644 (file)
--- 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.
index 7fb19a1c73612885d2a66823881bcb3331660e38..40b21906d597598ac1448182950ee24e0fa194de 100644 (file)
@@ -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))
        {
index 6d8e966e967d68749e0ad5bc5a4f25662c8b074e..25e52fa901caab7514bf23d1cff554c185f53e2e 100644 (file)
@@ -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 */