HOME | Library | JRobin API | Utilities | Support | About Us | Forum

JRobin API
JRobin and RRDTool, compared
Quick reference
Tutorial
Working example
Core API
Graphing API
Templates API
Standalone graphing engine
Backends
Javadoc

# Templates API

Creating JRobin RRD files and graphs from your Java code is quite straightforward (see Core API and Graphing API pages for detailed instructions). This approach (all creation parameters are hard-coded in your java source) is probably sufficient in most cases, but in complex, live projects you will probably need something more flexible. Simply, you don't want to recompile your source code each time when you want to change the background color of the graph from white to yellow. JRobin templates should address this issue in a logical way. Now, you are able to put all RRD file/graph creation parameters and options in an external XML file and use it to create as many RRD files/graphs as needed.

Template API is available since JRobin 1.3.0.

## Creating RRD files from XML templates

Here is a sample XML code containing all available creation parameters and options of a new RRD file:

     <rrd_def>
         <path>test.rrd</path>
         <!-- not mandatory -->
         <start>1000123456</start>
         <!-- not mandatory -->
         <step>300</step>
         <!-- at least one datasource must be supplied -->
         <datasource>
             <name>input</name>
             <type>COUNTER</type>
             <heartbeat>300</heartbeat>
             <min>0</min>
             <max>U</max>
         </datasource>
         <datasource>
             <name>temperature</name>
             <type>GAUGE</type>
             <heartbeat>400</heartbeat>
             <min>U</min>
             <max>1000</max>
         </datasource>
         <!-- at least one archive must be supplied -->
         <archive>
             <cf>AVERAGE</cf>
             <xff>0.5</xff>
             <steps>1</steps>
             <rows>600</rows>
         </archive>
         <archive>
             <cf>MAX</cf>
             <xff>0.6</xff>
             <steps>6</steps>
             <rows>7000</rows>
         </archive>
     </rrd_def>

This XML template will be parsed by RrdDefTemplate class. Some notes on the template syntax:

- There is a strong relation between the XML template syntax and the syntax of `RrdDef` class methods. If you are not sure what some XML tag means, check javadoc for the corresponding class.
- starting timestamp can be supplied either as a long integer (like: 1000243567) or as an ISO formatted string (like: 2004-02-21 12:25:45)
- whitespaces are not harmful
- floating point values: anything that cannot be parsed will be treated as Double.NaN (like: U, unknown, 12r.23)
- comments are allowed.

Any part of the text between `<some_tag>` and `</some_tag>` in the template can be replaced with a variable of the following form: `${variable_name}`. Use `setVariable()` overloaded methods from the RrdDefTemplate class to replace template variables with real values at runtime.

Typical usage scenario:

- Create your XML template and save it to a file (template.xml, for example)
- Replace hardcoded template values with variables if you want to change them during runtime (from your Java code). For example, file path should not be hardcoded in the template - you probably want to create many different RRD files starting from the same XML template. For example, your XML template could start with:

       <rrd_def>
           <path>${path}</path>
           <step>300</step>
           ...

- In your Java code, create RrdDefTemplate object using your XML template file:

       RrdDefTemplate t = new RrdDefTemplate(new File(template.xml));

- Then, specify real values for template variables:

       t.setVariable("path", "demo/test.rrd");

- Once all template variables are set, use the template object to create RrdDef object. This object is eventually used to create new JRobin RRD file:

       RrdDef def = t.getRrdDef();
       RrdDb rrd = new RrdDb(def);
       rrd.close();

You should create new RrdDefTemplate object only once for each XML template (this is recommended, but not mandatory). Single template object can be reused to create as many RrdDef objects as needed, with different values specified for template variables. XML synatax check is performed only once - the first definition object gets created relatively slowly, but it will be created much faster next time. If you change the XML template, you'll have to restart your Java application, but without source code recompilation.

Note that RrdDefTemplate class is not thread safe: if you use the same RrdDefTemplate object in several different threads, you should synchronize their access to the template object.

## Creating RRD graphs from XML templates

