cancel
Showing results for 
Search instead for 
Did you mean: 
Login & Join the DevCentral Connects Group to watch the Recorded LiveStream (May 12) on Basic iControl Security - show notes included.

Problem this snippet solves:

This PowerShell application will illustrate how to pull out the rolled up Http Statistics taking from all of the Http Profiles.

I was digging through the iControl interfaces the other day and it's still amazing to me, after being around since the beginning of the API, to find new and cool stuff hiding in there. Today's find was lurking within the System.Statistics interface. There are literally dozens of method calls to pull out all sorts of useful statistics and the one I picked for today is the System HTTP Statistics which are a rollup of all HTTP Profiles' statistics. This application will build a report on everything you wanted to know from an HTTP level such as how many 5xx responses have been served to the number of bytes of compressed video and the RAM cache hits and misses.

Code :

# The contents of this file are subject to the "END USER LICENSE AGREEMENT FOR F5
# Software Development Kit for iControl"; you may not use this file except in
# compliance with the License. The License is included in the iControl
# Software Development Kit.
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
#
# The Original Code is iControl Code and related documentation
# distributed by F5.
#
# The Initial Developer of the Original Code is F5 Networks,
# Inc. Seattle, WA, USA. Portions created by F5 are Copyright (C) 1996-2007 F5 Networks,
# Inc. All Rights Reserved.  iControl (TM) is a registered trademark of F5 Networks, Inc.
#
# Alternatively, the contents of this file may be used under the terms
# of the GNU General Public License (the "GPL"), in which case the
# provisions of GPL are applicable instead of those above.  If you wish
# to allow use of your version of this file only under the terms of the
# GPL and not to allow others to use your version of this file under the
# License, indicate your decision by deleting the provisions above and
# replace them with the notice and other provisions required by the GPL.
# If you do not delete the provisions above, a recipient may use your
# version of this file under either the License or the GPL.
#----------------------------------------------------------------------------
param (
  $g_bigip = $null,
  $g_uid = $null,
  $g_pwd = $null,
  $g_subset = $null
);

Set-PSDebug -strict;

#-------------------------------------------------------------------------
# function Write-Usage
#-------------------------------------------------------------------------
function Write-Usage()
{
  Write-Host "Usage: GlobalHttpStats.ps1 host uid pwd [subset = all|http|compression|cache]";
  exit;
}

#-------------------------------------------------------------------------
# function Get-TimeFromTimeStamp
#-------------------------------------------------------------------------
function Get-TimeFromTimeStamp()
{
  param ($TimeStamp);
  $dt = new-object -typename System.DateTime
  $dt = $dt.AddYears($TimeStamp.year-1).AddMonths($TimeStamp.month-1).AddDays($TimeStamp.day-1)
  $dt = $dt.AddHours($TimeStamp.hour).AddMinutes($TimeStamp.minute).AddSeconds($TimeStamp.second);
  return $dt;
}

