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 bb95181..3d529a6 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 7fb19a1..40b2190 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 6d8e966..25e52fa 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 */