Finding Template Execution Stack in ColdFusion

Posted July 5, 2006 at 2:39 PM by Ben Nadel

Tags: ColdFusion

There have been times when I wanted to get a list of all the ColdFusion templates that were executed during a single page call. I wanted to get a list similar to that of the debugging information that shows at the bottom of the page when debugging output is turned on. To figure it out, I looked at the template that handles the current debugging. When you look in the file, getting this information is actually really simple. To get a stack trace, you just have to create a ColdFusion service factory and ask for the debugging service:

  • <!--- Create ColdFusion service factory instance. --->
  • <cfset objFactory = CreateObject(
  • "java",
  • "coldfusion.server.ServiceFactory"
  • ) />
  •  
  • <!--- Get the debugging service from the service factory. --->
  • <cfset objDebugging = objFactory.GetDebuggingService() />
  •  
  • <!---
  • Get the events table. This includes all events
  • that have taken place, not just template executions.
  • This is returned as a query.
  • --->
  • <cfset qEvents = objDebugging.GetDebugger().GetData() />
  •  
  • <!---
  • Now that we have all the events in query format, do a
  • query of queries to get only events that were template
  • executions event.
  • --->
  • <cfquery name="qTemplates" dbtype="query">
  • SELECT
  • line,
  • parent,
  • template,
  • endtime,
  • starttime
  • FROM
  • qEvents
  • WHERE
  • type = 'Template'
  • ORDER BY
  • template ASC
  • </cfquery>
  •  
  • <!--- Dump out the query of template. --->
  • <cfdump var="#qTemplates#" />

That's all there is to it. As far as I know, the ServiceFactory stuff was not documented in ColdFusion MX 6, and was considered "unsupported", but I think that in ColdFusion 7, this is a fully supported factory object and is available for programmers to leverage.



Reader Comments

Oct 30, 2008 at 2:36 PM // reply »
6 Comments

Hi Ben,

Thanks for posting this -- just this morning I needed code to solve this problem (for my debugging library) and your sample works great. I've refactored it into a UDF, and made a few tweaks. Would you mind if I submitted the UDF to CFLib.org? I'll of course give you credit for the original work.

Thanks again.
Nolan


Oct 30, 2008 at 4:22 PM // reply »
10,640 Comments

@Nolan,

I am sure I learned this trick somewhere else (not sure I deserve credit).


Mar 5, 2010 at 1:07 PM // reply »
1 Comments

Hey Ben,

When I try implementing this I keep getting a "Value Must Be Initialized Before Use" error. I am assuming this may have to do with the fact that I do not have debug turned on inside CF Administrator. Is it possible in invoke this without turning on debug in the administrator...or is there a way to turn on debug for one page instance and not the entire server? There are times when I only want to debug for a single page that is giving me trouble but I don't want to risk showing debug details to everyone, especially in a production environment.

Any insight would be most excellent and much appreciated.

Ron


Mar 8, 2010 at 7:02 PM // reply »
10,640 Comments

@Ron,

From what I remember, you *might* need to have debugging turned on.

You could try to throw an error and then catch it and look at the tag context... this is an "expensive" approach; but, if you're doing it for debugging, it should work.


Roe
Jul 12, 2010 at 12:37 PM // reply »
9 Comments

Once again Ben, You Da Man!


Jul 12, 2010 at 2:47 PM // reply »
10,640 Comments

@Paul,

Awesome - glad this helped.


Dec 9, 2010 at 4:49 PM // reply »
6 Comments

I am doing code cleanup on a project and need to collect the templates that are unused. If we have the set of templates used then obviously the unused are just the complement of that set. I use a similar method the collect the templates(and if a cfc, the method called):
<cftry>
<cfobject action="CREATE" type="JAVA" class="coldfusion.server.ServiceFactory" name="factory">
<cfset cfdebugger = factory.getDebuggingService()>
<cfcatch type="Any"></cfcatch>
</cftry>
<cfobject action="CREATE" type="JAVA" class="java.lang.String" name="ST">
<cfset qEvents = cfdebugger.getDebugger().getData()>
<cfquery dbType="query" name="cfdebug_templates_summary" debug="false">
SELECT distinct template
FROM qEvents
WHERE type = 'Template'
</cfquery>
<cfloop query="cfdebug_templates_summary">
<cfscript>
//need a java string so we can split on a regex
temp=ST.init(template);
a=temp.split("\sfrom\s");
temp2=trim(a[arraylen(a)]);
re="\|(.*?)(\(|\])";
//now find the method called
sRet=refind(re,temp,1,true);
if(arraylen(sRet.pos)>1){
temp3=trim(mid(temp,sRet.pos[2],sRet.len[2]));
}else{
temp3="";
}
a=ST.init(temp2).split("wwwroot\\");
out=a[arraylen(a)];
if(temp3!=""){
out&=":" & temp3;
}
</cfscript>
<cflog file="templatesused" text="#out#">
</cfloop>


