Merge branch 'ff/oracle'
[collectd.git] / src / notify_desktop.c
1 /**
2  * collectd - src/notify_desktop.c
3  * Copyright (C) 2008  Sebastian Harl
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by the
7  * Free Software Foundation; only version 2 of the License is applicable.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
17  *
18  * Author:
19  *   Sebastian Harl <sh at tokkee.org>
20  **/
21
22 /*
23  * This plugin sends desktop notifications to a notification daemon.
24  */
25
26 #include "collectd.h"
27 #include "common.h"
28 #include "plugin.h"
29 #include "configfile.h"
30
31 #include <glib.h>
32 #include <libnotify/notify.h>
33
34 #define log_info(...) INFO ("notify_desktop: " __VA_ARGS__)
35 #define log_warn(...) WARNING ("notify_desktop: " __VA_ARGS__)
36 #define log_err(...) ERROR ("notify_desktop: " __VA_ARGS__)
37
38 #define DEFAULT_TIMEOUT 5000
39
40 static int okay_timeout = DEFAULT_TIMEOUT;
41 static int warn_timeout = DEFAULT_TIMEOUT;
42 static int fail_timeout = DEFAULT_TIMEOUT;
43
44 static int set_timeout (oconfig_item_t *ci, int *timeout)
45 {
46         if ((0 != ci->children_num) || (1 != ci->values_num)
47                         || (OCONFIG_TYPE_NUMBER != ci->values[0].type)) {
48                 log_err ("%s expects a single number argument.", ci->key);
49                 return 1;
50         }
51
52         *timeout = (int)ci->values[0].value.number;
53         if (0 > *timeout)
54                 *timeout = DEFAULT_TIMEOUT;
55         return 0;
56 } /* set_timeout */
57
58 static int c_notify_config (oconfig_item_t *ci)
59 {
60         int i = 0;
61
62         for (i = 0; i < ci->children_num; ++i) {
63                 oconfig_item_t *c = ci->children + i;
64
65                 if (0 == strcasecmp (c->key, "OkayTimeout"))
66                         set_timeout (c, &okay_timeout);
67                 else if (0 == strcasecmp (c->key, "WarningTimeout"))
68                         set_timeout (c, &warn_timeout);
69                 else if (0 == strcasecmp (c->key, "FailureTimeout"))
70                         set_timeout (c, &fail_timeout);
71         }
72         return 0;
73 } /* c_notify_config */
74
75 static int c_notify (const notification_t *n)
76 {
77         NotifyNotification *notification = NULL;
78         NotifyUrgency       urgency      = NOTIFY_URGENCY_LOW;
79         int                 timeout      = okay_timeout;
80
81         char summary[1024];
82
83         if (NOTIF_WARNING == n->severity) {
84                 urgency = NOTIFY_URGENCY_NORMAL;
85                 timeout = warn_timeout;
86         }
87         else if (NOTIF_FAILURE == n->severity) {
88                 urgency = NOTIFY_URGENCY_CRITICAL;
89                 timeout = fail_timeout;
90         }
91
92         ssnprintf (summary, sizeof (summary), "collectd %s notification",
93                         (NOTIF_FAILURE == n->severity) ? "FAILURE"
94                                 : (NOTIF_WARNING == n->severity) ? "WARNING"
95                                 : (NOTIF_OKAY == n->severity) ? "OKAY" : "UNKNOWN");
96
97         notification = notify_notification_new (summary, n->message, NULL, NULL);
98         if (NULL == notification) {
99                 log_err ("Failed to create a new notification.");
100                 return -1;
101         }
102
103         notify_notification_set_urgency (notification, urgency);
104         notify_notification_set_timeout (notification, timeout);
105
106         if (! notify_notification_show (notification, NULL))
107                 log_err ("Failed to display notification.");
108
109         g_object_unref (G_OBJECT (notification));
110         return 0;
111 } /* c_notify */
112
113 static int c_notify_shutdown (void)
114 {
115         plugin_unregister_init ("notify_desktop");
116         plugin_unregister_notification ("notify_desktop");
117         plugin_unregister_shutdown ("notify_desktop");
118
119         if (notify_is_initted ())
120                 notify_uninit ();
121         return 0;
122 } /* c_notify_shutdown */
123
124 static int c_notify_init (void)
125 {
126         char *name         = NULL;
127         char *vendor       = NULL;
128         char *version      = NULL;
129         char *spec_version = NULL;
130
131         if (! notify_init (PACKAGE_STRING)) {
132                 log_err ("Failed to initialize libnotify.");
133                 return -1;
134         }
135
136         if (! notify_get_server_info (&name, &vendor, &version, &spec_version))
137                 log_warn ("Failed to get the notification server info. "
138                                 "Check if you have a notification daemon running.");
139         else {
140                 log_info ("Found notification daemon: %s (%s) %s (spec version %s)",
141                                 name, vendor, version, spec_version);
142                 free (name);
143                 free (vendor);
144                 free (version);
145                 free (spec_version);
146         }
147
148         plugin_register_notification ("notify_desktop", c_notify);
149         plugin_register_shutdown ("notify_desktop", c_notify_shutdown);
150         return 0;
151 } /* c_notify_init */
152
153 void module_register (void)
154 {
155         plugin_register_complex_config ("notify_desktop", c_notify_config);
156         plugin_register_init ("notify_desktop", c_notify_init);
157         return;
158 } /* module_register */
159
160 /* vim: set sw=4 ts=4 tw=78 noexpandtab : */
161