{
public delegate int CollectdInitCallback ();
public delegate int CollectdReadCallback ();
+ public delegate int CollectdWriteCallback (ValueList vl);
public interface IValue /* {{{ */
{
this._time = 0.0;
}
+ internal ValueList (value_data_s vd,
+ int values_len, value_u[] values, int[] values_types)
+ :base (vd.host,
+ vd.plugin, vd.plugin_instance,
+ vd.type, vd.type_instance)
+ {
+ this._time = vd.time;
+ this._interval = vd.interval;
+
+ this._values = new ArrayList (values_len);
+ for (int i = 0; i < values_len; i++)
+ {
+ IValue iv;
+
+ if (values_types[i] == Collectd.DS_TYPE_GAUGE)
+ iv = new GaugeValue (values[i].gauge);
+ else
+ iv = new DeriveValue (values[i].derive);
+
+ this._values.Insert (i, iv);
+ }
+ }
+
public ValueList (ValueList vl)
:base (vl)
{
} /* }}} struct value_u */
[StructLayout (LayoutKind.Sequential)]
- struct value_list_s /* {{{ */
+ struct value_data_s /* {{{ */
{
- public value_u[] values;
- public int values_num;
public double time;
public double interval;
[MarshalAs(UnmanagedType.LPStr)]
[MarshalAs(UnmanagedType.LPStr)]
public string type_instance;
- public value_list_s (ValueList vl)
+ /* Create a value_data_s structure from a ValueList object */
+ public value_data_s (ValueList vl)
{
- IList values = vl.GetValues ();
-
- this.values_num = values.Count;
- this.values = new value_u[this.values_num];
- for (int i = 0; i < values.Count; i++)
- {
- IValue v = values[i] as IValue;
-
- if (v is GaugeValue)
- this.values[i].gauge = v.ToDouble ();
- else
- this.values[i].derive = v.ToLong ();
- }
this.time = vl.Time;
this.interval = vl.Interval;
this.type = vl.Type;
this.type_instance = vl.TypeInstance;
}
- } /* }}} struct value_list_s */
+ } /* }}} struct value_data_s */
+
+ internal class WriteMarshaler /* {{{ */
+ {
+ private CollectdWriteCallback _func;
+
+ public WriteMarshaler (CollectdWriteCallback func)
+ {
+ this._func = func;
+ }
+
+ public int invoke (value_data_s vd,
+ int values_len, value_u[] values, int[] values_types)
+ {
+ return (this._func (new ValueList (vd, values_len, values, values_types)));
+ }
+ } /* }}} class WriteMarshaler */
/// <summary>
/// This is the main class for interacting with collectd.
/// </remarks>
public class Collectd /* {{{ */
{
- private static Hashtable _readFunctions = new Hashtable ();
private static Hashtable _initFunctions = new Hashtable ();
+ private static Hashtable _readFunctions = new Hashtable ();
+ private static Hashtable _writeFunctions = new Hashtable ();
+
+ private delegate int MarshaledWriteCallback (value_data_s vd,
+ int values_len,
+ [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] value_u[] values,
+ [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] int[] values_types);
+
+ /* Const membes are static by default, so we're not allowed to specify that
+ * again. */
+ public const int DS_TYPE_COUNTER = 0;
+ public const int DS_TYPE_GAUGE = 1;
+ public const int DS_TYPE_DERIVE = 2;
+ public const int DS_TYPE_ABSOLUTE = 3;
[DllImport("__Internal", EntryPoint="plugin_log")]
private extern static int _log (
[MarshalAs(UnmanagedType.LPStr)] string name,
CollectdReadCallback func);
+ [DllImport("__Internal", EntryPoint="dotnet_register_write")]
+ private extern static int _registerWrite (
+ [MarshalAs(UnmanagedType.LPStr)] string name,
+ MarshaledWriteCallback func);
+
[DllImport("__Internal", EntryPoint="dotnet_dispatch_values")]
- private extern static int _dispatchValues (value_list_s vl);
+ private extern static int _dispatchValues (ref value_data_s vd,
+ int values_len,
+ /* [MarshalAs(UnmanagedType.LPArray)] */ value_u[] values
+ );
/// <summary>Logs an error message.</summary>
/// <remarks>Do not include a newline at the end.</remarks>
return (_registerRead (name, func));
}
+ public static int RegisterWrite (string name, CollectdWriteCallback func)
+ {
+ WriteMarshaler marshaler = new WriteMarshaler (func);
+
+ /* Keep a copy of the object so it isn't garbage collected */
+ if (_writeFunctions.Contains (name))
+ return (-1);
+ _writeFunctions.Add (name, marshaler);
+
+ return (_registerWrite (name, new MarshaledWriteCallback (marshaler.invoke)));
+ }
+
/// <summary>Dispatches a <code>ValueList</code> to the daemon.</summary>
public static int DispatchValues (ValueList vl)
{
- return (_dispatchValues (new value_list_s (vl)));
+ IList list = vl.GetValues ();
+ value_data_s vd = new value_data_s (vl);
+ int values_len = list.Count;
+ value_u[] values = new value_u[values_len];
+
+ for (int i = 0; i < values_len; i++)
+ {
+ IValue v = list[i] as IValue;
+
+ if (v is GaugeValue)
+ values[i].gauge = v.ToDouble ();
+ else
+ values[i].derive = v.ToLong ();
+ }
+
+ return (_dispatchValues (ref vd, values_len, values));
}
} /* }}} class Collectd */
}
struct dotnet_value_list_s
{
- value_t *values;
- int values_len;
double time;
double interval;
- char *host;
- char *plugin;
- char *plugin_instance;
- char *type;
- char *type_instance;
+ const char *host;
+ const char *plugin;
+ const char *plugin_instance;
+ const char *type;
+ const char *type_instance;
};
-typedef struct dotnet_value_list_s dotnet_value_list_t;
+typedef struct dotnet_value_list_s dotnet_value_data_t;
#define CB_TYPE_INIT 2
struct dotnet_callback_info_s;
};
typedef int (*dotnet_read_cb) (void);
+typedef int (*dotnet_write_cb) (dotnet_value_data_t *vd,
+ int values_len, value_t *values, int *values_types);
static MonoDomain *_domain = NULL;
static dotnet_callback_info_t *callback_list = NULL;
return ((*cb) ());
} /* }}} int dotnet_read */
+static int dotnet_write (const data_set_t *ds, const value_list_t *vl, /* {{{ */
+ user_data_t *ud)
+{
+ dotnet_write_cb cb = ud->data;
+ dotnet_value_data_t vd;
+ int values_types[vl->values_len];
+ int status;
+ int i;
+
+ DEBUG ("dotnet plugin: dotnet_write ();");
+
+ memset (&vd, 0, sizeof (vd));
+ vd.time = CDTIME_T_TO_DOUBLE (vl->time);
+ vd.interval = CDTIME_T_TO_DOUBLE (vl->interval);
+ vd.host = vl->host;
+ vd.plugin = vl->plugin;
+ vd.plugin_instance = vl->plugin_instance;
+ vd.type = vl->type;
+ vd.type_instance = vl->type_instance;
+
+ for (i = 0; i < ds->ds_num; i++)
+ values_types[i] = ds->ds[i].type;
+
+ status = (*cb) (&vd, vl->values_len, vl->values, values_types);
+ return (status);
+} /* }}} int dotnet_write */
+
/*
* Functions exposed to .Net
*/
return (0);
} /* }}} int dotnet_register_read */
-int dotnet_dispatch_values (dotnet_value_list_t *dvl) /* {{{ */
+int dotnet_register_write (const char *name, dotnet_write_cb cb) /* {{{ */
+{
+ user_data_t ud;
+
+ DEBUG ("dotnet plugin: dotnet_register_write (\"%s\");", name);
+
+ memset (&ud, 0, sizeof (ud));
+ ud.data = cb;
+ ud.free_func = NULL;
+
+ plugin_register_write (name, dotnet_write, &ud);
+
+ return (0);
+} /* }}} int dotnet_register_write */
+
+int dotnet_dispatch_values (dotnet_value_data_t *vd, /* {{{ */
+ int values_len, value_t *values)
{
value_list_t vl = VALUE_LIST_INIT;
- vl.values = dvl->values;
- vl.values_len = dvl->values_len;
+ DEBUG ("dotnet_dispatch_values (vd = %p, values_len = %i, values = %p);",
+ (void *) vd, values_len, (void *) values);
- if (dvl->time > 0.0)
- vl.time = DOUBLE_TO_CDTIME_T (dvl->time);
+ vl.values_len = values_len;
+ vl.values = values;
+
+ if (vd->time > 0.0)
+ vl.time = DOUBLE_TO_CDTIME_T (vd->time);
else
vl.interval = 0;
- if (dvl->interval > 0.0)
- vl.interval = DOUBLE_TO_CDTIME_T (dvl->interval);
+ if (vd->interval > 0.0)
+ vl.interval = DOUBLE_TO_CDTIME_T (vd->interval);
else
vl.interval = interval_g;
- sstrncpy (vl.host, dvl->host, sizeof (vl.host));
- sstrncpy (vl.plugin, dvl->plugin, sizeof (vl.plugin));
- sstrncpy (vl.plugin_instance, dvl->plugin_instance, sizeof (vl.plugin_instance));
- sstrncpy (vl.type, dvl->type, sizeof (vl.type));
- sstrncpy (vl.type_instance, dvl->type_instance, sizeof (vl.type_instance));
+ sstrncpy (vl.host, vd->host, sizeof (vl.host));
+ sstrncpy (vl.plugin, vd->plugin, sizeof (vl.plugin));
+ sstrncpy (vl.plugin_instance, vd->plugin_instance, sizeof (vl.plugin_instance));
+ sstrncpy (vl.type, vd->type, sizeof (vl.type));
+ sstrncpy (vl.type_instance, vd->type_instance, sizeof (vl.type_instance));
return (plugin_dispatch_values (&vl));
} /* }}} int dotnet_dispatch_values */
MonoClass *class;
MonoObject *obj;
+ DEBUG ("dotnet plugin: dotnet_load_class ("
+ "assembly_name = \"%s\", "
+ "name_space = \"%s\", "
+ "class_name = \"%s\");",
+ assembly_name, (name_space != NULL) ? name_space : "", class_name);
+
domain = mono_domain_create ();
if (domain == NULL)
{
return (-1);
}
+ DEBUG ("dotnet plugin: mono_runtime_object_init ();");
mono_runtime_object_init (obj);
DEBUG ("dotnet plugin: Successfully created a \"%s\" object.", class_name);