2 * /usr/share/doc/collectd/examples/myplugin.c
4 * A plugin template for collectd.
6 * Written by Sebastian Harl <sh@tokkee.org>
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.
15 * - plugins are executed in parallel, thus, thread-safe
16 * functions need to be used
17 * - each of the functions below (except module_register)
27 #ifndef __USE_ISOC99 /* required for NAN */
28 # define DISABLE_ISOC99 1
29 # define __USE_ISOC99 1
30 #endif /* !defined(__USE_ISOC99) */
33 # undef DISABLE_ISOC99
35 #endif /* DISABLE_ISOC99 */
39 #endif /* ! HAVE_CONFIG */
41 #include <collectd/collectd.h>
43 #include <collectd/common.h>
44 #include <collectd/plugin.h>
47 * data source definition:
48 * - name of the data source
49 * - type of the data source (DS_TYPE_GAUGE, DS_TYPE_COUNTER)
50 * - minimum allowed value
51 * - maximum allowed value
53 static data_source_t dsrc[1] =
55 { "my_ds", DS_TYPE_GAUGE, 0, NAN }
59 * data set definition:
60 * - name of the data set
61 * - number of data sources
62 * - list of data sources
64 * NOTE: If you're defining a custom data-set, you have to make that known to
65 * any servers as well. Else, the server is not able to store values using the
66 * type defined by that data-set.
67 * It is strongly recommended to use one of the types and data-sets
68 * pre-defined in the types.db file.
70 static data_set_t ds =
72 "myplugin", STATIC_ARRAY_SIZE (dsrc), dsrc
76 * This function is called once upon startup to initialize the plugin.
78 static int my_init (void)
80 /* open sockets, initialize data structures, ... */
82 /* A return value != 0 indicates an error and causes the plugin to be
85 } /* static int my_init (void) */
88 * This is a utility function used by the read callback to populate a
89 * value_list_t and pass it to plugin_dispatch_values.
91 static int my_submit (gauge_t value)
93 value_list_t vl = VALUE_LIST_INIT;
95 /* Convert the gauge_t to a value_t and add it to the value_list_t. */
96 vl.values = &(value_t) { .gauge = value };
99 /* Only set vl.time yourself if you update multiple metrics (i.e. you
100 * have multiple calls to plugin_dispatch_values()) and they need to all
101 * have the same timestamp. */
102 /* vl.time = cdtime(); */
104 sstrncpy (vl.plugin, "myplugin", sizeof (vl.plugin));
106 /* it is strongly recommended to use a type defined in the types.db file
107 * instead of a custom type */
108 sstrncpy (vl.type, "myplugin", sizeof (vl.type));
109 /* optionally set vl.plugin_instance and vl.type_instance to reasonable
110 * values (default: "") */
112 /* dispatch the values to collectd which passes them on to all registered
114 return plugin_dispatch_values (&vl);
118 * This function is called in regular intervalls to collect the data.
120 static int my_read (void)
122 /* do the magic to read the data */
123 gauge_t value = random ();
125 if (my_submit (value) != 0)
126 WARNING ("myplugin plugin: Dispatching a random value failed.");
128 /* A return value != 0 indicates an error and the plugin will be skipped
129 * for an increasing amount of time. */
131 } /* static int my_read (void) */
134 * This function is called after values have been dispatched to collectd.
136 static int my_write (const data_set_t *ds, const value_list_t *vl,
139 char name[1024] = "";
142 if (ds->ds_num != vl->values_len) {
143 plugin_log (LOG_WARNING, "DS number does not match values length");
147 /* get the default base filename for the output file - depending on the
148 * provided values this will be something like
149 * <host>/<plugin>[-<plugin_type>]/<instance>[-<instance_type>] */
150 if (0 != format_name (name, 1024, vl->host, vl->plugin,
151 vl->plugin_instance, ds->type, vl->type_instance))
154 for (i = 0; i < ds->ds_num; ++i) {
155 /* do the magic to output the data */
156 printf ("%s (%s) at %i: ", name,
157 (ds->ds->type == DS_TYPE_GAUGE) ? "GAUGE" : "COUNTER",
160 if (ds->ds->type == DS_TYPE_GAUGE)
161 printf ("%f\n", vl->values[i].gauge);
163 printf ("%lld\n", vl->values[i].counter);
166 } /* static int my_write (data_set_t *, value_list_t *) */
169 * This function is called when plugin_log () has been used.
171 static void my_log (int severity, const char *msg, user_data_t *ud)
173 printf ("LOG: %i - %s\n", severity, msg);
175 } /* static void my_log (int, const char *) */
178 * This function is called when plugin_dispatch_notification () has been used.
180 static int my_notify (const notification_t *notif, user_data_t *ud)
182 char time_str[32] = "";
183 struct tm *tm = NULL;
187 if (NULL == (tm = localtime (¬if->time)))
190 n = strftime (time_str, 32, "%F %T", tm);
194 printf ("NOTIF (%s): %i - ", time_str, notif->severity);
196 if ('\0' != *notif->host)
197 printf ("%s: ", notif->host);
199 if ('\0' != *notif->plugin)
200 printf ("%s: ", notif->plugin);
202 if ('\0' != *notif->plugin_instance)
203 printf ("%s: ", notif->plugin_instance);
205 if ('\0' != *notif->type)
206 printf ("%s: ", notif->type);
208 if ('\0' != *notif->type_instance)
209 printf ("%s: ", notif->type_instance);
211 printf ("%s\n", notif->message);
213 } /* static int my_notify (notification_t *) */
216 * This function is called before shutting down collectd.
218 static int my_shutdown (void)
220 /* close sockets, free data structures, ... */
222 } /* static int my_shutdown (void) */
225 * This function is called after loading the plugin to register it with
228 void module_register (void)
230 plugin_register_log ("myplugin", my_log, /* user data */ NULL);
231 plugin_register_notification ("myplugin", my_notify,
232 /* user data */ NULL);
233 plugin_register_data_set (&ds);
234 plugin_register_read ("myplugin", my_read);
235 plugin_register_init ("myplugin", my_init);
236 plugin_register_write ("myplugin", my_write, /* user data */ NULL);
237 plugin_register_shutdown ("myplugin", my_shutdown);
239 } /* void module_register (void) */