Wednesday, July 16, 2008

Simple, Powerful Debugging Tip for CFML Development

The big project I've been working on recently is 100% backend batch XML processing on a rather large scale, and as a consequence of the fact that it's all batch processing, the backend piece of the application (which is the vast majority of it) has no user interface.

The complete lack of UI presents some unique challenges, particularly since tracking every last bit of what goes on in the batch processing, keeping track of when errors occur, etc. is vital to the success of the system as a whole.

First and foremost, if you aren't using cflog regularly in your development process, go read the docs and start using it. In my opinion cflog and the use of custom error types are the two most underutilized things in CFML development, and particularly in a moderately complex system with no UI, this combination is key to knowing exactly what's occuring (and when) in the system.

Moving on to the real point of my post, when a system like this is in production, even given your best efforts you can pretty much depend on the fact that at some point you'll get bad data that will cause processing of said data to fail. When debugging a data problem that's causing a particular iteration of the processing to throw an error, copying a massive database into development every time you need to troubleshoot (sometimes under time pressures) just isn't an option, and I'm rather wary of pointing my local machine to the production database (and in some cases due to permissions, etc. this isn't possible). Also, in some cases what you need to troubleshoot may be in a loop, and only one iteration of the loop is causing issues, so you can't exactly throw in a cfabort to see what's going on.

So what to do?

Back to our friend cflog. Go to the part of the code where the data is causing issues with the processing, which in this case we'll assume is a loop, and use cflog to write out as little or as much information as you need to a log file. Simple, powerful, loop friendly, and no cfaborts needed.

Now for what I think is the really cool part: use this in combination with the tail command on Linux or Mac (or Cygwin on Windows), and you can see the log data immediately as it's being written.

So for example, on OS X I map to the drive on the production Windows server where the CF logs are being written. Then open a terminal window, cd to /Volumes/DRIVE_MAP_NAME and navigate into CF's log directory. Do a tail -F LOG_FILE_NAME and that will "follow" the log file so you'll see updates to the log file as they happen. Again, simple stuff, but just what I needed to debug a system with no UI on a production server without disrupting the system as a whole.


Have you looked into FusionDebug? It is an essential CF Debugging tool for me now.

Cool tip.

I've started using cfdump with the output attribute for logging as I get the coolness of cfdump and the ease of specifying the file location in the output attribute.

Hi Matt,

Great post and suggestion! Just wanted to add that if you don't have Linux/Max or Cygwin, there are several "tail" viewers out there specifically BareMetal's BareTail or BareTailPro ( that let's view files like you suggested. It even has a command line utility to do the same as native tail linux command.


I'd like to second the Mike's recommendation for FusionDebug.

It's a little pricey (I can't remember but I want to say it's $300 or so--about twice that for tek support) but it really gets the job done.

I like using the Console app on OS X to watch log files. It is just a little bit more prettier then using tail. I see it does have some filtering abilities as well.

Just wanted to point out that Mach-II's logging package is independent of the framework itself and can easily be setup with ColdSpring and injected into model components. The nice thing is that logging package has few bundled loggers -- CFLogLogger, EmailLogger and MachIILogger. Because of the unified logging API, you can attach multiple loggers to the logging infrastructure and have them watch and filter the passed logging messages based on logging severity / channel. I've been thinking of writing a logger that logs to a port similar to what you can do with Apache Commons logging as there are tools that you point to a port and watch messages as they come in even if you cannot get access to tail or the log files directly in real time.

I'll 3rd Fusion Debug, but also remember that CF 8 ships with a similar debugging tool now. Don't you get a free one with the Dev Edition of CF?

Also, if you're using CFEclipse, go to Window > Other Views > ColdFusion > CF Log Viewer. Point it at your logs directory and it gives you tail functionality as well.

There are other Eclipse "tail" plugins that work with the standard java log files too (i.e. application.log, exception.log).


Where is your blog entry (or docs) on how to use the logging component? :-)

Matt Williams did a nice Intro to Mach-II Logging on our wiki:

If you are using it independently from Mach-II, you'll be most interested in the Additional Resources section on using the Utility Connector. Although it should how to use Mach-II managed log factories in CS, you can see how to setup up your own log factory in CS.

Thanks for all the comments--well aware of FusionDebug (actually own it!) and the CF 8 debugger, but personally I don't like configuring my production servers for debugging in that way. Handy, yes, so maybe that's just my own feeling about it. Just seems a lot less intrusive (and equally as effective in this case) to throw some logging in there.

Glad Peter brought up the Mach-II logging package--that's a very powerful feature of Mach-II 1.6 but the cool thing is you can use it outside Mach-II as well! We'll have much more information about it very soon.

Thursday, July 10, 2008

CFML as a Language: The Java Parallel

Since we're finally getting to the point in the CFML community that we're discussing CFML as a language independent of the various CFML engines, I think Brian Cunningham's post "What Hath Java Wrought" is a very interesting parallel discussion happening in the Java world. These are exactly the types of discussions I hope happen with CFML.


Wow. That's an awesome article. Interesting to see Java community have so many similar complaints.

Could you please provide an article summary? That would make it easy for some of us.



It's an interesting dilemma for any language that has been around a while and it's particularly interesting to hear Java described as "easy to learn". You're right of course that the exact same discussion could happen with "Java" replaced by "CFML" :)

I don't know anything about this author or his Java experience, but I wanted to stop reading here:

"Java is popular because of one rather simple reason:

It's easy to use."

That's probably not correct--for a programmer who can't or won't deal with pointers, maybe it's easier, but one can probably find a thousand forums where people are complaining about how hard it is to say "Hello World."

As for his beef about backward compatibility, again, I'm just not sure what he's getting at. With each release, there are many things that are deprecated and later abandoned. Though you might be able to run a particular 1.2 app in a 1.5 JVM, if you try to compile it from source, you'll probably be surprised at how loudly the compiler bitches at you.

Adding closures and generics doesn't scare me, nor should it scare you. A lot of developers could get through an entire career without ever using a closure, so why should it matter to them if the language allows it? Sure, bad programmers will abuse it, but they'll be abusing a lot more than just a particularly complex language feature.

In short, I say: Meh.

Wednesday, July 2, 2008

Connecting to Cisco VPN on Ubuntu

Made yet another step forward in my pursuit of full-time Linux usage today, namely connecting to a Cisco VPN. I did try the vpnc application that several people suggested but, to put it in technical terms, it "didn't like" our VPN hardware. (I'm sure there's just some setting that needs to be tweaked.) It imported my PCF file fine but would always timeout on the connection.

So I got a hold of the official Cisco VPN client for Linux (version 4.8.01), and while it did need a bit of compiling and a patch applied for Ubuntu 8.04, it works great! I did find one blog post in particular that was helpful (thanks Arun!), and if you get an error on Ubuntu 8.04 (which I didn't) you might check out another post on Arun's blog.

Yes, you do have to fire the VPN client up from a terminal so it's not as pretty as the Mac version, but it works just fine and is overflowing with geek cred.

Since I also fixed the LDAP lookup issue in Evolution that I mentioned in my post yesterday, I think the remaining piece of the puzzle is finding something that's compatible with Microsoft Messenger (not the public network side of it), which is a huge nice to have but might be asking a bit much.


Update on this--very weird DNS issues are keeping me from using this full-time. Apparently the Cisco client messes with resolv.conf. It's a bizarre problem because it works for a while and then suddenly you lose DNS.

I'm sure there's a fix, just haven't had time to look into it yet.

@Matt: I'm having exactly the same DNS problem you comment. Have you found any solution?

Yep Joan--just install resolvconf: