Browse files

Added support for ColdFire debug output in trace.cfm.

  • Loading branch information...
1 parent 50c5dfd commit 8a04560a7bd8769a946580cf7130b543c7d4f505 @mpaperno committed Jan 24, 2012
Showing with 356 additions and 24 deletions.
  1. +356 −24 cftags/trace.cfm
View
380 cftags/trace.cfm
@@ -2,9 +2,10 @@
Name: trace.cfm
Author: Maxim Paperno
Created: Jan. 2012
- Last Updated: 1/19/2012
- Version: 2.0
- History: Updated to handle trace calls via firelogger.cfc
+ Last Updated: 1/23/2012
+ Version: 2.1
+ History: Added compatiblity for ColdFire debugging output. Added check for firelogger.cfm debug template is active. (jan-23-12)
+ Updated to handle trace calls via firelogger.cfc (jan-19-12)
Initial version based on ColdFire project by Nathan Mische & Raymond Camden
Serves two functions:
@@ -26,9 +27,14 @@ This template is ignored if firelogger not active or causes an error (fall throu
<!--- run on tag end if we can --->
<cfif thisTag.executionMode eq "end" or not thisTag.hasEndTag>
- <!--- are we using firelogger? --->
- <cfif StructKeyExists(GetHttpRequestData().headers,"X-FireLogger")
- AND ( StructKeyExists(attributes, "var") OR StructKeyExists(attributes, "text") )>
+ <!--- are we using firelogger or coldfire? --->
+ <cfif ( StructKeyExists(attributes, "var") OR StructKeyExists(attributes, "text") )
+ AND (
+ StructKeyExists(GetHttpRequestData().headers, "X-FireLogger")
+ OR ( StructKeyExists(GetHttpRequestData().headers, "x-coldfire-enhance-trace")
+ AND StructKeyExists(GetHttpRequestData().headers, "User-Agent")
+ AND FindNoCase("ColdFire", GetHttpRequestData().headers["User-Agent"]) )
+ )>
<!--- !!! second parameter true/false determines if trace writes to a log file or not. !!! --->
<cfset doTrace(attributes, true)>
@@ -38,7 +44,7 @@ This template is ignored if firelogger not active or causes an error (fall throu
<cfinclude template="trace_adobe.cfm">
</cfif>
-</cfif>
+</cfif>
<!--- /if running as end tag or has no end tag --->
<!--- supporting functions --->
@@ -69,13 +75,13 @@ This template is ignored if firelogger not active or causes an error (fall throu
if ( StructKeyExists(attributes, "var") ) {
if ( IsDefined("caller.#attributes.var#") ) {
try {
- obj = caller[attributes.var];
+ obj = caller[attributes.var];
} catch (any e) {
- obj = e.message;
+ obj = e.message;
}
} else {
- obj = "[undefined]";
- }
+ obj = "[undefined]";
+ }
}
// is there a simple message to log?
@@ -84,19 +90,19 @@ This template is ignored if firelogger not active or causes an error (fall throu
msg = attributes.text;
} catch (any e) {
msg = e.message;
- }
+ }
} else if ( StructKeyExists(attributes, "var") ) {
// if there's no message to log but we have a variable then
// save the variable name as the message
- msg = attributes.var & " = ";
+ msg = attributes.var & " = ";
}
- // don't bother with firelogger if inline output is desired
- if ( !attributes.inline ) {
+ // don't bother with firelogger if inline output is desired or headers aren't present
+ if ( !attributes.inline && StructKeyExists(GetHttpRequestData().headers, "X-FireLogger") ) {
if ( !IsDefined("request.__firelogger__") || !isStruct(request.__firelogger__) || !structKeyExists(request.__firelogger__, "console") ) {
if ( !IsDefined("request.__firelogger__") ) {
- request.__firelogger__ = {};
+ request.__firelogger__ = {};
}
request.__firelogger__.console = new us.wdg.cf.firelogger(
fallbackLogMethod="none",
@@ -118,11 +124,11 @@ This template is ignored if firelogger not active or causes an error (fall throu
if ( ListLen(attributes.category) GT 2 ) {
request.__firelogger__.console.setLoggerFGColor(ListGetAt(attributes.category, 3));
} else {
- request.__firelogger__.console.setLoggerFGColor("white");
- }
+ request.__firelogger__.console.setLoggerFGColor("white");
+ }
} else {
- request.__firelogger__.console.resetLoggerBadge();
- }
+ request.__firelogger__.console.resetLoggerBadge();
+ }
} else {
request.__firelogger__.console.resetLoggerBadge();
}
@@ -137,8 +143,8 @@ This template is ignored if firelogger not active or causes an error (fall throu
}
}
-
- </cfscript>
+
+ </cfscript>
<!--- if debugger is active, log enhanced trace --->
<cfif IsDebugMode()>
@@ -193,6 +199,15 @@ This template is ignored if firelogger not active or causes an error (fall throu
<cfif StructKeyExists(attributes, "var")>
<!--- set the variable name into a blank column ("name" is not usually populated for traces) --->
<cfset QuerySetCell(data, "name", attributes.var, row) />
+
+ <!--- if coldfire debug is enabled, log the trace in a serialized format it can parse. --->
+ <cfif FindNoCase("coldfire.cfm", cfdebugger.settings.debug_template) AND StructKeyExists(GetHttpRequestData().headers, "x-coldfire-enhance-trace")>
+ <cfset obj = coldfire_trace_udf_encode(local.obj)>
+ <!--- if we're not using firelogger.cfm debug template, log plain-text output like the standard trace does. --->
+ <cfelseif NOT ReFindNoCase("firelogger\d*\.cfm", cfdebugger.settings.debug_template)>
+ <cfset obj = attributes.var & " = " & isSerializable(local.obj)>
+ </cfif>
+
<cfset QuerySetCell(data, "result", local.obj, row) />
</cfif>
@@ -315,7 +330,324 @@ This template is ignored if firelogger not active or causes an error (fall throu
} catch (any e) {}
return ret;
- }
-</cfscript>
+ }
+</cfscript>
+
+<!--- this is included unchanged from coldfire version of trace.cfm to maintain compatibility with ColdFire --->
+
+<cffunction
+ name="coldfire_trace_udf_encode"
+ returntype="string"
+ output="false"
+ hint="Converts data from CF to JSON format">
+
+ <cfargument name="data" type="any" required="Yes" />
+ <!---
+ The following argument allows for formatting queries in query or struct format
+ If set to query, query will be a structure of colums filled with arrays of data
+ If set to array, query will be an array of records filled with a structure of columns
+ --->
+ <cfargument name="queryFormat" type="string" required="No" default="query" />
+ <cfargument name="queryKeyCase" type="string" required="No" default="upper" />
+ <cfargument name="stringNumbers" type="boolean" required="No" default=false >
+ <cfargument name="formatDates" type="boolean" required="No" default=false >
+
+ <!--- VARIABLE DECLARATION --->
+ <cfset var jsonString = "" />
+ <cfset var tempVal = "" />
+ <cfset var arKeys = "" />
+ <cfset var colPos = 1 />
+ <cfset var i = 1 />
+
+ <cfset var ignoreStructKeys = "_CF_HTMLASSEMBLER,__COLDFIREVARIABLEVALUES__,__firelogger__">
+ <cfset var ignoreFunctionPrefix = "coldfire_udf">
+
+ <cfset var _data = arguments.data />
+
+ <cfset var recordcountKey = "" />
+ <cfset var columnlistKey = "" />
+ <cfset var columnlist = "" />
+ <cfset var dataKey = "" />
+ <cfset var column = "" />
+
+ <!--- ARRAY --->
+ <cfif IsArray(_data) AND NOT IsBinary(_data)>
+ <cfset jsonString = ArrayNew(1)/>
+ <cfloop from="1" to="#ArrayLen(_data)#" index="i">
+ <cfset tempVal = coldfire_trace_udf_encode( _data[i], arguments.queryFormat, arguments.queryKeyCase ) />
+ <cfset ArrayAppend(jsonString, tempVal) />
+ </cfloop>
+ <cfreturn "[" & ArrayToList(jsonString,",") & "]" />
+
+ <!--- BINARY --->
+ <cfelseif IsBinary(_data)>
+ <cfset jsonString = ArrayNew(1)/>
+ <cfloop from="1" to="#Min(ArrayLen(_data),1000)#" index="i">
+ <cfset ArrayAppend(jsonString,_data[i]) />
+ </cfloop>
+ <cfreturn "{""__cftype__"":""binary"",""data"":""" & ArrayToList(jsonString,"") & """,""length"":" & ArrayLen(_data) & "}" />
+ <!--- BOOLEAN --->
+ <cfelseif IsBoolean(_data) AND NOT IsNumeric(_data) AND NOT ListFindNoCase("Yes,No", _data)>
+ <cfreturn LCase(ToString(_data)) />
+
+ <!--- CUSTOM FUNCTION --->
+ <cfelseif IsCustomFunction(_data)>
+ <cfset md = GetMetaData(_data) />
+ <cfif CompareNoCase(Left(md.name,Len(ignoreFunctionPrefix)),ignoreFunctionPrefix) eq 0>
+ <cfreturn "coldfire_ignore_value" />
+ <cfelse>
+ <cfset jsonString = ArrayNew(1) />
+ <cfset ArrayAppend(jsonString,"""__cftype__"":""customfunction""")>
+ <cfset arKeys = StructKeyArray(md) />
+ <cfloop from="1" to="#ArrayLen(arKeys)#" index="i">
+ <cfset tempVal = coldfire_trace_udf_encode( md[ arKeys[i] ], arguments.queryFormat, arguments.queryKeyCase ) />
+ <cfset ArrayAppend(jsonString, '"' & arKeys[i] & '":' & tempVal) />
+ </cfloop>
+ <cfreturn "{" & ArrayToList(jsonString,",") & "}" />
+ </cfif>
+
+ <!--- NUMBER --->
+ <cfelseif NOT stringNumbers AND IsNumeric(_data) AND NOT REFind("^0+[^\.]",_data)>
+ <cfreturn ToString(_data) />
+
+ <!--- DATE --->
+ <cfelseif IsDate(_data) AND arguments.formatDates>
+ <cfreturn '"#DateFormat(_data, "mmmm, dd yyyy")# #TimeFormat(_data, "HH:mm:ss")#"' />
+
+ <!--- WDDX --->
+ <cfelseif IsWDDX(_data)>
+ <cfwddx action="wddx2cfml" input="#_data#" output="tempVal" />
+ <cfreturn "{""__cftype__"":""wddx"",""data"":" & coldfire_trace_udf_encode( tempVal, arguments.queryFormat, arguments.queryKeyCase ) & "}" />
+
+ <!--- STRING --->
+ <cfelseif IsSimpleValue(_data)>
+ <cfreturn '"' & Replace(JSStringFormat(_data), "/", "\/", "ALL") & '"' />
+
+ <!--- OBJECT --->
+ <cfelseif IsObject(_data)>
+ <cfset md = GetMetaData(_data) />
+ <cfset arKeys = StructKeyArray(md) />
+
+ <cfif ArrayLen(arKeys) eq 0>
+ <!--- java object --->
+ <cftry>
+ <cfset jsonString = ArrayNew(1) />
+ <cfset ArrayAppend(jsonString,"""__cftype__"":""java""") />
+
+ <!--- get the class name --->
+
+ <cfset ArrayAppend(jsonString,'"CLASSNAME":"' & _data.getClass().getName() & '"') />
+
+ <!--- get object method data, this could probabaly use some work --->
+
+ <cfset methods = _data.getClass().getMethods()>
+ <cfset methodStruct = StructNew() />
+ <cfset methodArray = ArrayNew(1) />
+ <cfloop from="1" to="#ArrayLen(methods)#" index="i">
+ <cfset methodString = methods[i].getName() & "(" />
+ <cfset params = methods[i].getParameterTypes()>
+ <cfset delim = ""/>
+ <cfloop from="1" to="#ArrayLen(params)#" index="x">
+ <cfset methodString = methodString & delim & " " & params[x].getCanonicalName() />
+ <cfset delim = "," />
+ </cfloop>
+ <cfset methodString = methodString & ")" />
+ <cfset methodStruct[methods[i].getName()] = StructNew() />
+ <cfset methodStruct[methods[i].getName()].method = methodString />
+ <cfset methodStruct[methods[i].getName()].returntype = methods[i].getReturnType().getCanonicalName() />
+ </cfloop>
+ <cfset sortedKeys = StructSort(methodStruct,"textnocase","asc","method") />
+
+ <cfloop from="1" to="#ArrayLen(sortedKeys)#" index="i">
+ <cfset ArrayAppend(methodArray,methodStruct[sortedKeys[i]]) />
+ </cfloop>
+ <cfset tempVal = coldfire_trace_udf_encode( methodArray, arguments.queryFormat, arguments.queryKeyCase ) />
+
+ <cfset ArrayAppend(jsonString,'"METHODS":' & tempVal) />
+
+ <!--- get object field data, not getting values --->
+ <cfset fields = _data.getClass().getFields()>
+ <cfset fieldStruct = StructNew() />
+ <cfset fieldArray = ArrayNew(1) />
+ <cfloop from="1" to="#ArrayLen(fields)#" index="i">
+ <cfset fieldStruct[fields[i].getName()] = StructNew() />
+ <cfset fieldStruct[fields[i].getName()].field = fields[i].getType().getName() & " " & fields[i].getName() />
+ <cfset fieldStruct[fields[i].getName()].value = fields[i].getType().getName() />
+ </cfloop>
+ <cfset sortedKeys = StructSort(fieldStruct,"textnocase","asc","field") />
+
+ <cfloop from="1" to="#ArrayLen(sortedKeys)#" index="i">
+ <cfset ArrayAppend(fieldArray,fieldStruct[sortedKeys[i]]) />
+ </cfloop>
+
+ <cfset tempVal = coldfire_trace_udf_encode( fieldArray, arguments.queryFormat, arguments.queryKeyCase ) />
+
+ <cfset ArrayAppend(jsonString,'"FIELDS":' & tempVal) />
+
+
+ <cfreturn "{" & ArrayToList(jsonString,",") & "}" />
+
+ <cfcatch type="any">
+ <cfreturn "{""__cftype__"":""unknown""}" />
+ </cfcatch>
+ </cftry>
+ <cfelse>
+ <!--- component --->
+ <cfset jsonString = ArrayNew(1) />
+ <cfset ArrayAppend(jsonString,"""__cftype__"":""component""") />
+ <cfloop from="1" to="#ArrayLen(arKeys)#" index="i">
+ <cfif ListFind("NAME,FUNCTIONS",arKeys[i])>
+ <cfset tempVal = coldfire_trace_udf_encode( md[ arKeys[i] ], arguments.queryFormat, arguments.queryKeyCase ) />
+ <cfset ArrayAppend(jsonString, '"' & arKeys[i] & '":' & tempVal) />
+ </cfif>
+ </cfloop>
+ <cfreturn "{" & ArrayToList(jsonString,",") & "}" />
+ </cfif>
+
+ <!--- STRUCT --->
+ <cfelseif IsStruct(_data)>
+ <cfset jsonString = ArrayNew(1) />
+ <cfset ArrayAppend(jsonString,"""__cftype__"":""struct""") />
+ <cfset arKeys = StructKeyArray(_data) />
+ <cfloop from="1" to="#ArrayLen(arKeys)#" index="i">
+ <cfif ListFindNoCase(ignoreStructKeys, arKeys[i]) eq 0>
+ <cfset tempVal = coldfire_trace_udf_encode( _data[ arKeys[i] ], arguments.queryFormat, arguments.queryKeyCase ) />
+ <cfif tempVal neq "coldfire_ignore_value">
+ <cfset ArrayAppend(jsonString, '"' & arKeys[i] & '":' & tempVal) />
+ </cfif>
+ </cfif>
+ </cfloop>
+ <cfreturn "{" & ArrayToList(jsonString,",") & "}" />
+
+ <!--- QUERY --->
+ <cfelseif IsQuery(_data)>
+ <!--- Add query meta data --->
+ <cfif arguments.queryKeyCase EQ "lower">
+ <cfset recordcountKey = "recordcount" />
+ <cfset columnlistKey = "columnlist" />
+ <cfset columnlist = LCase(_data.columnlist) />
+ <cfset dataKey = "data" />
+ <cfelse>
+ <cfset recordcountKey = "RECORDCOUNT" />
+ <cfset columnlistKey = "COLUMNLIST" />
+ <cfset columnlist = UCase(_data.columnlist) />
+ <cfset dataKey = "DATA" />
+ </cfif>
+ <cfset jsonString = ArrayNew(1) />
+ <cfset ArrayAppend(jsonString,"""#recordcountKey#"":#_data.recordcount#,") />
+ <cfset ArrayAppend(jsonString,"""#columnlistKey#"":""#columnlist#"",") />
+ <cfset ArrayAppend(jsonString,"""#dataKey#"":") />
+
+ <!--- Make query a structure of arrays --->
+ <cfif arguments.queryFormat EQ "query">
+ <cfset ArrayAppend(jsonString,"{") />
+ <cfset colPos = 1 />
+
+ <cfloop list="#_data.columnlist#" delimiters="," index="column">
+ <cfif colPos GT 1>
+ <cfset ArrayAppend(jsonString,",") />
+ </cfif>
+ <cfif arguments.queryKeyCase EQ "lower">
+ <cfset column = LCase(column) />
+ </cfif>
+ <cfset ArrayAppend(jsonString,"""#column#"":[") />
+
+ <cfloop from="1" to="#_data.recordcount#" index="i">
+ <!--- Get cell value; recurse to get proper format depending on string/number/boolean data type --->
+ <cfset tempVal = coldfire_trace_udf_encode( _data[column][i], arguments.queryFormat, arguments.queryKeyCase ) />
+
+ <cfif i GT 1>
+ <cfset ArrayAppend(jsonString,",") />
+ </cfif>
+ <cfset ArrayAppend(jsonString,tempVal) />
+ </cfloop>
+
+ <cfset ArrayAppend(jsonString,"]") />
+
+ <cfset colPos = colPos + 1 />
+ </cfloop>
+ <cfset ArrayAppend(jsonString,"}") />
+ <!--- Make query an array of structures --->
+ <cfelse>
+ <cfset ArrayAppend(jsonString,"[") />
+ <cfloop query="_data">
+ <cfif CurrentRow GT 1>
+ <cfset ArrayAppend(jsonString,",") />
+ </cfif>
+ <cfset ArrayAppend(jsonString,"{") />
+ <cfset colPos = 1 />
+ <cfloop list="#columnlist#" delimiters="," index="column">
+ <cfset tempVal = coldfire_trace_udf_encode( _data[column][CurrentRow], arguments.queryFormat, arguments.queryKeyCase ) />
+
+ <cfif colPos GT 1>
+ <cfset ArrayAppend(jsonString,",") />
+ </cfif>
+
+ <cfif arguments.queryKeyCase EQ "lower">
+ <cfset column = LCase(column) />
+ </cfif>
+ <cfset ArrayAppend(jsonString,"""#column#"":#tempVal#") />
+
+ <cfset colPos = colPos + 1 />
+ </cfloop>
+ <cfset ArrayAppend(jsonString,"}") />
+ </cfloop>
+ <cfset ArrayAppend(jsonString,"]") />
+ </cfif>
+
+ <!--- Wrap all query data into an object --->
+ <cfreturn "{" & ArrayToList(jsonString,"") & "}" />
+
+ <!--- XML DOC --->
+ <cfelseif IsXMLDoc(_data)>
+ <cfset jsonString = ArrayNew(1) />
+ <cfset ArrayAppend(jsonString,"""__cftype__"":""xmldoc""") />
+ <cfset arKeys = ListToArray("XmlComment,XmlRoot") />
+ <cfloop from="1" to="#ArrayLen(arKeys)#" index="i">
+ <cfif ListFindNoCase(ignoreStructKeys, arKeys[i]) eq 0>
+ <cfset tempVal = coldfire_trace_udf_encode( _data[ arKeys[i] ], arguments.queryFormat, arguments.queryKeyCase ) />
+ <cfif tempVal neq "coldfire_ignore_value">
+ <cfset ArrayAppend(jsonString, '"' & arKeys[i] & '":' & tempVal) />
+ </cfif>
+ </cfif>
+ </cfloop>
+ <cfreturn "{" & ArrayToList(jsonString,",") & "}" />
+
+ <!--- XML ELEMENT --->
+ <cfelseif IsXmlElem(_data)>
+ <cfset jsonString = ArrayNew(1) />
+ <cfset ArrayAppend(jsonString,"""__cftype__"":""xmlelem""") />
+ <cfset arKeys = ListToArray("XmlName,XmlNsPrefix,XmlNsURI,XmlText,XmlComment,XmlAttributes,XmlChildren") />
+ <cfloop from="1" to="#ArrayLen(arKeys)#" index="i">
+ <cfif ListFindNoCase(ignoreStructKeys, arKeys[i]) eq 0>
+ <cfset tempVal = coldfire_trace_udf_encode( _data[ arKeys[i] ], arguments.queryFormat, arguments.queryKeyCase ) />
+ <cfif tempVal neq "coldfire_ignore_value">
+ <cfset ArrayAppend(jsonString, '"' & arKeys[i] & '":' & tempVal) />
+ </cfif>
+ </cfif>
+ </cfloop>
+ <cfreturn "{" & ArrayToList(jsonString,",") & "}" />
+
+ <!--- XML NODE --->
+ <cfelseif IsXmlNode(_data)>
+ <cfset jsonString = ArrayNew(1) />
+ <cfset ArrayAppend(jsonString,"""__cftype__"":""xmlnode""") />
+ <cfset arKeys = ListToArray("XmlName,XmlType,XmlValue") />
+ <cfloop from="1" to="#ArrayLen(arKeys)#" index="i">
+ <cfif ListFindNoCase(ignoreStructKeys, arKeys[i]) eq 0>
+ <cfset tempVal = coldfire_trace_udf_encode( _data[ arKeys[i] ], arguments.queryFormat, arguments.queryKeyCase ) />
+ <cfif tempVal neq "coldfire_ignore_value">
+ <cfset ArrayAppend(jsonString, '"' & arKeys[i] & '":' & tempVal) />
+ </cfif>
+ </cfif>
+ </cfloop>
+ <cfreturn "{" & ArrayToList(jsonString,",") & "}" />
+
+ <!--- UNKNOWN OBJECT TYPE --->
+ <cfelse>
+ <cfreturn "{""__cftype__"":""unknown""}" />
+ </cfif>
+</cffunction>
+

0 comments on commit 8a04560

Please sign in to comment.