-
Notifications
You must be signed in to change notification settings - Fork 24
Create a Custom Logger: Part 2
Part Two: Building a Logger
How-To originally by Peter J. Farrell (peter@…)
- Objective
- Where We Left Off
- Deciding On Our Technical Needs
- Anatomy of a Logger
- Continue Reading How-To: Create a Custom Logger
This How-To is a working document and has not been completed.
The object of this how-to document is to help Mach-II developers learn how to the leverage the Mach-II logging package so they can create loggers that perform functionality that is not provided by the bundled loggers in the framework. This is part two in a series on How-To: Create a Custom Logger. If you have not read part one, check out Part One - Introduction and Concept Overview before continuing.
In the previous part of this series, we left off with the objective of creating a custom logger that takes log messages, uses JSON to encode them and sends the JSON as HTTP headers back to the browser to be read by the Firefox Firebug plugin or Live Headers. For the sake of complexity, we won't be building an add-on to the !Firebug extension that displays the JSON nicely because it is out of the scope of this how-to article at the moment. This task would be rather complex and complicated if we were rolling our own solution, however you will still how simple it will be for us to complete this task using the Mach-II logging package.
I want to also note that is how-to's code will probably not bullet proof as certain application servers (like Tomcat) don't like HTTP headers over a certain size. If this was being build for a production system, we would probably add additional logic to break the JSON data into smaller HTTP header packets to account for this potential defect.
There are several technical decisions we need to make before we can start coding. Let's look in depth at some of them.
Since we are going to push the messages to the browser, we are going to encode them with JSON and attach them to the HTTP response that the browser receives as HTTP headers. This means we need to have all the messages available to use at the end of the request. We need to choose or build a logging adapter. Considering our technical needs, the ScopeAdapter
, which bundled with Mach-II, is the best choice since it will log all the messages during the request to the "request" scope which we can then encode with JSON and send them to the browser.
As we discussed in part one of this series, the Mach-II logging package allows you to filter messages by utilizing a logging filter. At this point, our technical needs do not dictate any special filtering, however we will use the GenericChannelFilter
which is bundled with the logging package.
As you may know, Adobe ColdFusion 8 ships with built-in-functions (BIFs) to encode CFML data types into JSON. Other CFML engines (at the time of the writing of this part), do not have BIFs that accomplish this functionality. We will be using a UDF available from CFLib called JSONEncode to accomplish the task. This allows our example logger we are building to be cross CFML compatible. On a side bar, this is an important consideration to take into account when building application that may be deployed to one or more CFML engines. If you are building an application that is being sold/leased/open-sourced, your business objects probably include supporting multiple CFML engines.
This is a valid thought, however for the sake of simplicity we won't be adding many configuration parameters to our custom logger. Some parameters might be a flag that only sends the JSON to the browser if the CFML engine's debugging mode is on and the request is coming from an approved IP address. Other options might be mundane as allowing an user to swap in a different .cfm display template (which is not applicable in this case, but very applicable to the Mach-II logger that outputs messages at the bottom of the browser output).
Before we can start coding, we need to look at the data and methods provided by the MachII.logging.loggers.AbstractLogger
. Our logger is going to extend this component which provides an interface for methods that we will need to implement as well as helper methods to ease the development of the custom logger.
Just like other components you may develop that extend Mach-II components, the AbstractLogger
uses a configure()
method (which we will for sure sure) for custom configuration instead of an init()
method. Do not override the init()
method because, well technical reasons aside, it is not the Mach-II way of doing things. The configure()
method is where we are going to setup our log adapter and our logging filter as well as setup any of our "fancy" configuration parameters.
Other behavior that the AbstractLogger
provides are getters/setters to set the logging level, set if logging is enabled,