6574330412417dee9de23b98715fc9ba4882eafe
1 /*
2 * SysDB - src/include/core/plugin.h
3 * Copyright (C) 2012 Sebastian 'tokkee' Harl <sh@tokkee.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
28 #ifndef SDB_CORE_PLUGIN_H
29 #define SDB_CORE_PLUGIN_H 1
31 #include "sysdb.h"
32 #include "core/object.h"
33 #include "core/store.h"
34 #include "core/time.h"
35 #include "core/timeseries.h"
37 #include "liboconfig/oconfig.h"
39 #include <stdarg.h>
40 #include <stdbool.h>
42 #ifdef __cplusplus
43 extern "C" {
44 #endif
46 typedef struct {
47 sdb_time_t interval;
48 } sdb_plugin_ctx_t;
49 #define SDB_PLUGIN_CTX_INIT { 0 }
51 typedef struct {
52 char *plugin_name;
53 char *filename;
55 /* public attributes */
56 char *description;
57 char *copyright;
58 char *license;
60 int version;
61 int plugin_version;
62 } sdb_plugin_info_t;
63 #define SDB_PLUGIN_INFO_INIT { \
64 /* plugin_name */ NULL, /* filename */ NULL, /* desc */ NULL, \
65 /* copyright */ NULL, /* license */ NULL, \
66 /* version */ -1, /* plugin_version */ -1 }
68 /* this should be used in the header of a plugin to avoid
69 * missing prototype warnings/errors for the plugin init
70 * function */
71 #define SDB_PLUGIN_MAGIC \
72 int sdb_module_init(sdb_plugin_info_t *info)
74 typedef struct {
75 bool do_loop;
76 sdb_time_t default_interval;
77 } sdb_plugin_loop_t;
78 #define SDB_PLUGIN_LOOP_INIT { 1, 0 }
80 /*
81 * sdb_plugin_load:
82 * Load (any type of) plugin by loading the shared object file and calling the
83 * sdb_module_init function. If specified, 'plugin_ctx' fine-tunes the
84 * behavior of the plugin. If specified, the plugin will be looked up in
85 * 'basedir', else it defaults to the package libdir.
86 */
87 int
88 sdb_plugin_load(const char *basedir, const char *name,
89 const sdb_plugin_ctx_t *plugin_ctx);
91 /*
92 * sdb_plugin_set_info:
93 * Fill in the fields of the sdb_plugin_info_t object passed to the
94 * sdb_module_init function. This information is used to identify the plugin
95 * and also to provide additional information to the user.
96 */
97 enum {
98 SDB_PLUGIN_INFO_DESC, /* plugin description: string */
99 SDB_PLUGIN_INFO_COPYRIGHT, /* plugin copyright: string */
100 SDB_PLUGIN_INFO_LICENSE, /* plugin license: string */
101 SDB_PLUGIN_INFO_VERSION, /* libsysdb version: integer */
102 SDB_PLUGIN_INFO_PLUGIN_VERSION /* plugin version: integer */
103 };
105 int
106 sdb_plugin_set_info(sdb_plugin_info_t *info, int type, ...);
108 /*
109 * plugin callback functions:
110 * See the description of the respective register function for what arguments
111 * the callbacks expect.
112 *
113 * The specified name of callback functions is prepended with the plugin name
114 * before being registered with the core.
115 */
117 typedef int (*sdb_plugin_config_cb)(oconfig_item_t *ci);
118 typedef int (*sdb_plugin_init_cb)(sdb_object_t *user_data);
119 typedef int (*sdb_plugin_collector_cb)(sdb_object_t *user_data);
120 typedef char *(*sdb_plugin_cname_cb)(const char *name,
121 sdb_object_t *user_data);
122 typedef int (*sdb_plugin_shutdown_cb)(sdb_object_t *user_data);
123 typedef int (*sdb_plugin_log_cb)(int prio, const char *msg,
124 sdb_object_t *user_data);
126 /*
127 * sdb_plugin_register_config:
128 * Register a "config" function. This will be used to pass on the
129 * configuration for a plugin. The plugin has to make sure that the function
130 * can be called multiple times in order to process multiple <Plugin> blocks
131 * specified in the configuration file(s).
132 *
133 * Returns:
134 * - 0 on success
135 * - a negative value else
136 */
137 int
138 sdb_plugin_register_config(sdb_plugin_config_cb callback);
140 /*
141 * sdb_plugin_register_init:
142 * Register an "init" function. All "init" functions will be called after
143 * finishing the config parsing and before starting any other work. The
144 * functions will be called in the same order as they have been registered,
145 * that is, functions of different plugins will be called in the same order as
146 * the appropriate "Load" statements in the config file.
147 *
148 * If the "init" function returns a non-zero value, *all* callbacks of the
149 * plugin will be unloaded.
150 *
151 * Arguments:
152 * - user_data: If specified, this will be passed on to each call of the
153 * callback. The function will take ownership of the object, that is,
154 * increment the reference count by one. In case the caller does not longer
155 * use the object for other purposes, it should thus deref it.
156 *
157 * Returns:
158 * - 0 on success
159 * - a negative value else
160 */
161 int
162 sdb_plugin_register_init(const char *name, sdb_plugin_init_cb callback,
163 sdb_object_t *user_data);
165 /*
166 * sdb_plugin_register_collector:
167 * Register a "collector" function. This is where a backend is doing its main
168 * work. This function will be called whenever an update of a backend has been
169 * requested (either by regular interval or by user request). The backend
170 * should then query the appropriate data-source and submit all values to the
171 * core.
172 *
173 * Arguments:
174 * - interval: Specifies the regular interval at which to update the backend.
175 * If this is NULL, global settings will be used.
176 * - user_data: If specified, this will be passed on to each call of the
177 * callback. The function will take ownership of the object, that is,
178 * increment the reference count by one. In case the caller does not longer
179 * use the object for other purposes, it should thus deref it.
180 *
181 * Returns:
182 * - 0 on success
183 * - a negative value else
184 */
185 int
186 sdb_plugin_register_collector(const char *name,
187 sdb_plugin_collector_cb callback,
188 const sdb_time_t *interval, sdb_object_t *user_data);
190 /*
191 * sdb_plugin_register_cname:
192 * Register a "cname" (canonicalize name) function. This type of function is
193 * called whenever a host is stored. It accepts the hostname and returns a
194 * canonicalized hostname which will then be used to actually store the host.
195 * If multiple such callbacks are registered, each one of them will be called
196 * in the order they have been registered, each one receiving the result of
197 * the previous callback. If the function returns NULL, the original hostname
198 * is not changed. Any other value has to be dynamically allocated. It will be
199 * freed later on by the core.
200 *
201 * Returns:
202 * - 0 on success
203 * - a negative value else
204 */
205 int
206 sdb_plugin_register_cname(const char *name, sdb_plugin_cname_cb callback,
207 sdb_object_t *user_data);
209 /*
210 * sdb_plugin_register_shutdown:
211 * Register a "shutdown" function to be called after stopping all update
212 * processes and before shutting down the daemon.
213 *
214 * Arguments:
215 * - user_data: If specified, this will be passed on to each call of the
216 * callback. The function will take ownership of the object, that is,
217 * increment the reference count by one. In case the caller does not longer
218 * use the object for other purposes, it should thus deref it.
219 */
220 int
221 sdb_plugin_register_shutdown(const char *name,
222 sdb_plugin_shutdown_cb callback,
223 sdb_object_t *user_data);
225 /*
226 * sdb_plugin_register_log:
227 * Register a "log" function to be called whenever logging is to be done.
228 *
229 * Arguments:
230 * - user_data: If specified, this will be passed on to each call of the
231 * callback. The function will take ownership of the object, that is,
232 * increment the reference count by one. In case the caller does not longer
233 * use the object for other purposes, it should thus deref it.
234 */
235 int
236 sdb_plugin_register_log(const char *name, sdb_plugin_log_cb callback,
237 sdb_object_t *user_data);
239 /*
240 * sdb_plugin_register_timeseries_fetcher:
241 * Register a "time-series fetcher" to be called whenever retrieving a
242 * time-series from a data-store or information about it. The fetch callback
243 * will receive an identifier describing where to retrieve the data from (e.g.
244 * a filename or some kind of URL) and options which further describe the
245 * query.
246 *
247 * The name is used literally (without prepending the plugin name) to look up
248 * the appropriate fetcher callback.
249 *
250 * Arguments:
251 * - user_data: If specified, this will be passed on to each call of the
252 * callback. The function will take ownership of the object, that is,
253 * increment the reference count by one. In case the caller does not longer
254 * use the object for other purposes, it should thus deref it.
255 */
256 int
257 sdb_plugin_register_timeseries_fetcher(const char *name,
258 sdb_timeseries_fetcher_t *fetcher, sdb_object_t *user_data);
260 /*
261 * sdb_plugin_register_writer:
262 * Register a "writer" implementation to be used when adding an object to the
263 * store. It is invalid to register an incomplete writer which does not
264 * implement all of the writer interface.
265 *
266 * Arguments:
267 * - user_data: If specified, this will be passed on to each call of the
268 * callbacks. The function will take ownership of the object, that is,
269 * increment the reference count by one. In case the caller does not longer
270 * use the object for other purposes, it should thus deref it.
271 */
272 int
273 sdb_plugin_register_writer(const char *name,
274 sdb_store_writer_t *writer, sdb_object_t *user_data);
276 /*
277 * sdb_plugin_register_reader:
278 * Register a "reader" implementation for querying the store. It is invalid to
279 * register an incomplete reader which does not implement all of the reader
280 * interface.
281 *
282 * Arguments:
283 * - user_data: If specified, this will be passed on to each call of the
284 * callbacks. The function will take ownership of the object, that is,
285 * increment the reference count by one. In case the caller does not longer
286 * use the object for other purposes, it should thus deref it.
287 */
288 int
289 sdb_plugin_register_reader(const char *name,
290 sdb_store_reader_t *reader, sdb_object_t *user_data);
292 /*
293 * sdb_plugin_unregister_all:
294 * Unregister all registered plugins and destruct their user-data objects.
295 */
296 void
297 sdb_plugin_unregister_all(void);
299 /*
300 * sdb_plugin_get_ctx, sdb_plugin_set_ctx:
301 * The plugin context defines a set of settings that are available whenever a
302 * plugin has been called. It may be used to pass around various information
303 * between the different component of the library without having each and
304 * every plugin care about it.
305 *
306 * If non-NULL, sdb_plugin_set_ctx stores the previous context in the location
307 * pointed to by 'old'.
308 */
309 sdb_plugin_ctx_t
310 sdb_plugin_get_ctx(void);
311 int
312 sdb_plugin_set_ctx(sdb_plugin_ctx_t ctx, sdb_plugin_ctx_t *old);
314 /*
315 * sdb_plugin_current:
316 * Retrieve information about the plugin (if any) from which the current call
317 * into the core originated. The return value may not be modified.
318 *
319 * Returns:
320 * - information about the current plugin if we were called from some
321 * plugin's callback function
322 * - NULL else
323 */
324 const sdb_plugin_info_t *
325 sdb_plugin_current(void);
327 /*
328 * sdb_plugin_configure:
329 * Configure the plugin called 'name' using the config tree 'ci'. The plugin
330 * name is the same as the one used when loading the plugin.
331 *
332 * Returns:
333 * - 0 on success
334 * - a negative value else
335 */
336 int
337 sdb_plugin_configure(const char *name, oconfig_item_t *ci);
339 /*
340 * sdb_plugin_reconfigure_init, sdb_plugin_reconfigure_finish:
341 * Reconfigure all plugins. This happens in multiple steps: first, call
342 * sdb_plugin_reconfigure_init to deconfigure all plugins by calling their
343 * config callbacks with a NULL config tree and unregistering all callbacks.
344 * Then, sdb_plugin_configure and other functions may be used to provide the
345 * new configuration or load new plugins. For all plugins which were already
346 * loaded before, sdb_module_init will be called with a NULL argument when
347 * reloading them.
348 * Finally, sdb_plugin_reconfigure_finish will clean up leftover pieces, like
349 * unloading plugins which are no longer in use.
350 *
351 * Returns:
352 * - 0 on success
353 * - a negative value else
354 */
355 int
356 sdb_plugin_reconfigure_init(void);
357 int
358 sdb_plugin_reconfigure_finish(void);
360 /*
361 * sdb_plugin_init_all:
362 * Initialize all plugins using their registered "init" function.
363 *
364 * Returns:
365 * The number of failed initializations.
366 */
367 int
368 sdb_plugin_init_all(void);
370 /*
371 * sdb_plugin_shutdown_all:
372 * Shutdown all plugins using their registered "shutdown" function.
373 *
374 * Returns:
375 * The number of failed shutdowns.
376 */
377 int
378 sdb_plugin_shutdown_all(void);
380 /*
381 * sdb_plugin_collector_loop:
382 * Loop until loop->do_loop is false, calling the next collector function on
383 * each iteration and once its next update interval is passed.
384 *
385 * Returns:
386 * - 0 on success
387 * - a negative value else
388 */
389 int
390 sdb_plugin_collector_loop(sdb_plugin_loop_t *loop);
392 /*
393 * sdb_plugin_cname:
394 * Returns the canonicalized hostname. The given hostname argument has to
395 * point to dynamically allocated memory and might be freed by the function.
396 * The return value will also be dynamically allocated (but it might be
397 * unchanged) and has to be freed by the caller.
398 */
399 char *
400 sdb_plugin_cname(char *hostname);
402 /*
403 * sdb_plugin_log:
404 * Log the specified message using all registered log callbacks. The message
405 * will be logged with the specified priority.
406 */
407 int
408 sdb_plugin_log(int prio, const char *msg);
410 /*
411 * sdb_plugin_logf:
412 * Log a formatted message. See sdb_plugin_log for more information.
413 */
414 int
415 sdb_plugin_vlogf(int prio, const char *fmt, va_list ap)
416 __attribute__((format(printf, 2, 0)));
417 int
418 sdb_plugin_logf(int prio, const char *fmt, ...)
419 __attribute__((format(printf, 2, 3)));
421 /*
422 * sdb_plugin_fetch_timeseries:
423 * Fetch the time-series identified by 'id' from a backend data-store of the
424 * specified 'type'. The type has to match an existing time-series fetcher
425 * callback's name. The identifier is passed through to the callback which
426 * then needs to make sense of it. The time-series option specify which data
427 * to fetch.
428 *
429 * Returns:
430 * - a time-series on success
431 * - NULL else
432 */
433 sdb_timeseries_t *
434 sdb_plugin_fetch_timeseries(const char *type, const char *id,
435 sdb_timeseries_opts_t *opts);
437 /*
438 * sdb_plugin_describe_timeseries:
439 * Fetch information about the time-series identified by 'id' from a backend
440 * data-store of the specified 'type'. The type has to match an existing
441 * time-series fetcher callback's name. The identifier is passed through to
442 * the callback which then needs to make sense of it.
443 *
444 * Returns:
445 * - a time-series information object on success
446 * - NULL else
447 */
448 sdb_timeseries_info_t *
449 sdb_plugin_describe_timeseries(const char *type, const char *id);
451 /*
452 * sdb_plugin_query:
453 * Query the store using the query specified by 'ast'. The result will be
454 * written to 'buf' and any errors will be written to 'errbuf'.
455 *
456 * Returns:
457 * - 0 on success
458 * - a negative value else
459 */
460 int
461 sdb_plugin_query(sdb_ast_node_t *ast,
462 sdb_store_writer_t *w, sdb_object_t *wd, sdb_strbuf_t *errbuf);
464 /*
465 * sdb_plugin_store_host, sdb_plugin_store_service, sdb_plugin_store_metric,
466 * sdb_plugin_store_attribute, sdb_plugin_store_service_attribute,
467 * sdb_plugin_store_metric_attribute:
468 * Store an object in the database by sending it to all registered store
469 * writer plugins.
470 *
471 * Returns:
472 * - 0 on success
473 * - a negative value else
474 */
475 int
476 sdb_plugin_store_host(const char *name, sdb_time_t last_update);
477 int
478 sdb_plugin_store_service(const char *hostname, const char *name,
479 sdb_time_t last_update);
480 int
481 sdb_plugin_store_metric(const char *hostname, const char *name,
482 sdb_metric_store_t *store, sdb_time_t last_update);
483 int
484 sdb_plugin_store_attribute(const char *hostname, const char *key,
485 const sdb_data_t *value, sdb_time_t last_update);
486 int
487 sdb_plugin_store_service_attribute(const char *hostname, const char *service,
488 const char *key, const sdb_data_t *value, sdb_time_t last_update);
489 int
490 sdb_plugin_store_metric_attribute(const char *hostname, const char *metric,
491 const char *key, const sdb_data_t *value, sdb_time_t last_update);
493 #ifdef __cplusplus
494 } /* extern "C" */
495 #endif
497 #endif /* ! SDB_CORE_PLUGIN_H */
499 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */