Since I’m on IRC constantly anyway, I like the various web applications I maintain to be there with me, letting me know if there’s a problem, or when someone is using a feature I implemented — that sort of thing. Because of the integration between ColdFusion and Java, this hasn’t been such a hard thing to do historically. However, with recent changes to Mach-II’s logging framework, the implementation just got easier and cleaner.
Mach-II introduced Loggers in version 1.6 “to give developers a full blown logging package with extensibility to customize”, which is exactly what we’re going to take advantage of. If you’d like to read up on the MachII Logging framework, check out the wiki entry.
The first step is the Java library that will handle the IRC calls. I chose the martyr library because you don’t need to modify or extend it in order to use it for simple use cases, such as this one. If you’re feeling adventurous, you could use the more well known PircBot. I have used both; if you’re interested in getting a working logger, use martyr; if you eventually want to have a fully fledged IRC bot, try PircBot.
To install martyr, simply drop the file martyr.jar in your ColdFusion classpath (${ColdFusion Installation Dir}/lib).
Okay, let’s start coding! Fire up your favorite text editor and create the following skeleton:
<cfcomponent displayname="IRCLogger.Logger" extends="MachII.logging.loggers.AbstractLogger" output="false" hint="A logger for sending logging information to an IRC channel."> <!--- PROPERTIES ---> <cfset variables.instance.loggerTypeName = "IRC" /> <!--- INITIALIZATION / CONFIGURATION / DECONFIGURATION ---> <cffunction name="configure" access="public" returntype="void" output="false" hint="Configures the logger."> </cffunction> <cffunction name="deconfigure" access="public" returntype="void" output="false"> </cffunction> <!--- PUBLIC FUNCTIONS ---> <cffunction name="onRequestEnd" access="public" returntype="void" output="false" hint="Here the logger displays its data"> </cffunction> <cffunction name="preRedirect" access="public" returntype="void" output="false" hint="Pre-redirect logic for this logger."> <cfargument name="data" type="struct" required="true" hint="Redirect persist data struct." /> </cffunction> <cffunction name="postRedirect" access="public" returntype="void" output="false" hint="Post-redirect logic for this logger."> <cfargument name="data" type="struct" required="true" hint="Redirect persist data struct." /> </cffunction> <cffunction name="getConfigurationData" access="public" returntype="struct" output="false" hint="Gets the configuration data for this logger including adapter and filter."> </cffunction> <!--- PROTECTED FUNCTIONS ---> <!--- ACCESSORS ---> </cfcomponent>
The configure and deconfigure methods are hooks that get called when the logger is being initialized by the framework and when the framework unloads the logger, respectively. You would want to put your startup/shutdown logic here. For our IRC example, these methods are where we will create and destroy the IRC connection object.
The onRequestEnd method is a callback that gets executed (surprise) at the end of the request lifecycle before the user’s page is rendered. This is where the logger renders its data into a cohesive output. In the Mach-II logger, this means outputing a nice HTML table structure with all the logging data gathered during the request lifecycle. For our IRC logger, that means taking all the logging information gathered during the request lifecyle and formatting it into an easy-to-read string (or strings) to be sent to an IRC channel.
The preRedirect and postRedirect functions are somewhat tricky. Conceptually they are easy to understand, but they delve the deepest into the Mach-II logging voodoo. They are at their core callbacks that happen before and after a redirect, respectively. During these callbacks you will want to persist and then restore all the logging information gathered thus far. If you’re confused at this prospect, I will expound on these functions in Part 3, so keep reading!
The getConfigurationData function is my favorite, because it’s the easiest to understand. Its job is simply to return information about this logger. I’m pretty sure that’s how the Mach-II Dashboard gets its nice logger display data.
Okay, we have our skeleton and we know roughly what’s going on. Part 2 is going to cover some boring housekeeping that’s necessary for IRC, then it will describe what we need to do to implement configure and deconfigure. Part 3 will be on the persisting and restoring of the logging data, and will wrap up our IRC logger with some Mach-II configuration code.
Now we’ll take a break for bourbon and regroup in the morning.