This question has come up a couple of times recently in support/pre-sales queries. Essentially the question is why can’t FusionReactor see the values of variables (eg LOCAL/VARIABLES/REQUEST scope etc)?
FusionReactor is a low-overhead Java production server monitor designed for light-weight 24×7 use. It let’s you see what’s happening on your server right now and the recent past. It has other features that can prevent a server from failing and alerting based on rule-sets etc but that’s out of the scope for this question. If you think about the tool, it really has to be very low overhead to not skew the metrics you’re seeing and be of high value. A page is typically processing and running through many lines of code per second – as that happens, variables are constantly being created and updated. If we were to try and show variables in FusionReactor, the variable would most likely have changed it’s value by the time you’ve read it. One option of course would be to stop processing until further input – but then we’d really be a step-debugger (let me introduce you to FusionDebug now – the first & fastest CFML step-debugger and the only one that works with both Adobe CF and Railo). Another would be to only show variable values at the end of a request, or perhaps when each query executes. If you’re interested in variable values at the end of the request, you’re probably debugging something. This is where a step-debugger would be useful or you can output the value to DB/file/screen. If you’re interested in variable values when a query executes, it’s probably because you want to know what query is going to be run – if that’s the case, you really should just wrap your datasource and have FusionReactor tell you the query (and it’s query params) along with other useful data (like how fast the DB query was, how quickly the resultset travelled over the network, how many rows were returned, etc).
The most worthwhile argument I’ve seen was to capture variable values at the time a request fails – but then this opens another question of what is a failed request? A server 500 error? Well what if you try/catch the error and give the user some other route to continue – how would FusionReactor know to capture the variable values?
Now we’ve dealt with the logical reasons why we should or should not have this feature, the next is to think about the technical overhead – reading, storing and managing these variable values would be very costly – in both execution time and memory. For example, what if your request has a 200MB file in memory? Should FusionReactor take a copy of that memory so that it can display/notify you of it? Of course, these are loaded questions but hopefully they start to explain why this feature isn’t present. However, read on because there’s a very simplistic way to see what you want…
FusionReactor supplies an API. One of the API methods provides a way of giving FusionReactor some information to store & display with the request details. It’s quite simple to include in your code and would let you easily push any information you want for display in FusionReactor. This is most commonly used for things like tracking long running functions (eg: consider a credit card authorization call in an e-commerce application)…
<cfset frapiClass = createObject("java", "com.intergral.fusionreactor.api.FRAPI") / <cfset frapi = frapiClass.getInstance() / !--- Note: The above two lines only need to be done once per request. You could put the variables into request scope and re-use multiple times. --- cfset frapi.trace( "Calling doCCAuth()..." ) / cfset ccAuthResult = doCCAuth(cardNumber, expiryDate, cvv) / cfset frapi.trace( "Completed doCCAuth. Result = #ccAuthResult#" ) / !--- Note: FusionReactor will automatically time-stamp the traces so you know how long the call has taken ---
Taking this idea, we can easily have FusionReactor display all our (simple) variables (eg with LOCAL scope):
<cfset frapiClass = createObject("java", "com.intergral.fusionreactor.api.FRAPI") / cfset frapi = frapiClass.getInstance() / cfloop collection="#LOCAL#" index="key" <cfset frapi.trace( "LOCAL.#key# = #LOCAL[key]#" ) / /cfloop
If your scope contains complex variables (query, array, struct, object, etc) then you could serialize them to JSON or provide a toString() method as preferred.
A big hello from CFUnited!
Myself (David Stockton) and my colleagues (Darren Pywell & David Tattersall) are all at CFUnited this week. We have a FREE copy of FusionAnalytics to give away so don’t be shy – come and speak to us for a chance to win!!
Plus, ask nicely and we’ve got FREE goodies for everyone we speak to!
We’re in the vendor area between Adobe & Railo – look for the ShareDox, FusionReactor, FusionAnalytics & Intergral banners… plus this good looking guy:
See you there!
We consult with a lot of different types of company. Sometimes there’s a lot of security process to deal with. This is great when you’re trying to stop un-authorized access but can sometimes hamper the speed of response an outside agency can give.
In one such incident we were trying to identify the IP address of a slow uploading client – this we could then link to a client account and identify where the issue was coming from. At the first stage we weren’t able to access any of the remote clients network. Using good old email the client was able to send me a copy of all the FusionReactor Crash Protection alerts. These fire under certain conditions alerting the recipient of a potential issue. You can read more about crash protection on the FusionReactor website.
Now the emails are a great feature but they’re not very easy to analyse over 100’s of emails. So we created a quick tool to analyse the crash protection emails for just this sort of event. And now we’re making it available to you… FREE!
FusionReactor CrashProtection EMail Analyzer
Now you have a list of all the slow pages (over 60seconds) and which IPs they’ve come from and which page(s) they’ve hit – all without direct access to FusionReactor. Also great if you’ve only got access to the emails (eg your logs have rotated).
Phew – Sound like too much work? Save the hassle and get FusionAnalytics or contact us now!