Working With Time-series Data in PNDA

In a previous post I talked about integrating OpenDaylight with PNDA. In this post I will start to make use of the data coming from OpenDaylight by building a Spark streaming application to create time-series datasets. This lets us use the Grafana application in PNDA to display time-series graphs.


For this example, I have used this if-table-collector OpenDaylight project which uses SNMP to collect the IF-MIB ifTable. Instructions for setting it up are in the project README.

The previous post provided instructions for how to set up event streaming from OpenDaylight to PNDA. It concluded with data getting stored in PNDA HDFS. This post will continue where we left off and show how PNDA can process the incoming data in another way.

A Scala App For Spark Streaming

The good folk from the PNDA team have provided this kafka-spark-opentsdb example project which we can use as a template for building our Spark streaming application.

The Application Package

This is the anatomy of a PNDA Spark streaming application:


The properties.json file is a descriptor for properties that can be configured when deploying the application to a PNDA cluster. We need to tailor this file to set useful defaults for the application.

The opentsdb.json file is a descriptor of OpenTSDB metric names that will be created when the application is deployed. We need to modify this file to define the metric names we need in OpenTSDB:

    { "name": "iftable.inpkts" },
    { "name": "iftable.outpkts" }

The upstart.conf file provides the Java command-line to run the Spark streaming application.

The Scala Code

The main entry point for the application is The application is structured like this:

PndaConsumer            // initialisation code
  - KafkaPipeline       // constructs a spark pipeline
    - KafkaInput        // spark input stream
    - OpenTSDBOutput    // producer at end of pipeline

The main work is done by OpenTSDBOutput – it transforms each message into a set of time-series data points that then get pushed to OpenTSDB. Here we extract values of interest from the XML input payload, construct a JSON time-series data point and POST it to OpenTSDB.

partition.foreach(event => {
  val host = event.getHostIp
  val timestamp = event.getTimestamp
  val payload = scala.xml.XML.loadString(event.getRawdata)
  val interface = (payload \\ "IfDescr").text
  val inPkts = (payload \\ "IfInUcastPkts").text
  val outPkts = (payload \\ "IfOutUcastPkts").text

  List(("inpkts", inPkts), ("outpkts", outPkts)).map{ 
    case (name, value) => {
      val body = f"""{
        | "metric": "iftable.$name" ,
        | "value": "$value",
        | "timestamp": $timestamp,
        | "tags": {"host": "$host", "interface": "$interface"}

      var openTSDBUrl = "http://" + opentsdbIP + "/api/put"
      try {
        val httpClient = new DefaultHttpClient()
        val post = new HttpPost(openTSDBUrl)
        post.setHeader("Content-type", "application/json")
        post.setEntity(new StringEntity(body))
      } catch {
        case NonFatal(t) => { }
      count += 1

The code is currently very simple to aid readability and could easily be improved by pushing data points to OpenTSDB in batches.

Deploying the Application

The first step to deploying an application on PNDA is to push it to the PNDA application repository, where $(SERVER) is the pnda-edge host:

curl -XPUT \
  http://$(SERVER):8888/packages/pnda-kso-iftable-app-0.0.1.tar.gz \
  --data-binary @target/universal/pnda-kso-iftable-app-0.0.1.tar.gz

Once this is done, it is possible to deploy the package from the PNDA console.

As soon as the application is deployed, it is possible to go to the Grafana dashboard and start to build new graphs that utilise the metrics being published by the application.


The final PNDA application can be found here:


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s