Tech Tips on DevCentral
   
You are here: Tutorials > Tech Tips

Current Articles | Categories | Search | Syndication

Automated Gomez Performance Monitoring

by Joe - 5805 views Article Rating

gomez_solutionsGomez provides an on-demand platform that you use to optimize the performance, availability and quality of your Web and mobile applications. It identifies business-impacting issues by testing and measuring Web applications from the “outside-in” — across your users, browsers, mobile devices and geographies — using a global network of 100,000+ locations, including the industry’s only true Last Mile.

F5 and Gomez have partnered to provide a users of both technologies an easy way to integrate the two together.  In this article I will focus on the Web Performance Management component of the Gomez Platform.  Key features of their Web Performance Management solution include

  • Rapidly detect and troubleshoot problems that directly impact your customers.
    • Identify the root cause of issues using real-user passive monitoring.
    • Ensure web application availability and performance for key user segments.
  • Optimize web application performance
    • Improve web experiences across mobile, streaming, and web applications.
    • Reduce downtime and response times with detailed object-level, page, connection, and host data across multiple browsers.
  • Make smart technology investments and manage service providers effectively
    • Quantify the benefits of technology investments such as Content Delivery Networks (CDNs), virtualization, and infrastructure changes.
    • Ensure service level agreement compliance

All of these features can be possible by simply inserting a small section of client side JavaScript code into your web page requests.  Now, for a small site with only a couple of pages, this is fairly simple to do, but for sites like DevCentral with many 1000’s of pages, it is very cumbersome and requires developer support for integration.  In addition to that, application level changes typically require a testing cycle before being deployed into production.

The Client-side Script

The Gomez script looks something like this:

   1: <SCRIPT LANGUAGE="JavaScript"><!--
   2: var gomez={gs: new Date().getTime(), acctId:'XXXXXX', pgId:'', grpId:''};
   3: //--></SCRIPT> 
   4: <script src="/js/axfTag.js" type="text/javascript"></script>

The key configuration components are the following variables

  • acctId – Your Gomez Application id to link client page request to your Gomez Account
  • pgId – An optional page identifier that allows you to give a page, or set of pages, a unique user friendly name in the reporting.
  • grpId – An optional group identifier that you can use to further identify your page views.  This is highly useful in multi-datacenter deployments when you would like to differentiate the servers serving up your applications.

Enter iRules

With our embedded scripting technology iRules on the BIG-IP, deploying this client script code across all of your application becomes very simple.  Since all of your application traffic is traveling through the BIG-IP, it makes perfect sense to “inject” this code at the network layer.  That is exactly what I’m going to do with this solution.

Prerequsites

Make sure your Virtual Server is configured as follows:

 

  • Ensure that your Virtual Server has the default (or custom) “stream” profile assigned in it’s configuration.
  • Your Virtual Server must also have an associated HTTP Profile with the “Response Chunking” property set to “Rechunk”.

Handling The Request

