This page applies to an earlier version of the AppDynamics App IQ Platform.
For documentation on the latest version, see the 4.4 Documentation.


On this page:

Related pages:

Your Rating:
Results:
PatheticBadOKGoodOutstanding!
42 rates

If you are using Apache as your web container, or or you are currently using, or willing to use, Apache as a reverse proxy, you can use a container substitution module to automatically inject the JavaScript agent into your pages.  The module intercepts the response object as it is being returned and makes a string substitution.

(info) This method uses two Apache modules:  mod_substitute and mod_filter. Read the Apache documentation here and here.

Download the Agent

You must first download the JavaScript agent from the Browser Monitoring  configuration screen.

  1. From the left navigation menu, select Configuration > Instrumentation > End User Monitoring.
  2. Click the Web JavaScript Instrumentation tab.
  3. Scroll down to the Instrument your HTML pages with the JavaScript Agent panel.

  4. Click Download the JavaScript Agent.

  5. Click Save to File to save it.

  6. Place it somewhere accessible to the Apache instance. The name of the saved file should be "adrum.js".

(info) You can also use an AppDynamics hosted version of the adrum script instead of downloading it and placing it on your local system. See Options in Using Manual Injection for the Browser RUM JavaScript Agent, in the "Using a Hosted Version of the JavaScript Agent" section.

Configure Apache

The basic set-up takes four steps:

  1. Make Sure the Modules are Loaded
  2. Create an Adrum Configuration File
  3. Add the Location of the Adrum Configuration File to httpd.conf
  4. Restart the Web Server

Make Sure the Modules are Loaded

Check your global Apache httpd.conf file and make sure that the following two LoadModule commands are in the file:

LoadModule substitute_module modules/mod_substitute.so
LoadModule filter_module modules/mod_filter.so

Create an Adrum Configuration File

Create a file named adrum.conf with contents similar to the example below, based on your Apache version. ( See this Stack Overflow post for details.) In this case, the substitution rule covers the location of the entire site (Location /) but you can also recursively select a specific directory and its subdirectories by using /somedirectory.  

Sample adrum.conf Apache 2.2

<Location "/">
	SetOutputFilter INFLATE;SUBSTITUTE;DEFLATE 
	AddOutputFilterByType SUBSTITUTE text/html 
	Substitute "s|<head>|<head><script>window['adrum-start-time'] = new Date().getTime();</script><script src='/adrum.js'></script>|inq"
</Location>

Sample adrum.conf Apache 2.4 

<Location "/">
AddOutputFilterByType SUBSTITUTE text/html
Substitute "s|<head>|<head><script>window['adrum-start-time'] = new Date().getTime();</script><script src='/adrum.js'></script>|in"
</Location>

Where /adrum.js is the path to a copy of the adrum file that is accessible to the server.  The flags after the are:

  • i -  matching is case-insensitive
  • n -  pattern is treated as a fixed string (removing the n means the pattern is treated as a regular expression) 
  • q - module does not flatten the buckets after each substitution - this can speed performance.  

For more information, see the Apache module docs here.  

If your <head> tag has an attribute like <head lang="en">, you can use a regex in the substitution string and omit the n flag.  For example:

Substitute "s|(<head[^>]*>)|$1<script>window['adrum-start-time'] = new Date().getTime();</script><script src='/adrum.js'></script>|iq"

Note the timer initialization: <script>window['adrum-start-time'] = new Date().getTime();</script>. Injecting these scripts as close as possible to the top of the document, preferably right after the <head> tag, ensures the best possible timings.

(info) If you use <meta> tags, you should place them right after your <head> tag, and then place the JavaScript agent directly after the last <meta> tag. This can avoid issues with some versions of IE.

(Optional) Adjust for gzipped resources

If your page is compressed, the substitution won't work unless the content is INFLATEd, the substitution is made, and then the content is DEFLATEd. There are multiple ways to do this.  For example, in the FilterProvider line:

FilterProvider AdrumFilter INFLATE;SUBSTITUTE;DEFLATE resp=Content-Type $text/html

See this Stack Overflow post for more information.  If you are using Apache as a proxy, you can also instruct it not to accept gzip-encoded content.

Add the Location of the Adrum Configuration File to httpd.conf

Add the following line to your global Apache httpd.conf file:

Include [absolutePathTo]/adrum.conf

Alternatively you can add the directives to the httpd.conf file directly instead of creating a separate adrum file.

Restart the Web Server

To pick up the new configuration, restart:

sudo apchectl -k restart

(info) If you get a warning "Useless use of AllowOverride in line 2 of [absolutePathTo]/adrum.conf", it can be ignored.  It simply means the AllowOverride is redundant.  You can remove it if you wish.

Possible variations on the script string can be found in Options in Using Manual Injection for the Browser RUM JavaScript Agent and Customizing the JavaScript Agent.

Alternates

If you are setting up your automatic injection using an Apache instance that is configured as a reverse proxy, you must use the Location directive based method described above, with the ProxyPass and ProxyPassReverse directives also in the Location directive.  If you are using an Apache instance that is your primary web container you have two additional options for describing the actual substitution step:

Use the Directory Directive

You can use the Directory directive instead of the Location directive.  

Use .htaccess 

Add lines similar to this to an .htaccess file in the base document directory for your site, replacing your filter name for <MyFilter>.  If you don't have an .htaccess file, create one:

Apache 2.2

AllowOverride Options
FilterDeclare <MyFilter>
FilterProvider <MyFilter> SUBSTITUTE resp=Content-Type $text/html
FilterChain <MyFilter>
Substitute "s|<head>|<head><script src='/adrum.js'></script>|inq"

Apache 2.4

AddOutputFilterByType SUBSTITUTE text/html
Substitute "s|<head>|<head><script>window'adrum-start-time' = new Date().getTime();</script><script src='/adrum.js'></script>|in"

Where /adrum.js is the path to a copy of the adrum file that is accessible to the server.   Make sure .htaccess is world-readable.