![]() |
|||||||||||||||
|
JRobin 1.4.0 released!
What's new in JRobin 1.4.0?BackendsThe core package was completely redesigned. High level JRobin classes implementing the whole RRD logic are now clearly separated from the I/O backend (low level classes implementing actual I/O operations). Default backend shipped with 1.4.0 is based on extremely fast java.nio.* library. It's true that it takes more memory (borrowed from the OS directly), but it runs almost four times faster than before. Backends are also "switchable": with a single line of code you can force JRobin to use the an improved and faster version of the I/O engine found in 1.3.1 release. And that's not all: your RRD data can be maintained in memory, you don't have to use files. For those who want to create their own, custom RRD backends (RDBMS based, for example), there is a simple skeleton for it. Please refer to the backend page to for the whole explanation. Speed, more speedJust run the StressTest from the main JRobin library. It should perform more than 2.500 RRD updates per second on a modest PC (this is at least 2-3 times faster than before). RrdGraphDef: new setResolution() optionThis sets the resolution with which to fetch values from the RRD datasources. This is the equivalent to RRDtool's --step option. RrdGraphDef: RrdBackendFactory specification with datasourceThe RrdBackendFactory is an entirely new core feature that's being introduced with JRobin 1.4.0. It allows for far better control over RRD datasources, and can offer tremendous performance enhancement. It basically comes down to the fact that you can now also use RRD datasources by storing them purely in memory, or on disk but using the new - high performance - Java NIO package. Both NIO and MEMORY are many times faster than the traditional FILE access. Please refer to the backends page for more information on the RrdBackendFactory. It is possible to specify the backend in a RrdGraphDefTemplate or RrdExportDefTemplate by adding a <backend>BACKEND_NAME</backend> tag to a RRD def. RrdGraphDef: NewsetLowerLimit() optionGrid range specification has been altered so you can specify only lower or upper limit values, while leaving the other limit for auto-scaling. Because of the common use, a separate method setLowerLimit(value) has been added to allow easier specification of the lower limit. The setLowerLimit(value) is the equivalent of setGridRange(value, Double.NaN, false). The XML template equivalents are: <options> <!-- Both options have the same effect --> <lower_limit>0</lower_limit> <grid_range> <lower>0</lower> <upper>U</upper> <rigid>false</rigid> </grid_range> </options> RrdGraph: New render option with Graphics2D passingA new method was added to RrdGraph allowing you to render a JRobin graph onto a Graphics2D object you pass yourself. The method is of the form renderImage(Graphics2D, width, height). Additionally an extra method was added to retrieve a JRobin graph directly as its underlying BufferedImage: getBufferedImage(width, height). In both cases auto-sizing of the graph is done by specifying a width and height of 0. Live example is available: java -cp jrobin-demo-1.4.0.jar org.jrobin.demo.graph.SwingDemo RrdGraphDef: new setLazy() optionLike with Rrdtool, the lazy option can be used to make sure images only get generated if they are outdated. In other words, if the RRD datasources have a last update time that is after the last graph generation time. The last graph generation time is determined by the 'last modified' timestamp of the file. Live example is available: java -cp jrobin-demo-1.4.0.jar org.jrobin.demo.graph.LazyDemo In a windowless environment be sure to specify RrdGraphDef: Zero value for the end timestampIf you put 0 (zero) as the end timestamp of a RrdGraphDef time period, the graph will be generated until the last completed sample (in time! not value!). This is almost the same as graphing until the current time, only the graph will automatically adjust the range so it shows the last completed sample. If the last sample is correct, you will no longer see NaN values at the very end of the graph. The StressTest demo contains a sample use of this feature. RrdGraphDef: New datasource type (Sdef) in graph definitionsJRobin now offers an entirely new datasource, internally called Sdef. This datasource represents the result of a consolidation function applied to another datasource, much like the gprint() method does. A specified Sdef datasource can be used in any Cdef datasource with RPN calculation, and can be derived from any other datasource. It can also be used in the normal way for plotting or drawing comments. Example code: graphDef.datasource( "in", RRD_FILE, "input", "AVERAGE" ); graphDef.datasource( "avgIn", "in", "AVERAGE" ); // Sdef graphDef.datasource( "deviation", "in,avgIn,-" ); graphDef.area( "deviation", Color.BLUE, "Deviation from average" ); graphDef.line( "avgIn", Color.RED, "Average incoming" ); and the corrseponding code in the XML template would be: <datasources> ... <def> <name>avgIn</name> <datasource>in</datasource> <cf>AVERAGE</cf> </def> ... </datasources> Live example is available in the SwingDemo application (already mentioned on this page) RrdGraphDef: added time() methodYou can now plot a timestamp with a specified format on a JRobin graph. You can either specify the timestamp in several ways, or you can omit the timestamp, in which case the 'current time' will be plotted. The current time in this case would be the time when the graph generation encounters the Time command. The format of the text is like normal comment, only it should contain a @t marker to specficy where the timestamp should be. The timestamp will then be printed according to the provided pattern. The pattern can be a pattern string for a SimpleDateFormat object, or it can be any DateFormat object you created: // Specific time rrdGraphDef.time("First day of the year: @t@l", "dd-MM-yyyy", new GregorianCalendar(2004, Calendar.JANUARY, 1)); // Current time rrdGraphDef.time( "@lGenerated: @t@c", "HH:mm:ss"); There is a set of corresponding XML tags for the RrdGraphDef template. If the value tag is omitted, the current time will be used. Otherwise, the value tag can be specified like the start and end time of the graph: as an absolute time in seconds since the epoch, or as an ISO timestamp of the form: <!-- This would print out the current time --> <time> <format>Current time: @t</format> <pattern>MMM dd, yyyy HH:mm:ss</pattern> </time> <!-- This would print out: january 2004 (in your locale) --> <time> <format>Month: @t</format> <pattern>MMMM yyyy</pattern> <value>2004-01-01 12:00:00</value> </time></graph> Live example is available in the SwingDemo application (already mentioned on this page): Added RRD export functionality like RRDtool XPORT commandJRobin now supports data export functionality, much like the original RRDtool does, with a few extra touches ofcourse. Since 1.4.0 export has been introduced in the form of RrdExport, RrdExportDef and ExportData classes. It works very much like graphing does, here's a quick example: // Create a def for export specification RrdExportDef def = new RrdExportDef( startTime, endTime ); def.datasource( "ds", "test.rrd", "datasource", "AVERAGE" ); def.export( "ds", "A single datasource" ); // Pass the def to the exporter, fetch the export data, but no more than 50 rows // If you don't specify the maximum number of rows to retrieve, 400 will be used RrdExport export = new RrdExport( def ); ExportData data = export.fetch( 50 ); // Dump the exported data to XML in a file data.exportXml( "export-data.xml" ); // Or request a value directly from the exported data double value = data.getAggregate( "ds", "MAX" ); // We can also request the value as a string, much like with GPRINT System.out.println( data.print( "ds", "MAX", "Maximum: @5.2" ) ); The ExportData class corresponds to the public RrdDataSet interface, as does the FetchData class (the result of a direct fetch on an RRD). The RrdDataSet interface gives you a number of useful methods that can be used to retrieve and calculate data or for example pass it on to an external graphing or charting library. UNLIKE with RRDtool, it is not necessary to specify what data to export, by default all datasources requested will be exported. However, as soon you specify a datasource to export, using the export() construct, by default the system will revert to the so called 'strict' export like RRDtool, and only export the datasources you explicitly specified. You can override this behaviour by calling setStrictExport(boolean) method manually. If you disable strict export, you can set legends for only a few datasources, but still have all datasources in the ExportData set. The RrdExportDef is a subset of the RrdGraphDef and introduces a new XML Template very much alike. An example: <rrd_export_def> <span> <start>${start}</start> <end>${end}</end> </span> <datasources> <def> <name>bytesIn</name> <rrd>${rrd}</rrd> <source>ifInOctets</source> <cf>AVERAGE</cf> </def> <def> <name>bitsIn</name> <rpn>bytesIn,8,*</rpn> </def> </datasources> <exports> <export> <datasource>bitsIn</datasource> <legend>Bits Incoming</legend> </export> <export> <datasource>bytesIn</datasource> <legend>Bytes Incoming</legend> </export> </exports> </rrd_export_def> An ExportData object can directly be recreated from an export XML file, like: ExportData data = new ExportData( new File("export-data.xml"), true ); The second parameter determines if the legends in the export XML should be used to name the datasources. If set to false, the datasources will get named sequentially of the form 'd1', 'd2'... unless you specify a different prefix in the ExportData constructor, like in: ExportData data = new ExportData( new File("export-data.xml"), "mydata"); // The imported datasources will be named 'mydata1', 'mydata2' ... Because of the XML import functionality, you can easily import regular RRDtool XPORT xml data into a JRobin ExportData set. Furthermore, ExportData can be set as a datasource in a normal RrdGraphDef, allowing you to generate graphs directly from RRDtool exported data. Simply add a number of ExportData objects to a RrdGraphDef: RrdGraphDef graphDef = new RrdGraphDef(); ... graphDef.addExportData( exportData1 ); graphDef.addExportData( exportData2 ); ... And there is the RrdGraphDefTemplate XML variation: <datasources> ... <export_data> <file>/export_data/exportdata1.xml</file> <ds_name_prefix>traffic</ds_name_prefix> </export_data> <export_data> <file>/export_data/exportdata2.xml</file> <use_legend_names>true</use_legend_names> </export_data> <export_data> <file>/export_data/exportdata3.xml</file> </export_data> ... </datasources> Every RrdGraphDef is also a RrdExportDef. This means you can pass a RrdGraphDef directly to an RrdExport, you can generate the ExportData from the corresponding graph. However, if you are interested in both generating the graph and retrieving the ExportData, it is better to use the export functionality of RrdGraph, in order to generate the data only once. A simple example: RrdGraphDef graphDef = new RrdGraphDef( startTime, endTime ); ... RrdGraph graph = new RrdGraph( graphDef ); // Save the graph image graph.saveAsPNG( graphFile ); // Get the export data ExportData data = graph.getExportData(); // Do something with the exported data // Store max values in a relational database for example. Note: RrdGraph also contains two fetchExportData methods. These will calculate the ExportData again based on the passed RrdGraphDef. Use the getExportData() method after creating the image to save a calculation roundtrip, it can save you many CPU cycles, use fetchExportData() if you want to retrieve the export data without generating the graph, or if you want to re-generate it after changing the graphDef or with a lower maxRows limit. The workings of JRobin export are demonstrated in the combined ExportDemo. The ExportDemo is actually two different apps: ExportExportDemo, that exports data from two rrd files and dumps the result in some XML files: java -cp jrobin-demo-1.4.0.jar org.jrobin.demo.graph.ExportExportDemo ...and the ExportImportDemo that reads in the output from ExportExportDemo and generates a graph from it: java -cp jrobin-demo-1.4.0.jar org.jrobin.demo.graph.ExportImportDemo New demo utilities: GraphTemplate and ExportTemplateJRobin 1.4.0 comes with two new demo applications: GraphTemplate and ExportTemplate. These are command-line utilities that allow you to generate output (a graph or export data) based on a template XML file (RrdGraphDefTemplate or RrdExportDefTemplate). The programs are very similar, and if they detect parameters in the template XML (${param}), they will ask for the values of these parameters interactively. java -cp jrobin-demo-1.4.0.jar \ org.jrobin.demo.graph.GraphTemplate \ [-img (png|gif|jpg)] [-w width] [-h height] [-q jpegQuality] \ <template_file> <image_name> Command parameters are:
java -cp jrobin-demo-1.4.0.jar \ org.jrobin.demo.graph.ExportTemplate \ [-m maxRows] [-f <dump_file>] \ <template_file> Command parameters are:
Improved LinearInterpolator classThere is a new interpolation method in the LinearInterpolator class. It is now possible to interpolate data points in a (time, value) plane with a single best-fit line. The slope of the line will be calculated so that the total square distance of real data points from from the best-fit line is at minimum. Rich PlottableDemoMany users asked how to create those fancy-looking gradient-filled graphs. All those tricks are now included in the PlottableDemo. New FetchSourceList class and setDatasources() optionIt often happens you want to generate a different batch of graphs, but using the same set of datasources. Use of aFetchSourceList combined with the new RrdGraphDef.setDatasources() method allows you to manage the graph datasources separately, and passing them on to a RrdGraphDef in one go. Please note, FetchSourceList only touches on the subject of RrdDb datasources, not combined, static or plottable definitions. When generating multiple graphs with the lazy flag set, using the same datasources, the use of a single FetchSourceList (with the persistent option set) can offer serious performance enhancement: FetchSourceList list = new FetchSourceList( 2, true, new RrdOpener(true, true) ); list.add( "in", RRD_FILE, "in", "AVERAGE" ); list.add( "out", RRD_FILE, "out", "AVERAGE" ); ... list.openAll(); // Retrieve all RrdDb instances ... // Create basic GraphDef graphDef.setDatasources( list ); // Set the datasources ... // Generate graph (one or more) list.releaseAll(); // Release all RrdDb instances New RrdOpener classThe RrdOpener class represents a wrapper object to be used for opening and closing RrdDb instances. A FetchSourceList requires an RrdOpener to access the RrdDb objects related to the datasources. The RrdGraph object used to generate the graphs is itself a child class of RrdOpener, and is the default opener used for graph datasources. You can override this behaviour, by providing the datasources as a persistent FetchSourceList, with its own RrdOpener. Be aware you must manually control releasing or closing all RrdDbs when finished with them. The use of RrdOpener is in creating child classes that override the general retrieve and release methods, allowing central management of the RrdDb instances. This could for example easily be used to count how many times a RdbDb is retrieved, or to map the name of the RrdDb to say a database record. Live example is available in LazyDemo (already mentioned on this page). Restructured web siteAt least, it looks better now. Importan release notes
Copyright © 2003, 2004 Sasa Markovic & Arne Vandamme. All Rights Reserved. |