################################################################################ 
## Invoke-Inline.ps1 (originally from Lee Holmes)
## Library support for inline C# 
## 
## Modified by Joel Bennett to accept include statements, and return collections
##
## Usage 
##  1) Define just the body of a C# method, and store it in a string.  "Here 
##     strings" work great for this.  The code can be simple: 
## 
##     $codeToRun = "Console.WriteLine(Math.Sqrt(337));" 
## 
##     or more complex, using result.Add(): 
## 
##     $codeToRun = @" 
##         string firstArg = (string) ((System.Collections.ArrayList) arg)[0]; 
##         int secondArg = (int) ((System.Collections.ArrayList) arg)[1]; 
## 
##         Console.WriteLine("Hello {0} {1}", firstArg, secondArg ); 
##      
##         result.Add(secondArg * 3); 
##     "@ 
## 
##  2) If you must pass arguments, you should make them strongly-typed, 
##   so that PowerShell doesn't wrap it as a PsObject. 
## 
##  3) Invoke the inline code, optionally retrieving the return value.  You can 
##     set the return values in your inline code by assigning it to the 
##     "return" collection as shown above. 
## 
##     $result = Invoke-Inline $usingStatements, $codeToRun $arguments 
##     $result = Invoke-Inline  $codeToRun $arguments 
## 
## 
##     If your code is simple enough, you can even do this entirely inline: 
## 
##     Invoke-Inline "Console.WriteLine(Math.Pow(337,2));" 
##   
################################################################################ 
function Invoke-Inline()
{
  param(
    [string[]] $code, 
    [object[]] $arguments,
    [string[]] $reference = @()
  )

  ## Stores a cache of generated inline objects.  If this library is dot-sourced 
  ## from a script, these objects go away when the script exits. 
  if(-not (Test-Path Variable:\inlineCode.Cache))
  {
    ${GLOBAL:inlineCode.Cache} = @{}
  }

  $using = $null;
  $source = $null;
  if($code.length -eq 1) {
    $source = $code[0]
  } elseif($code.Length -eq 2){
    $using = $code[0]
    $source = $code[1]
  } else {
    Write-Error "You have to pass some code, or this won't do anything ..."
  }

  ## un-nesting magic (why do I need this?)
  $params = @()
  foreach($arg in $arguments) { $params += $arg }
  $arguments = $params

  ## The main function to execute inline C#.   
  ## Pass the argument to the function as a strongly-typed variable.  They will  
  ## be available from C# code as the Object variable, "arg". 
  ## Any values assigned to the "returnValue" object by the C# code will be  
  ## returned to MSH as a return value. 

  ## See if the code has already been compiled and cached 
  $cachedObject = ${inlineCode.Cache}[$source] 
  #Write-Verbose "Type: $($arguments[0].GetType())"

  ## The code has not been compiled or cached 
  if($cachedObject -eq $null)
  {
    $codeToCompile = 
@"
    using System;
    using System.Collections.Generic;
    $using

    public class InlineRunner 
    { 
      public List Invoke(Object[] args) 
      { 
        List result = new List(); 

        $source 

        if( result.Count > 0 ) {
            return result;
        } else {
            return null;
        }
      } 
    } 
"@
    Write-Verbose $codeToCompile

    ## Obtains an ICodeCompiler from a CodeDomProvider class. 
    $provider = New-Object Microsoft.CSharp.CSharpCodeProvider 

    ## Get the location for System.Management.Automation DLL 
    $dllName = [PsObject].Assembly.Location

    ## Configure the compiler parameters 
    $compilerParameters = New-Object System.CodeDom.Compiler.CompilerParameters 

    $assemblies = @("System.dll", $dllName) 
    $compilerParameters.ReferencedAssemblies.AddRange($assemblies) 
    $compilerParameters.ReferencedAssemblies.AddRange($reference)
    $compilerParameters.IncludeDebugInformation = $true 
    $compilerParameters.GenerateInMemory = $true 

    ## Invokes compilation.  
    $compilerResults =
      $provider.CompileAssemblyFromSource($compilerParameters, $codeToCompile) 

    ## Write any errors if generated.         
    if($compilerResults.Errors.Count -gt 0) 
    { 
      $errorLines = "" 
      foreach($error in $compilerResults.Errors) 
      { 
        $errorLines += "`n`t" + $error.Line + ":`t" + $error.ErrorText 
      } 
      Write-Error $errorLines 
    } 
    ## There were no errors.  Store the resulting object in the object 
    ## cache. 
    else 
    { 
      ${inlineCode.Cache}[$source] = 
        $compilerResults.CompiledAssembly.CreateInstance("InlineRunner") 
    } 

    $cachedObject = ${inlineCode.Cache}[$source] 
   } 

   Write-Verbose "Argument $arguments`n`n$cachedObject"
   ## Finally invoke the C# code 
   if($cachedObject -ne $null)
   {
     return $cachedObject.Invoke($arguments)
   }
}

#-------------------------------------------------------------------------
# function Convert-To64Bit
#-------------------------------------------------------------------------
function Convert-To64Bit()
{
  param($high, $low);
  return Invoke-Inline "result.Add((Convert.ToUInt64($high)<<32) | (Convert.ToUInt64($low)));"
}

