ColdFusion has numerous debugging options. One of them includes a template execution report. This table includes every CFML template run as well as the total time spent on it, along with an average. Along with CFML templates, it also includes CFC method calls. One problem with this report, though, is that it considers CFC method calls with different arguments as different things to report. That's not bad at all. It may be that foo(1) is significantly slower than foo(0). However, I was looking for a report that gathered all the CFC calls together and gave more of a summary type report.
Luckily, ColdFusion's debugging templates are all unencrypted CFML templates. That means you can modify or add your own debugging templates. I copied the basic report (classic.cfm), and began working. The debugging data is a bit difficult to work with. For example, CFC calls don't have their own API in the debugging code. I plugged away a bit and was able to strip the data down to just the CFC and the method. I then added the report you see below:

To play with this, simply download the file here. Unzip, and copy to your cfusionmx7\wwwroot\web-inf\debug folder. Then go to your CF Admin, select classic2.cfm as your template, and then hit a page with any CFC call in it. I plan on modifying it a bit later to show both a min and max report on each CFC method.
Archived Comments
Ray,
Noticed the util cfc that you have in your blog directory (which isn't part of your normal distribution), what are you using for the colored code function. I've been using colorizer code from the old cfcomet.com site (its been down for awhile, maybe it will come back someday). Always looking for new code colorizer options.
Actually it is the same code, cleaned up a bit by a user (I forget who, his name is in the code though).
Thanks Ray,
I'm using your mod... and lovin it!!!
Thanks for another great tool. :)
Hey Ray, great job, highly useful, is there any way you know of to get the parameters that were passed in the the arguments?
Actually, the original data has that. I had to strip it out to 'summarize' the calls. If you wanted to rebreak it out, you could. You could then build a table that has the same details as the _default_ template, but ONLY shows CFCs. Make sense?
I've been googling for debugging for ColdFusion and, as well as this page, I found a couple of other tools. So far my favourite is FusionReactor (fusion-reactor.com) but I was wondering if anyone else had tried it and could let me know what they thought?
It's quite off topic, but I was hoping to find a copy of that cf-code colorizer.
Any ideas?
You mean the one in my blog? It's in the download.
Hi
I am unable to download the zip file which contains classic2.cfm.
Grab it here:
http://www.coldfusionjedi.c...
Ray,
I've been bugged by a problem in ColdFusion's debug Execution Time tree - it doesn't display properly when using Application.cfc. It would duplicate the last Application.cfc method called for as many methods that were called and place some cfc calls in the wrong location. This was especially frustrating when dealing with pages that heavily used cfcs.
I found a resolution to the problem and wanted to share the wealth. It appears the original issue was that when creating the tree, the child/parent comparison was only made on the template's filename and didn't include the function for cfcs. The reason for this was because the parent template is determined from the Template element in the stack trace's tagContext (from qEvents), which doesn't include the function for cfcs. I've remedied this by extracting the parent's function name from the raw_trace element in the stack trace's tagContext. This allows the child/parent comparison to take the function into account (especially in the case of Application.cfc).
Here's the fix:
In classic.cfm (or classic2.cfm), replace line 378 with
<code>
<pre>
raw_trace = a[i].stacktrace.tagcontext[x].raw_trace;
findFunctionPrefix = "$func"; // set prefix to account for length and position since CF doesn't have RegEx lookbehind assertion
findFunction = ReFindNoCase("(?=\" & findFunctionPrefix & ").*(?=\.runFunction\()",raw_trace,1,true);
if( findFunction.len[1] NEQ 0 AND findFunction.pos[1] NEQ 0 ) {
// get function name from raw_trace to allow for proper application.cfc tree rendering
parentfunction = Trim(Mid(raw_trace, findFunction.pos[1] + Len(findFunctionPrefix), findFunction.len[1] - Len(findFunctionPrefix)));
// append the function name (pulled from raw_trace) to the cfc template for tree root comparison.
parentIdList = listAppend(parentIdList, a[i].stacktrace.tagcontext[x].template & " | " & lcase(parentfunction));
} else {
parentIdList = listAppend(parentIdList, a[i].stacktrace.tagcontext[x].template);
}
</pre>
</code>
and replace line 391 with
<code>
<pre>
endToken = "("; // changed from | to ( to grab the function as well
</pre>
</code>
I hope this helps anyone else who has had this problem. Please let me know if there are any flaws in my logic.
Thanks,
Seth
Seth, please send a report on this to http://www.adobe.com/go/wish. This way they can know about the issue and your fix.
Ray, Thanks for the response. I sent the report to Adobe. Have you noticed the same issue when using Application.cfc?
I have not - but maybe I just overlook it now. :)