dotnet plugin: First stub for a .NET integration plugin using Mono.
authorFlorian Forster <octo@leeloo.lan.home.verplant.org>
Mon, 29 Nov 2010 15:30:56 +0000 (16:30 +0100)
committerFlorian Forster <octo@collectd.org>
Thu, 5 Apr 2012 08:22:02 +0000 (10:22 +0200)
configure.in
src/Makefile.am
src/dotnet.c [new file with mode: 0644]

index 2ea99cb..2f19471 100644 (file)
@@ -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
index f106fa1..f8d2a35 100644 (file)
@@ -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 (file)
index 0000000..cfc5922
--- /dev/null
@@ -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 <ff at octo.it>
+ **/
+
+#include "collectd.h"
+#include "plugin.h"
+#include "common.h"
+#include "configfile.h"
+
+#include <glib.h>
+#include <mono/jit/jit.h>
+#include <mono/metadata/assembly.h>
+
+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 */
+
+/*
+ * <Plugin dotnet>
+ *   <LoadPlugin "Foobar">
+ *     NameSpace "MyCompany"
+ *     Assembly "path/to/file.dll"
+ *   </LoadPlugin>
+ *
+ *   <Plugin "Foobar">
+ *     ...
+ *   </Plugin>
+ * </Plugin>
+ */
+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 : */