[Looking for Charlie's main web site?]

I'm speaking this evening on the Adobe CF Developer Week webinars: mine on CF Server Monitor

Hey folks, just a heads up (for those who may not have seen all the tweets and list messages) that this week is the Adobe CF Developer Week series of free webinars.

Update, Recording: Note that this session was recorded. You can view it here, but note that you must login with an Adobe ID to see it.

And I'm presenting a session tonight, Tuesday September 13, at 7pm Eastern, on "Understanding and Using the ColdFusion Server Monitor".

As many of you know, I'm pretty much a fanatic about the monitor, especially about truly understanding elements of it that many miss. And so in my talk this will not be just a dog and pony show, but I will talk about practical experiences with it, though presented to either those new to it or experienced with it.

Note that the times for all these devweek sessions is shown (on the Adobe site) as being Pacific time, so again mine is at 7pm, not 4pm, Eastern.

And yes, the sessions are being recorded and seem to be made available the next day.

Finally, beware that there is no one URL you can use to join in on all the Connect sessions, nor can you get the Connect session URL by going to the event page (via the first link above). Instead, you must register for each event (free) from that first page, to get each session's Connect URL--and you'll want to do that at least several minutes in advance of any session to have time to register, get the email, login, etc.

See you then.

PS Hey, while we're talking monitoring, note as well that if you've not heard, FusionReactor has come out with its new release 4, which has lots of great additions, especially FREC (or the FR Extensions for CF) which cause FR to grab and log lots of great info that the CF Server Monitor only shows and never logs. I'll be blogging about FR 4 soon, but plenty to see on their site. and FusionAnalytics is also just about to release, really!

I won't be discussing these at this talk, focused solely on the server monitor, but as I always tell folks, each tool has its use and often a single shop can benefit from having both (like I do, as do many of the clients I help with troubleshooting). You can find more from me about FR here in my blog. And I'll have lots more to say about FA and FR4 more soon.

CF911: Lies, Damned Lies, and CF Request Timeouts...What You May Not Realize

How often have you seen (or seen others complain of getting) an error from ColdFusion such as:

The request has exceeded the allowable time limit Tag: cfoutput

Do you know what this means? It's usually not what you think. I've even seen experienced CF developers who get thrown by this challenge. In this entry I'll try to help explain a very common problem and correct some misconceptions. I'll even contend that this info is often useless and indeed misleading (and therefore the feature producing it ought not be relied upon, and should even be turned off). Along the way, I'll share some things that I've not seen documented elsewhere.

Strap on your seatbelts. We're going for a bit of a ride (if it was easy and could be understood in the length of a tweet, then perhaps everyone would already understand it!) As always, I welcome feedback.

What the error usually does NOT mean, though most assume it

People are often mystified: "Why in the heck would a CFOUTPUT take a long time?"

Or perhaps they're a little more savvy as to what's happening, and they assume, "No, it's just that the CF timeout time was reached when it got to the CFOUTPUT". That could be.

Sadly though, in most cases, neither is what has happened. CF is usually NOT reporting that "here where the app timed out".

What the error usually DOES mean--the surprise

"OK, smarty-pants. What does the error really mean? Are you saying that CF is lying to me?" Well, often, yes, I'm afraid so, but it's not something nefarious.

Rather, what's more typically the explanation is that some previous activity in the page/request, such as a CFQUERY, CFHTTP, invocation of a web service, or the like is what really took a "long time".

If it was this which caused the request to exceed the timeout (either as defined in the CF Admin Settings page, or using CFSETTING RequestTimeout, or a Timeout attribute on a tag), you'd of course expect CF to report it then and there. The problem is that, often, it cannot report it "right then". And it's not its fault.

There are some operations CF/the JVM cannot interrupt

The problem is that CF (and the JVM) cannot interrupt a request while it's processing what's called a "native method". That is quite typically the mode that a request is in while it's waiting for a reply from a CFQUERY, CFHTTP, and so on. These operations talk to something outside of CF (like a database with CFQUERY, or another server with CFHTTP or web service call--which could even be requesting a page from the same CF instance, but technically the underlying Java httpclient process doesn't know that.) It could also happen with file or network operations.

So the request will wait for this long-running operation to finish. It can't stop it, not with the CF Admin request timeout, not with CFSETTING RequestTimeout, not with the kill features in the CF Server Monitor, FusionReactor, and SeeFusion. Nothing. It's like the Anti-Terminator: "it absolutely will not stop" (can't be terminated) until its task is completed.

So what happens when the long-running operation finishes? Is that when the request times out? An example

"Ok, I got it. The long-running operation (CFQUERY, CFHTTP, whatever) will not stop until it's finished. What happens then?"

Well, you see, that's where the confusion comes in. Let's use an example to make things crystal clear.

Say that the CF admin timeout is 60 seconds (not at all uncommon), or perhaps you set the timeout to 60 for a given template using CFSETTING. Anyway, let's say that the request in question gets 2 seconds into processing when it starts running a long-running query (for example). Let's say that query then takes 75 seconds. When the query is done, the request has now run for 77 seconds, which is 17 seconds beyond the timeout time.

We already know that it won't stop the CFQUERY itself (at least until the query is finished). But guess what: it also will NOT report that the timeout has been exceeded on that line (whatever it was, CFQUERY, CFHTTP, etc.) From my experience, CF doesn't check the time against the timeout at the end of operations, but rather at the beginning.

So instead, it will proceed to the next line of code. You'd think, "ok, then, it will stop on whatever is the next line of code and give you the error there, right?" Sadly, not necessarily, and it only adds to the confusion of the timeout message.

CF checks the time at the start of the next operation, but sadly only on SOME tags

So it's bad enough that it won't report the error on the tag that DID run long. Instead, we saw that it will proceed to the next tag/function. But curiously (tragically), CF will often NOT stop on THE next line of code.

Instead, I've observed that it only seems to check the time (against the timeout) at the beginning of CERTAIN tags, such as CFOUTPUT, CFLOOP, CFQUERY, and so on. Yes, I'm saying that I've confirmed that it will skip over various other tags (such as CFSET, or CFSCRIPT code, and more). I've not yet found any documentation as to the details of this.

So this is where the error gets confusing

So the bottom line is that not only does the the request NOT stop on the tag/function that took a long time, it doesn't even stop on "the next line" after that, which can make things all the more confusing/challenging to resolve.

Indeed, this is why you often see the error reporting as having occurred on a tag other than what was really the problem, and why you also can't just look at whatever was *the* line of code preceding that.

So what can you do with this information?

I don't mean to paint an entirely bleak picture. All is not lost. It's just a little more challenging than it should be.

At least first of all you can now know that when you see this error, you should NOT assume that it's reporting the line that really caused the problem. You can and should consider whether some earlier operation in the code could have taken a long time. In my experience, this is usually the situation.

I'll talk in a moment about some other tools that can help you understand where the time is really being taken. First, I do want to offer a clarification, lest anyone read my meaning too literally.

Are you saying the error message is always lying?

Well, no. You'll notice that I peppered my opening paragraphs with "usually", because it's certainly possible that a request could indeed be stopped on the very line that DID exceed the timeout.

Consider in our example that if the long-running query had run for only 57 seconds. Now, since it had taken 2 seconds before that, it now is one second short of timing out. Let's say the request then proceeds to loop over a query resultset or do some other operations that might take it a couple more seconds. When it does finally exceed the timeout, it may well happen right on the very tag that CF Reports as having "crossed" the timeout time.

But given the problem of how it only reports that on some tags (and not all), it could still be in this situation that it reports the wrong line of code. Just consider all the above as you evaluate what to make of the situation.

So how can I know what tag did take a long time?

So how can you know what tag is taking a long time, when a request it running long? or did take a long time, if it finished in the past? This is a bit more challenging. The good news is that there are tools that can help, including the CF Enterprise Server Monitor, FusionReactor, and SeeFusion.

Let's focus first on using these tools to catch requests while they're still running, which could be valuable if your server is hanging up because of some long-running requests. Then we'll talk about using the tools to capture the same information and make it available by email to review later.

The underlying feature/solution: stack tracing

In either case, whether watching requests live or capturing information about them to review in the future, and in all three tools, the solution to identifying why a request is long-running will be based on "stack tracing" that request.

This is a feature built-into the JVM, which is exposed easily by these tools, but missed entirely by many. More than that, some misunderstand stack tracing as something only shown at the bottom of error pages. (That is indeed a stack trace, but it's not nearly as useful as what I'm referring to here, which is for getting information on request while they're running, not when they have had an error.)

Stack tracing a running request will allow you to see exactly what line of CFML (if any) is running at that very moment, which again can be vital for resolving problems of long-running requests.

CF Enterprise Server Monitor

First, if you run CF Enterprise (8 or 9), you can use the CF Server Monitor to watch requests while running and see more details about them. If you use the available "start monitoring" button, you can see what requests are running in "Active Requests". Further, if you enable "start profiling", then if you double-click a running request, you can see in the middle of the next page a "stack trace", which shows the exact line of code that was executing at the time you double-clicked the request.

(Yes, I'm aware of the potential overhead of using the Server Monitor, though some people do over-state it in my experience. I'll point to other resources I've done on the Monitor, where I discuss its pros and cons, in a moment.)

Of course, viewing that stack trace at a random point in time during the life of a request could well mean simply that you'd see it executing just any random line, where perhaps a millisecond later CF will have moved on to another. The key is to refresh the stack trace, to see if CF indeed HAS moved on to a new line. If not, that line would be a smoking gun to investigate. Sadly the refresh icon in the Monitor doesn't update the details while viewing a running request. You need to go back to the list of active requests, open the request again, and repeat your observation.

Tools like FusionReactor and SeeFusion

Fortunately, tools like FusionReactor and SeeFusion make that refresh a lot easier, to obtain a stack trace while request is running. Each offers a button to take a stack trace of a running request. From the page they show you can usually determine the line of CFML code that's running (they each offer a little more stack trace detail than the CF Server Monitor does, but I'll point you soon to a resource to help you better understand them.)

More important, each of these tools offer a refresh button to refresh the stack trace, so that you can properly determine if the line that's executing has changed while you're refreshing.

That said, I will note that FusionReactor offers an important advantage with respect to that refresh operation: it ties the stack trace display to the specific CFML page that was being viewed (in Running Requests page) when you selected it. So if that request ends while you're looking at its stack trace, and you refresh it, FusionReactor will report that it's finished.

SeeFusion, on the other hand, would not. It knows only the thread id on which the requested page was running, so that if the request ends and you refresh the stack trace, it only knows to refresh the stack trace for whatever request is running on that thread. It can't (and won't) tell you if the given request has in fact ended, so you could now be looking at a new (and different) request, which could be quite confusing in this situation. It's incumbent upon you to notice (when using SeeFusion) that the stack trace you see in indeed for the same request you started with. (FR gives each request its own internal request id, which is how it avoids that problem.)

Catching running requests details when you're not watching the monitor tools

Of course, it's only possible to use the stack tracing features above if you can be on the server running the monitor tools when the problem occurs, right?

Well, not exactly: all three tools offer features to watch for a long-running request which can then send you notification by email of the details that would include a thread dump, which is a stack trace of all running requests.

In the CF Server Monitor, these are called Alerts. FusionReactor refers to them as Crash Protection notifications, and SeeFusion refers to this as "Active Monitoring Rules". See the documentation for each tool to find more information.

Learning more about stack tracking and the monitor tools

For more on all this, I discuss the idea of taking stack traces and thread dumps (which is a list of all stack traces for all current threads) in another blog entry.

I also discuss the CF Server Monitor, FusionReactor, and SeeFusion in several blog entries. The links just used are to the respective categories about each here in my blog. I've also discussed these topics (monitoring, stack tracing, and more) in various articles and presentations I've done.

The step debugger

Finally, some may point out that you can also get an idea of the time spent on any tag/function within a request if you use the interactive Step Debugger (whether that built into CFBuilder or the commercial FusionDebug alternative). As you step through the code, it would be clear if you got "hung up" on a line, though I don't know that I'd favor this as a solution here. Still, I've discussed these also in various blog entries, articles, and presentations.

(Sadly, you can't rely on the typical end-of-page debugging output, as enabled in the CF Admin, because that output is only shown if the request completes. We're referring here to pages that end in error.)

Can't I force CF to timeout some specific tags?

Again, in my experience (as I focus on CF server troubleshooting as a consultant), the root cause of problems in most "long-running" requests in CF is that some one tag or function is running long.

So could we perhaps force CF to timeout that specific tag? Well, yes and no.

You can, in fact, (and should) consider whether the tag in question might have its own TIMEOUT attribute or feature (and whether it will really help, as I'll explain.) Let's look at each of them.

Setting Timeout on CFHTTP, CFINVOKE, and others

There is indeed a TIMEOUT attribute on CFHTTP. Unfortunately, it won't ALWAYS keep the operation from exceeding that timeout. I've not quite put my finger on it (just haven't experimented completely), but if I had to guess, I'd say that it could be that if the operation is in the midst of returning data (from the server to CF), then it could perhaps time it out, whereas if it's waiting for the output then it may not be able to. Anyone know for sure?

There is also a TIMEOUT on CFINVOKE (for use when calling web services). Curiously, though, there is no TIMEOUT for use with CFOBJECT when calling web services (try it, it won't work, and none is documented). More curious still is that there IS a timeout available for use with createObject() (when calling a web service), though only by way of an argstruct argument that's new in CF8, which I have blogged about. Note as well that, according to the docs, that only times out the process of obtaining the WSDL, not the execution of any method in the web service.

There are also timeouts on various other operations that talk to something outside of CF (cfmail, cfftp on open/close operations, cfldap, cfpop, cffeed), though again it seems reasonable to expect that these may not always honor the timeout at the exact time given, as discussed above.

Setting Timeout on CFQuery

What about the elephant in the room, CFQUERY? Well, yes, it does have a TIMEOUT attribute, but many have found that it often does not timeout the query. Like the CFHTTP, I wonder if it may be a question of whether it's waiting for output (which likely can't be interrupted) or starting to receive it (which likely can be).

I will note that there's some promise in this regard, though for now not from CFML itself, but rather from the updated JDBC drivers in CF9 and the addition of a new timeout option in the CF Admin Datasource Advanced Settings page. You'll see that there is a new "query timeout" option that was not in CF before 9. I have blogged about it in more detail. It's not perfect: people are reporting different experiences with it (see the comments in the blog entry), and note (more important) that for now there seems no corresponding connection between this and the CFQUERY TIMEOUT attribute. (As I note there, I have raised a bug about this.) Still, it may be better than nothing and could help many, if you're on CF9.

So is there really nothing I can do for the hung requests?

OK, so we've explained why the requests don't timeout, often because they're talking to some remote process that is not responding. But what CAN you do when you're in this boat? Well, other than trying to add timeouts to the code as discussed above, generally nothing, at least for the requests that are already running.

And certainly a restart of CF will kill them off, or at least stop CF trying to talk to the remote process. (Of course, it's possible that upon restart, new requests will come in and try to connect to the same non-responsive or slow-responding remote process, so it could come right back.)

Stop the request on the remote server

But while you can't do much from WITHIN CF for these hung requests, there's one other way you may be able to stop the madness: stop the request on the remote server.

Once you can determine exactly what tag it is that's hung up (with the stack tracing tools above), you could then target whatever it was waiting for: the database server, a remote page called via CFHTTP, an exchange server using CFLDAP, etc.

Since the tools that let you stack trace the running request also show you the time the request started, you could use that info to go to the administrator of whatever service you're calling and ask if THEY may be able to kill the request. As soon as what you're waiting for stops, the CF request will continue. (Of course, it may only continue for a few milliseconds before it will be timed out by CF, as I discussed above, which is why I'm no fan of the CF request timeout feature, and think it should be turned off. More on that in a moment.)

Beware: you may not always find the remote server still "hung up"

Back to this issue of finding and killing the remote process that CF may be waiting for (that's causing your hung request), I should note that there may be times when you would go to the remote administrator and say, "look, I have this long-running CF requests that's waiting for this process (query, ldap request, web page, etc.) that is waiting forever for something that is running long on your server". And they may look and see nothing on their ends that's running long. Doh!

Yep, it can happen, for various reasons, so just be sensitive to this. You may really then have no way at all to kill the hung request. But note, again, that you may be able to use this observation to do something more to prevent the problem in the future, perhaps on the remote server side.

For instance, I've heard some describe problems where CFQUERY processing has hung talking to an Oracle database and (if I've got it right) the problem is an inconsistency between the CF datasource connection timeout and Oracle's "session" timeout. If anyone has more details on that, please do share.

But my point is simply that CF may be "waiting" for a call that will never be answered and can't be terminated from the other end. Again, in such cases, you can only kill them by restarting CF, and then you need to investigate how/why the call to the remote server are getting hung up in the first place. That's where logging information for diagnostic purposes may really come in handy, as is discussed next.

Logging what CF is getting hung up, to show to the remote administrator

If this problem (of calls to remote servers that take too long or get hung up) is happening often, and/or you can't always be logged in to see when it's happening using the tools above, another idea is to log for yourself whenever you make such a call to a remote server (that you know tends to hang up), such as putting a CFLOG statement before and after the CFHTTP, CFLDAP, CFQUERY, etc.

At least then you'll be able to see when it does and doesn't take a long time. The log would also help you by showing when it logs a start but no stop.

You could also code it so that it only logs when it's slow, but being able to confirm that it's generally fast and only sometimes slow may be itself useful diagnostic info.

Note that CF 9.0.1 by default adds new logging that does automatically log the start and end of calls to cfhttp, cffeed, and more to corresponding new logs (http.log, feed.log, etc.), which could also help.

Finally, as for logging the queries, you can get that from FusionReactor and SeeFusion automatically, as their "jdbc wrapper" features allow you to log every query (or optionally only those slower than a certain time). There is also a new "log activity" feature in the "advanced settings" of a CF datasource definition that could also log DB activity, though it is quite verbose and a tad unwieldy (not one line/row per query like the other two tools).

Bottom line: I'm no fan of request timeout features

So all that said, I'll repeat and clarify that I'm no fan of request timeout features, not that in the CF Admin, nor that offered in CF monitoring tools that offer to "kill requests" automatically, like the CF Server Monitor Alerts, FusionReactor's crash protection, and SeeFusion's active monitoring rules. I don't think they should be used, personally.

Let me be clear: I do love those tools and use them and help people use them daily. And I do love and highly recommend the features in those tools for sending you *alerts* when requests exceed a given time. What I don't like is them trying to kill them automatically, for all the reasons I outlined above. So I tell clients to turn off the "timeout requests" feature (though it does still make sense to use TIMEOUT attributes on certain tags, or may make sense to implement the CFSETTING RequestTimeOut on some page where you know that the reason it runs long is not one of these things that can't be killed anyway.)

Instead, I recommend (and help my clients daily) to use the alert info (from the CF Server Monitor, or FR or SF) to be notified if/when requests ARE taking too long--and NOT to kill them. Note that these tools all send the notice *as soon as* the request takes too long (whatever time you set), whereas CF's "log slow requests" feature only logs when requests end--and that's only IF they do end without failing.

So yes, get notified that requests are taking too long. Use the info in the alerts, which includes the stack trace info I discuss above. Do find and resolve the problem. Don't rely on (or in my opinion even use) auto-kill features, when in fact they nearly never are able to kill really problematic requests anyway.

Yes, yes, I do realize that there are some requests that CAN be interrupted by these timeout/kill features, but I'll assert that such requests are far less commonly the cause of any serious problems. Your mileage may vary, of course. But I make my statement based on several hundred instances of helping folks solve typical CF server problems.

So why is the "timeout requests" setting there?

One last thought worth considering: someone might reasonably ask, "Charlie, why are you such a hater of the setting? If Adobe has it there, it must be for a good reason."

Here's what I'd say to that: sure, when CF originally ran on C++ (prior to CF 6), perhaps this setting could be reasonably relied upon to ensure that requests would not run any longer than the set time. (I don't recall, but perhaps even then there may have been at least SOME tags that it couldn't interrupt.) But clearly since CF 6, in the Java model, this is no longer the case.

And yet if you read the Admin page, or its help, or the docs, or the comments from nearly anyone who considers the setting, the presumption is that this WILL stop requests from running longer than the x number of seconds indicated.

Why am I so impassioned/manic about this?

I hope I've made clear in this entry why I think that's not only wrong to conclude (in nearly all cases), but worse it sets up a tragic misconception of how CF works. If you think this should and will stop long requests (or that the alert features of the monitors will kill them), then you're going to be in for a shock when requests do hang up for an extended period of time. What are the implications?

  • You may totally under-estimate how many simultaneous request threads you should enable.
  • You may never pay attention to tools like CFSTAT or jrun metrics (to observe at least "how many requests are running" at any given time), which will help you see if/when requests are hung.
  • You may never bother to learn how to use the CF Server Monitor (or FR or SF), all of which can go still further and show not just how many requests are running (possibly hung) but a) how long, b) what the URL is, c) what the IP address is, and so much more, which can help you find and resolve problems.
  • You may never bother to learn how to do the stack tracing that I discuss above, which is often vital to understanding where and why any given request is hung (or was at the time an alert was thrown)
  • You may never bother to analyze logs that show the activity patterns (how many requests are running at periodic intervals, such as the FusionReactor "resource log" reports.) It's really THAT information that is vital to your understanding what to set for your simultaneous requests setting.
  • and so on

All of this info (and understanding) is VITAL to a very important and common class of CF server troubleshooting: why is CF up but not responding? It may be that requests are hung.

But if you assume, "well, they can't be running any more than x seconds", then you'll start to think "so it must be something else", and you figure you may as well just restart CF. Or you start reading about how someone suggests you change your JVM settings (which may have NOTHING TO DO with this problem, and not only not solve it but could cause new ones), and so on.

Again, I see this all the time. I hope by this entry to have helped avoid some of the very common misunderstandings on this subject that I frequently see either on lists, or in emails to me, or in my consulting engagements. If I seem passionate about it, it's because I am. Same with the memory issues I discuss in the related and similarly titled entry, CF911: Lies, damned lies, and when memory problems not be at all what they seem, Part 1.

Need More Help?

I mentioned above that I provide CF Server Troubleshooting consulting. If you need some help understanding how to apply the information above to your specific problem (or need help with any CF server, or CFBuilder, problem), I'm happy to help.

I don't need to come on-site, nor do you need to give me remote access. Instead, we can work easily and securely right over the web using Adobe Connect.

And I don't have any minimum time-block requirement--and I even offer a satisfaction guarantee. To learn more, including rate plans, see my consulting page. (I hope some will forgive this brief commercial here. I don't generally mention it, but since some say that they didn't know I offer such services, it seemed an appropriate point to mention it.)

Conclusion

So phew, another really long blog entry. But I hope it may help some people (and help some who help others).

As always, I welcome your feedback, corrections, additions, etc. Really, I ask for your feedback. If it helped, please say so. My blog doesn't get the traffic of many others. I often see that hundreds of people have read things, but few ever comment. I can't know if it's that I've answered every question (I can hope so), or that you weren't impressed. Like the guy said in Dirty Harry, "I gots to know". :-) Sometimes, all it takes is a few people to "prime the pump" and start commenting to lead others to do so. Why not grab the handle? :-) And if you think this would be helpful info for others, please do share it (tweet about it, mention it on mailing lists/forums when you see the problem raised, etc.)

I'm planning to better organize and package CF server troubleshooting resources (mine and others). We have a lot of great info out there for those solving CF problems. It can just be a challenge to sort through it all. I hope to help solve that. Look for more news to come on that front in time.

Some code to throttle rapid requests to your CF server from one IP address

Some time ago I implemented some code on my own site to throttle when any single IP address (bot, spider, hacker, user) made too many requests at once. I've mentioned it occasionally and people have often asked me to share it, which I've happily done by email. Today with another request I decided to post it and of course seek any feedback.

It's just a rough cut. I haven't thought it through thoroughly (wow, how's that for an alliteration!). Still, while I know there are couple of concerns that will come to mind for some readers and I try to address those at the end, it does work for me and has helped improve my server's stability and reliability.

Background: do you need to care? Perhaps more than you realize

As background, in my consulting to help people troubleshoot CF server problems, one of the most common surprises I help people discover is that their servers are often being bombarded by spiders, bots, hackers, people grabbing their content, rss readers, or even just their own internal/external ping tools (monitoring whether the server is up.)

It can either be that there are many more than they expect, coming more often than they expect, or they may come extremely fast to your server (even many times a second). This throttle tool helps deal with the latter.

Why you can't "just use robots.txt and call it a day"

Yes, I do know that there is a robots.txt standard (or "robots exclusion protocol") which, if implemented on your server, robots should follow so as not to abuse your site. And it does offer a crawl-delay option.

The first problem is that some of the things I allude to above aren't bots in the classic sense (such as RSS readers, ping tools). They don't "crawl" your site, so they don't regard that they need to be told how/where to look. They're just coming looking for a given page.

The second problem is that some bots simply ignore the robots.txt, or don't honor all of it. For instance, while Google honors the file in terms of what it should look at, my understanding is that it instead requires you to implement the webmaster toolkit for your site to control its crawl rate.

Then, too, if you may have multiple sites on your server, the spider or bot may not consider that in deciding to send a wave of requests to your server. It may say "I'll only send requests to domain x at a rate of 1 per second", but it may not realize that it's sending requests to domains x, y, z (and a, b, and c) all of which are one server/cluster, which could lead a single server to in fact be hit far more than once a second (in that scenario). It may seem that's an edge case, but honestly it's not that unusual from what I've observed.

Finally, another reason all this becomes a concern is that of course there can be many spiders, bots, and other automated requests all hitting your server at once sometimes. My tool can't help with that, but it can at least the other points above.

(As with so much in IT and this very space, things do change, so what's true today may change, or one may have old knowledge, so as always I welcome feedback.)

The code

So I hope I've made the case for why you should consider some throttling, such that too many requests from one IP address are rejected. I've done it in a two-fold approach, sending both plain text and an http header that is appropriate for this sort of "slow down" kind of rejection. You can certainly change it to your taste.

I've just implemented it as a UDF (user-defined function). Yes, I could have also written at in all CFscript (which would run in any release, as there nothing that couldn't be written in script in that code--well, except the CFLOG, which could be removed). But since CF6 added the ability to define UDFs with tags, and to keep things simplest for the most people, I've just done it as tags. Feel free to modify it to all script if you'd like. It's just a starting point.

I simply drop the UDF into my application.cfm (or application.cfc, as appropriate). Yes, one could include it, or implement it as a CFC method if they wished.

<cffunction name="limiter">
   <!---
      Written by Charlie Arehart, charlie@carehart.org, in 2009
      - Throttles requests made more than "count" times within "duration" seconds.
      - sends 503 status code for bots to consider as well as text for humans to read
      - also logs to a new "limiter.log" that is created automatically in cf logs directory, tracking when limits are hit, to help fine tune
      - note that since it relies on the application scope, you need to place the call to it AFTER a cfapplication tag in application.cfm
   --->

   <cfargument name="duration" type="numeric" default=3>
   <cfargument name="count" type="numeric" default="3">

   <cfif not IsDefined("application.rate_limiter")>
      <cfset application.rate_limiter = StructNew()>
      <cfset application.rate_limiter[CGI.REMOTE_ADDR] = StructNew()>
      <cfset application.rate_limiter[CGI.REMOTE_ADDR].attempts = 1>
      <cfset application.rate_limiter[CGI.REMOTE_ADDR].last_attempt = Now()>
   <cfelse>
      <cfif StructKeyExists(application.rate_limiter, CGI.REMOTE_ADDR) and DateDiff("s",application.rate_limiter[CGI.REMOTE_ADDR].last_attempt,Now()) LT arguments.duration>
         <cfif application.rate_limiter[CGI.REMOTE_ADDR].attempts GT arguments.count>
            <cfoutput><p>You are making too many requests too fast, please slow down and wait #arguments.duration# seconds</p></cfoutput>
            <cfheader statuscode="503" statustext="Service Unavailable">
            <cfheader name="Retry-After" value="#arguments.duration#">
            <cflog file="limiter" text="#cgi.remote_addr# #application.rate_limiter[CGI.REMOTE_ADDR].attempts# #cgi.request_method# #cgi.SCRIPT_NAME# #cgi.QUERY_STRING# #cgi.http_user_agent# #application.rate_limiter[CGI.REMOTE_ADDR].last_attempt#">
            <cfset
      application.rate_limiter[CGI.REMOTE_ADDR].attempts = application.rate_limiter[CGI.REMOTE_ADDR].attempts + 1>

            <cfset application.rate_limiter[CGI.REMOTE_ADDR].last_attempt = Now()>
            <cfabort>
         <cfelse>
            <cfset
      application.rate_limiter[CGI.REMOTE_ADDR].attempts = application.rate_limiter[CGI.REMOTE_ADDR].attempts + 1>

            <cfset application.rate_limiter[CGI.REMOTE_ADDR].last_attempt = Now()>
         </cfif>
      <cfelse>
         <cfset application.rate_limiter[CGI.REMOTE_ADDR] = StructNew()>
         <cfset application.rate_limiter[CGI.REMOTE_ADDR].attempts = 1>
         <cfset application.rate_limiter[CGI.REMOTE_ADDR].last_attempt = Now()>
      </cfif>
   </cfif>
</cffunction>

Then I call the UDF, using simply cfset limiter(), as shown below. That's it. No arguments need be passed to it, unless you want to override the defaults of limiting things to 3 requests from one IP address within 3 seconds.

<!-- the following must be done after cfapplication -->
<cfset limiter()>

Note that since the UDF relies on the application scope, you need to place the call to it AFTER a cfapplication tag if using application.cfm.

Caveats and more

There are definitely a few points to consider, and some concerns/observations that readers may have.

  • First, BlueDragon fans will want to point out that they don't need to code a solution at all (or use this), because it's had a CFTHROTTLE tag for several years. Indeed it has. I do wish Adobe would implement it in CF (I'm not aware of it existing in Railo). Until then, perhaps this will help others has it has me.
  • More important, some will be quick to point out a potential flaw in the approach of throttling by IP address is that you may have some visitors who are behind a proxy where they appear to your server to all be coming from one ip address. Fair enough. This is a dilemma that requires more handling. For instance, the BD CFThrottle tag implements this with a TOKEN attribute allowing you to key on yet another field in the request headers. I didn't choose to bother with that, as in my case (on my site), I just am not that worried about the problem. You may need to, so beware. Again, the log will help you determine how much it's doing any work at all.
  • And some may recommend (and others may want to consider) instead doing this throttling at the servlet filter level, rather than CFML (something I've written about before .) Yep, since CF runs atop a servlet engine (JRun by default), you could indeed do that, which could apply then to all applications on your entire CF server (rather than implemented per application like above.) And there are indeed throttling servlet filters, such as this one. Again, I offer this for those who aren't interested in that.
  • And of course, an inevitable question/concern some may have is, "but if you slow down a bots, might that that not affect what they think about your site? Might they stop crawling entirely?" I suppose that's a consideration that each will have to make for themselves. I implemented this several months ago and haven't noticed any change either in my page ranks, my own search results, etc. That's all just anecdotal, of course. And again, things can change. I'll say that of course you use this at your own risk. I just offer it for those who may want to consider it, and want to save a little time trying to code up a solution. Again, I welcome feedback if it could be improved.
  • Now, one other gotcha to consider, if you implement this and try to test it: some browsers have a built-in throttling mechanism of their own and they won't send more than x requests to a given domain from the browser at a time. I've spoken on this before, and you can read more from yslow creator Steve Souders. So while you may think you can just hit refresh 4 times to force this, it may not quite work that way. What I have found is that if you wait for each request to finish and then do the refresh (and do that 4 times), you'll get the expected message. Again, use the logs for real verification of whether the throttling is really working for real users, and to what extent.
  • There is of course another nasty effect of spiders, bots, and other automated requests, and that's the risk of an explosion of sessions which could eat away at your java heap space. People often accuse CF of a memory leak, which it's really just this issue. I've written on it before (see the related entries at the bottom here, above the comments). This suggestion about throttling requests may help a little with that, but it really is a bigger problem with other solutions, that I allude to in the other entries.
  • Finally, yes, I realize I could and should post this to the wonderful CFlib repository, and I surely will. I wouldn't mind getting some feedback if anyone sees any issues with it. I'm sure there's some improvement that could be made. I just wanted to get it out, as is, given that it works for me and may help others.
Besides feedback/corrections/suggestions, please do also let me know here if it's helpful for you.

Free tools for SAN monitoring, VM Monitoring and more...and their educational site

Folks know that I like to share news of tools (see my CF411 site), but I want to point out here a couple of free ones in particular that may address problems people are having in new/modern configurations: one is a tool for monitoring a SAN, and the other is for monitoring VMs.

It also gives me a chance to offer some props for the site of the company behind the tools, SolarWinds, which again many may find valuable in educating not only about the tools but the topics that the tools help with.

The free SAN and VM monitoring tools

The two tools (and one more for bonus) are:
  • SolarWinds Free SAN Monitor - keep a close eye on the performance & capacity of your storage arrays and become a storage superhero!
    Note also:
  • VM Monitor - continuously monitor a VMware® ESX Server and its virtual machines with at-a-glance virtualization health statistic
    Note also:
  • WMI Monitor - monitor your Windows® apps and servers in real time, using built-in, community-sourced, and customizable application templates!
    Note also:

I haven't yet used them myself, so this isn't so much a recommendation of the tools but rather a recommendation that you consider them if you are interested in what they have to offer.

The company offers still more free tools, as well commercial ones of course.

A company that gets how to educate you about their products

You may have noticed above that I offered as well links to videos about each product. SolarWinds has really done a great job offering educational resources, especially videos, and organizing them into categories such as tech talks, webcasts, and more.

Indeed, if you may be new to network management (which can be a broad and/or deep subject, appealing variously to generalist IT geeks and hard-core network admins), they offer lots of compelling introductory resources, including their geek guides and even certification training . Of course they also have a helpful blog and twitter feed.

Just as I previously praised the Mura folks as a "company who got it right" in terms of setting up a compelling, informative web site for IT folks, I really have to say the same for the SolarWinds folks. Congrats, and thanks.

I'll be speaking at cf.Objective() on "Stack Tracing CFML Requests to Solve Problems"

Though I got the news a couple of weeks ago that my submission to cf.Objective() 2010 had been accepted, I only tweeted my delight about it and didn't blog it. Here's the description:

"CF911: Stack Tracing CFML Requests to Solve Problems"

Regardless of what CFML server monitoring tool(s) you have, or even if none, did you know that you can use a feature called "stack traces" to be able to pinpoint the exact line of code that a CFML request is running at any time? Did you know how to use that information to troubleshoot performance/stability problems? Do you know how to obtain that information either manually or automatically (such as during a crash while you're not watching)? Do you know how to obtain that information in any of the CFML Server Monitors (FusionReactor, SeeFusion, the CF8/9 Enterprise Server Monitor), or with free command line tools? And how to do this for any CFML engine (CF, Railo, BlueDragon, etc.)? Do you know how to interpret the information once you get it?

In this session, veteran CF troubleshooter Charlie Arehart will help remove the mystery from using stack traces. It really is amazingly simple with the right tools, and it can be incredibly useful to solve otherwise thorny problems, once you understand how to interpret the information.

Of course, I'm thrilled to be heading back to Minneapolis. I spoke there previously in 2008 and 2007 but couldn't attend in 2009. It'll be great to see all the fine folks who run and attend this unique conference.

BTW, I just saw also that CFUnited announced another round of topics accepted today and I see a topic whose title if very similar, "How to Read a Stack Trace", by the inimitable Daryl Banttari. It's hard to tell from his brief description how similar these will be, but Daryl is awesome so I'm sure I'll learn much from his. (I was literally just about to offer mine as another CFUnited submission but now won't of course. :-) Hopefully another of my submissions will be accepted, so I can keep my streak of having spoken at every CFUnited since they started.)

Anyway, the good news is that whichever conference you go to, this important (and often misunderstood) topic will be covered! :-)

Spying on ORM database interactions: Hibernate, Transfer, etc. on any CFML engine

As people use CF9's ORM feature (or other ORMs like Transfer and Reactor, or indeed Hibernate, on any CFML engine), they may be left wondering what sort of SQL interactions happen "under the covers" between the ORM framework and the database engine (whether in a given request, or perhaps at startup of CF).

Well, there are several ways you can watch them, as this entry will discuss, and some may be better suited to the job than others. It can be very interesting to discover what's going on, especially if you're having any suspected performance problems which you think may be related to ORM processing (or just if you wonder what all it does for you).

As for spying on the SQL, of course ORM support is just a different way that the CFML engine (through the ORM framework) sends SQL to a database via a regular DSN, just like any other request, so there's nothing really "tricky" about this. It's just about realizing that while you don't write the SQL yourself, it's still generated by the CFML engine/ORM framework, and you may not realize/consider the available tools which can spy on it, just like any other DB processing from within CF. Indeed, some people may not even realize how many options exist to spy on JDBC interactions from their CFML engine to the database engine.

The good news is that there are several approaches, some included in CF (some depending on the edition), and some available separately which would work in any edition of CF or the other CFML engines (Open BlueDragon, Railo, etc.), and with any of the ORM frameworks. And again, some may be better than others for certain challenges.

(FWIW, besides the aforementioned Transfer and Reactor, there are still other ORM solutions for CFML, which I mention in my CF411 list as CFML ORM Frameworks. Indeed, note that you can run Hibernate on CF prior to CF9, if you want to.)

Built-in ORM Logging Option

First, note that there is indeed a built-in option in the CF ORM setup where one can enable logging, settable in the application.cfc: see the this.ormsettings option and its available key/value pair, logSQL="true".

There are several resources where you can learn more on that (and a related log4j property file approach to logging this). Besides the CF9 docs page on the ORM settings, there is also a blog entry by Adobe engineer Rupesh Kumar.

The default is to log this information to the console, but you can manipulate those log4j settings to tell it to use a file (see the links above). Even so, this will result in quite a lot of data being logged, which you will then need to connect back to your specific requests. The following approaches may be preferable.

Using FusionReactor or SeeFusion

Users of any CF edition (6+) or CFML engine can use tools like SeeFusion and FusionReactor, which have always had the ability to monitor database interactions by "wrapping" the datasource to be monitored. FusionReactor engineer John Hawksley has posted a recent article specifically on monitoring CF9's ORM interaction, in the FR Devnet site, Using FusionReactor's JDBC Driver Wrapper With ColdFusion 9 ORM. Its concepts would apply to any ORM, of course.

Similarly, I've written generically about FusionReactor's database monitoring feature in What is the FusionReactor datasource monitoring feature? Why would I use it? Powerful stuff. As I point out in that article, the concepts discussed apply as well to SeeFusion's ability to monitor queries by wrapping datasources.

That said, it's worth noting that FusionReactor does have a couple of advantages, in that it provides for the display of all queries for a given request (while viewing the details of that request), whereas SeeFusion only lets you see the slowest query in a given request. FusionReactor also provides a separately available display of all the slowest queries (across all requests). It also logs every query (connecting it to a given request as well), while SeeFusion (Enterprise, at least) can also log the slowest queries to a database.

And note that both of these track any requests coming out of CF, not just those associated with a given request. So if there is ORM SQL that is associated with the startup of CF, that's tracked too. (And for those aware of issues with CF's Client Variables, such DB activity is also tracked, even that done by the hourly purge, which takes place on a background, non-jrpp thread.)

CF Enterprise Server Monitor

Those running CF 8 or 9 (Enterprise only) will find that its available Server Monitor does offer built-in monitoring of the SQL executed against CF datasources, at least, as long as you enable "Start Profiling" (which also enables other features, and overhead, as well). In this way, the Enterprise Server Monitor can monitor database interactivity, including ORM interactions.

Unlike FusionReactor (and like SeeFusion), it focuses only on showing queries that exceed certain limits, and at that it shows them only in a "Slowest Queries" interface, tracking the slowest queries among all requests. The CF Enterprise Server Monitor also has no logging ability at all.

Being able to see every single DB interaction for a given request (or across all requests) may be all the more interesting for discovering/observing what's happening with ORM interactivity.

Another alternative CF feature

Still another little-known feature for spying on JDBC interactions in CF is by way of the JDBC "spy" feature, which does in fact allow logging of all JDBC interactions mde from within CF. This feature was first enabled by way of the DataDirect 3.5 driver update which was made available (as an optional upgrade for 6 and 7) in the CF 7.02 timeframe. I wrote about the Spy feature back back in Aug 2006.

Since then, CF 8 (and now 9) offer it instead as a new "log activity" option in the "advanced settings" for a datasource definition in the CF Admin (which is disabled by default). I pointed this out in another entry from 2007 as one of many easily missed changes for the CF 8 Admin.

This "log activity" output is not as easy to interpret as FusionReactor's logs, and can indeed be voluminous (moreso than FR's), so be careful. Anyway, it's one of the several ways you can monitor JDBC interactions between CFML and your DB engine. Again, any of these may be useful for monitoring any of your CFML/database interactions.

