Wowza stats collector with RRD (perl)

This perl script connects to a Wowza origin server and the connectioncounts.xml HTTPProvider function and extracts current connection counts at an interval specified on the command line (defaults every 10 seconds). Commandline options to write to an RRD file and silent operation. RRD file used in this example is described over here. This can be graphed with these commands.

#!/usr/bin/perl
use strict;

# use module
use XML::Simple;
use Data::Dumper;
use LWP::UserAgent;
use Getopt::Std;
use RRDs;

my $interval=0;
my $rrd_file="/var/rrd/streams-2011.rrd";

our($opt_r,$opt_q,$opt_i,$opt_s);
getopts('rqi:s:');

# Command-line options:
#
# -i <seconds>      Specifies polling interval
# -q                Silent operation (for running in a cron job)
# -r                Outputs to RRD
# -s <server>       Specifies server to poll

# Set default interval
if (!$opt_i) { $interval = 10; } else { $interval = $opt_i; }

!$opt_s && die('Please specify a server to query');

while (1) {

my $ua = new LWP::UserAgent;
$ua->timeout(10);

# Set up connection
my $wowza_url = "http://$opt_s:1935/connectioncounts.xml";
my $wowza_request = new HTTP::Request GET => $wowza_url;
my $wowza_result = $ua->request($wowza_request);

# create object

my $hlssum = 0;
my $rtspsum = 0;
my $flashsum = 0;
my $iphonesum = 0;
my @streamcount = 0;
my %namecount = 0;

if($wowza_result->is_success) {
 my $wowza_xml = new XML::Simple;
 my $wowza_data = $wowza_xml->XMLin($wowza_result->content);
 my $loopindex = 0;
 #Loop through all Streams

 for my $stream (@{$wowza_data->{VHost}->{Application}->{ApplicationInstance}->{Stream}})
  {
   $loopindex++;
   $flashsum += $stream->{SessionsFlash};
   $hlssum += $stream->{SessionsCupertino};
   $rtspsum += $stream->{SessionsRTSP};
   $streamcount[$loopindex] = $stream->{SessionsFlash} + $stream->{SessionsCupertino} + $stream->{SessionsRTSP};
   $namecount{$stream->{Name}} = $streamcount[$loopindex];
  }
 } else {
  !$opt_q && print " [ERR] ";
 }

# You'll need to alter the %namecount hashes here to accomodate for your own stream names. 

$opt_r && RRDs::update("/var/rrd/streams-2011.rrd","N:$namecount{'mobile-1'}:$namecount{'mobile-2'}:$hlssum:$rtspsum:$flashsum:$namecount{'ipad.smil'}:$namecount{'mobile.smil'}");
if (!$opt_q) { $opt_r && print "[RRD] "; }

!$opt_q && print "[ F: $flashsum: H $hlssum : R $rtspsum ]";
!$opt_q && print "[ Low: $namecount{'mobile-1'} High: $namecount{'mobile-2'} ]";
!$opt_q && print "[ iOS: $namecount{'ipad.smil'} Roku: $namecount{'mobile.smil'} ]";
!$opt_q && print "[ StreamClass | High: $namecount{'playlist-high'} Low: $namecount{'playlist-low'} ]n";

sleep($interval);
}
  • http://www.engagetv.com Gerbrand

    this looks promising. there seems to be a type in line 54:

    for my $stream (@{$wowza)data->{VHost}->{Application}->{ApplicationInstance}->{Stream}})

    should read (i think):

    for my $stream (@{$wowza_data->{VHost}->{Application}->{ApplicationInstance}->{Stream}})

    • Anonymous

      Ah, good catch, thanks!

  • Pingback: Inside Wowza Startup Packages | Streaming My Consciousness

  • jasonvincent

    Seems interesting… I just started to use EC2 and Wowza so I will test it out to see what happens.
    Only one thing about the script, you declared $rrd_file at the top but then used the filepath itself rather than the variable later down.

  • http://twitter.com/gerbrand Gerbrand Oudenaarden

    Hi,

    I keep getting the following error:

    Not a HASH reference at ./get_wowza_connections.pl line 54.
    I can print a dump of the hash of the xml that looks just fine, so I must be overlooking something very silly, but I don’t see it. What could I be doing wrong? The only thing I changed was the URL of the connection xml page.

    • http://blog.ianbeyer.com Ian B

      That’s a function of Perl’s XML parsing – sometimes it returns an array (if there’s more than one repeater), and sometimes a hash (only one repeater). I haven’t found a good way to deal with this in perl. It’s much easier in PHP. 

  • LagaV

    Ian, great stuff you are doing here. Just some comments regarding this script:

    a) URL changed for me (line 35):

    Your script: my $wowza_url = “http://$opt_s:1935/connectioncounts.xml”;

    Option: my $wowza_url = “http://$opt_s:8086/connectioncounts.xml”;

    b) I had some errors with just one stream running, but some digging on stackoverflow.com helped (line 54):

    Your script: my $wowza_data = $wowza_xml->XMLin($wowza_result->content);

    Option: my $wowza_data = $wowza_xml->XMLin($wowza_result->content, ForceArray => ['Stream']);

    LagaV

Go to Top