Mar 4, 2011 at 4:36 PM // reply »
1 Comments

Hi Ben,

I need to know if I can reach a serviceFactory Class but per coldfusion instance, specifically.


Mar 15, 2011 at 8:37 PM // reply »
3 Comments

Any ideas on how to pull the template list if you *don't* have debugging turned on? I can't get debugging turned on but it would sure save my sanity if I could see that template stack.


May 25, 2011 at 2:53 PM // reply »
4 Comments

@Ben

"@Ron, From what I remember, you *might* need to have debugging turned on."

I was getting the same error as Ron, on top of Enable Request Debugging Output, I had to add my IP address to the Debugging IP Addresses.

Also the Post Comment button no worky in FireFox 4.


Aug 23, 2011 at 10:40 AM // reply »
2 Comments

You can also get the tag context via:

<cfset oException = createObject("java","java.lang.Exception").init() >
<cfdump var="#oException#">

Now, what I want is to get my hands on the cfquery /cfstoredproc information including the starttime/enddimt values so I can instrument our DB interactions and run some coverage analysis. This information is available in the bjDebugging.GetDebugger().GetData() object but, as has been noted, I need to have "Enable Request Debugging" turned on. I'm sure this info is maintained somewhere in the java bowels.


Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
InVision App - Prototyping Made Beautiful With Prototyping Tools Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
Feb 12, 2012 at 3:37 AM
Learning ColdFusion 8: CFImage Part III - Watermarks And Transparency
Hi Ben, Just to ask currently it is placed bottom right corner, if i need to replace the same rendered image on the bottom left side or in the bottom center, how that can be calculated. bottom ce ... read »
Feb 11, 2012 at 9:29 PM
Use jQuery's SlideDown() With Fixed-Width Elements To Prevent Jumping
I can't say how glad I am that I found your post. Thank you very much. ... read »
Feb 10, 2012 at 7:21 PM
jQuery AJAX Strips Script Tags And Inserts Them After Parent-Most Elements
Update! Instead of $(eval(options.insertAfter)).after(data['insertData']); I now use: var ajaxNode = document.createElement('span'); var parent = $(eval(options.insertAfter))[0].parentNode; ... read »
Feb 10, 2012 at 6:18 PM
jQuery AJAX Strips Script Tags And Inserts Them After Parent-Most Elements
encountered this same, what I consider, jQuery bug last week. I'm building a site in which I load some content via AJAX. This content contains Linkedin share button placeholders which Linkedin API ne ... read »
Feb 10, 2012 at 11:30 AM
Cross-Origin Resource Sharing (CORS) AJAX Requests Between jQuery And Node.js
After you understand the concepts here, this is an awesome cheatsheet for enabling CORS in just about anything http://enable-cors.org/ ... read »
JM
Feb 10, 2012 at 9:10 AM
My Safari Browser SQLite Database Hello World Example
@Amy, Here is a very good tutorial on how to use JOIN: http://www.sqltutorial.org/sqljoin-innerjoin.aspx ... read »
Feb 10, 2012 at 4:42 AM
Building A Twitter-Inspired RESTful API Architecture In ColdFusion
This is great, very useful Ben. I spotted a small typo in the api.cgm listing: <cfthrow type="Unauthroized" /> Cheers Stefan ... read »
Feb 9, 2012 at 10:35 PM
CFDirectory Filtering Uses Pipe Character For Multiple Filters (Thanks Steve Withington)
I was wondering if there would be a filter you could apply so that you got everything but what you included in the filter. As in show me all docs that are not a .pdf. ... read »