From 6106d8df99851f4e3ceba02203d81dd49a3f607f Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Mon, 19 May 2008 23:08:17 +0200 Subject: [PATCH] desktop_notification: Added a plugin to send desktop notifications. This plugin sends desktop notifications to a notification daemon, as defined in the Desktop Notification Specification (see http://www.galago-project.org/specs/notification/). The timeout after which to expire the displayed notification may be configured in collectd.conf. Signed-off-by: Sebastian Harl Signed-off-by: Florian Forster --- README | 9 +++ configure.in | 7 ++ src/Makefile.am | 9 +++ src/collectd.conf.in | 7 ++ src/collectd.conf.pod | 26 ++++++++ src/desktop_notification.c | 160 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 218 insertions(+) create mode 100644 src/desktop_notification.c diff --git a/README b/README index 904e7c73..aad6a702 100644 --- a/README +++ b/README @@ -230,6 +230,12 @@ Features * Notifications can be handled by the following plugins: + - desktop_notification + Send a desktop notification to a notification daemon, as defined in + the Desktop Notification Specification. To actually display the + notifications, notification-daemon is required. + See http://www.galago-project.org/specs/notification/. + - exec Execute a program or script to handle the notification. See collectd-exec(5). @@ -333,6 +339,9 @@ Prerequisites * libnetsnmp (optional) For the `snmp' plugin. + * libnotify (optional) + For the `desktop_notification' plugin. + * liboping (optional, if not found a version shipped with this distribution can be used) Used by the `ping' plugin to send and receive ICMP packets. diff --git a/configure.in b/configure.in index 3876b4f1..57fb82c6 100644 --- a/configure.in +++ b/configure.in @@ -1738,6 +1738,10 @@ then fi AM_CONDITIONAL(BUILD_WITH_LIBNETSNMP, test "x$with_libnetsnmp" = "xyes") +PKG_CHECK_MODULES([LIBNOTIFY], [libnotify], + [with_libnotify="yes"], + [with_libnotify="no ($LIBNOTIFY_PKG_ERRORS)"]) + with_upsclient_config="libupsclient-config" with_upsclient_cflags="" with_upsclient_libs="" @@ -2469,6 +2473,7 @@ AC_PLUGIN([battery], [$plugin_battery], [Battery statistics]) AC_PLUGIN([cpu], [$plugin_cpu], [CPU usage statistics]) AC_PLUGIN([cpufreq], [$plugin_cpufreq], [CPU frequency statistics]) AC_PLUGIN([csv], [yes], [CSV output plugin]) +AC_PLUGIN([desktop_notification], [$with_libnotify], [Desktop notifications]) AC_PLUGIN([df], [$plugin_df], [Filesystem usage statistics]) AC_PLUGIN([disk], [$plugin_disk], [Disk usage statistics]) AC_PLUGIN([dns], [$with_libpcap], [DNS traffic analysis]) @@ -2598,6 +2603,7 @@ Configuration: libmysql . . . . . $with_libmysql libnetlink . . . . $with_libnetlink libnetsnmp . . . . $with_libnetsnmp + libnotify . . . . . $with_libnotify liboconfig . . . . $with_liboconfig libopenipmi . . . . $with_libopenipmipthread liboping . . . . . $with_liboping @@ -2628,6 +2634,7 @@ Configuration: cpu . . . . . . . . $enable_cpu cpufreq . . . . . . $enable_cpufreq csv . . . . . . . . $enable_csv + desktop_notification $enable_desktop_notification df . . . . . . . . $enable_df disk . . . . . . . $enable_disk dns . . . . . . . . $enable_dns diff --git a/src/Makefile.am b/src/Makefile.am index 21022493..194c1a7b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -181,6 +181,15 @@ collectd_LDADD += "-dlopen" csv.la collectd_DEPENDENCIES += csv.la endif +if BUILD_PLUGIN_DESKTOP_NOTIFICATION +pkglib_LTLIBRARIES += desktop_notification.la +desktop_notification_la_SOURCES = desktop_notification.c +desktop_notification_la_CFLAGS = $(LIBNOTIFY_CFLAGS) +desktop_notification_la_LDFLAGS = -module -avoid-version $(LIBNOTIFY_LIBS) +collectd_LDADD += "-dlopen" desktop_notification.la +collectd_DEPENDENCIES += desktop_notification.la +endif + if BUILD_PLUGIN_DF pkglib_LTLIBRARIES += df.la df_la_SOURCES = df.c diff --git a/src/collectd.conf.in b/src/collectd.conf.in index e900ce81..eaa3de19 100644 --- a/src/collectd.conf.in +++ b/src/collectd.conf.in @@ -21,6 +21,7 @@ FQDNLookup true @BUILD_PLUGIN_CPU_TRUE@LoadPlugin cpu @BUILD_PLUGIN_CPUFREQ_TRUE@LoadPlugin cpufreq @BUILD_PLUGIN_CSV_TRUE@LoadPlugin csv +@BUILD_PLUGIN_DESKTOP_NOTIFICATION_TRUE@LoadPlugin desktop_notification @BUILD_PLUGIN_DF_TRUE@LoadPlugin df @BUILD_PLUGIN_DISK_TRUE@LoadPlugin disk @BUILD_PLUGIN_DNS_TRUE@LoadPlugin dns @@ -93,6 +94,12 @@ FQDNLookup true # StoreRates false # +# +# OkayTimeout 1000 +# WarningTimeout 5000 +# FailureTimeout 0 +# + # # Device "/dev/hda1" # Device "192.168.0.2:/mnt/nfs" diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod index afa05711..2c4ff462 100644 --- a/src/collectd.conf.pod +++ b/src/collectd.conf.pod @@ -265,6 +265,32 @@ number. =back +=head2 Plugin C + +This plugin sends a desktop notification to a notification daemon, as defined +in the Desktop Notification Specification. To actually display the +notifications, B is required and B has to be +able to access the X server. + +The Desktop Notification Specification can be found at +L. + +=over 4 + +=item B I + +=item B I + +=item B I + +Set the I, in milliseconds, after which to expire the notification +for C, C and C severities respectively. If zero has +been specified, the displayed notification will not be closed at all - the +user has to do so herself. These options default to 5000. If a negative number +has been specified, the default is used as well. + +=back + =head2 Plugin C =over 4 diff --git a/src/desktop_notification.c b/src/desktop_notification.c new file mode 100644 index 00000000..3b6af07f --- /dev/null +++ b/src/desktop_notification.c @@ -0,0 +1,160 @@ +/** + * collectd - src/desktop_notification.c + * Copyright (C) 2008 Sebastian Harl + * + * 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 + * Free Software Foundation; only version 2 of the License is applicable. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Author: + * Sebastian Harl + **/ + +/* + * This plugin sends desktop notifications to a notification daemon. + */ + +#include "collectd.h" +#include "plugin.h" +#include "configfile.h" + +#include +#include + +#define log_info(...) INFO ("desktop_notification: " __VA_ARGS__) +#define log_warn(...) WARNING ("desktop_notification: " __VA_ARGS__) +#define log_err(...) ERROR ("desktop_notification: " __VA_ARGS__) + +#define DEFAULT_TIMEOUT 5000 + +static int okay_timeout = DEFAULT_TIMEOUT; +static int warn_timeout = DEFAULT_TIMEOUT; +static int fail_timeout = DEFAULT_TIMEOUT; + +static int set_timeout (oconfig_item_t *ci, int *timeout) +{ + if ((0 != ci->children_num) || (1 != ci->values_num) + || (OCONFIG_TYPE_NUMBER != ci->values[0].type)) { + log_err ("%s expects a single number argument.", ci->key); + return 1; + } + + *timeout = (int)ci->values[0].value.number; + if (0 > *timeout) + *timeout = DEFAULT_TIMEOUT; + return 0; +} /* set_timeout */ + +static int c_notify_config (oconfig_item_t *ci) +{ + int i = 0; + + for (i = 0; i < ci->children_num; ++i) { + oconfig_item_t *c = ci->children + i; + + if (0 == strcasecmp (c->key, "OkayTimeout")) + set_timeout (c, &okay_timeout); + else if (0 == strcasecmp (c->key, "WarningTimeout")) + set_timeout (c, &warn_timeout); + else if (0 == strcasecmp (c->key, "FailureTimeout")) + set_timeout (c, &fail_timeout); + } + return 0; +} /* c_notify_config */ + +static int c_notify (const notification_t *n) +{ + NotifyNotification *notification = NULL; + NotifyUrgency urgency = NOTIFY_URGENCY_LOW; + int timeout = okay_timeout; + + char summary[1024]; + + if (NOTIF_WARNING == n->severity) { + urgency = NOTIFY_URGENCY_NORMAL; + timeout = warn_timeout; + } + else if (NOTIF_FAILURE == n->severity) { + urgency = NOTIFY_URGENCY_CRITICAL; + timeout = fail_timeout; + } + + ssnprintf (summary, sizeof (summary), "collectd %s notification", + (NOTIF_FAILURE == n->severity) ? "FAILURE" + : (NOTIF_WARNING == n->severity) ? "WARNING" + : (NOTIF_OKAY == n->severity) ? "OKAY" : "UNKNOWN"); + + notification = notify_notification_new (summary, n->message, NULL, NULL); + if (NULL == notification) { + log_err ("Failed to create a new notification."); + return -1; + } + + notify_notification_set_urgency (notification, urgency); + notify_notification_set_timeout (notification, timeout); + + if (! notify_notification_show (notification, NULL)) + log_err ("Failed to display notification."); + + g_object_unref (G_OBJECT (notification)); + return 0; +} /* c_notify */ + +static int c_notify_shutdown (void) +{ + plugin_unregister_init ("desktop_notification"); + plugin_unregister_notification ("desktop_notification"); + plugin_unregister_shutdown ("desktop_notification"); + + if (notify_is_initted ()) + notify_uninit (); + return 0; +} /* c_notify_shutdown */ + +static int c_notify_init (void) +{ + char *name = NULL; + char *vendor = NULL; + char *version = NULL; + char *spec_version = NULL; + + if (! notify_init (PACKAGE_STRING)) { + log_err ("Failed to initialize libnotify."); + return -1; + } + + if (! notify_get_server_info (&name, &vendor, &version, &spec_version)) + log_warn ("Failed to get the notification server info. " + "Check if you have a notification daemon running."); + else { + log_info ("Found notification daemon: %s (%s) %s (spec version %s)", + name, vendor, version, spec_version); + free (name); + free (vendor); + free (version); + free (spec_version); + } + + plugin_register_notification ("desktop_notification", c_notify); + plugin_register_shutdown ("desktop_notification", c_notify_shutdown); + return 0; +} /* c_notify_init */ + +void module_register (void) +{ + plugin_register_complex_config ("desktop_notification", c_notify_config); + plugin_register_init ("desktop_notification", c_notify_init); + return; +} /* module_register */ + +/* vim: set sw=4 ts=4 tw=78 noexpandtab : */ + -- 2.11.0