This is the second part of a three-part series. To read the first part, click here.
Let’s dive right in with some boring IRC housekeeping. Since this logger is an IRC-based logger, we’re going to have to store things like server and channel, so let’s make those properties of the object:
<!--- PROPERTIES ---> <cfset variables.instance.loggerTypeName = "IRC" /> <cfset variables.instance.server = "" /> <cfset variables.instance.channel = "" /> <cfset variables.instance.nick = "" /> <cfset variables.instance.bot = "" />
In this case, server is the IRC server we’ll be connecting to; channel is the channel you want the logger to join; nick is the IRC nickname for the bot, and bot is the actual Java object that will be doing all the IRC trickery for us.
Unfortunately we have to do a little more in the way of boring housekeeping code: getters and setters. I’ll just copy/paste so we can knock these out and move to something more interesting.
<!--- ACCESSORS ---> <cffunction name="setServer" access="private" returntype="void" output="false"> <cfargument name="server" type="string" required="true" /> <cfset variables.instance.server = arguments.server /> </cffunction> <cffunction name="getServer" access="public" returntype="string" output="false"> <cfreturn variables.instance.server /> </cffunction> <cffunction name="setChannel" access="private" returntype="void" output="false"> <cfargument name="channel" type="string" required="true" /> <cfset variables.instance.channel = arguments.channel /> </cffunction> <cffunction name="getChannel" access="public" returntype="string" output="false"> <cfreturn variables.instance.channel /> </cffunction> <cffunction name="setNick" access="private" returntype="void" output="false"> <cfargument name="nick" type="string" required="true" /> <cfset variables.instance.nick = arguments.nick /> </cffunction> <cffunction name="getNick" access="public" returntype="string" output="false"> <cfreturn variables.instance.nick /> </cffunction> <cffunction name="setBot" access="private" returntype="void" output="false"> <cfargument name="bot" type="any" required="true"/> <cfset variables.instance.bot = arguments.bot/> </cffunction> <cffunction name="getBot" access="private" returntype="any" output="false"> <cfreturn variables.instance.bot/> </cffunction>
Now that these properties are in place, let’s dive into the configure method. First we need to set up the filter and the adapter.
The filter of a logger is simply a configurable object that filters out logging messages based on channels. Say you get along in your development of a Mach-II application and you decide you no longer want to see Mach-II debugging messages. You could disable the Mach-II Logger, or you could introduce a filter set to weed out all those debugging messages. I’ll get more into filter configuration in Part 3.
The adapter is the object you’ll eventually be using when you say getLog().debug("your error message"). That method call bubbles all the way into the adapter of the logging interface. The adapter handles all the actual logging of messages and stores all the logging data. We’ll be using these more in Part 3 when we handle redirects.
Let’s look at some code:
<cffunction name="configure" access="public" returntype="void" output="false" hint="Configures the logger."> <cfset var filter = CreateObject("component", "MachII.logging.filters.GenericChannelFilter").init(getParameter("filter", "")) /> <cfset var adapter = CreateObject("component", "MachII.logging.adapters.ScopeAdapter").init(getParameters()) /> <!--- Set the filter to the adapter ---> <cfset adapter.setFilter(filter) /> <!--- Configure and set the adapter ---> <cfset adapter.configure() /> <cfset setLogAdapter(adapter) />
This code simply sets up the filter and adapter. These default objects (GenericChannelFilter and ScopeAdapter) are probably what you want 99% of the time. If there’s enough demand I might write an entry about writing your own adapter or filter.
Let’s finish off the configure method by storing some of the preferences we’ll be passing to our logger via the mach-ii.xml config file and setting up the Java IRC connection object:
<!--- Configure the remaining parameters ---> <cfif isParameterDefined("server")> <cfset setServer(getParameter("server")) /> <cfelse> <cfthrow type="IrcLogger" message="A parameter named 'server' is required. The IRC server to which the logger will connect."> </cfif> <cfif isParameterDefined("channel")> <cfset setChannel(getParameter("channel")) /> <cfelse> <cfthrow type="IrcLogger" message="A parameter named 'channel' is required. The IRC channel which the logger will join."> </cfif> <cfif isParameterDefined("nick")> <cfset setNick(getParameter("nick")) /> <cfelse> <cfthrow type="IrcLogger" message="A parameter named 'nick' is required. The nick of the bot that will represent the logger."> </cfif> <cfset setBot(createObject("java", "f00f.net.irc.martyr.IRCConnection").init())/> <cfset createObject("java", "f00f.net.irc.martyr.services.AutoRegister").init(getBot(), getNick(), getNick(), getNick())/> <cfset createObject("java", "f00f.net.irc.martyr.services.AutoResponder").init(getBot())/> <cfset createObject("java", "f00f.net.irc.martyr.services.AutoJoin").init(getBot(), getChannel())/> <cfset createObject("java", "f00f.net.irc.martyr.services.AutoReconnect").init(getBot()).go(getServer(), 6667)/> </cffunction>
If you don’t quite follow all of the createObject lines toward the end, that’s perfectly fine. We’re simply setting up the Java object that will connect to the IRC server. Just note that the bot object property will point to the IRCConnection object, as we’ll need that for the deconfigure method.
Which we will fill out now. What does the deconfigure method do? It simply executes code that needs to happen when the logger is unloaded by the framework. In our case, we’d like for the IRCConnection to disconnect from the server and shut down. With that in mind, let’s write some code:
<cffunction name="deconfigure" access="public" returntype="void" output="false"> <cfset var quitCommand = createObject("java", "f00f.net.irc.martyr.commands.QuitCommand").init("Client exiting...")/> <cfset getBot().sendCommand(quitCommand)/> <cfset getBot().stop()/> </cffunction>
Pretty simple.
If you’re following along so far, what we have is a nearly functioning IRC logger. In the next part we’ll actually get to logging some messages, dealing with redirects, and configuring the logger to work with Mach-II. If you have any questions or corrections, please feel free to comment on this entry.
As for me, as always, it’s time for some bourbon.