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 */
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 */
21 #if ! HAVE_CONFIG_H
23 #include <stdlib.h>
25 #include <string.h>
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 */
37 #include <time.h>
39 #endif /* ! HAVE_CONFIG */
41 #include <collectd/collectd.h>
42 #include <collectd/common.h>
43 #include <collectd/plugin.h>
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 };
57 /*
58 * data set definition:
59 * - name of the data set
60 * - number of data sources
61 * - list of data sources
62 *
63 * NOTE: If you're defining a custom data-set, you have to make that known to
64 * any servers as well. Else, the server is not able to store values using the
65 * type defined by that data-set.
66 * It is strongly recommended to use one of the types and data-sets
67 * pre-defined in the types.db file.
68 */
69 static data_set_t ds =
70 {
71 "myplugin", STATIC_ARRAY_SIZE (dsrc), dsrc
72 };
74 /*
75 * This function is called once upon startup to initialize the plugin.
76 */
77 static int my_init (void)
78 {
79 /* open sockets, initialize data structures, ... */
81 /* A return value != 0 indicates an error and causes the plugin to be
82 disabled. */
83 return 0;
84 } /* static int my_init (void) */
86 /*
87 * This function is called in regular intervalls to collect the data.
88 */
89 static int my_read (void)
90 {
91 value_t values[1]; /* the size of this list should equal the number of
92 data sources */
93 value_list_t vl = VALUE_LIST_INIT;
95 /* do the magic to read the data */
96 values[0].gauge = random ();
98 vl.values = values;
99 vl.values_len = 1;
100 vl.time = time (NULL);
101 sstrncpy (vl.host, hostname_g, sizeof (vl.host));
102 sstrncpy (vl.plugin, "myplugin", sizeof (vl.plugin));
104 /* it is strongly recommended to use a type defined in the types.db file
105 * instead of a custom type */
106 sstrncpy (vl.type, "myplugin", sizeof (vl.plugin));
107 /* optionally set vl.plugin_instance and vl.type_instance to reasonable
108 * values (default: "") */
110 /* dispatch the values to collectd which passes them on to all registered
111 * write functions */
112 plugin_dispatch_values (&vl);
114 /* A return value != 0 indicates an error and the plugin will be skipped
115 * for an increasing amount of time. */
116 return 0;
117 } /* static int my_read (void) */
119 /*
120 * This function is called after values have been dispatched to collectd.
121 */
122 static int my_write (const data_set_t *ds, const value_list_t *vl,
123 user_data_t *ud)
124 {
125 char name[1024] = "";
126 int i = 0;
128 if (ds->ds_num != vl->values_len) {
129 plugin_log (LOG_WARNING, "DS number does not match values length");
130 return -1;
131 }
133 /* get the default base filename for the output file - depending on the
134 * provided values this will be something like
135 * <host>/<plugin>[-<plugin_type>]/<instance>[-<instance_type>] */
136 if (0 != format_name (name, 1024, vl->host, vl->plugin,
137 vl->plugin_instance, ds->type, vl->type_instance))
138 return -1;
140 for (i = 0; i < ds->ds_num; ++i) {
141 /* do the magic to output the data */
142 printf ("%s (%s) at %i: ", name,
143 (ds->ds->type == DS_TYPE_GAUGE) ? "GAUGE" : "COUNTER",
144 (int)vl->time);
146 if (ds->ds->type == DS_TYPE_GAUGE)
147 printf ("%f\n", vl->values[i].gauge);
148 else
149 printf ("%lld\n", vl->values[i].counter);
150 }
151 return 0;
152 } /* static int my_write (data_set_t *, value_list_t *) */
154 /*
155 * This function is called when plugin_log () has been used.
156 */
157 static void my_log (int severity, const char *msg, user_data_t *ud)
158 {
159 printf ("LOG: %i - %s\n", severity, msg);
160 return;
161 } /* static void my_log (int, const char *) */
163 /*
164 * This function is called when plugin_dispatch_notification () has been used.
165 */
166 static int my_notify (const notification_t *notif, user_data_t *ud)
167 {
168 char time_str[32] = "";
169 struct tm *tm = NULL;
171 int n = 0;
173 if (NULL == (tm = localtime (¬if->time)))
174 time_str[0] = '\0';
176 n = strftime (time_str, 32, "%F %T", tm);
177 if (n >= 32) n = 31;
178 time_str[n] = '\0';
180 printf ("NOTIF (%s): %i - ", time_str, notif->severity);
182 if ('\0' != *notif->host)
183 printf ("%s: ", notif->host);
185 if ('\0' != *notif->plugin)
186 printf ("%s: ", notif->plugin);
188 if ('\0' != *notif->plugin_instance)
189 printf ("%s: ", notif->plugin_instance);
191 if ('\0' != *notif->type)
192 printf ("%s: ", notif->type);
194 if ('\0' != *notif->type_instance)
195 printf ("%s: ", notif->type_instance);
197 printf ("%s\n", notif->message);
198 return 0;
199 } /* static int my_notify (notification_t *) */
201 /*
202 * This function is called before shutting down collectd.
203 */
204 static int my_shutdown (void)
205 {
206 /* close sockets, free data structures, ... */
207 return 0;
208 } /* static int my_shutdown (void) */
210 /*
211 * This function is called after loading the plugin to register it with
212 * collectd.
213 */
214 void module_register (void)
215 {
216 plugin_register_log ("myplugin", my_log, /* user data */ NULL);
217 plugin_register_notification ("myplugin", my_notify,
218 /* user data */ NULL);
219 plugin_register_data_set (&ds);
220 plugin_register_read ("myplugin", my_read);
221 plugin_register_init ("myplugin", my_init);
222 plugin_register_write ("myplugin", my_write, /* user data */ NULL);
223 plugin_register_shutdown ("myplugin", my_shutdown);
224 return;
225 } /* void module_register (void) */