Merge branch 'master' of octo@verplant.org:/var/lib/git/collectd
[collectd.git] / contrib / examples / myplugin.c
1 /*
2  * /usr/share/doc/collectd/examples/myplugin.c
3  *
4  * A plugin template for collectd.
5  *
6  * Written by Sebastian Harl <sh@tokkee.org>
7  *
8  * This is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License as published by the Free
10  * Software Foundation; only version 2 of the License is applicable.
11  */
12
13 /*
14  * Notes:
15  * - plugins are executed in parallel, thus, thread-safe
16  *   functions need to be used
17  * - each of the functions below (except module_register)
18  *   is optional
19  */
20
21 #if ! HAVE_CONFIG_H
22
23 #include <stdlib.h>
24
25 #include <string.h>
26
27 #ifndef __USE_ISOC99 /* required for NAN */
28 # define DISABLE_ISOC99 1
29 # define __USE_ISOC99 1
30 #endif /* !defined(__USE_ISOC99) */
31 #include <math.h>
32 #if DISABLE_ISOC99
33 # undef DISABLE_ISOC99
34 # undef __USE_ISOC99
35 #endif /* DISABLE_ISOC99 */
36
37 #include <time.h>
38
39 #endif /* ! HAVE_CONFIG */
40
41 #include <collectd/collectd.h>
42 #include <collectd/common.h>
43 #include <collectd/plugin.h>
44
45 /*
46  * data source definition:
47  * - name of the data source
48  * - type of the data source (DS_TYPE_GAUGE, DS_TYPE_COUNTER)
49  * - minimum allowed value
50  * - maximum allowed value
51  */
52 static data_source_t dsrc[1] =
53 {
54         { "my_ds", DS_TYPE_GAUGE, 0, NAN }
55 };
56
57 /*
58  * data set definition:
59  * - name of the data set
60  * - number of data sources
61  * - list of data sources
62  */
63 static data_set_t ds =
64 {
65         "myplugin", STATIC_ARRAY_SIZE (dsrc), dsrc
66 };
67
68 /*
69  * This function is called once upon startup to initialize the plugin.
70  */
71 static int my_init (void)
72 {
73         /* open sockets, initialize data structures, ... */
74
75         /* A return value != 0 indicates an error and causes the plugin to be
76            disabled. */
77     return 0;
78 } /* static int my_init (void) */
79
80 /*
81  * This function is called in regular intervalls to collect the data.
82  */
83 static int my_read (void)
84 {
85         value_t values[1]; /* the size of this list should equal the number of
86                                                   data sources */
87         value_list_t vl = VALUE_LIST_INIT;
88
89         /* do the magic to read the data */
90         values[0].gauge = random ();
91
92         vl.values     = values;
93         vl.values_len = 1;
94         vl.time       = time (NULL);
95         strcpy (vl.host, hostname_g);
96         strcpy (vl.plugin, "myplugin");
97         /* optionally set vl.plugin_instance and vl.type_instance to reasonable
98          * values (default: "") */
99
100         /* dispatch the values to collectd which passes them on to all registered
101          * write functions - the first argument is used to lookup the data set
102          * definition */
103         plugin_dispatch_values ("myplugin", &vl);
104
105         /* A return value != 0 indicates an error and the plugin will be skipped
106          * for an increasing amount of time. */
107     return 0;
108 } /* static int my_read (void) */
109
110 /*
111  * This function is called after values have been dispatched to collectd.
112  */
113 static int my_write (const data_set_t *ds, const value_list_t *vl)
114 {
115         char name[1024] = "";
116         int i = 0;
117
118         if (ds->ds_num != vl->values_len) {
119                 plugin_log (LOG_WARNING, "DS number does not match values length");
120                 return -1;
121         }
122
123         /* get the default base filename for the output file - depending on the
124          * provided values this will be something like
125          * <host>/<plugin>[-<plugin_type>]/<instance>[-<instance_type>] */
126         if (0 != format_name (name, 1024, vl->host, vl->plugin,
127                         vl->plugin_instance, ds->type, vl->type_instance))
128                 return -1;
129
130         for (i = 0; i < ds->ds_num; ++i) {
131                 /* do the magic to output the data */
132                 printf ("%s (%s) at %i: ", name,
133                                 (ds->ds->type == DS_TYPE_GAUGE) ? "GAUGE" : "COUNTER",
134                                 (int)vl->time);
135
136                 if (ds->ds->type == DS_TYPE_GAUGE)
137                         printf ("%f\n", vl->values[i].gauge);
138                 else
139                         printf ("%lld\n", vl->values[i].counter);
140         }
141         return 0;
142 } /* static int my_write (data_set_t *, value_list_t *) */
143
144 /*
145  * This function is called when plugin_log () has been used.
146  */
147 static void my_log (int severity, const char *msg)
148 {
149         printf ("LOG: %i - %s\n", severity, msg);
150         return;
151 } /* static void my_log (int, const char *) */
152
153 /*
154  * This function is called when plugin_dispatch_notification () has been used.
155  */
156 static int my_notify (const notification_t *notif)
157 {
158         char time_str[32] = "";
159         struct tm *tm = NULL;
160
161         int n = 0;
162
163         if (NULL == (tm = localtime (&notif->time)))
164                 time_str[0] = '\0';
165
166         n = strftime (time_str, 32, "%F %T", tm);
167         if (n >= 32) n = 31;
168         time_str[n] = '\0';
169
170         printf ("NOTIF (%s): %i - ", time_str, notif->severity);
171
172         if ('\0' != *notif->host)
173                 printf ("%s: ", notif->host);
174
175         if ('\0' != *notif->plugin)
176                 printf ("%s: ", notif->plugin);
177
178         if ('\0' != *notif->plugin_instance)
179                 printf ("%s: ", notif->plugin_instance);
180
181         if ('\0' != *notif->type)
182                 printf ("%s: ", notif->type);
183
184         if ('\0' != *notif->type_instance)
185                 printf ("%s: ", notif->type_instance);
186
187         printf ("%s\n", notif->message);
188         return 0;
189 } /* static int my_notify (notification_t *) */
190
191 /*
192  * This function is called before shutting down collectd.
193  */
194 static int my_shutdown (void)
195 {
196         /* close sockets, free data structures, ... */
197         return 0;
198 } /* static int my_shutdown (void) */
199
200 /*
201  * This function is called after loading the plugin to register it with
202  * collectd.
203  */
204 void module_register (void)
205 {
206         plugin_register_log ("myplugin", my_log);
207         plugin_register_notification ("myplugin", my_notify);
208         plugin_register_data_set (&ds);
209         plugin_register_read ("myplugin", my_read);
210         plugin_register_init ("myplugin", my_init);
211         plugin_register_write ("myplugin", my_write);
212         plugin_register_shutdown ("myplugin", my_shutdown);
213     return;
214 } /* void module_register (void) */
215