Here is an example of a properly formatted XML template with all available options in it (unwanted options can be removed):

    <rrd_graph_def>
         <span>
             <!-- ISO FORMAT: yyyy-MM-dd HH:mm:ss -->
             <start>2004-02-27 13:35:00</start>
             <!-- timestamp in seconds is also allowed -->
             <end>1234567890</end>
         </span>
         <options>
             <anti_aliasing>true</anti_aliasing>
             <arrow_color>#FF0000</arrow_color>
             <axis_color>#00FF00</axis_color>
             <back_color>#00FF00</back_color>
             <background>#FFFFFF</background>
             <base_value>1024</base_value>
             <canvas>#112211</canvas>
             <left_padding>55</left_padding>
             <default_font>
                 <name>Times</name>
                 <style>BOLD ITALIC</style>
                 <size>15</size>
             </default_font>
             <default_font_color>#000000</default_font_color>
             <frame_color>#0000FF</frame_color>
             <front_grid>true</front_grid>
             <grid_range>
                 <lower>100</lower>
                 <upper>200</upper>
                 <rigid>false</rigid>
             </grid_range>
             <grid_x>true</grid_x>
             <grid_y>false</grid_y>
             <border>
                 <color>#00FFFF</color>
                 <width>2</width>
             </border>
             <major_grid_color>#00FF00</major_grid_color>
             <major_grid_x>true</major_grid_x>
             <major_grid_y>false</major_grid_y>
             <minor_grid_color>#00FFFF</minor_grid_color>
             <minor_grid_x>true</minor_grid_x>
             <minor_grid_y>false</minor_grid_y>
             <overlay>overlay_image.png</overlay>
             <show_legend>true</show_legend>
             <show_signature>false</show_signature>
             <time_axis>
                 <!-- ALLOWED TIME UNITS: SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, YEAR -->
                 <min_grid_time_unit>HOUR</min_grid_time_unit>
                 <min_grid_unit_steps>4</min_grid_unit_steps>
                 <maj_grid_time_unit>DAY</maj_grid_time_unit>
                 <maj_grid_unit_steps>2</maj_grid_unit_steps>
                 <date_format>HH:mm</date_format>
                 <center_labels>true</center_labels>
                 <first_day_of_week>SUNDAY</first_day_of_week>
             </time_axis>
             <time_axis_label>time</time_axis_label>
             <title>Graph title</title>
             <title_font>
                 <name>Verdana</name>
                 <style>BOLD</style>
                 <size>17</size>
             </title_font>
             <title_font_color>#FF0000</title_font_color>
             <units_exponent>6</units_exponent>
             <value_axis>
                 <grid_step>100</grid_step>
                 <label_step>200</label_step>
             </value_axis>
             <vertical_label>voltage [V]</vertical_label>
         </options>
         <datasources>
             <def>
                 <name>input</name>
                 <rrd>test1.rrd</rrd>
                 <source>inOctets</source>
                 <cf>AVERAGE</cf>
             </def>
             <def>
                 <name>output</name>
                 <rrd>test2.rrd</rrd>
                 <source>outOctets</source>
                 <cf>MAX</cf>
             </def>
             <def>
                 <name>input8</name>
                 <rpn>input,8,*</rpn>
             </def>
             <def>
                 <name>output8</name>
                 <rpn>output,8,*,-1,*</rpn>
             </def>
         </datasources>
         <graph>
             <area>
                 <datasource>input</datasource>
                 <color>#FF0000</color>
                 <legend>Input traffic</legend>
             </area>
             <area>
                 <datasource>output</datasource>
                 <color>#00FF00</color>
                 <legend>Output traffic</legend>
             </area>
             <stack>
                 <datasource>input8</datasource>
                 <color>#AA00AA</color>
                 <legend>Stacked input@r</legend>
             </stack>
             <line>
                 <datasource>input</datasource>
                 <color>#AB7777</color>
                 <legend>Input traffic@l</legend>
             </line>
             <line>
                 <datasource>output</datasource>
                 <color>#AA00AA</color>
                 <legend>Output traffic@r</legend>
                 <width>2</width>
             </line>
             <area>
                 <time1>2004-02-25 12:00:01</time1>
                 <time2>1000222333</time2>
                 <value1>1001.23</value1>
                 <value2>2765.45</value2>
                 <color>#AABBCC</color>
                 <legend>simeple two point area</legend>
             </area>
             <line>
                 <time1>1000111444</time1>
                 <time2>2004-02-25 12:00:01</time2>
                 <value1>1009.23</value1>
                 <value2>9002.45</value2>
                 <color>#AABB33</color>
                 <legend>simple two point line</legend>
                 <width>5</width>
             </line>
             <gprint>
                 <datasource>input</datasource>
                 <cf>AVERAGE</cf>
                 <format>Average input: @2@c</format>
             </gprint>
             <gprint>
                 <datasource>output</datasource>
                 <cf>TOTAL</cf>
                 <format>Total output: @2@r</format>
                 <base>1024</base>
             </gprint>
             <hrule>
                 <value>1234.5678</value>
                 <color>#112233</color>
                 <legend>horizontal rule</legend>
                 <width>3</width>
             </hrule>
             <vrule>
                 <time>2004-02-22 17:43:57</time>
                 <color>#112299</color>
                 <legend>vertical rule</legend>
                 <width>6</width>
             </vrule>
             <comment>Created with JRobin</comment>
         </graph>
     </rrd_graph_def>

