I have this code for counting Requests:
<cfobject type="JAVA" action="Create" name="thread" class="java.lang.Thread">
<!--- Get all stack traces from the thread object --->
<cfset stackTrace = thread.getAllStackTraces()>
<!--- Convert the entrySet into an array --->
<cfset stackArray = stackTrace.entrySet().toArray()>
<cfset requestCount = 0 />
<!--- Loop over the entrySet array --->
<cfloop from="1" to="#ArrayLen(stackArray)#" index="sIndex">
<!--- Get the current thread values --->
<cfset thisThread = stackArray[sIndex].getValue()>
<!--- Loop over current thread values --->
<cfloop from="1" to="#ArrayLen(thisThread)#" index="tIndex">
<!--- Get the filename for this thread --->
<cfset thisThreadFile = thisThread[tIndex].getFileName()>
<!--- If the file name contains .cfm output it --->
<cfif isDefined("thisThreadFile") AND thisThreadFile CONTAINS ".cfm">
<cfset requestCount += 1 />
</cfif>
</cfloop>
</cfloop>
<cfset json_object = structNew()>
<cfset json_object["active_requests"] = JavaCast("int", requestCount)>
<cfoutput>#serializeJSON(json_object)#</cfoutput>
I need to be able to not count multiples on the stack trace. What would be the best way to do that?
答案 0 :(得分:0)
If you mean only count unique files names, instead of a counter, use a structure. Structures only store unique keys.
Create an empty structure before the outer loop. Then add matching file names to it inside the inner loop. (I'd recommend using isNull instead of isDefined and list functions to get the file extension)
<cfset uniqueFileNames = {}>
<cfloop from="1" to="#ArrayLen(stackArray)#" index="sIndex">
...
<cfloop ....>
<!--- If the file name ENDS with .cfm include it --->
<cfif !isNull(thisThreadFile) && listLast(thisThreadFile, ".") eq "cfm">
<cfset uniqueFileNames[thisThreadFile] = true>
</cfif>
</cfloop>
</cfloop>
Finally, get the number of unique files with structCount():
<cfset json_object["active_requests"] = structCount(uniqueFileNames)>
Suggested Improvements
Since you're using 2016, switching to "array" loops and structure shorthand will make the code even simpler. Complete example:
<cfset thread = createObject("java", "java.lang.Thread")>
<cfset allTraces = thread.getAllStackTraces()>
<cfset traceArray = allTraces.entrySet().toArray()>
<cfset uniqueFileNames = {}>
<cfloop array="#traceArray#" index="currThread">
<cfloop array="#currThread.getValue()#" index="thisThread">
<cfset thisThreadFile = thisThread.getFileName()>
<cfif !isNull(thisThreadFile) AND lcase (thisThreadFile).endsWith(".cfm")>
<cfset uniqueFileNames[thisThreadFile] = true>
</cfif>
</cfloop>
</cfloop>
<cfset json_object = {"active_requests" = structCount(uniqueFileNames)}>
<cfoutput>#serializeJSON(json_object)#</cfoutput>