Skip to main content
Kinetic Community

Configuring custom log files

Customized logging within Kinetic Request allows you to extend the application to provide relevant information in whatever format you desire.  This can be a powerful feature for development, troubleshooting, and even reporting.  Have you ever wanted to know how many people are accessing your Kinetic forms?  What terms or services people are searching for within your catalog?  How long certain actions are taking?  All of this information can easily be logged without a single application change through our themeing or bundling strategies.

Usage

This article includes a simple "access log" implementation that logs the page name, associated template and catalog names, and the IP address of the requester whenever a Kinetic form is displayed.  This functionality can be implemented in two easy steps.

  1. Copy the accessLog.jspf logging fragment file into your theme or bundle.
        (Themes) %KINETIC_ROOT%/themes/%THEME_NAME%
        (Bundles) %KINETIC_ROOT%/themes/%BUNDLE_NAME%/packages/base
  2. Add <%@include file="logAccess.jspf"%> to the JSP used for rendering your Kinetic forms, anywhere after the customerSurvey variable has been initialized (see the Example section below for more details).
        (Themes) %KINETIC_ROOT%/themes/%THEME_NAME%/displayPage.jsp
        (Bundles) %KINETIC_ROOT%/themes/%BUNDLE_NAME%/packages/base/display.jsp    

This will configure the JSP to write a log statement to the %KINETIC_ROOT%/logs/access.log file indicating that a Kinetic form page was accessed.  The log file will look similar to:

  2012-04-23 12:05:40,405 [75.146.154.237] (ACME) iPad request, Initial Page

  2012-04-23 12:05:48,994 [75.146.154.237] (ACME) iPad request, Confirmation Page
  2012-04-23 12:07:17,284 [75.146.154.237] (ACME) Employee Onboarding, Initial Page
  2012-04-23 12:07:48,437 [75.146.154.237] (ACME) Employee Onboarding, Items selection
  2012-04-23 12:08:23,868 [75.146.154.237] (ACME) Employee Onboarding, Phone Page
  2012-04-23 12:08:31,895 [75.146.154.237] (ACME) Employee Onboarding, Business card page
  2012-04-23 12:08:37,535 [75.146.154.237] (ACME) Employee Onboarding, PC page
  2012-04-23 12:08:42,183 [75.146.154.237] (ACME) Employee Onboarding, Confirmation Page
  2012-04-23 12:17:39,376 [75.146.154.237] (ACME) New server registration, Initial Page
  2012-04-23 12:18:12,950 [75.146.154.237] (ACME) New server registration, Confirmation Page

Example

Below is a sample of the first few lines of the ACME Air theme's displayPage.jsp and the Klean bundle's display.jsp files, including the @include directive used to load the logAccess.jspf logging fragment.  Because the logAccess.jspf logging fragment leverages the customerSurvey variable to obtain the name of the catalog, template, and page for the request, @include directive must be placed after the customerSurvey variable is declared (in the Klean bundle, this is done in the packageInitialization.jspf loader fragment).

ACME Air Theme

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<jsp:useBean id="customerSurvey" scope="request" class="com.kd.kineticSurvey.beans.CustomerSurvey"/>
<jsp:useBean id="UserContext" scope="session" class="com.kd.kineticSurvey.beans.UserContext"/>
<%@include file="logAccess.jspf"%>
<%@page contentType="text/html; charset=UTF-8"%>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
        <title><jsp:getProperty name="customerSurvey" property="surveyTemplateName"/></title>
...
 
Klean Bundle
<%-- Set the page content type, ensuring that UTF-8 is used. --%>
<%@page contentType="text/html; charset=UTF-8"%>
<%-- Include the package initialization file. --%>
<%@include file="framework/includes/packageInitialization.jspf"%>
<%-- Log access to the page. --%>
<%@include file="framework/includes/logAccess.jspf"%>

<!DOCTYPE html>
<html>
    <head>
        <title><%=customerRequest.templateName()%></title>
...

Technical Details

Apache Log4j is the Java logging framework that is used within Kinetic products.  Kinetic Request automatically includes this library as a jar file within the web application.  The Apache Log4j library exposes instances of the "Logger" class.  Each instance has a unique name, and calling Logger.getLogger on a name that was previously configured will return the existing logger.  The below file initialize a new Logger using the name com.kineticdata.loggers.access if it doesn't already exist, and writes the name of the catalog, template, and page whenever a Kinetic Form page is displayed.

File: logAccess.jspf

<%-- 
  USAGE
  To leverage this file, include it in the same directory as the JSP used for
  the rendering of Kinetic forms and include the following line somewhere
  after the +customerSurvey+ bean has been declared:
    <%@include file="logAccess.jspf"%>
--%>
<%
    // LOGGER CONFIGURATION SECTION
    // The following code block configures the specified logger the first time
    // it is requested.  There are multiple configuration values within within
    // this section.
    if (org.apache.log4j.LogManager.exists("com.kineticdata.loggers.access") == null) {
        // Calculate the path to the %KINETIC_HOME%/logs/access.log file
        String logFile = getServletContext().getRealPath("/logs/access.log");
        // Initialize a Rolling file appender that will log up to 500MB of 
        // access information over 50 10MB files.
        org.apache.log4j.Layout layout = 
            new org.apache.log4j.PatternLayout("%d{ISO8601} %m%n");
        org.apache.log4j.RollingFileAppender appender = 
            new org.apache.log4j.RollingFileAppender(layout, logFile);
        appender.setMaxBackupIndex(50);
        appender.setMaxFileSize("10MB");
        // Set the access logger to use the rolling file appender previously configured
        org.apache.log4j.Logger logger = 
            org.apache.log4j.Logger.getLogger("com.kineticdata.loggers.access");
        logger.addAppender(appender);
        // Log the initialization
        logger.info("Initialized logger.");
    }

    // LOG MESSAGE SECTION
    // The following code block prepares and executes a log message when
    // specific criteria are met.  This section could be customized to implement
    // logging for other actions (such as searching), or to include additional
    // information (such as the length of time an action takes).
    if (customerSurvey != null) {
        // Retrieve the logger
        org.apache.log4j.Logger logger = 
            org.apache.log4j.Logger.getLogger("com.kineticdata.loggers.access");
        // Determine the catalog information
        String catalogName = customerSurvey.getCategory();
        String templateName = customerSurvey.getSurveyTemplateName();
        String pageName = customerSurvey.getPageName();
        // Log the specified information
        logger.info("["+request.getRemoteAddr()+"] ("+catalogName+") "+templateName+", "+pageName);
    }
%>