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 »
11,314 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 »
11,314 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 »
10 Comments

Once again Ben, You Da Man!


Jul 12, 2010 at 2:47 PM // reply »
11,314 Comments

@Paul,

Awesome - glad this helped.


Dec 9, 2010 at 4:49 PM // reply »
8 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 »
3 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
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
Jun 20, 2013 at 2:17 AM
ColdFusion NumberFormat() Exploration
Nice read thanks Ben, Is there a way to mask a negative number? Long story short in the finance sector when you go 'short' on a stock you want the price to fall this is a good thing because you are ... read »
Jun 20, 2013 at 1:09 AM
The Beauty Of The jQuery Each() Method
my html code : <html> <head> <script type="text/javascript" src="jquery.js"></script> <script type="text/javascript" src="nss.js"> ... read »
Jun 19, 2013 at 11:31 PM
Directive Link, $observe, And $watch Functions Execute Inside An AngularJS Context
@Ben, bunch to learn indeed, but thats fun part : ) ... read »
Jun 19, 2013 at 10:41 PM
Referencing ColdFusion Query Columns In A Loop Using Both Array And Dot Notation
Burdock-roots Are you going fat day by day? You need to be good for your family and make some money too. So we bring for you a best product that helps you to be more energetic every day. You will b ... read »
Jun 19, 2013 at 9:52 PM
Working With Inherited Collections In AngularJS
I recognize the applicability of your solution, and how easy it makes to share data across multiple views or even "submodules" of rather simple application. But it seems to me that it creat ... read »
Jun 19, 2013 at 9:38 PM
Directive Link, $observe, And $watch Functions Execute Inside An AngularJS Context
@Alesei, Glad you like it. Even after working with AngularJS for months, I still get a bunch of unexpected, "$digest is already in progress". So hard to debug sometimes! ... read »
Jun 19, 2013 at 9:36 PM
Working With Inherited Collections In AngularJS
@Mike, The relationship of $scope values is definitely an interesting thing! But it's not simple - it really forces you to understand prototypal inheritance, which is not at all a simple topic! Gla ... read »
Jun 19, 2013 at 9:35 PM
Experimenting With The Amazon Simple Storage Service (S3) API Using ColdFusion
@Joe, Oh, super interesting! I had only thought to url-encode the signature; but I think that's because the S3 docs actually have a special NOTE telling you to do so. It would have never occurred t ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools