Configuring Logging in SCXML

SCXML uses commons-logging [1], a wrapper that works between others with Log4J [2]. In any case after you decide what logging engine is best suitable for your project you need to set it up before SCXML is able to actually log ussing commons-logging.

Log4J

Use Case # 1

problem: You are using SCXML which in turns uses commons-logging but your code cannot use commons-logging.

solution: You need to initialize one of the supported by commons-logging engines like Log4J. You better use a separate file to log SCXML-commons traces.

implementation: If you do not want to include a new resource into your project (you can use properties file or xml file for Log4J configuration), you can choose (not reccomended but in some cases necessary) to configure it programmatically:

    logger = LogManager.exists("scxml.app.log");
    if (logger == null)
    {
        Logger logger = Logger.getLogger("scxml.app.log");
        Logger rootLogger = Logger.getRootLogger();
        SimpleLayout rootLayout = new SimpleLayout();
        Appender rootAppender = new ConsoleAppender();
        rootLogger.addAppender(rootAppender);
        rootLogger.setLevel(Level.OFF);

	//Specific layout pattern for custom application
        String pattern = "%d{yyyy/MM/dd HH:mm:ss.SSS} @ " + Constants.LOG_HINT + " @ SCXML Engine @ %m%n";
        PatternLayout layout = new PatternLayout(pattern);
        boolean append = true;
        boolean bufferedIO = false;
        int bufferSize = 10;
        String filename = "completePathOfYourFileNameAddingTimestampToNameForExample.log";
        if(logger.getAppender("scxml.app.appdr") == null)
            {
                FileAppender appdr = null;
                try
                    {
                        appdr = new FileAppender(layout, filename, append, bufferedIO, bufferSize);
                        appdr.setImmediateFlush(true);
                        appdr.setName("scxml.app.appdr");
                    }
                    catch (IOException e)
                    {
                        //deal with it.
                    }
                        logger.addAppender(appdr);
                        logger.setLevel(Level.INFO);
                        logger.setAdditivity(false);
                    }
                }
        }
    }

With the code above you will be able to obtain the info messages from Var and Assign needed to debug what is going on inside the State Machine Engine (Using last version of commons-logging 1.1 and Log4J 1.2.14 the TRACE comes up like a DEBUG message so at least for these versions it makes sense to use INFO instead):

For Var:

String msg = "Var." + name + "=" + varStr;
        if( appLog.isInfoEnabled() )
           appLog.info( msg );

Warning: With the above Log4J version you should avoid using the same file to log your custom System messages and the ones from commons-SCXML if your System does not use commons-logging as well. Otherwise you might experiment some flushing problems resulting in trace lines missing in the output. There are several posts related to this issue and there is no a clear and homegeneous solution about it.

Resources

[1] http://jakarta.apache.org/commons/logging/commons-logging-1.0.4/docs/guide.html

[2] http://logging.apache.org/log4j/docs/manual.html

  • No labels