#-------------------------------------------------------------------------
# Get-GlobalHttpStatistics
#-------------------------------------------------------------------------
function Get-GlobalHttpStatistics()
{
  param($subset = $null);
  if ( $subset -eq $null ) { $subset = "all"; }
  
  Write-Host "Global HTTP Statistics"
  
  $stat_obj = New-Object -TypeName System.Object;
  
  $SystemStatistics = (Get-F5.iControl).SystemStatistics.get_http_statistics();
  $t = Get-TimeFromTimeStamp $SystemStatistics.time_stamp;
  $Statistics = $SystemStatistics.statistics;
  
  $stat_obj | Add-Member -Type noteProperty -Name "Time Stamp" $t;
  $stat_obj | Add-Member -Type noteProperty -Name "--------------------------------" "";

  foreach($Statistic in $Statistics)
  {
    $val = Convert-To64Bit $Statistic.value.high $Statistic.value.low;
    $bDisplay = 0;
    switch ($Statistic.type)
    {
      "STATISTIC_HTTP_COOKIE_PERSIST_INSERTS" {
        $label = "Cookie Persist Header Inserts";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "http"))
      }
      "STATISTIC_HTTP_2XX_RESPONSES" {
        $label = "Responses - 2xx";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "http"))
      }
      "STATISTIC_HTTP_3XX_RESPONSES" {
        $label = "Responses - 3xx";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "http"))
      }
      "STATISTIC_HTTP_4XX_RESPONSES" {
        $label = "Responses - 4xx";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "http"))
      }
      "STATISTIC_HTTP_5XX_RESPONSES" {
        $label = "Responses - 5xx";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "http"))
      }
      "STATISTIC_HTTP_TOTAL_REQUESTS" {
        $label = "Requests  - Total";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "http"))
      }
      "STATISTIC_HTTP_GET_REQUESTS" {
        $label = "Requests  - HTTP GET";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "http"))
      }
      "STATISTIC_HTTP_POST_REQUESTS" {
        $label = "Requests  - HTTP POST";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "http"))
      }
      "STATISTIC_HTTP_V9_REQUESTS" {
        $label = "Requests  - v0.9";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "http"))
      }
      "STATISTIC_HTTP_V10_REQUESTS" {
        $label = "Requests  - v1.0";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "http"))
      }
      "STATISTIC_HTTP_V11_REQUESTS" {
        $label = "Requests  - v1.1";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "http"))
      }
      "STATISTIC_HTTP_V9_RESPONSES" {
        $label = "Responses - v0.9";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "http"))
      }
      "STATISTIC_HTTP_V10_RESPONSES" {
        $label = "Responses - v1.0";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "http"))
      }
      "STATISTIC_HTTP_V11_RESPONSES" {
        $label = "Responses - v1.1";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "http"))
      }
      "STATISTIC_HTTP_MAXIMUM_KEEPALIVE_REQUESTS" {
        $label = "Requests  - Maximum Keepalive";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "http"))
      }
      "STATISTIC_HTTP_BUCKET_1K_RESPONSES" {
        $label = "Responses - under 1k";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "http"))
      }
      "STATISTIC_HTTP_BUCKET_4K_RESPONSES" {
        $label = "Responses - From 1-4k";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "http"))
      }
      "STATISTIC_HTTP_BUCKET_16K_RESPONSES" {
        $label = "Responses - From 4-16k";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "http"))
      }
      "STATISTIC_HTTP_BUCKET_32K_RESPONSES" {
        $label = "Responses - From 16-32k";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "http"))
      }
      "STATISTIC_HTTP_BUCKET_64K_RESPONSES" {
        $label = "Responses - From 32-64k";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "http"))
      }
      "STATISTIC_HTTP_PRE_COMPRESSION_BYTES" {
        $label = " Pre Compression Bytes";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "compression"))
      }
      "STATISTIC_HTTP_POST_COMPRESSION_BYTES" {
        $label = "Post Compression Bytes";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "compression"))
      }
      "STATISTIC_HTTP_NULL_COMPRESSION_BYTES" {
        $label = "     Compression Bytes - Null";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "compression"))
      }
      "STATISTIC_HTTP_HTML_PRE_COMPRESSION_BYTES" {
        $label = " Pre Compression Bytes - HTML";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "compression"))
      }
      "STATISTIC_HTTP_HTML_POST_COMPRESSION_BYTES" {
        $label = "Post Compression Bytes - HTML";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "compression"))
      }
      "STATISTIC_HTTP_CSS_PRE_COMPRESSION_BYTES" {
        $label = " Pre Compression Bytes - CSS";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "compression"))
      }
      "STATISTIC_HTTP_CSS_POST_COMPRESSION_BYTES" {
        $label = "Post Compression Bytes - CSS";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "compression"))
      }
      "STATISTIC_HTTP_JS_PRE_COMPRESSION_BYTES" {
        $label = " Pre Compression Bytes - JavaScript";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "compression"))
      }
      "STATISTIC_HTTP_JS_POST_COMPRESSION_BYTES" {
        $label = "Post Compression Bytes - JavaScript";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "compression"))
      }
      "STATISTIC_HTTP_XML_PRE_COMPRESSION_BYTES" {
        $label = " Pre Compression Bytes - XML";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "compression"))
      }
      "STATISTIC_HTTP_XML_POST_COMPRESSION_BYTES" {
        $label = "Post Compression Bytes - XML";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "compression"))
      }
      "STATISTIC_HTTP_SGML_PRE_COMPRESSION_BYTES" {
        $label = " Pre Compression Bytes - SGML";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "compression"))
      }
      "STATISTIC_HTTP_SGML_POST_COMPRESSION_BYTES" {
        $label = "Post Compression Bytes - SGML";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "compression"))
      }
      "STATISTIC_HTTP_PLAIN_PRE_COMPRESSION_BYTES" {
        $label = " Pre Compression Bytes - Plain";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "compression"))
      }
      "STATISTIC_HTTP_PLAIN_POST_COMPRESSION_BYTES" {
        $label = "Post Compression Bytes - Plain";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "compression"))
      }
      "STATISTIC_HTTP_OCTET_PRE_COMPRESSION_BYTES" {
        $label = " Pre Compression Bytes - Octet";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "compression"))
      }
      "STATISTIC_HTTP_OCTET_POST_COMPRESSION_BYTES" {
        $label = "Post Compression Bytes - Octet";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "compression"))
      }
      "STATISTIC_HTTP_IMAGE_PRE_COMPRESSION_BYTES" {
        $label = " Pre Compression Bytes - Image";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "compression"))
      }
      "STATISTIC_HTTP_IMAGE_POST_COMPRESSION_BYTES" {
        $label = "Post Compression Bytes - Image";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "compression"))
      }
      "STATISTIC_HTTP_VIDEO_PRE_COMPRESSION_BYTES" {
        $label = " Pre Compression Bytes - Video";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "compression"))
      }
      "STATISTIC_HTTP_VIDEO_POST_COMPRESSION_BYTES" {
        $label = "Post Compression Bytes - Video";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "compression"))
      }
      "STATISTIC_HTTP_AUDIO_PRE_COMPRESSION_BYTES" {
        $label = " Pre Compression Bytes - Audio";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "compression"))
      }
      "STATISTIC_HTTP_AUDIO_POST_COMPRESSION_BYTES" {
        $label = "Post Compression Bytes - Audio";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "compression"))
      }
      "STATISTIC_HTTP_OTHER_PRE_COMPRESSION_BYTES" {
        $label = " Pre Compression Bytes - Other";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "compression"))
      }
      "STATISTIC_HTTP_OTHER_POST_COMPRESSION_BYTES" {
        $label = "Post Compression Bytes - Other";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "compression"))
      }
      "STATISTIC_HTTP_RAM_CACHE_HITS" {
        $label = "RAM Cache - Hits";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "cache"))
      }
      "STATISTIC_HTTP_RAM_CACHE_MISSES" {
        $label = "RAM Cache - Misses";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "cache"))
      }
      "STATISTIC_HTTP_RAM_CACHE_TOTAL_MISSES" {
        $label = "RAM Cache - Total Misses";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "cache"))
      }
      "STATISTIC_HTTP_RAM_CACHE_HIT_BYTES" {
        $label = "RAM Cache - Hit Bytes";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "cache"))
      }
      "STATISTIC_HTTP_RAM_CACHE_MISS_BYTES" {
        $label = "RAM Cache - Miss Bytes";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "cache"))
      }
      "STATISTIC_HTTP_RAM_CACHE_TOTAL_MISS_BYTES" {
        $label = "RAM Cache - Total Miss Bytes";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "cache"))
      }
      "STATISTIC_HTTP_RAM_CACHE_SIZE" {
        $label = "RAM Cache - Size";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "cache"))
      }
      "STATISTIC_HTTP_RAM_CACHE_COUNT" {
        $label = "RAM Cache - Count";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "cache"))
      }
      "STATISTIC_HTTP_RAM_CACHE_EVICTIONS" {
        $label = "RAM Cache - Evictions";
        $bDisplay = (($subset -eq "all") -or ($subset -eq "cache"))
      }
      default {
        $label = $Statistic.type
        $bDisplay = 1;
      }
    }
    if ( $bDisplay -ne 0 )
    {
      #Write-Host "$label : $val"
      $stat_obj | Add-Member -Type noteProperty -Name $label $val;
    }
  }
  $stat_obj | format-list
}

#-------------------------------------------------------------------------
# Do-Initialize
#-------------------------------------------------------------------------
function Do-Initialize()
{
  if ( (Get-PSSnapin | Where-Object { $_.Name -eq "iControlSnapIn"}) -eq $null )
  {
    Add-PSSnapIn iControlSnapIn
  }
  $success = Initialize-F5.iControl -HostName $g_bigip -Username $g_uid -Password $g_pwd;
  
  return $success;
}

#-------------------------------------------------------------------------
# Main Application Logic
#-------------------------------------------------------------------------
if ( ($g_bigip -eq $null) -or ($g_uid -eq $null) -or ($g_pwd -eq $null) )
{
  Write-Usage;
}

if ( Do-Initialize )
{
  Get-GlobalHttpStatistics $g_subset;
}
else
{
  Write-Error "ERROR: iControl subsystem not initialized"
}
Version history
Last update:
‎09-Mar-2015 12:10
Updated by:
Contributors