[Asterisk-Dev] Bandwidth application / Call Counting application

John Todd jtodd at loligo.com
Mon May 31 18:10:42 MST 2004


After some long discussions with another Asterisk consultant this afternoon, some ideas were formulated.

The concept of measuring bandwidth and figuring out channel counts has come up on several occasions in my work with Asterisk.  Limited bandwidth to an upstream WAN, or simply wanting to know how much traffic is flowing around seems like a good set of data to have.  If we can get this data from Asterisk (I know it exists) collected in one place, then maybe some measurement becomes more easily integrated.  The concept of making this available from the Manager interface would mean that things would easily be accessible to RRDTool, MRTG, or what-have-you after some very simple shell scripts.  "What you measure, you manage." as the saying goes.  I propose "app_bandwidth" below.

We have specific call counting features in the "groupcount", but it doesn't seem like a really handy solution for more global questions, especially when we try to get answers based on things that aren't easily accessible by dialplan space (i.e.: codec usage.)  I think something for simply counting usage against some type of filter would be very useful for dialplan redirection.  I propose "app_callcount" below.

I'll add these to the seemingly infinite pile of "applications which seem to be very handy, but will not be implemented any time soon because John can't pay for them, nor can he program."

JT


I wish there were two applications that looked like the following:

app_bandwidth:

Bandwidth(RESULTVARIABLE,[[[-]TECHNOLOGY[/PEER]]|...],[[[-]CODEC]|...],OPTIONS,[[[-]NETWORK/MASK]|...] )

RESULTVARIABLE:  
  This variable is populated with a long integer of the estimated bits per second being transmitted and received by the Asterisk server.  Note that this value will be double what a uni-directional call will consume, since Asterisk has to handle both transmit and receive for a single leg.  In other words, a single G.711 SIP call will result in a number like "240000" since that's 80 * 2 * 2.

TECHNOLOGY/PEER:
  The technology can be specified by itself, or optionally with the peer name.  The keyword "all" can be used by itself, or can substitute for either side of the technology/peername value.  A minus "-" sign in front of either the technology or peername excludes that particular combination from the computation.  Multiple technology/peername values or subsets can be used, separated by the pipe "|" character, and also negative and positive inclusions can be applied at the same time.  The last match encountered is used when evaluating include/exclude logic.

CODEC:
  The codecs to include or exclude in the evaluation.  The keyword "all" can be used to represent all possible codecs.  A minus "-" sign can be used to exclude a codec from the evaluation.  Mixes of multiple codecs (or the "all" wildcard) can be specified with the pipe "|" character in between entries of either inclusive or exclusive status.  The last match encountered is used when evaluating include/exclude logic.  If not specified, "all" is assumed.

