Welcome!

You will be redirected in 30 seconds or close now.

ColdFusion Authors: Yakov Fain, Jeremy Geelan, Maureen O'Gara, Nancy Y. Nee, Tad Anderson

Related Topics: ColdFusion

ColdFusion: Article

Integrating log4j and CFMX

An open source Java project gives developers new capabilities

Unless you've never developed a Web application, or for that matter, an application of any size, you've undoubtedly encountered a situation where the application wasn't doing what it was doing when you developed it ("It worked fine for me!") or when it was tested ("I swear we tested this!").

The application might be slow, it could be throwing a SQL error, or maybe a form submission is causing your application to throw an error. Usually it's an end user that reports this information to you and usually you'd like way more information than what you're getting over the phone, through e-mail, or through your help-desk system. To get more information, you may have at some point injected code into your production application that output data to the browser or wrote data to a text file. It might have been something as simple as using the <cfoutput> tag to show a SQL query, a <cfdump> to show a data structure, or maybe you looked at cfstat and perfmon. If you're using ColdFusion 5 or greater, you might have used the <cflog> tag to log data to a file.

All of these solutions, while simple, have their disadvantages. Injecting debugging code into a production application is error prone and may be impossible (sometimes developers aren't given access to the production application). If you wrote a custom tag or used the <cflog> tag, the debugging code is always on, which means that your log files could (and probably will) grow to be unmanageably large and probably unusable. (Technically it is possible to turn off the <cflog> tag by using security sandboxes in ColdFusion MX. To do this, browse to the "Sandbox Security" page in ColdFusion Administrator. Then you must create a security sandbox for the directory that you want to disable <cflog> for. Finally, edit the sandbox you created and disable the <cflog> tag by moving it from the left-hand select box to the right-hand select box. You must then restart ColdFusion MX for your change to take place.)

Wouldn't it be nice to be able to leave logging code in your application and then be able to change the granularity at runtime? If you agree, read on!

Log4j is an open source Java project that gives the developer the ability to control which log statements are output with arbitrary granularity. It is fully configurable at runtime using external configuration files and most important, it can be utilized within ColdFusion. In this article, I'll introduce you to the basics of log4j; show examples of how log4j can be used within ColdFusion; talk about some tips and tricks; and point you to further resources for developing applications with log4j.

This article is not intended to be an in-depth introduction to log4j. There are numerous tutorials available on the Web, some of which are highlighted at the end of this article.

Before getting started, you'll need to make sure that you have appropriately configured your system:

  • ColdFusion MX must be installed. You'll see that I'm using the ColdFusion MX Enterprise integrated Web server running on port 8300 throughout the examples. Note that while log4j can probably be utilized by versions of ColdFusion prior to MX, I will not be providing examples or configuration tips for those versions.
  • You'll need to confirm that the log4j JAR file exists in your ColdFusion installation. On most systems, log4j will exist in either {$jrun4_install} serverscfusioncfusion-earcfusion-warWEB-INFcfusionlib or {$cfusion_install}lib.
  • If you plan on developing a Java-based CFX tag to utilize log4j (from the research I've done), you'll need to use version 1.1.3 of log4j, which is not the latest version of log4j, but is the version included with ColdFusion MX. You'll find a link in the resources section of this article that points to the earlier versions of log4j, specifically version 1.1.3. For various reasons, you cannot use the latest versions of log4j and ColdFusion MX due to incompatibilities between version 1.1.3 and version 1.2.8 (the most recent version of log4j).
  • Finally, create a folder in /cfusionmx/wwwroot/ called "log4j", into which you'll put the source code for this article (code examples for this article appear at the end, and can be downloaded from www.sys-con.com/coldfusion/sourcec.cfm).
What Is log4j and Why Should You Use It?
As I mentioned briefly above, log4j is an open source Java project that gives the developer the ability to control which log statements are output with arbitrary granularity at runtime. Unpacked a little more, log4j enables you to inject logging code into your application during development, leave it there during production, and then configure the level of logging (i.e., only error messages but not warning messages), the section of your application you want logging from, and the endpoint you'd like the logging to reach, all using a simple properties file or an XML document.

You should use log4j for a couple of reasons. First, with the addition of ColdFusion components in ColdFusion MX (which include object-oriented concepts and structures), ColdFusion developers have the ability to create encapsulated classes that exist within packages. For instance, a company that sells hardware products might have a ColdFusion component named

com.mycompany.catalog.product.saw

How do you debug or track the logic that exists in the "saw" methods? You could use <cflog>, but then you'd either have a separate log file for each component (i.e.; <cflog file="saw" type="information" text="The saw has been instantiated.">) or you'd have one big log file with a lot of unrelated entries, and no way to turn on logging for just the saw component.

Second, <cflog>, <cfoutput>, or writing your own logging custom tag or component most likely assumes that the log messages should end up in a text file or be written to the browser as part of the returned HTML. log4j makes no such assumptions. Instead, you can configure log4j to output to the system log, to your own custom text file, to a database, to a message queue, to e-mail, or to the Windows Event log. In fact, you can configure log4j to output data to almost anything that receives data, because you can write your own "Appenders," which are the tools that receive your logging message and then hand it off to the appropriate recipient. Writing an appender is beyond the scope of this article, but there are numerous tutorials available on the Web (some of which are highlighted at the end of this document).

Finally, you should use log4j because it's extremely fast. log4j was designed from the ground up to be as fast as possible. It's highly unlikely that something you write during the last week of your development cycle will be as fast or as reliable as log4j.

Hopefully at this point your appetite has been whetted and you want to see how it works! Let's get to it!

Using log4j and ColdFusion MX
Integrating log4j into your application is relatively straightforward. First you use the CreateObject() function to get access to the log4j Category class:

categoryObject = CreateObject("java", "org.apache.log4j.Category");

The Category object, probably the most used class in the log4j package, defines a static method in Java (which means that you don't have an instance of the Category class before using it) called "getInstance()" and returns an instance of the Category class specific to the section of code you want to use logging in. When using log4j in Java, you'll almost always use the fully qualified name of the class as the argument to the "getInstance()" method like this:

categoryInstance = Category.getInstance("com.mycompany.MyClass");

However, because you're using log4j in ColdFusion MX, you'll probably want to either: a) standardize on a common naming system for your code (using names like "com.mycompany.database" or "com.mycompany.products"); or b) if you're using ColdFusion components use the GetMetaData() function to return the name of the component. For instance, given an instance of a ColdFusion component called "theInstance", you can retrieve the name like this:

componentName = GetMetaData(theInstance).name;

So back to log4j. You have a variable called "categoryObject" and you want to call the "getInstance()" method on that class to return an instance of the Category class (which will handle the actual logging), specific to the section of code you're using. You'll end up with something like this (if you're not logging inside the CFC):

logger = categoryObject.getInstance("com.mycompany.product");

or if you're using a ColdFusion component you might have something like this (if the logging is occurring inside the CFC):

logger = categoryObject.getInstance(getMetaData(this).name);

That was the hard part! The only thing left to do is log the message. The Category instance (called "logger" in the example above) has five ways of logging the message: fatal(), error(), warn(), info(), and debug(). Each of these methods is considered to be of a specific priority with fatal() being the highest priority, and debug() being the lowest priority. You use the one that makes the most sense for the section of code you're working on. For example, let's say you're working on a simple guest book form submission. After saving the information about the guest book submission to a database, you want to log that the submission was successful. This is purely informational and as such your code would look like this:

categoryObject = CreateObject("java", "org.apache.log4j.Category");
logger = categoryObject.getInstance("com.mycompany.guestbook");
logger.info("guest book submission saved successfully.");

To make it more interesting, let's say that you have a flaky database. Sometimes the database goes down, so you want to log any errors that happen as a result. You'd use the error() method instead:

<cftry>
<cfquery name="save" datasource="mydb">
INSERT INTO guestbook(name, email)
VALUES ('Aaron', 'myemail')
</cfquery>
<cfcatch>
<cfset categoryObject = CreateObject("java", "org.apache.log4j.Category")>
<cfset logger = categoryObject.getInstance("com.mycompany.guestbook")>
<cfset logger.error(cfcatch.message)>
</cfcatch>
</cftry>

If you've been following along with your favorite IDE, you're probably wondering where all this data is being sent. Right now everything you've done is being ignored because by default, log4j isn't going to log anything. You have to specify what categories of code you want logged, which priorities you want logged, and where you want that information logged to. So let's get to the configuration!

There are three ways to configure log4j. The first and easiest is by using the BasicConfigurator class. Just like the Category class, you must first use the ColdFusion CreateObject() function:

configurator = CreateObject("java", "org.apache.log4j.BasicConfigurator");

and then you call the "configure()" method:

configurator.configure();

The two lines of code above set up log4j to log all messages to the standard output stream, which in the case of ColdFusion MX is the log file named "cfusion-out.log", located in {cfusion}/logs/ or in {cfusion}/runtime/logs/. While simple, this isn't very helpful and could get to be harmful, so let's move to the second configuration option.

The PropertyConfigurator class gives you the ability to specify a text configuration file (technically a Java properties file). To configure log4j using the PropertyConfigurator class, you'll first use the CreateObject function to get access to the PropertyConfigurator class and then you'll call the "configure()" method on the class with the full path to the properties configuration file:

configurator = CreateObject("java", org.apache.log4j.PropertyConfigurator");
configurator.configure("c:mysiteconfig.properties");

Third and finally, you could use the DOMConfigurator, which is a class that allows you to provide an XML configuration file. The syntax is not much different than the PropertyConfigurator:

configurator = CreateObject("java", "org.apache.log4j.xml.DOMConfigurator");
configurator.configure("C:mysiteconfig.xml");

The configuration files are the magic in the process. The configuration files allow you to direct logging to different "Appenders"; things like the console, a text file, e-mail, a message queue, or the Windows Event Log. In short, specify the category you want to set up for logging by specifying the name of the category that you used in the code examples above:

<category name="com.mycompany.products">
<priority value="info"/>
<appender-ref ref="logfile"/>
</category>

and then specify the priority and which appender you'd like to use. In the example above, I've specified that I want to see messages with a priority of "info" or higher (which includes everything but "debug" messages) and that I want the messages to be sent to an appender called "logfile". Next you'd configure the appender, which in the above example is called "logfile":

<appender name="logfile" class="org.apache.log4j.FileAppender">
<param name="File" value="C:\mysite\logging.log" />
<param name="Append" value="true" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%t %-5p %c{2} - %m%n"/>
</layout>
</appender>

Because the configuration files aren't really related to ColdFusion, I'll leave it up to you to read about the available patterns (ways of arranging the data in the log file) and appenders (methods of storing the data) in the log4j documentation (links available at the end of this article).

Tips and Tricks
log4j is a resource not unlike a database or an e-mail server. You don't want to use it unnecessarily because it can, and most likely will, slow down an application in production. As such, one of the first things you should do is to make sure your application performs adequately with logging turned off (i.e., in the configuration file, don't create a <category> element for any of your sections, this effectively turns logging off). Make sure to test your application before and after inserting log4j statements to ensure that log4j isn't slowing your application down too much.

Second, one of the most expensive operations when using log4j is the configuration operation. If possible, make sure to initialize log4j only once by using an init() method in a ColdFusion component or by using your own custom logic. For instance, you might write something like this in your Application.cfm:

<cfscript>
if (NOT IsDefined("application.init") {
configurator = CreateObject("java", "org.apache.log4j.xml.DOMConfigurator");
configurator.configure("c:mysiteconfig.xml");
application.init = true;

}
</cfscript>

The "configure()" method need only be called once because internally it modifies a static variable (a variable whose storage is allocated for the entire execution of a program), which means that log4j will remain configured as long as the ColdFusion server process is running. Note that this also means that the configuration you use applies to all the Web applications running in this instance (if you have multiple instances of ColdFusion MX then you don't have to worry about this).

Finally, the log4j team recognized that string concatenation can be an expensive operation in and of itself. As such, they included some utility methods in the Category class that let you first check to see if the logging method you want to use is even enabled. For example, the following block of code requires ColdFusion to first evaluate the "guest book was signed by " & #email#' string before sending data to the info() method.

categoryInstance = CreateObject("java", "org.apache.log4j.Category");
logger = categoryInstance.getInstance("com.foo");
logger.info("guest book was signed by " & #email#);

However, you can use the isInfoEnabled() method to verify that "info" messages should even be logged. Going back to the example above, it would actually be marginally faster to do this:

categoryInstance = CreateObject("java", "org.apache.log4j.Category");
logger = categoryInstance.getInstance("com.foo");
if (logger.isInfoEnabled()) {
logger.info("guest book was signed by " & #email#);
}

Likewise, you could also use the "isDebugEnabled()" method to verify that debug operations should be logged.

Further Resources
I've included two sample ColdFusion scripts at the end of this article, "log4j_sample_propertyconfig.cfm" and "log4j_sample_xmlconfig.cfm," (Listing 1 and Listing 2) as well as the corresponding configuration files for each ("sample_config.properties" and "sample_config.xml"; Listing 3 and Listing 4).

  • Third-Party Logging API: http://sys-con.com/story/passwordprompt?storyid=36144
  • log4j documentation: http://jakarta.apache.org/log4j/docs/index.html
  • log4j earlier releases: http://jakarta.apache.org/log4j/docs/earlier.html
  • log4j configuration: http://webforums.macromedia.com/coldfusion/ messageview.cfm?catid=273&threadid=726244
  • ColdFusion debugging: www.forta.com/blog/index.cfm?mode=e&entry=920
  • Harness the power of log4j with Jabber: www.106.ibm.com/developerworks/java/library/j-instlog/
  • log4j appenders: www.qos.ch/ac2001/F11-90.html
  • The complete log4j manual: www.qos.ch/shop/products/clm_t.jsp
  • More Stories By Aaron Johnson

    Aaron Johnson is a senior software engineer at Jive Software. He lives with his wonderful wife, young son and dog in a Portland, Oregon. You can find out more by reading his blog at http://cephas.net/blog/.

    Comments (0)

    Share your thoughts on this story.

    Add your comment
    You must be signed in to add a comment. Sign-in | Register

    In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


    @ThingsExpo Stories
    Imagine if you will, a retail floor so densely packed with sensors that they can pick up the movements of insects scurrying across a store aisle. Or a component of a piece of factory equipment so well-instrumented that its digital twin provides resolution down to the micrometer.
    In his keynote at 18th Cloud Expo, Andrew Keys, Co-Founder of ConsenSys Enterprise, provided an overview of the evolution of the Internet and the Database and the future of their combination – the Blockchain. Andrew Keys is Co-Founder of ConsenSys Enterprise. He comes to ConsenSys Enterprise with capital markets, technology and entrepreneurial experience. Previously, he worked for UBS investment bank in equities analysis. Later, he was responsible for the creation and distribution of life settle...
    BnkToTheFuture.com is the largest online investment platform for investing in FinTech, Bitcoin and Blockchain companies. We believe the future of finance looks very different from the past and we aim to invest and provide trading opportunities for qualifying investors that want to build a portfolio in the sector in compliance with international financial regulations.
    No hype cycles or predictions of a gazillion things here. IoT is here. You get it. You know your business and have great ideas for a business transformation strategy. What comes next? Time to make it happen. In his session at @ThingsExpo, Jay Mason, an Associate Partner of Analytics, IoT & Cybersecurity at M&S Consulting, presented a step-by-step plan to develop your technology implementation strategy. He also discussed the evaluation of communication standards and IoT messaging protocols, data...
    Coca-Cola’s Google powered digital signage system lays the groundwork for a more valuable connection between Coke and its customers. Digital signs pair software with high-resolution displays so that a message can be changed instantly based on what the operator wants to communicate or sell. In their Day 3 Keynote at 21st Cloud Expo, Greg Chambers, Global Group Director, Digital Innovation, Coca-Cola, and Vidya Nagarajan, a Senior Product Manager at Google, discussed how from store operations and ...
    In his session at 21st Cloud Expo, Raju Shreewastava, founder of Big Data Trunk, provided a fun and simple way to introduce Machine Leaning to anyone and everyone. He solved a machine learning problem and demonstrated an easy way to be able to do machine learning without even coding. Raju Shreewastava is the founder of Big Data Trunk (www.BigDataTrunk.com), a Big Data Training and consulting firm with offices in the United States. He previously led the data warehouse/business intelligence and B...
    "IBM is really all in on blockchain. We take a look at sort of the history of blockchain ledger technologies. It started out with bitcoin, Ethereum, and IBM evaluated these particular blockchain technologies and found they were anonymous and permissionless and that many companies were looking for permissioned blockchain," stated René Bostic, Technical VP of the IBM Cloud Unit in North America, in this SYS-CON.tv interview at 21st Cloud Expo, held Oct 31 – Nov 2, 2017, at the Santa Clara Conventi...
    A strange thing is happening along the way to the Internet of Things, namely far too many devices to work with and manage. It has become clear that we'll need much higher efficiency user experiences that can allow us to more easily and scalably work with the thousands of devices that will soon be in each of our lives. Enter the conversational interface revolution, combining bots we can literally talk with, gesture to, and even direct with our thoughts, with embedded artificial intelligence, whic...
    Product connectivity goes hand and hand these days with increased use of personal data. New IoT devices are becoming more personalized than ever before. In his session at 22nd Cloud Expo | DXWorld Expo, Nicolas Fierro, CEO of MIMIR Blockchain Solutions, will discuss how in order to protect your data and privacy, IoT applications need to embrace Blockchain technology for a new level of product security never before seen - or needed.
    Leading companies, from the Global Fortune 500 to the smallest companies, are adopting hybrid cloud as the path to business advantage. Hybrid cloud depends on cloud services and on-premises infrastructure working in unison. Successful implementations require new levels of data mobility, enabled by an automated and seamless flow across on-premises and cloud resources. In his general session at 21st Cloud Expo, Greg Tevis, an IBM Storage Software Technical Strategist and Customer Solution Architec...
    When shopping for a new data processing platform for IoT solutions, many development teams want to be able to test-drive options before making a choice. Yet when evaluating an IoT solution, it’s simply not feasible to do so at scale with physical devices. Building a sensor simulator is the next best choice; however, generating a realistic simulation at very high TPS with ease of configurability is a formidable challenge. When dealing with multiple application or transport protocols, you would be...
    Nordstrom is transforming the way that they do business and the cloud is the key to enabling speed and hyper personalized customer experiences. In his session at 21st Cloud Expo, Ken Schow, VP of Engineering at Nordstrom, discussed some of the key learnings and common pitfalls of large enterprises moving to the cloud. This includes strategies around choosing a cloud provider(s), architecture, and lessons learned. In addition, he covered some of the best practices for structured team migration an...
    Smart cities have the potential to change our lives at so many levels for citizens: less pollution, reduced parking obstacles, better health, education and more energy savings. Real-time data streaming and the Internet of Things (IoT) possess the power to turn this vision into a reality. However, most organizations today are building their data infrastructure to focus solely on addressing immediate business needs vs. a platform capable of quickly adapting emerging technologies to address future ...
    We are given a desktop platform with Java 8 or Java 9 installed and seek to find a way to deploy high-performance Java applications that use Java 3D and/or Jogl without having to run an installer. We are subject to the constraint that the applications be signed and deployed so that they can be run in a trusted environment (i.e., outside of the sandbox). Further, we seek to do this in a way that does not depend on bundling a JRE with our applications, as this makes downloads and installations rat...
    Widespread fragmentation is stalling the growth of the IIoT and making it difficult for partners to work together. The number of software platforms, apps, hardware and connectivity standards is creating paralysis among businesses that are afraid of being locked into a solution. EdgeX Foundry is unifying the community around a common IoT edge framework and an ecosystem of interoperable components.
    DX World EXPO, LLC, a Lighthouse Point, Florida-based startup trade show producer and the creator of "DXWorldEXPO® - Digital Transformation Conference & Expo" has announced its executive management team. The team is headed by Levent Selamoglu, who has been named CEO. "Now is the time for a truly global DX event, to bring together the leading minds from the technology world in a conversation about Digital Transformation," he said in making the announcement.
    In this strange new world where more and more power is drawn from business technology, companies are effectively straddling two paths on the road to innovation and transformation into digital enterprises. The first path is the heritage trail – with “legacy” technology forming the background. Here, extant technologies are transformed by core IT teams to provide more API-driven approaches. Legacy systems can restrict companies that are transitioning into digital enterprises. To truly become a lead...
    Digital Transformation (DX) is not a "one-size-fits all" strategy. Each organization needs to develop its own unique, long-term DX plan. It must do so by realizing that we now live in a data-driven age, and that technologies such as Cloud Computing, Big Data, the IoT, Cognitive Computing, and Blockchain are only tools. In her general session at 21st Cloud Expo, Rebecca Wanta explained how the strategy must focus on DX and include a commitment from top management to create great IT jobs, monitor ...
    "Cloud Academy is an enterprise training platform for the cloud, specifically public clouds. We offer guided learning experiences on AWS, Azure, Google Cloud and all the surrounding methodologies and technologies that you need to know and your teams need to know in order to leverage the full benefits of the cloud," explained Alex Brower, VP of Marketing at Cloud Academy, in this SYS-CON.tv interview at 21st Cloud Expo, held Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clar...
    The IoT Will Grow: In what might be the most obvious prediction of the decade, the IoT will continue to expand next year, with more and more devices coming online every single day. What isn’t so obvious about this prediction: where that growth will occur. The retail, healthcare, and industrial/supply chain industries will likely see the greatest growth. Forrester Research has predicted the IoT will become “the backbone” of customer value as it continues to grow. It is no surprise that retail is ...