ColdFusion Debugging and Profiling
While I'm thinking about CFUnited I just wanted to point out a few not so well known features in CF.
To be fair, this is inspired by Charlie Aerharts presentation about their new profiler tools. Seeing the crowd's reaction I realized that many people must not know that most of what they showed is already in ColdFusion (as of CF6).
- 1) Dumping the complete struct in debug output
- 2) logging all errors to a file
- 3) Profiler
What you may not realize that you can modify the default debug output yourself, and add dump tag output. This output is a just a simple .cfm page located in the "/WEB-INF/debug/" folder.
You can create your own file, or edit the classic.cfm. For instance if you wanted to have a cfdump view of your application scope you can just replace lines 677 with <cfdump var='#application#'>
This one has a few options. The first, if you're using CF7, you can use the new Application.cfm onError() method. With this you can just use cffile to write the error object to a log file.
The second option, which is doable in CF6+, is to edit the default error template. Just like the ColdFusion debug output the ColdFusion error templates are also .cfm pages. These are located in the "/web-inf/exception" folder. You can modify these to do what ever you need to with the error messages; send them in an email, write the error to a log file, just change the error formatting so it matches the rest of your site when an error happens.
Since CF6 ColdFusion has shipped with two views for your debug output "summary" and "tree".
"Summary" is the default and what you've seen in ColdFusion since the early days of CF (not sure which version it first appeared in, 2 or 3). It provides a listing of all the templates, CFC's and custom tags called with a total execution time for each template.
What you may not of realized is that there is also the "Tree" view, this view provides your with a detailed profiler type of view for the page. It creates a tree of the templates used to create the page. Showing you each individual template, custom tag, cfc execution (with cfc arguments) and the execution path that was taken to get to that page, just like a profiler does. (And you didn't need to buy JProbe. ;)
This "Tree" view allows you figure out exactly which template is slow. For instance perhaps you loop over a custom tag 3 times, with this view you could see that the 3rd time the execution time triples. This would tell you that their must be something different with the arguments of the 3rd request, something that causes your code to take a different slower path.
Note: Like a profiler, not like the "Summary" view, the tree view also displays the template execution time of the .cfm and all of it's children, instead of just the time spend on each template. This allows you to follow the slow running branches easier. If you need to know the just the individual template execution time it a simple matter of adding up the 1st level children and subtracting that from the total for the template.
Granted we do have some area of improvement, for instance we don't drill down to the individual tag counts for each .cfm. If you have any debugging idea for future versions of CF, please send them my way. What we can improve? What we can add? Etc... Perhaps the first thing to do is make the tree view the default for CF :)


<br/>
I honestly think the debugging in Eclipse for Java is terrific. Something akin to that would be great.<br/>
<br/>
Doug<br/>
<ul>
<li>Grouping the execution time of related functions and tags to give a high level view of what type of operations in a particular request is taking the longest, as well as provide a percentage break down for them. For example, grouping queries in a group, XML related functions in a group, struct related functions in a group, etc. This also gives things when people are complaining about X being slow... "look, the queries are taking 80% of the time on this page.. it's not ColdFusion that is slow"<br/>
</li>
<li>Some sort of supported/documented debugging API might be useful.. ie OnRequestEnd, you could grab the debugging params which were most important to you via the debugging API and save them to a log to review after load testing an application, etc This would also be helpful to debug event gateways with I would think if you could easily output the debug output of reach request to a file.</li>
</ul>
<p>--nimer</p>
<p>can either of you, or better both of you, send me some kind of test case that I can run. I haven't heard anything about this tree not showing all of the CFC's that were called. </p>
<p>thanks</p>
<br/>
I often find myself breaking down things percentage-wise post load testing to present to stakeholders if something is running too slow and I can't find a way to make it perform better. Something to the effect of telling them we should think about pulling X piece of functionality out because it eats-up 15% of the processing time but isn't that useful to the end-user, or that it will add X percent more time to something if we have to do it multiple times, etc.<br/>
<br/>
Actually after re-reading Paul's comment and what you wrote about the debugger (I'm sometimes guilty of skimming stuff too quickly while at work), it looks like it's behaving as advertised, so I'm not actually having that problem.<br/>
<p>I have often found that Allaire/Macromedia has often left out some of the coolest features that are available out of thier documentation.</p>
<p> </p>
<br/>
First - the debug templates make use of the ServiceFactory. That is supposed to be a no-no. Are you recommending us to use that anyway? (As far as I know, there is no other choice.)<br/>
<br/>
Secondly - there are, as far as I know, no docs on the 'mega-query' returned and used by the debugger. I'd love to see a doc explaining each of the columns. As it stands, I'm slowly writing my own doc as I try to grok classic.cfm.<br/>
For now the only way is with the service factory. I need to fix that ;)</p>
<p>You can get it through the adminapi, getDebugRecordSet(), but the method is locked down and requires authentication, which it shouldn't.</p>
<p>One thing you may not know, you can use the addDebugEvent() method of the adminapi to add your own custom rows of debug data, while you are running your pages. These will then be available in the debug recordset in your debug template. I used this, ok the service factory, in the cf_timer tag (before it was a real cftag) in CF6. </p>
<p> </p>
<p>Any ideas on how to point this stuff out better? For now I'll just keep blogging what I can.</p>
<p> </p>
<p>Does anyone have any custom revisions to the debugging template they'd like to share? I'm very interested in seeing what others are doing with the debugging.</p>
at the most you could wrap them in your own CF_TAGS, and then you can output what you want around them.
---nimer