#!/usr/bin/perl use strict; # use module use XML::Simple; use Data::Dumper; use LWP::UserAgent; use Getopt::Std; use RRDs; use Scalar::Util 'reftype'; # Parse Commandline options: # q: quiet # r: write to RRD # i: specify refresh interval (default 10s) my $interval; our($opt_r,$opt_q,$opt_i); getopts('rqi:'); if (!$opt_i) { $interval = 10; } else { $interval = $opt_i; } while (1) { #establish forever loop # Poll Origin server for list of active edge servers my $lb_ua = new LWP::UserAgent; my $lb_url = "http://wms.rezonline.org:1935/loadbalancer?serverInfoXML"; my $lb_req = new HTTP::Request GET => $lb_url; my $lb_res = $lb_ua->request($lb_req); my @lb_ip; if($lb_res->is_success) { my $lb_xml = new XML::Simple; my $lb_data = $lb_xml->XMLin($lb_res->content); # Dump raw XML (for debugging) # print Dumper($lb_data); # check reference type: # if HASH, only single server is running, and XML returns without an array wrapping single element # if ARRAY, multiple servers, each one inside an array element. my $reference = reftype $lb_data->{LoadBalancerServer}; # Check to see how to handle this... if ( $reference eq 'ARRAY' ) { for my $lb_server (@{$lb_data->{LoadBalancerServer}}) { if ($lb_server->{status} eq "RUNNING") { #print "ID: $lb_server->{serverId} at $lb_server->{redirect}n"; push @lb_ip, $lb_server->{redirect}; } } } elsif ( $reference eq 'HASH' ) { if ($lb_data->{LoadBalancerServer}->{status} eq "RUNNING") { push @lb_ip, $lb_data->{LoadBalancerServer}->{redirect}; } } else { print "unknown reference type - abortingn"; } } # End is_success loop my $arraysize = @lb_ip; #print "Array size: $arraysize elements: n"; # Step through the returned array of edge IPs and gather stats # Scope total variables my %streamTotal = 0; foreach (@lb_ip) { # print "Gathering stats for edge server at $_n"; my $ua = new LWP::UserAgent; $ua->timeout(10); my $edgeurl = "http://$_:1935/connectioncounts.xml?flat"; # Make sure you use FLAT mode here, otherwise the XML is a pain to parse when there are multiple server applications my $edgereq = new HTTP::Request GET => $edgeurl; my $edgeres = $ua->request($edgereq); # create object my $cupertinosum = 0; #Apple HLS my $rtspsum = 0; #RTSP my $flashsum = 0; #RTMP my $sanjosesum = 0; #Flash HTTP my $smoothsum = 0; #Silverlight Smooth Streaming my $streamcount = 0; #Total Streams my %namecount = 0; #Streams per published stream if($edgeres->is_success) { my $edgexml = new XML::Simple; my $edgedata = $edgexml->XMLin($edgeres->content, ForceArray => 1); my $loopindex = 0; for my $stream (@{$edgedata->{Stream}}) { # At some point we're going to want to filter out the publishing points and only look at the edge application # in which case, check for applicationName and ignore based on that $loopindex++; $flashsum += $stream->{sessionsFlash}; $rtspsum += $stream->{sessionsRTSP}; $cupertinosum += $stream->{sessionsCupertino}; $sanjosesum += $stream->{sessionsSanJose}; $smoothsum += $stream->{sessionsSmooth}; $streamcount += $stream->{sessionsTotal}; $namecount{$stream->{streamName}} = $streamcount; } # End of FOR loop } else { print " X "; # Indicate that server poll was not successful } # End of if loop my $rokusum = $namecount{'roku.smil'} + $namecount {'mobile.smil'}; #$start60 = $circbuf[-6]; #$start90 = $circbuf[-9]; # #shift (@circbuf); # #push (@circbuf,$flashsum); #$delta60=$flashsum-$start60; #$delta90=$flashsum-$start90; !$opt_q && print "$_ : $streamcount "; !$opt_q && print "[ F: $flashsum: H $cupertinosum : R $rtspsum ]"; !$opt_q && print "[ Low: $namecount{'mobile-1'} High: $namecount{'mobile-2'} ]"; !$opt_q && print "[ iOS: $namecount{'ipad.smil'} Roku: $namecount{'roku.smil'},$namecount{'mobile.smil'} ]n"; #!$opt_q && print "[ StreamClass | High: $namecount{'playlist-high'} Low: $namecount{'playlist-low'} ]n"; $streamTotal{'Cupertino'} += $cupertinosum; $streamTotal{'Flash'} += $flashsum; $streamTotal{'SanJose'} += $sanjosesum; $streamTotal{'Smooth'} += $smoothsum; $streamTotal{'RTSP'} += $rtspsum; $streamTotal{'Roku'} += $namecount{'roku.smil'}; $streamTotal{'iOS'} += $namecount{'ipad.smil'}; $streamTotal{'Total'} += $streamcount; } # End stats gathering loop per server !$opt_q && print "Total: $streamTotal{'Total'} [F: $streamTotal{'Flash'} H: $streamTotal{'Cupertino'}(iOS: $streamTotal{'iOS'} Roku: $streamTotal{'Roku'}) SJ: $streamTotal{'SanJose'} SL: $streamTotal{'Smooth'}]"; $opt_r && RRDs::update("/var/rrd/streams-2011.rrd","N:$streamTotal{'Smooth'}:$streamTotal{'SanJose'}:$streamTotal{'Cupertino'}:$streamTotal{'RTSP'}:$streamTotal{'Flash'}:$streamTotal{'iOS'}:$streamTotal{'Roku'}"); if (!$opt_q) { $opt_r && print "[RRD] "; } !$opt_q && print "n"; sleep($interval); } # End of Forever Loop