1 /*****************************************************************************
2 * RRDLIB .NET Binding
3 *****************************************************************************
4 * Created 2010/06/29 by Chris Larsen
5 *
6 * This .NET interface allows the use of Tobias Oetiker's awesome RRDtool
7 * functions in .NET projects using the PInvoke method to load the rrdlib.dll
8 * To use, please make sure that you place the rrdlib.dll in the same
9 * directory as this dll, or change the "const string dll" to point to the
10 * proper location. For documentation, please see the RRDtool website at:
11 * http://oss.oetiker.ch/rrdtool/
12 * For useage examples, please see the rrd_binding_test project.
13 ****************************************************************************/
14 using System;
15 using System.Runtime.InteropServices;
17 /// <summary>
18 /// Contains data structures and methods for working with round robin databases.
19 /// </summary>
20 namespace dnrrdlib
21 {
22 /// <summary>
23 /// Information about a particular RRD parameter. The key is the name of the parameter,
24 /// type determines what kind of value we have, value is the value, and next is a
25 /// pointer to another info object.
26 /// </summary>
27 [StructLayout(LayoutKind.Explicit, Pack = 1)]
28 public struct rrd_info_t
29 {
30 [FieldOffset(0), MarshalAs(UnmanagedType.LPStr)]
31 public string key;
32 [FieldOffset(4)] // for 64 bit, set this to 8 and increment everyone else by 4
33 public rrd_info_type_t type;
34 [FieldOffset(8)]
35 public rrd_infoval_t value;
36 [FieldOffset(16)]
37 public IntPtr next;
38 }
40 /// <summary>
41 /// This is a chunk of data returned from an RRD object
42 /// </summary>
43 [StructLayout(LayoutKind.Sequential)]
44 public struct rrd_blob_t
45 {
46 public UInt32 size; /* size of the blob */
47 public IntPtr ptr; /* pointer */
48 };
50 /// <summary>
51 /// This contains the actual data values for an rrd_info_t structure.
52 /// NOTE: Only one of these will be valid per instance. Use the containing info_t's
53 /// type field to deteremine which of these to read.
54 /// NOTE: If the type is RD_I_STR, you have to marshal the string value yourself
55 /// </summary>
56 [StructLayout(LayoutKind.Explicit)]
57 public struct rrd_infoval_t
58 {
59 [FieldOffset(0)]
60 public UInt32 u_cnt;
61 [FieldOffset(0)]
62 public double u_val;
63 [FieldOffset(0)]
64 public IntPtr u_str;
65 [FieldOffset(0)]
66 public Int32 u_int;
67 [FieldOffset(0)]
68 public rrd_blob_t u_blo;
69 };
71 /// <summary>
72 /// Different rrd_info_t value types
73 /// </summary>
74 public enum rrd_info_type_t
75 {
76 RD_I_VAL = 0,
77 RD_I_CNT,
78 RD_I_STR,
79 RD_I_INT,
80 RD_I_BLO
81 };
83 /// <summary>
84 /// Direct bindings to the RRD Library for .NET applications. Uses the PInvoke method
85 /// of accessing the rrdlib.dll file.
86 /// </summary>
87 public class rrd
88 {
89 // Set this path to the location of your "rrdlib.dll" file
90 const string dll = @"rrdlib.dll";
92 // IMPORTS - Main methods
93 [DllImport(dll)] static extern Int32 rrd_create(Int32 argc, string[] argv);
94 [DllImport(dll)] static extern Int32 rrd_create_r([MarshalAs(UnmanagedType.LPStr)] string filename,
95 UInt32 pdp_step, Int32 last_up, Int32 argc, [MarshalAs(UnmanagedType.LPArray)] string[] argv);
96 [DllImport(dll)] static extern IntPtr rrd_info_r(string filename);
97 [DllImport(dll)] static extern void rrd_info_print(IntPtr data);
98 [DllImport(dll)] static extern Int32 rrd_update(Int32 argc, string[] argv);
99 [DllImport(dll)] static extern IntPtr rrd_update_v(Int32 argc, string[] argv);
100 [DllImport(dll)] static extern Int32 rrd_update_r(string filename, string template, Int32 argc,
101 string[] argv);
102 /* Do not use this until someone adds the FILE structure */
103 [DllImport(dll)] static extern Int32 rrd_graph(Int32 argc, string[] argv, ref string[] prdata,
104 ref Int32 xsize, ref Int32 ysize, /* TODO - FILE, */ ref double ymin, ref double ymax);
105 [DllImport(dll)] static extern Int32 rrd_graph_v(Int32 argc, string[] argv);
106 [DllImport(dll)] static extern Int32 rrd_fetch(Int32 argc, string[] argv, ref Int32 start,
107 ref Int32 end, ref UInt32 step, ref UInt32 ds_cnt, ref string[] ds_namv, ref IntPtr data);
108 [DllImport(dll)] static extern Int32 rrd_first(Int32 argc, string[] argv);
109 [DllImport(dll)] static extern Int32 rrd_first_r(string filename, Int32 rraindex);
110 [DllImport(dll)] static extern Int32 rrd_last(Int32 argc, string[] argv);
111 [DllImport(dll)] static extern Int32 rrd_last_r(string filename, Int32 rraindex);
112 [DllImport(dll)] static extern Int32 rrd_lastupdate(Int32 argc, string[] argv);
113 [DllImport(dll)] static extern Int32 rrd_lastupdate_r(string filename, ref Int32 ret_last_update,
114 ref UInt32 ret_ds_count, ref string[] ret_ds_names, ref string[] ret_last_ds);
115 [DllImport(dll)] static extern Int32 rrd_dump(Int32 argc, string[] argv);
116 [DllImport(dll)] static extern Int32 rrd_dump_r(string filename, string outname);
117 [DllImport(dll)] static extern Int32 rrd_xport(Int32 argc, string[] argv, Int32 unused,
118 ref Int32 start, ref Int32 end, ref UInt32 step, ref UInt32 col_cnt,
119 ref string[] leggend_v, ref IntPtr data);
120 [DllImport(dll)] static extern Int32 rrd_restore(Int32 argc, string[] argv);
121 [DllImport(dll)] static extern Int32 rrd_resize(Int32 argc, string[] argv);
122 [DllImport(dll)] static extern Int32 rrd_tune(Int32 argc, string[] argv);
124 // IMPORTS - Utility methods
125 [DllImport(dll)] static extern string rrd_strversion();
126 [DllImport(dll)] static extern Int32 rrd_random();
127 [DllImport(dll)] static extern string rrd_get_error();
129 // MAIN FUNCTIONS
131 /// <summary>
132 /// The create function of RRDtool lets you set up new Round Robin Database (RRD) files.
133 /// The file is created at its final, full size and filled with *UNKNOWN* data.
134 /// </summary>
135 /// <param name="argv">String array of command line arguments</param>
136 /// <returns>0 if successful, -1 if an error occurred</returns>
137 public static int Create(string[] argv)
138 {
139 return rrd_create(argv.GetUpperBound(0) + 1, argv);
140 }
142 /// <summary>
143 /// The create function of RRDtool lets you set up new Round Robin Database (RRD) files.
144 /// The file is created at its final, full size and filled with *UNKNOWN* data.
145 /// </summary>
146 /// <param name="filename">A full path to the location where you want the rrd to reside</param>
147 /// <param name="pdp_step">Specifies the base interval in seconds with which data will be fed into the RRD</param>
148 /// <param name="last_up">Timestamp of the last update</param>
149 /// <param name="argv">String array of command line arguments</param>
150 /// <returns>0 if successful, -1 if an error occurred</returns>
151 public static int Create(string filename, UInt32 pdp_step, Int32 last_up, string[] argv)
152 {
153 return rrd_create_r(filename, pdp_step, last_up, argv.GetUpperBound(0)+1, argv);
154 }
156 /// <summary>
157 /// Returns a linked list of rrd_info_t objects that describe the rrd file.
158 /// </summary>
159 /// <param name="filename">Full path to the rrd file</param>
160 /// <returns>An rrd_info_t object</returns>
161 public static rrd_info_t Info(string filename)
162 {
163 if (filename.Length < 1)
164 throw new Exception("Empty filename");
165 IntPtr ptr = rrd_info_r(filename);
166 if (ptr == IntPtr.Zero || (int)ptr < 1)
167 throw new Exception("Unable to extract information from rrd");
168 return (rrd_info_t)Marshal.PtrToStructure(ptr, typeof(rrd_info_t));
169 }
171 /// <summary>
172 /// The update function feeds new data values into an RRD. The data is time aligned (interpolated)
173 /// according to the properties of the RRD to which the data is written.
174 /// </summary>
175 /// <param name="argv">String array of command line arguments</param>
176 /// <returns>0 if successful, -1 if an error occurred</returns>
177 public static Int32 Update(string[] argv)
178 {
179 return rrd_update(argv.GetUpperBound(0) + 1, argv);
180 }
182 /// <summary>
183 /// The update function feeds new data values into an RRD. The data is time aligned (interpolated)
184 /// according to the properties of the RRD to which the data is written.
185 /// </summary>
186 /// <param name="argv">String array of command line arguments</param>
187 /// <returns>An rrd_info_t pointer with information about the update</returns>
188 public static IntPtr Update2(string[] argv)
189 {
190 return rrd_update_v(argv.GetUpperBound(0) + 1, argv);
191 }
193 /// <summary>
194 /// The update function feeds new data values into an RRD. The data is time aligned (interpolated)
195 /// according to the properties of the RRD to which the data is written.
196 /// </summary>
197 /// <param name="filename">Full path to the rrd to update</param>
198 /// <param name="template">List of data sources to update and in which order</param>
199 /// <param name="argv">String array of command line arguments</param>
200 /// <returns>0 if successful, -1 if an error occurred</returns>
201 public static Int32 Update(string filename, string template, string[] argv)
202 {
203 return rrd_update_r(filename, template, argv.GetUpperBound(0)+1, argv);
204 }
206 /// <summary>
207 /// Generate a graph from an RRD file. Specify all the graph options in the string array as you
208 /// normally would with the command line version.
209 /// </summary>
210 /// <param name="argv">String array of command line arguments</param>
211 /// <returns>0 if successful, -1 if an error occurred</returns>
212 public static Int32 Graph(string[] argv)
213 {
214 return rrd_graph_v(argv.GetUpperBound(0) + 1, argv);
215 }
217 /// <summary>
218 /// Returns an array of values for the period specified from a given rrd.
219 /// Specify your parameters in the argv array and check the referenced parameters for
220 /// values returned from the rrd
221 /// </summary>
222 /// <param name="argv">String array of command line arguments (must include the filename)</param>
223 /// <param name="start">Starting timestamp found in the rrd</param>
224 /// <param name="end">Ending timestamp found in the rrd</param>
225 /// <param name="step">The rrd's step value</param>
226 /// <param name="ds_cnt">Number of data sources found</param>
227 /// <param name="ds_namv">Names of data sources found</param>
228 /// <param name="data">Values found (in double type)</param>
229 /// <returns>0 if successful, -1 if an error occurred</returns>
230 public static Int32 Fetch(string[] argv, ref Int32 start, ref Int32 end, ref UInt32 step,
231 ref UInt32 ds_cnt, ref string[] ds_namv, ref IntPtr data)
232 {
233 return rrd_fetch(argv.GetUpperBound(0) + 1, argv, ref start, ref end, ref step, ref ds_cnt,
234 ref ds_namv, ref data);
235 }
237 /// <summary>
238 /// Returns the timestamp of the first value in the rrd given the rra index
239 /// </summary>
240 /// <param name="filename">Full path to the rrd file</param>
241 /// <param name="rraindex">0 based index of the rra to get a value for</param>
242 /// <returns>Unix timestamp if successful, -1 if an error occurred</returns>
243 public static Int32 First(string filename, int rraindex)
244 {
245 return rrd_first_r(filename, rraindex);
246 }
248 /// <summary>
249 /// Returns the timestamp of the first value in the rrd
250 /// </summary>
251 /// <param name="argv">String array of command line arguments</param>
252 /// <returns>Unix timestamp if successful, -1 if an error occurred</returns>
253 public static Int32 First(string[] argv)
254 {
255 return rrd_first(argv.GetUpperBound(0) + 1, argv);
256 }
258 /// <summary>
259 /// Returns the timestamp of the last value in the rrd given the rra index
260 /// </summary>
261 /// <param name="filename"></param>
262 /// <param name="filename">Full path to the rrd file</param>
263 /// <param name="rraindex">0 based index of the rra to get a value for</param>
264 /// <returns>Unix timestamp if successful, -1 if an error occurred</returns>
265 public static Int32 Last(string filename, int rraindex)
266 {
267 return rrd_last_r(filename, rraindex);
268 }
270 /// <summary>
271 /// Returns the timestamp of the last value in the rrd
272 /// </summary>
273 /// <param name="argv">String array of command line arguments</param>
274 /// <returns>Unix timestamp if successful, -1 if an error occurred</returns>
275 public static Int32 Last(string[] argv)
276 {
277 return rrd_last(argv.GetUpperBound(0) + 1, argv);
278 }
280 /// <summary>
281 /// Finds the timestamp of the last updated value in the rrd
282 /// </summary>
283 /// <param name="filename">Full path to the rrd file</param>
284 /// <param name="ret_last_update">Unix timestamp of the last update</param>
285 /// <param name="ret_ds_count">Number of data sources found</param>
286 /// <param name="ret_ds_names">Names of the data sources found</param>
287 /// <param name="ret_last_ds">Name of the last data source found</param>
288 /// <returns>0 if successful, -1 if an error occurred</returns>
289 public static Int32 Last_Update(string filename, ref Int32 ret_last_update, ref UInt32 ret_ds_count,
290 ref string[] ret_ds_names, ref string[] ret_last_ds)
291 {
292 return rrd_lastupdate_r(filename, ref ret_last_update, ref ret_ds_count, ref ret_ds_names,
293 ref ret_last_ds);
294 }
296 /// <summary>
297 /// Writes the contents of an rrd file to an XML file
298 /// </summary>
299 /// <param name="filename">Full path to the rrd file</param>
300 /// <param name="outname">Full path to write the XML output</param>
301 /// <returns>0 if successful, -1 if an error occurred</returns>
302 public static Int32 Dump(string filename, string outname)
303 {
304 return rrd_dump_r(filename, outname);
305 }
307 /// <summary>
308 /// Writes the contents of an rrd file to an XML file
309 /// </summary>
310 /// <param name="argv">String array of command line arguments</param>
311 /// <returns>0 if successful, -1 if an error occurred</returns>
312 public static Int32 Dump(string[] argv)
313 {
314 return rrd_dump(argv.GetUpperBound(0) + 1, argv);
315 }
317 /// <summary>
318 /// Grabs the values from an rrd. Similar to fetch but enables merging of multiple
319 /// rrds and calculations
320 /// </summary>
321 /// <param name="argv">String array of command line arguments</param>
322 /// <param name="start">Starting timestamp found in the rrd</param>
323 /// <param name="end">Ending timestamp found in the rrd</param>
324 /// <param name="step">Step size found in the rrd</param>
325 /// <param name="col_cnt">Number of data sources found in the rrd</param>
326 /// <param name="leggend_v">Add a legend</param>
327 /// <param name="data">Values from the rrd as double type</param>
328 /// <returns>0 if successful, -1 if an error occurred</returns>
329 public static Int32 Xport(string[] argv, ref Int32 start, ref Int32 end, ref UInt32 step,
330 ref UInt32 col_cnt, ref string[] leggend_v, ref IntPtr data)
331 {
332 return rrd_xport(argv.GetUpperBound(0) + 1, argv, 0, ref start, ref end, ref step, ref col_cnt,
333 ref leggend_v, ref data);
334 }
336 /// <summary>
337 /// Creates an rrd from an XML data dump
338 /// </summary>
339 /// <param name="argv">String array of command line arguments</param>
340 /// <returns>0 if successful, -1 if an error occurred</returns>
341 public static Int32 Restore(string[] argv)
342 {
343 return rrd_restore(argv.GetUpperBound(0) + 1, argv);
344 }
346 /// <summary>
347 /// Alters the size of an RRA and creates a new rrd in the dll's directory
348 /// NOTE: The new rrd may return unexpected results if you are not very careful
349 /// NOTE: This may crash in version 1.4.3
350 /// </summary>
351 /// <param name="argv">String array of command line arguments</param>
352 /// <returns>0 if successful, -1 if an error occurred</returns>
353 public static Int32 Resize(string[] argv)
354 {
355 return rrd_resize(argv.GetUpperBound(0) + 1, argv);
356 }
358 /// <summary>
359 /// Modify the characteristics of an rrd
360 /// </summary>
361 /// <param name="argv">String array of command line arguments</param>
362 /// <returns>0 if successful, -1 if an error occurred</returns>
363 public static Int32 Tune(string[] argv)
364 {
365 return rrd_tune(argv.GetUpperBound(0) + 1, argv);
366 }
368 // UTILITIES
369 /// <summary>
370 /// Returns a string with the numeric version of the rrdlib build version
371 /// </summary>
372 /// <returns>A string with version information</returns>
373 public static string Version()
374 {
375 return rrd_strversion();
376 }
378 /// <summary>
379 /// Generates a random number for testing rrdlib
380 /// </summary>
381 /// <returns>A random integer</returns>
382 public static int Random()
383 {
384 return rrd_random();
385 }
387 /// <summary>
388 /// Returns the latest error from rrdlib
389 /// </summary>
390 /// <returns>A string with the error message, or an emtpy string if no error occurred</returns>
391 public static string Get_Error()
392 {
393 return rrd_get_error();
394 }
396 /// <summary>
397 /// Formats and prints information in the object to the standard output
398 /// </summary>
399 /// <param name="info">rrd_info_t object with data to print</param>
400 public static void Info_Print(rrd_info_t info)
401 {
402 IntPtr newptr = Marshal.AllocHGlobal(Marshal.SizeOf(info));
403 Marshal.StructureToPtr(info, newptr, true);
404 rrd_info_print(newptr);
405 }
406 }
407 }