Logging and Custom Loggers

Mango Blog comes with a logging mechanism that is used to log failures, warnings or simply to debug plugins or other install issues.
By default, Mango will log certain failures (at this moment only plugin failures are logged) with log level “warning” or “error”. These logs are located in the database, in the table “log” (with your custom prefix).

How to change the logging level

The logging level is configured in the config.cfm in the node “logging”, in the entry “level”. It is set to “warning” by default. If you make a change to this setting, you need to go reload the configuration. If you wish to turn logging off, use “off” as the logging level.

How to use the logger from a plugin

If you want to add a log record, you need to use the main manager (by calling getManager() if you extend from BasePlugin) to ask for the logger:

logger = getManager().getLogger();

And the to use the logger, you need to call the method logMessage or logObject:

logMessage(level, message, category, owner):void
All arguments are strings.
For level you can use error, warning, info or debug.
Message is the actual log message you want to publish.
Category is a category name, such as “plugin”. Plugins wishing to log information should use category “plugin”.
Owner is the identification of the object logging the message. A plugin should use its id as the owner to make it easier for it to retrieve this information later.

logObject(level, object, description, category, owner):void
Object is any variable. Useful for sending faults (cfcatch object) or other complex object.
Description is a short message describing why you are logging this object’s information.

Managing information you logged

If you want to retrieve or delete information you sent to the logger, you can use the log manager. To access it, you must ask the main manager:

logManager = getManager().getLogsManager()

The log manager will provide the following public methods:
search(level, category, owner):array

The search method returns a query with log records. All arguments are optional.

deleteByCriteria(level, category, olderThan, owner):void
This will allow you to delete some log records you no longer need.

getLogCount(level, category, owner):numeric

Returns the total number of logs with given search criteria.

Creating custom loggers


The logger has a set of logging handlers. In the event of a log created, all handlers will be called to “publish” the log record. What each of the handlers does in its publish method is entirely up to them. So for example, you could create a logger to send an email when an error log record is created, or push a Flex Messaging message to all subscribed users for real time notification.

To create a logging handler, you need to create a ColdFusion component that implements the method:
Publish( logRecord): void

A log record is an object with the following properties:
'level
'category'
'message'
'owner'

There a two ways to add your custom logging handler to Mango’s logger. From a plugin,  you will use the main manager (by calling getManager() if you extend from BasePlugin) to get the logger, and then add the handler:

getManager().getLogger().addHandler(YOUR HANDLER INSTANCE);

Let’s say you created a logger called “EmailLogNotification” which you included in your plugin folder, then a more complete code would look like this, if you choose to add the logger in the init method:


<cffunction name="init" access="public" output="false" returntype="any">
    <cfargument name="mainManager" type="any" required="true" />
    <cfargument name="preferences" type="any" required="true" />
            
        <cfset var myLogger = ‘’ />
        <cfset super.init(argumentCollection=arguments) />

        <cfset myLogger = createObject(“component”,”EmailLogNotification”) />
        <cfset arguments.mainManager.getLogger().addHandler(myLogger) />
            
    <cfreturn this/>
</cffunction>

The plugin can configure the log handler with any information it needs before adding it to the logger.

The second way to add a custom log handler is by manually adding it to the configuration file. Only one custom logger can be added using this method. As an example, Mango comes with a logger called “FileLogger” that you can use by adding it to the configuration file as follows (you would do the same if you created your own logger):

Look for the node logging in your configuration file (config.cfm) and add an entry called component, where you enter the dotted path to your component (you can use a mapping or relative path from Mango.cfc’s location):

<node name="logging">
    <map>
        <entry key="level" value="error"/>
        <!-- if you want to use the file logger, add this: -->
        <entry key="component" value="utilities.FileLogger"/> -->
    </map>
    
    <!-- if you want to use the file logger, add this: -->
    <node name="settings">
        <map>
            <entry key="directory" value=""/>
        </map>
    </node>
</node>

You will also need to add a node called “settings” to add any information needed for your custom logger (ie: email address to send the log to, directory where to store the logs, etc). In the example above, we are specifying the directory for the file logger. All the entries you add there will be send to your handler in the init method as a structure. Your component, therefore, needs to implement an init method as follows:

    <cffunction name="init" access="public" output="false" returntype="any">
        <cfargument name="settings" type="struct" default="#structnew()#" required="false" />
        <cfargument name="blogid" type="string" required="false" default="default" />
    
    <---store settings--->

</cffunction>