From: Florian Forster Date: Mon, 29 Nov 2010 15:30:56 +0000 (+0100) Subject: dotnet plugin: First stub for a .NET integration plugin using Mono. X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=33b2be8ebb20ffcb7d335631971c82734ea3bbee;p=collectd.git dotnet plugin: First stub for a .NET integration plugin using Mono. --- diff --git a/configure.in b/configure.in index 2ea99cb4..2f194711 100644 --- a/configure.in +++ b/configure.in @@ -4863,6 +4863,7 @@ AC_PLUGIN([dbi], [$with_libdbi], [General database statistics]) AC_PLUGIN([df], [$plugin_df], [Filesystem usage statistics]) AC_PLUGIN([disk], [$plugin_disk], [Disk usage statistics]) AC_PLUGIN([dns], [$with_libpcap], [DNS traffic analysis]) +AC_PLUGIN([dotnet], [$with_libmono], [.NET language bindings]) AC_PLUGIN([email], [yes], [EMail statistics]) AC_PLUGIN([entropy], [$plugin_entropy], [Entropy statistics]) AC_PLUGIN([ethstat], [$plugin_ethstat], [Stats from NIC driver]) @@ -5138,6 +5139,7 @@ Configuration: libkvm . . . . . . . $with_libkvm libmemcached . . . . $with_libmemcached libmodbus . . . . . . $with_libmodbus + libmono . . . . . . . $with_libmono libmysql . . . . . . $with_libmysql libnetapp . . . . . . $with_libnetapp libnetlink . . . . . $with_libnetlink @@ -5195,6 +5197,7 @@ Configuration: df . . . . . . . . . $enable_df disk . . . . . . . . $enable_disk dns . . . . . . . . . $enable_dns + dotnet . . . . . . . $enable_dotnet email . . . . . . . . $enable_email entropy . . . . . . . $enable_entropy ethstat . . . . . . . $enable_ethstat diff --git a/src/Makefile.am b/src/Makefile.am index f106fa1a..f8d2a35c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -350,6 +350,17 @@ collectd_LDADD += "-dlopen" dns.la collectd_DEPENDENCIES += dns.la endif +if BUILD_PLUGIN_DOTNET +pkglib_LTLIBRARIES += dotnet.la +dotnet_la_SOURCES = dotnet.c +dotnet_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBMONO_CPPFLAGS) +#dotnet_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBMONO_CFLAGS) +dotnet_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBMONO_LDFLAGS) +dotnet_la_LIBADD = $(BUILD_WITH_LIBMONO_LIBS) +collectd_LDADD += "-dlopen" dotnet.la +collectd_DEPENDENCIES += dotnet.la +endif + if BUILD_PLUGIN_EMAIL pkglib_LTLIBRARIES += email.la email_la_SOURCES = email.c diff --git a/src/dotnet.c b/src/dotnet.c new file mode 100644 index 00000000..cfc59229 --- /dev/null +++ b/src/dotnet.c @@ -0,0 +1,204 @@ +/** + * collectd - src/dotnet.c + * Copyright (C) 2010 Florian Forster + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Florian Forster + **/ + +#include "collectd.h" +#include "plugin.h" +#include "common.h" +#include "configfile.h" + +#include +#include +#include + +static MonoDomain *domain = NULL; + +static int dotnet_log (int severity, MonoString *message) /* {{{ */ +{ + char *tmp = mono_string_to_utf8 (message); + + DEBUG ("dotnet_log (severity = %i, message = \"%s\");", severity, tmp); + + return (0); +} /* }}} int dotnet_log */ + +static int dotnet_register_read (MonoString *name, MonoObject *obj) /* {{{ */ +{ + char *name_utf8 = mono_string_to_utf8 (name); + MonoClass *class; + MonoMethod *method; + + DEBUG ("dotnet_register_read: name = \"%s\";", name_utf8); + + class = mono_object_get_class (obj); + + method = mono_class_get_method_from_name (mono_object_get_class (obj), + /* name = */ "read", /* param count = */ 0); + if (method == NULL) + { + ERROR ("dotnet_register_read: Can't find method read():int."); + return (-1); + } + + DEBUG ("dotnet_register_read: Class %s successfully registered.", + mono_class_get_name (class)); + return (0); +} /* }}} int dotnet_register_read */ + +static int dotnet_load_class (const char *assembly_name, /* {{{ */ + const char *name_space, const char *class_name) +{ + MonoAssembly *assembly; + MonoImage *image; + MonoClass *class; + MonoObject *obj; + + assembly = mono_domain_assembly_open (domain, assembly_name); + if (assembly == NULL) + { + ERROR ("dotnet plugin: mono_domain_assembly_open (\"%s\") failed.", + assembly_name); + return (-1); + } + + image = mono_assembly_get_image (assembly); + if (image == NULL) + { + ERROR ("mono_assembly_get_image failed."); + mono_jit_cleanup (domain); + return (-1); + } + + class = mono_class_from_name (image, + (name_space != NULL) ? name_space : "", + class_name); + if (class == NULL) + { + ERROR ("dotnet plugin: Looking up class \"%s\" in assembly \"%s\" failed.", + class_name, assembly_name); + return (-1); + } + + obj = mono_object_new (domain, class); + if (obj == NULL) + { + ERROR ("Creating a \"%s\" object failed.", class_name); + return (-1); + } + + mono_runtime_object_init (obj); + + DEBUG ("dotnet plugin: Successfully created a \"%s\" object.", class_name); + + return (0); +} /* }}} int dotnet_load_class */ + +/* + * + * + * NameSpace "MyCompany" + * Assembly "path/to/file.dll" + * + * + * + * ... + * + * + */ +static int dotnet_config_loadplugin (oconfig_item_t *ci) /* {{{ */ +{ + char *class_name = NULL; + char *name_space = NULL; + char *assembly_name = NULL; + int status; + int i; + + status = cf_util_get_string (ci, &class_name); + if (status != 0) + return (status); + assert (class_name != NULL); + + for (i = 0; i < ci->children_num; i++) + { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp ("NameSpace", child->key) == 0) + cf_util_get_string (child, &name_space); + else if (strcasecmp ("Assembly", child->key) == 0) + cf_util_get_string (child, &assembly_name); + else + WARNING ("dotnet plugin: Config option \"%s\" is not allowed here.", + child->key); + } + + if (assembly_name == NULL) + { + ERROR ("dotnet plugin: No \"Assembly\" option within this \"LoadPlugin\" " + "block (class \"%s\").", class_name); + sfree (class_name); + sfree (name_space); + } + + status = dotnet_load_class (assembly_name, name_space, class_name); + if (status != 0) + return (status); + + return (0); +} /* }}} int dotnet_config_loadplugin */ + +static int dotnet_config (oconfig_item_t *ci) /* {{{ */ +{ + int i; + + for (i = 0; i < ci->children_num; i++) + { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp ("LoadPlugin", child->key) == 0) + dotnet_config_loadplugin (child); + else + WARNING ("dotnet plugin: Ignoring unknown config option \"%s\".", + child->key); + } + + return (0); +} /* }}} int dotnet_config */ + +void module_register (void) +{ + domain = mono_jit_init (PACKAGE_NAME); + if (domain == NULL) + { + ERROR ("dotnet plugin: mono_jit_init failed."); + return; + } + + mono_add_internal_call ("CollectdAPI.Collectd::log", dotnet_log); + mono_add_internal_call ("CollectdAPI.Collectd::registerRead", dotnet_register_read); + + plugin_register_complex_config ("dotnet", dotnet_config); +} /* void module_register */ + +/* vim: set sw=2 sts=2 et fdm=marker : */