Generic DB Monitoring tools

Indeed, it's worth noting finally that while the focus here has been watching the DB interaction from CF (and the ORM framework) to the database (by watching the JDBC traffic going out of CF and returning), you could just as well watch the DB interactivity from the DB's perspective instead (watching it coming and and being returned).

There are many tools that can monitor database processing, available for each of the major databases (free and commercial). I list several such tools in one of my CF411 section, Database/SQL Monitoring Tools.

Hope all that's helpful, whether you use ORM or not.

Tracking number of CF sessions per application easily, and why you should care

Ever wanted to count how many sessions are active on your server, in total and per application, whether on CF 7 or 8? And regardless of whether you're using CF's regular sessions or the "new" J2EE sessions feature introduced in CF 6? Would you be surprised to find you could have a shocking number of active sessions?

Here's a nice simple solution, the free ServerStats tool, that provides that info. It's from Mark Lynch and while a couple years old still works just fine. Besides printing out the total count of sessions and the count per application, it also some information about CF memory use, number of processors, and more.

Of course, some will want to point out that the CF 8 Server Monitor offers session and memory info, but for those not on CF8 Enterprise, this is a useful alternative. Also, some may want to point out that the solution described here uses internal objects that may be disabled (and are also undocumented and unsupported). I discuss both these points below. There are also some other approaches people take, which I also mention briefly.

Why care about number of sessions?

So why care so much about how many sessions are active on a CF server? If there are 10 or 20, or maybe a 100, does it really make a difference? No, not likely. But what if you find that there are 90,000? I'm not kidding. I was helping someone just last week when we discovered this. It's not as unusual as you may think.

Often when I'm helping people solve problems with their CF servers, one of the first things I want to help them discover is just how many sessions they have active at any time. With the potential impact of spiders and bots creating huge numbers of sessions, which could have an impact on memory and also on other aspects of performance, it's definitely one of the first things to look into.

So how's Mark's code tracking them?

Mark's entry is a summary of things he'd discussed in a few blog entries about how to leverage internal CF/Java objects to provide the info, and that one entry offers a downloadable zip with a single CFM file and a directory of CFCs and custom tags. You can just extract the zip into a web-accessible directory and run it. No need to create custom tag mappings, etc.

Many folks have known about and blogged about these internal CF/Java objects, coldfusion.runtime.SessionTracker and coldfusion.runtime.ApplicationScopeTracker, over the years. They're undocumented and unsupported, so you use them at your own risk, but again I've confirmed that Mark's code works against CF 7 and 8 (and I'll assume 6 as well.) You can google to learn more from him and others on these.

CF8 Enterprise has other solutions

Of course, those on CF 8 Enterprise (or Developer) have still other approaches to this, whether in the CF8 Server Monitor (see its active sessions page) or the Admin API's servermonitoring.cfc. But if you're not CF8 Enterprise (and even if you are) this solution can help.