OPTIONS:
  e = estimate usage for calls which are active but media is not through Asterisk (i.e.: re-INVITE'ed SIP sessions)  Default is to not estimate these sessions.
  k = kilobyte per second reply (normally kilobits per second)
  m = megabyte per second reply (normally kilobits per second)

NETWORK/MASK:
  The CIDR notation networks to include or exclude from the comparison. A minus "-" sign can be used to exclude a network from the evaluation.  Mixes of multiple networks can be specified with the pipe "|" character in between entries of either inclusive or exclusive status.  The last match encountered is used when evaluating include/exclude logic.  If not specified, it is assumed that all networks should be included in the evaluation.


Examples of Use: 

Report bandwidth on all active SIP sessions for all codecs, and put result into ${BW}
  exten => _X.,1,BandwidthCalc(BW,SIP,all)

Report bandwidth on all active IAX2 sessions for all peers, but only report G.711 streams, and return result into ${BW}:
  exten => _X.,1,BandwidthCalc(BW,IAX2,ulaw|alaw)

Report bandwidth on all active sessions, except for sessions involving network 10.0.0.0/8, and put result into ${BW}:
  exten => _X.,1,BandwidthCalc(BW,all,all,,-10.0.0.0/8)

Report bandwidth on all active sessions, except for 10.0.0.0/8 and also excluding any G.711 channels, and put result into ${BW}:
  exten => _X.,1,BandwidthCalc(BW,all,all|-ulaw|-alaw,,-10.0.0.0/8)

Report bandwidth on all active SIP sessions going to 128.151.0.0/8 and put result into ${BW}:
  exten => _X.,1,BandwidthCalc(BW,SIP,all,,128.151.0.0/8)

Report bandwidth on all active IAX2 sessions going to the peer known as "voiceplump" and put result into ${VP}
  exten => _X.,1,BandwidthCalc(VP,IAX2/voiceplump)



Discussion:
  The system does not compute "real" bandwidth, meaning that the actual packets in and out are not counted.  That's a different, and much more complex, computation (though it's probable that data already exists in Asterisk somewhere.)  The system only guesses, based on previously built tables of codec bandwidth usage.

  IAX2 channels which have been released are not computed, since the server has no knowledge of those sessions or even if they still exist.  SIP is a different story, since Asterisk keeps state for those calls even if the media stream is directly between the two endpoints, and the system can optionally include those estimated volumes in it's output if the "e" option is presented.

  ZAP channels are automatically excluded unless included, and are treated as G.711 calls.  Users should be cautious to only include TDMoE channels in their specification.  The system actually treats any Zap channels included as "up" all the time at 64kbps, so including Zap channel types is kind of useless.

  SIP and IAX2 channel specifications will encompass any calls that come in or go out through that particular named user/peer/friend (automatically accounts for naming conventions, SRV records, and network/mask permissions by using only the peer definitions.)

  The application treats each leg as a discrete call, and does not care where calls are originating/terminating or how they connect.

  Perhaps a file could be created (bandwidth.conf?) which contained a static list of each codec and it's estimated bits-per-second usage in a trunked and non-trunked environment, and app_bandwidth would draw it's conclusions from those figures.

  Kilobits per second are assumed to be symmetric for inbound/outbound path on each call leg.  I know that there are some very rare circumstances under which codecs may be mis-matched for each direction of a call leg, but inclusion of code to catch this subtle eventuality is left as an exercise to the programmer.   

  Variable bitrate codecs are a big question mark here - we should actually know the bitrate, somewhere, but I don't know if that's ever stored in Asterisk anywhere.

  Trunked calls for IAX2 should be considered at a different value than non-trunked calls, but of course the first call in a trunk should have non-trunked values because it carries the IP overhead.  (i.e.: G.729 in a trunk means that the first call creates a ~30kbps stream, and then every subsequent call in the trunk adds 9.6kbps.)

  I don't know enough about the manager interface to say how difficult it would be to add this application as a new manager interface command, but it seems like it would be a Good Thing.




app_callcount:

CallCount(RESULTVARIABLE,[[[-]TECHNOLOGY[/PEER]]|...],[[[-]CODEC]|...],OPTIONS,[[[-]NETWORK/MASK]|...] )

 (see app_bandwidth description)


Examples of Use:

Count the number of active sessions going to the IAX2 peer known as "voiceplump" and put that number in ${VP}:
  exten => _X.,1,BandwidthCalc(VP,IAX2/voiceplump)

Count the number of active sessions going to the SIP peer known as "mybiggateway", subtract those calls which are using G.729, and put the resulting number in ${VP}:
  exten => _X.,1,BandwidthCalc(VP,SIP/mybiggateway,all|-g729)


Discussion:
  This takes almost the exact same arguments as Bandwidth, except there are no options (yet.)  The resulting variable stored in RESULTVARIABLE is the number of calls that are active that match the criteria given.  




References:
 IAX2 trunking vs. non-trunking bandwidth usage
  http://lists.digium.com/pipermail/asterisk-users/2003-June/014788.html




More information about the asterisk-dev mailing list