[frs-232] Capturing ColdFusion’s Debug Output in FusionReactor

Capturing ColdFusion's Debug Output in FusionReactor

It would be great if you could capture the debug data from every page run but hide it away from the user so that they don't even see it. It's easy to do this with FusionReactor.

ColdFusion's powerful debug data output feature that lets you see lots of useful debugging information about the page run. Unfortunately the data is lost as soon as you run the next page in the browser window/tab and is only visible to the user that ran the page.

Requirements

FusionReactor
FusionDebug

The Article

We're all familiar with ColdFusion's debug output at the end of a CFML page. Many CFML programmers use it as the primary way of debugging CFML code.

There are a few problems with the way that debug data is made available to us however such as the fact that the only user that can see the debug output is the user that ran the page. This is even more of a problem if you want to see the debug data but don't want to scare the user that ran the page. Of course it's possible in CF to restrict the IP addresses that generate debug output but sometimes you want to be able to see the debug output from other users without them seeing it. It's easy to do with FRAPI.

About FRAPI

FRAPI is a powerful and easy to use API that allows you to take control of FusionReactor programatically. Using FRAPI you can change the running configuration of FusionReactor or add extra debugging information to requests using just a few lines of code.

Here's how to instantiate the FRAPI interface in CFML. Once we have FRAPI available we add extra information to a request data recorded in FusionReactor using FRAPI's trace() function:

      	<cftry>
            <cfset frapi = createObject("java", "com.intergral.fusionreactor.api.FRAPI").getInstance()>
            <cfset frapi.trace( "Hello FRAPI!")>
            <cfcatch>
                <!--- FRAPI isn't available so FusionReactor probably isn't installed --->
            </cfcatch>
        </cftry>

Note that we always wrap FRAPI calls in a TRY/CATCH block. The reason for this is that FusionReactor may not be installed on every computer that you run the code on. The TRY/CATCH blocks will make sure that FRAPI calls will have no influence on your code even if FusionReactor isn't installed.

To try FRAPI, create a "frapitest.cfm" file with the CFML code above and run the page on a system that has FusionReactor installed. After the page has completed go into FusionReactor's Request History, select the Request Details for the request and click on the Markers tab to see the "Hello FRAPI!" message. Cool no? FRAPI tracks messages on the request as soon as trace() is called so it's possible to see the trace() statements in the Markers tab updating as a page is being run!

So how would we capture CF's debug output? We don't want to add FRAPI code to every page that we write that's for sure. We need to understand how ColdFusion's debug output is done to know how to capture it.

When enabled, CF Debug output is appended at the end of the page output by rCF running a "Debug Output Formatting" template. This is simply a piece of CFML code to that formats the debugging information into HTML. What's even better is the fact that the you can write your own and tell ColdFusion to use your template instead of the default one. So what if we wrote a CF Debug Template that simply calls FRAPI and adds that debug data to the FusionReactor Request using trace() calls? This means that the information would be available in FusionReactor but the user wouldn't even know that debug output was enabled because the FRAPI trace() calls don't output anything. It's that easy! Ok, there is always a but…

…but I don't know how to access all of this CF Debug Data and for sure it's complex, right?

The CF Debug data structures are fairly complex and very powerful but this is reason that few people ever write there own CF Debug Formatting template. The good news is we don't need to know anything about it due to a powerful CFML tag called <CFSAVECONTENT>. I know that the advanced CFML programmers out there just went… "OK, I get it…", but for the rest of us let's go into a little more detail on how we can do this.

<CFSAVECONTENT> is a tag that allows the programmer to capture output into a variable instead of sending it back to the user. Using <CFSAVECONTENT> we can capture the output from the classic CF debugging template into a variable and then simply call FRAPI's trace() function passing that variable as the information to record! Easy!

FRAPI.CFM

        <cftry>
            <cfset frapi = createObject("java", "com.intergral.fusionreactor.api.FRAPI").getInstance()>
            <cfsavecontent variable="debugData"><cfinclude template="classic.cfm"></cfsavecontent>
            <cfset frapi.trace( debugData )>
            <cfcatch>
                <!--- FRAPI isn't available so FusionReactor probably isn't installed --->
            </cfcatch>
        </cftry>

All we have to do now is add our FRAPI Debug Template (frapi.cfm) to the CF debug templates by simply copying it folder where debug templates are placed, typically <coldfusion folder>/wwwroot/WEB-INF/debug.

Finally we have to Enable Request Debugging Output and select our new ("frapi.cfm") template as the Debugging Output Format in the ColdFusion Administrator -> Debug Output Settings page.

The next time you (or anyone) runs a CF page FusionReactor will capture the Debug data for the page. To see the data simple go to the FusionReactor->Request History, select the Request Detail for the request and then click on the Markers tab to see the CF Debugging Data for the page.

Notes

  1. Performance
    ColdFusion pages run slower when debugging is enabled and on some applications enabling CF Debug Output can seriously impact the performance of the server. You should test this on your applications before enabling debugging a production server.
  2. Memory
    FusionReactor will record the debug output on each request that it keeps in it's request history. This will use some memory; for example, if you have a Request History size of 100 requests and the average debug output data size is 20Kbytes then FusionReactor will use 2Mbytes of memory to
    record the debug data.
  3. Data
    The amount of debug data recorded is controlled via the settings on the Debug Output Settings page and the classic.cfm debug formatting output template. The data will not be added to FusionReactor until the page completes because this is when CF calls the Debug Output Formatting page. The
    debug data captured will honor any Debugging IP Address restrictions that you configure in the CF Administrator.

Fast Track

  1. Copy the frapi.cfm file linked to this article to your ColdFusion Debug Formatting Template folder (typically): <coldfusion folder>/wwwroot/WEB-INF/debug
  2. Select Debugging Output Format: "frapi.cfm" in the ColdFusion Administrator -> Debug Output.
  3. Enable Request Debugging Output in the ColdFusion Administrator->Debug Output Settings Settings
  4. Run a CF page.
  5. In FusionReactor->Request History select the Request Detail for the request and then click on the Markers tab to see the CF Debugging Data from the page.

Summary

FRAPI is a powerful way to capture extra debugging information on requests and makes FusionReactor a powerful platform for debugging on both development and production servers.

Issue Details

Type: DevNet
Issue Number: FRS-232
Components: Compression, Content Filters, CPU + Memory, Crash Protection, Enterprise Dashboard, FR Enterprise Dashboard Desktop Application, FusionReactor Settings, Installer, JDBC, License + Activation, Logging, Metrics, Request Managment, Thread Management
Environment:
Resolution: Fixed
Last Updated: 03/Nov/11 3:36 PM
Affects Version: 2.0, 2.0.3, 2.0.4, 3.0, 3.0.1, 3.5
Fixed Version: 2.0.3, 2.0.4, 3.0, 3.0.1, 3.5
Server:
Platform: Windows XP, Windows 2000, Windows 2003, Linux, MacOS, Solaris, Windows Vista, Windows x64, AIX, Windows 7, Windows 2008
Related Issues:

FRS-237: Creating Daily FusionReactor Log Files

FRS-280: Setting VM Options via FRAPI

Comments are closed.