(For any who may wonder, no, neither FusionReactor nor SeeFusion offer this info, since it's technically internal to CF. They could call upon these methods, but since they're undocumented, I can understand that they choose not to. And while they could call upon underlying J2EE objects for J2EE sessions, those would not work for those who don't use J2EE sessions.)

JRun Metrics and other solutions

And yes, there's still another way to get at least a count of all J2EE sessions, using the available JRun Metrics. While it has the benefit of tracking the info over time, it does track the session count only if you've enabled J2EE Sessions in the CF Admin, and even then it tracks only the total of all sessions, not a count per app.

Of course, there have been various solutions offered to solve the problem of session tracking, such as those that track sessions in code (within your application) by storing them in an array in the application or server scope, and so on. The nice thing about using the internal CF/Java objects is that the apps being tracked don't need to be altered at all.

Potential Security Gotcha

Of course, therein lies a potential security risk. Anyone running such code on any CF server can have access to the sort of info that these internal CF/Java objects offer. The example above (Mark Lynch's) doesn't really expose much to worry about (unless the names of apps on a server is sensitive, where one user on the server shouldn't know that another app exists on it, which may be true in a shared hosting environment.) But more important, if one digs deeper into these objects, they do expose more details, including the values of variables in session scopes across all applications. That could be considered very sensitive.

As such, there have long been a couple of solutions that Adobe has provided to enable an administrator to shut down the use of these internal objects.

First, in CF 5 and above, it's been possible to set security for the entire server (or a given app in CF Enterprise) to make it impossible to call any Java objects (yes, you could call Java objects starting in CF 4.51). To learn more about this option, called Resource Security in CF Standard, and Sandbox Security in CF Enterprise, see my 2-part article series for the Adobe Security Developer Center from Sept 2002, "ColdFusion Security, Part One: Understanding Sandbox/Resource Security" and "Part Two: Sandbox/Resource Basics", both available at my articles site.

That approach is a little brute-force though, and throws the baby out with the bathwater if you have legitimate use of java objects.

So in CF8 finally, Adobe added a new feature that permits an Administrator to disable JUST access to the these underlying internal CF/java objects. See the CF Admin "Server Settings" section, "Settings" page, and its "Disable access to internal ColdFusion Java components" checkbox. The option takes effect immediately.

It's certainly more effective if one wants to control to this info, but of course it will make code that relies on it fail, with an error like:

Permission denied for creating Java object: coldfusion.runtime.SessionTracker

I'll point out that since most of the folks I help with run their own servers, they're just not worried about disabling these internal java objects, since they can control what code runs on the servers.

So if you want to quickly find out how many sessions you're running, per application, check out Mark's code. You can also get much more info from these internal objects, if you want to explore. I'm working on a tool to provide some still more powerful information that I started working on years ago based on these objects. But until that's ready, I had occasion today to point out this working alternative to a customer, and thought I'd pass it along here.

CF911: CF 8 Server Monitor reports "ColdFusion Server is unavailable" (solution)

Here's another entry in my CF911 series. If you try to open the CF8 server monitor and get the error "ColdFusion Server is unavailable", the problem may be in your web server configuration. In this entry, I help you confirm if you're getting the problem I refer to here, and of course I show the solution (3 actually), with a caveat.

Here's a screenshot of what you may see:

Note that this is not an error related to logging in. You do need to fill in a username to log into the Server Monitor, even if CF is set to only ask for a password when logging into the Admin. Just use "admin". This and other facets about the CF8 Server Monitor are covered in a 4-part series of articles I did in the Adobe Dev Center, starting here.

Confirming this is the cause of your Monitor challenge

From my observation, this error is related to a problem with the Flex client being able to talk to the server using a URL it needs to use, and the problem is web server related.

You can confirm if what I'm about to describe is your issue by trying to access the URL that the server monitor tries to use to access the Flex Gateway for CF, such as:

http://localhost/flex2gateway/

Actually, you should use whatever domain name/port you're using to access your CF Admin, which is then used when you ask it to open the CF8 monitor, which may be a URL like this:

http://yourserver/CFIDE/administrator/monitor/launch-monitor.cfm

Anyway, if that test attempt to open the /flex2gateway/ url comes back with a "file not found" (or 404) error, as opposed to a blank page, then you likely have the problem I'm describing, whereby your web server is mistakenly looking to verify that a file exists for the path you're specifying. You have 2 solutions.

First, let me note that this flex2gateway URL is not a file, nor a directory. It's a value intercepted by a servlet filter defined within CF. You need to tell your web server not to check for any existing file (it's trying to use one of the "default documents" that are used when only a path to the web server is provided.) Before launching into how to fix your web server, you may want to consider one other possibly simpler alternative.

Changing to use the Internal Web Server

Some will note that I've used no port above in the URL. That's why I point out for you to try whatever URL is used to access your Admin. In the case above (and the people who have reported this problem so far that I've seen, they've been trying to access the CF admin using their external web server, IIS.

If instead you were to use the CF internal web server to access the CF Admin, you'd have a port in the URL, like this:

http://yourserver:8500/CFIDE/administrator/monitor/launch-monitor.cfm

(or it could be 8300, or 8301: whatever is the port for accessing the built-in web server for CF, if you chose to implement that when CF was installed, and you are accessing the Admin that way.)

Well, I'd propose that if you DO use the internal web server, you probably won't get this error at all. The problem seems related to using IIS to access the Admin (and the CF 8 Server Monitor).

That said, I'll suggest that one quick solution folks can try is to see if indeed they can access their CF Admin (and monitor) using the internal web server. (If you can't or won't use it, I have the solution for getting it to work with IIS, in a moment.)

You just need to know what port to use to access the internal web server, if it's enabled.

First, you may find that if (on Windows) you use Start>Programs>Adobe>ColdFusion 8>Administrator that it will open using the built-in web server. If it does, see if using that gets you around this whole problem.

If that opens it with external web server (doesn't use a port like those above), or if you aren't on Windows and have no Start menu, you can also get the web server port (and indeed enabled it, if disabled) by way of the jrun.xml file. Rather than detail it here, I'll point you to a couple of resources:

Configuring the Macromedia ColdFusion MX built-in web server is an old technote, but the info still applies. Where it talks about disabling the internal web server, you'd want to reverse that, of course. There can be more subtleties and challenges to running the CF admin on the internal web server, if you don't configure it that way at the start, such as where are the /CFIDE files? Are they in the [cf]/wwwroot? or in your web server doc root, like inetpub/wwwroot? The built-in web server will look for them in the [cf]/wwwroot, so you may need to copy the CFIDE into this directory, or add a mapping to the built-in web server to point to the path as being located externally.

Making the change in IIS

Or you could just fix IIS to let you access the server monitor via IIS. The problem may be due to a setting in IIS (verify that files exist) that you may have caused to be set. (I don't know if it's set by default when CF is configured to integrate with a site, but I wouldn't think it was, so maybe this affects those who add new sites or configure things manually.)

And since this problem may affect other Flash/Flex apps trying to talk to CF, it may be worth doing for all such users. But this does come with a caveat to be aware of, if you might be using NTLM security to control access to files requested via IIS. More in a moment.

I offer the solution for IIS 6 and 7. I don't know if the same problem can affect Apache. If so, and anyone can offer the solution for there, please do comment.

Making the change in IIS 6

For IIS 6, launch the IIS Manager and select the web site which has the CF Admin you're trying to use. (It may be that you've also configured IIS so that ALL web sites are configured for CF, in which case this setting would be not at the site-level but at the root server-level, so you'd select the server name instead in the left IIS pane.)

From there, right-click and choose properties, and then select the "home directory" tab, then in the "application settings" area click the "configuration" button, and in the "wildcard mappings" section you should see something like "C:\ColdFusion8\runtime\lib\wsconfig\1\jrun_iis6_wildcard.dll" (which will be different, of course, for the JRun4-based Multiserver deployment).

This value is implemented here during the install of CF if you tell it to integrate with IIS, or by your running the CF Web Server Configuration tool after the fact.

Select it, and choose Edit, and if the "Verify that file exists" option is checked, un-check it. This setting can be confusing: you may think it means "verify that the named executable exists", but it doesn't. It refers to whether files requested and passed through this handler should be checked to confirm if THEY exist. Here's a depiction of the setting and how to get there.

Now try the URL above, and it should no longer give a 404. Then try again to login into the Admin. (Actually, you may find that you can just click the "cancel" button and it will login, even if the values for username and password are blank. I find this helpful when the CF server is temporarily unresponsive too, and the Monitor login screen pops up.) Hopefully the server monitor now works for you.

Note that this was NOT about changing the handler mapping for .cfm files, which also offers an option to control the "verify that file exists".

A caveat about access via IIS to NTLM secured files, and another alternative

Thanks to Mike Gillespie for the following notice and clarification. If you use NTLM security (windows integrated authentication in IIS) to secure files accessed via IIS, then you DO NOT WANT TO make the above change for your IIS site. I share below what he offered to me.

But I'd point out again that even with that issue, you could still use the built-in web server is a solution. Or, sticking with IIS, you could also create a new IIS site just for accessing the CF admin and monitor, and make the change above for that site only.

Anyway, if you do use NTLM security to control access to sites requested via IIS, consider the following:

The check that file exists option is required if you want to use NTLM perms to secure .cfm files. http://www.adobe.com/go/tn_18516 (Steps 1-4)

If you have a secure folder on your webserver put a .htm file and a .cfm file in it. Do not give your ID access to that folder. In IIS turn on clear text and NTLM auth.

With the "check that File Exists" option unchecked, try this test.

Try to access the .htm file in the browser - access denied

Try to access the .cfm file in the folder, - access GRANTED - so much for NTLM perms

Now check the box and try again (you will need to recycle cf and IIS)

Try to access the .htm file in the browser - access denied

Try to access the .cfm file in the folder, - access denied as it should be - but flash forms and server monitor are dead.

So "fixing" the Server Monitor problem on an authenticated server just broke the security of the server for the sake of monitoring... [frown>]

In a nutshell.

If you implement this so that CF pages can be authenticated against Windows Security http://www.adobe.com/go/tn_18516, then Flash forms break (and the server monitor too). So to get flash forms (and the server monitor) working, you have to implement this, which fixes flash forms (though every user gets their own personal file on disk on the server that has to be cleaned up) but it does not fix the server monitor.

It is the "check that file exists" selection that breaks the Server Monitor (and flash forms).

On a cf webserver that grants anonymous access there is no reason to check the "check that file exists" box. However, on a server that does authenticate users for NTLM file access, that box should be checked.

This section above was added after the entry was first posted.

The change for IIS 7. None needed?

For IIS 7, it's a little different. I actually run IIS 7 (Vista) and am not sure how/where the wildcard mapping equivalent got created (I may have fudged it manually), but it's now listed as a "Handler Mapping" (in the properties for a web site). In my case, it's labeled "AboMapperCustom-32635", but just look at those listed as handling "*" meaning all requests. It's listed with a value of IsapiModule in the Handler column. (If you're looking at a specific site, and the "Entry type" column says "Inherited", then there is another mapping at the server level, so select your server name in the left IIS panel, and repeat.)

Even so, I see no option to control "verify that file exists", so maybe this problem can't happen in IIS 7. I will say, FWIW, that there is indeed a an equivalent to that "verify that file exists" option, at least for specific extension handler mappings. Look a the one for .cfm, for instance. Double-click it to see its properties, and note a new button called "request restrictions". It has an option, "Invoke handler only if request is mapped to", and an option of "file". Again, though, this does not affect requests to non-cfm requests like that for the /flex2gateway/ URL.

About other Flex/Flash apps

As I said, it may be that the info above will help other Flex apps having trouble talking to CF (the CF8 monitor is a Flex app), but I'll note that this problem doesn't affect all Flex apps: only those that connect to CF via IIS.

For instance, on this same server where this problem occurred, there was never any problem using FusionReactor (which is also a Flex app). It was working fine the whole time. But then its default behavior is also to use its own Built-in web server, so requests weren't going through IIS. If I did try to use IIS to access FusionReactor, then it too failed (with a file not found), and the fix above solved that.

A 12-page Intro/Review of FusionReactor 3

If you missed my 12-page introduction and review of FusionReactor 3 in the last issue of the FusionAuthority Quarterly Update, Volume II Issue IV which came out earlier this summer, well, the good folks at the magazine, Michael and Judith, have kindly chosen to post the article online:

FusionReactor: ColdFusion Server Healthcare (and What's New in Version 3) (PDF)

Thanks, folks! I hope it might serve as a useful intro for those who've not seen the tool (whether in its older or newer version), which can be used to monitor CF 6, 7, and 8. That CF8 support is important not only for those running CF8 Standard, which doesn't have the CF8 Server Monitor, and also even for those who can run the CF8 Server Monitor, as there are some useful benefits of using it even on CF8 Enterprise). Note that FR also works with Railo and OpenBlueDragon, as well as BlueDragon/J2EE and indeed any J2EE application (including LiveCycle Data Services) and any J2EE engine (JBoss, Tomcat, WebSphere, etc.)

The article can also serve as a review of features that those already using the tool may have missed, or you can focus on what's new in FR 3 (quite a bit).

Check out the article, and the tool, including the available live demo in addition to the 10 day trial. I'll note that the live demo is running at a lower level of authority (one of the new features of FR 3), so you don't see and can't do all with it that you might as a full admin user.

I'll arrange to do a demo of the tool on an upcoming CF Meetup session, whether on its own or along with other monitoring tools for CF which I've discussed before.

45 Page User Guide for the CF 8 Server Monitor

If you're exploring the ColdFusion 8 Server Monitor, or perhaps have been using it and wonder if you may be getting all you can out of it, I want to point out an available 45-page user guide for it.

Ok, that's a bit of a tease. I'm referring to my 4-part series of articles on the Monitor available in the Adobe Dev Center. While I did them several months ago, I still often see people ask questions that are answered there, so I wanted to take a moment to remind folks of its existence. I realize that everyone may not keep up on the articles posted in the DevCenter (but I'll note that I offered an entry recently on how to keep up on new postings there and elsewhere.)

My CF8 Server Monitor article series was divided into 4 parts, which I've listed below. I also show here each articles's sections. (Note that the "table of contents" offered on the left of the online articles doesn't always list each section heading: it's more for breaking up the articles into managable sized online pages, which is too bad if one uses them as a gauge of the article's sections.) I've also broken down the sections into subsections.

  • Part 1: Using the Server Monitor in development
    • Unlocking the "black box"
    • Starting and using the Monitor
    • What it means to "Start Monitoring" (or not)
    • Useful monitoring for development
      • Tracking shared scope memory utilization
      • Track slowest tags or function calls
      • Tracking largest variables in a request
      • Tracking JVM Memory Usage
      • Tracking cached queries
      • Tracking large, slow, and frequent queries
  • Part 2: Using the Server Monitor in production
    • Challenges in managing a production ColdFusion 8 server
    • More zero-overhead reports
      • Template Cache status tracking
      • Session tracking revisited: active sessions over time
      • Tracking ColdFusion errors
    • Reports enabled with monitoring, profiling, or memory tracking
      • Avg Response Time and Requests Per Second
      • Active Requests
      • Queued/running requests over time
      • Finding heavy hitters
      • Active Queries
    • Aborting unresponsive or troublesome requests
  • Part 3: Automated monitoring and request management with Alerts and Snapshots
    • Automated monitoring and request management with Alerts
      • Toward 24x7 operations
      • Configuring Alerts
      • Available actions (overview)
      • Types of alerts
      • Viewing Alerts data
      • Available alert actions (details)
    • Substantial diagnostic details with Snapshots
      • The Snapshots page
      • Viewing snapshots
      • Stack traces within the Snapshot
      • Accessing past snapshot data
  • Part 4: Multiserver Monitor, Admin API monitoring, and more
    • An enterprise dashboard with the Multiserver Monitor
      • Opening the Multiserver Monitor
      • Adding new monitors
      • Observing the status of a monitored server
    • Some possible challenges using the Multiserver monitor
      • Securing the monitoring of your server
      • Be careful with browser caching and the cross-domain file
      • Multiserver Monitor configuration is stored per the domain used to open it
    • Programmatic Monitoring with the Admin API
    • Tweaking the Monitor in the Settings section
      • The General settings tab
      • The Filter Settings tab
      • The Profiling Filter tab
      • The Aliasing tab
      • The Refresh, Reset All Statistics buttons
    • Miscellaneous aspects of the Monitor
      • Flash Remoting must be enabled
      • Start settings remain enabled
      • Monitoring even when the server is becoming unresponsive

I hope you'll see from the above that there could be much more to the CF monitor than you may have realized. Each of the subsections often has lots of useful tips, tricks, and traps that I've observed over a year of use in both development and production.

And though I make the point in the articles, I'll repeat that some of the features come with zero overhead. I've blogged about that before. Don't let people tell you never to use it because it will harm your server's performance. As I say in each of the above, it's only the "Start memory tracking" button (one of 3 at the top) that could be trouble (and maybe "start profiling", but to a much less worrisome extend). But you don't even need to use the 3rd (and least obtrusive button) "start monitoring" to get a lot of great value from it. I stress more about this in parts 1 and 2 of the series.

What about FusionReactor and SeeFusion?

Of course, my support for the CF Server Monitor doesn't diminish my enthusiasm for alternatives like FusionReactor and SeeFusion, nor do I see one replacing the other as I've written about before. Each does something the other may not do, and I see value in each of them (and even have recommended running more than one at a time to solve certain problems).

See my corresponding blog categories on these, at the right, to find more entries on FR and SF, as well as the CF8 Server Monitor.

I just want to help people make the most of whatever monitor they use.

Available for Consulting Help as well

I'll throw in, as well, that if you need help using any of these tools, or doing any CF server troubleshooting, I'm available for consulting help, whether online or on-site, for as little time as is needed to help solve the problem. See my consulting page for more information. I've helped many organizations, large and small, resolve nagging problems, using either (or none) of these monitoring tools.

Feel free to contact me any time to pose a problem related to performance, stability, or similar errors or problems, and I'll let you know if it's something I can help with.

Averse to reading 45 pages online? you don't need to

For those who don't fancy the prospect of reading 45 pages of content online, note that I'm referring to the page count as it would be if you printed the available "printable version" (offered on all DevCenter articles). You can use that feature yourself to obtain a single long HTML page for each article, and then if you want you could print that out. (And if you use features in your printer to print multiple pages to a side and 2-sided, as I discuss here, you can fit it all in just a few pieces of paper!) (Update: tipicalcharlie domain is no more, but page recovered using Archive.org.)

I'll add that for those who prefer watching over reading, I've also given presentations about the monitor at several conferences and user groups (some available as online recordings), which you can find at my presentations page.

More Entries

BlogCFC was created by Raymond Camden. This blog is running version 5.005.

Managed Hosting Services provided by
Managed Dedicated Hosting