This XML template will be parsed by RrdGraphDefTemplate class. There is a strong relation between the XML template syntax and the syntax of `RrdGraphDef` class methods. If you are not sure what some XML tag means, check javadoc for the corresponding class. Some notes on the template syntax:

- hard-coded timestamps in templates should be long integeres (like: 1000243567) or ISO formatted strings (like: 2004-02-21 12:25:45)
- whitespaces are not harmful
- use `true`, `on`, `yes`, `y`, or `1` to specify boolean `true` value (anything else will be treated as `false`).
- floating point values: anything that cannot be parsed will be treated as Double.NaN (like: U, unknown, 12r.23)
- use #RRGGBB format to specify colors.
- valid font styles are: PLAIN, ITALIC, BOLD, BOLD ITALIC
- comments are allowed.

Any part of the text between `<some_tag>` and `</some_tag>` in the template can be replaced with a variable of the following form: `${variable_name}`. Use `setVariable()` overloaded methods from the RrdGraphDefTemplate class to replace template variables with real values at runtime (in your Java code).

Typical usage scenario:

- Create your XML template and save it to a file (template.xml, for example)
- Replace template values with variables if you want to change them during runtime. For example, time span should not be hard-coded in the template - you probably want to create many different graphs with different time spans from the same XML template. The same is probably true for the graph title. For example, your XML template could look like:

       <rrd_graph_def>
           <span>
               <start>${start}</start>
               <end>${end}</end>
           </span>
           <options>
               <title>GRAPH: ${title}</title>
               ...
           </options>
           ...

- In your Java code, create RrdGraphDefTemplate object using your XML template file:

       RrdGraphDefTemplate t = new RrdGraphDefTemplate(new File(template.xml));

- Then, specify real values for all template variables:

       t.setVariable("start", new GregorianCalendar(2004, 2, 25));
       t.setVariable("end", new GregorianCalendar(2004, 2, 26));
       t.setVariable("title", "My first template based graph");

- Once all template variables are set, use the template object to create RrdGraphDef object. This object is eventually used to create JRobin grahps:

       RrdGraphDef gdef = t.getRrdGraphDef();
       RrdGraph g = new RrdGraph(gdef);
       g.saveAsPNG("graph.png");

You should create new RrdGraphDefTemplate object only once for each XML template. Single template object can be reused to create as many RrdGraphDef objects as needed, with different values specified for template variables. XML synatax check is performed only once - the first graph definition object gets created relatively slowly, but it will be created much faster next time. If you change the XML template, you'll have to restart your Java application, but without source code recompilation.

Note that RrdGraphDefTemplate class is not thread safe: access to the template object from several threads should be synchronized.

## Templates demo

To see both template classes in action, run the the following demo (source code is provided with the distribution):

    java -cp jrobin-demo-{version}.jar \
         org.jrobin.demo.TemplatesDemo

If you run this demo in a headless environment (without X-server), be sure to specify

    -Djava.awt.headles=true

option on the command line.

Back to the top

Copyright © 2003, 2004 Sasa Markovic & Arne Vandamme. All Rights Reserved.