You’ll notice I utilized the ability to serve up content directly from the iRule to eliminate the need to deploy the Gomez bootstrap code to a separate server.  Also, by implementing it this way instead of injecting the code directly into the page response, allows the browser to cache that data and reduce the size of your page request.

   1: when HTTP_REQUEST {
   2:  
   3:   set GOMEZ_APP_ID "XXXXXX";
   4:   set GOMEZ_DEBUG 0;
   5:   set gws_luri [string tolower [HTTP::uri]]
   6:   
   7:   if { $gws_luri eq "/js/axftag.js" } {
   8:     
   9:     # -----------------------------------------------------------------------
  10:     # Serve up Gomez bootstrap javascript
  11:     # -----------------------------------------------------------------------
  12:     HTTP::respond 200 content [string map {LBR \{ RBR \}} {/*Gomez ...}] "Content-Type" "application/x-javascript";
  13:  
  14:   } else {
  15:     
  16:     # ---------------------------------------------------------------------
  17:     # Don't allow response data to be chunked
  18:     # ---------------------------------------------------------------------
  19:     if { [HTTP::version] eq "1.1" } {
  20:       # -------------------------------------------------------------------
  21:       # Force downgrade to HTTP 1.0, but still allow keep-alive connections.
  22:       # Since HTTP 1.1 is keep-alive by default, and 1.0 isn't,
  23:       # we need make sure the headers reflect the keep-alive status.
  24:       # -------------------------------------------------------------------
  25:       if { [HTTP::header is_keepalive] } {
  26:         HTTP::header replace "Connection" "Keep-Alive";
  27:       }
  28:     }
  29:   }
  30: }

So, for request for the Gomez Bootstrap code (“/js/axftag.js”), the iRule will serve it up.  Otherwise, it will allow the request to pass through to the backend server.

Also, you will need to update your GOMEZ_APP_ID variable with your personal Application Id supplied to you from your Gomez account.

 

Injecting The Client-Side JavaScript

Now that the request has gone through to the backend application, we are ready to handle the response from the servers.  We are going to utilize the Stream profile to do the actual content replacement.  It’s fast and very easy to configure. 

Since we only want to inject the client code in valid web page responses, I’ve added a check for Content-Type “text/html” as well as a success HTTP Response code (200).  Then we’ll create a variable for the Gomez client code with the embedded Application Id and set the Stream expression for the Stream Filter to insert it right before the end of the Head element (or Body element if the Head element doesn’t exist in the response).

 

   1: when HTTP_RESPONSE {
   2:   
   3:  # -------------------------------------------------------------------------
   4:  # Stream filter is disabled by default
   5:  # -------------------------------------------------------------------------
   6:  STREAM::disable;
   7:   
   8:  # -------------------------------------------------------------------------
   9:  # Only process stream replacement for a valid response and content type is html.
  10:  # -------------------------------------------------------------------------
  11:  if { ([HTTP::header Content-Type] starts_with "text/html") && ([HTTP::status] == 200) } {
  12:    
  13:    set gomez_client [subst {<SCRIPT LANGUAGE="JavaScript"><!--
  14: ar gomez={gs: new Date().getTime(), acctId:'$::GOMEZ_APP_ID', pgId:'', grpId:''};
  15: /--></SCRIPT> 
  16: script src="/js/axfTag.js" type="text/javascript"></script>
  17:  ];
  18:  
  19:    if { $::GOMEZ_DEBUG > 1 } { log local0. "Adding Gomez JavaScript"; }
  20:    if { $::GOMEZ_DEBUG > 2 } { log local0. "$gomez_client"; }
  21:    
  22:    # -----------------------------------------------------------------------
  23:    # Set the stream replacement expression
  24:    # -----------------------------------------------------------------------
  25:    set stream_expression "@</\[Hh]\[Ee]\[Aa]\[Dd]>@$gomez_client</head>@@<\[Bb]\[Oo]\[Dd]\[Yy]>@$gomez_client<body>@";
  26:    STREAM::expression $stream_expression;
  27:     
  28:    if { $::GOMEZ_DEBUG > 2 } { log local0. "Current Stream Expression: $stream_expression"; }
  29:     
  30:    # -----------------------------------------------------------------------
  31:    # Enable the stream filter for this request.
  32:    # -----------------------------------------------------------------------
  33:    STREAM::enable;
  34:    
  35:  } else {
  36:    if { $::GOMEZ_DEBUG > 1 } { log local0. "Ignoring type [HTTP::header Content-Type], status=[HTTP::status]" }
  37:  }
  38:    

I’ve included the STREAM_MATCHED event in the case that the Stream profile finds multiple matches.  After the first match, the Stream profile is disabled so that only one replacement occurs.

   1: when STREAM_MATCHED {
   2:   if { $::GOMEZ_DEBUG > 0 } { log local0. "URI: $gws_luri matched [STREAM::match]"; }
   3:  
   4:   # -------------------------------------------------------------------------
   5:   # We've found a match, so disable the stream profile for all subsequent
   6:   # matches in the response.
   7:   # -------------------------------------------------------------------------
   8:   STREAM::disable;
   9: }

Conclusion

With this simple iRule, you can now inject the Gomez client side JavaScript code in all of your applications without effecting your application teams.  In a future article, I will discuss how you can further customize this iRule by adding support for their Page and Group identifiers so if you want a little more granularity in the reporting, stay tuned.

Download

You can download the full script in the iRules CodeShare under GomezInjection



Rate This Article:

COMMENTS

posted @ Friday, May 21, 2010 4:27 PM by Colin Walker  

posted @ Thursday, November 17, 2011 8:23 AM by Don MacVittie  

posted @ Tuesday, December 20, 2011 7:02 PM   

Only registered users may post comments.
  
Subscriptions: Video  |  Audio  |  Tutorials  |  Tech Tips  |  Features  | 

More...

 

 

Essentials Quick Start Guides
iRules Wiki | iControl SDK | WebAccelerator Wiki iRules | iControl
FirePass Wiki | Advanced Design & Config Wiki WebAccelerator | FirePass

 

Videos

  

Audio

Cache in with LTM and iRules
Can iRules fix my cert mismatch errors?
Concurrent iControl Programming Explained
Cookie LoJack vi iRules
Creating An iControl PowerShell Monitoring Dashboard With Google Charts
Custom SNMP Traps
Exchange Persistence Duality and iRules
FTPS Offload via iRules
Getting Started with pyControl
iControl 101 - #19 - Time Conversions
iControl 101 - #20 - Port Lockdown
iControl 101 - #21 - Rate Classes
iControl 101 - #22 - GTM Data Centers
iControl Apps - #04 - Graceful Server Shutdown
iControl Apps - #05 - Rate Based Statistics
iControl Apps - #06 - Configuration Archiving
iControl Apps - #07 - System Http Statistics
iControl Apps - #08 - System IP Statistics
iControl Apps - #09 - TMM Statistics
iControl Apps - #10 - Bigpipe List
iControl Apps - #11 - Global GTM Statistics
iControl Apps - #12 - Global SSL Statistics
iControl Apps - #13 - System PVA Statistics
iControl Apps - #14 - Global Statistics
iControl Apps - #18 - Virtual Server Reverse Lookup
Investigating the LTM TCP Profile: Acknowledgements
Investigating the LTM TCP Profile: Congestion Control Algorithms
Investigating the LTM TCP Profile: ECN &amp; LTR
Investigating the LTM TCP Profile: Max Syn Retransmissions &amp; Idle Timeout
Investigating the LTM TCP Profile: Nagle’s Algorithm
Investigating the LTM TCP Profile: The Finish Line
Investigating the LTM TCP Profile: Windows &amp; Buffers
iRules 101 - #13 - TCL String Commands Part 1
iRules 101 - #14 - TCL String Commands Part 2
iRules 101 - #15 - TCL List Handling Commands
iRules Event Order
Managing The System Boot Location with iControl
Persisting SSL Connections
Replacing the WebSphere Apache Plugin with iRules
Ruby meets iControl: Creating VIPs
Ruby meets iControl: Making Wide IPs
Ruby Meets iControl: Switching Policies
Ten Steps to iRules Optimization
Unbind your LDAP servers with iRules
v.10 - A new iRules Namespace
v.10 - FastHTTP and Cookie Persistence
v.10 - iRules and the after command
v.10 - New class features in iRules
v.10 - Remote Authorization via TACACS&#43;
v10.1 - Configuring GTM's DNS Security Extensions

  

Features

  

Tutorials

  

iControl

  

iRules

  

Monitoring & Management

  

Advanced Design & Config

  

93,050 Members in 191 Countries and Growing!

Join DevCentral Today!

About DevCentral

F5 DevCentral is your source for the best technical documentation, discussion forums, blogs, media and more related to application delivery networking.

So dive in, meet your peers, and get familiar with DevCentral. We hope it makes your job easier and helps you get more from your F5 investment. If new to DevCentral, check out the Getting Started section. And if you have any problems, or think something could be easier to use, let us know.

Got It !

We've received your comment and transmitted it directly to DevCentral HQ.

Thanks for taking time to let us know what's on your mind. At DevCentral | Community Matters!

Get In Touch With Us

Have questions, suggestions or just want to get something off your chest?

Use our handy form below to Direct Connect with DevCentral Mission Control.

Send Us Feedback      or