Application Logging

The TIBCO ActiveMatrix platform supports application logging to standard out and using a logging API. For simple demonstration applications you can log to standard out. However, for product applications you should use the logging API.

Standard Output and Error Logging

The standard output and error streams from Java programs are directed to the log file of the node on which the program is running. For example, when you run the following example:
public class HelloWorldImpl extends AbstractHelloWorldImpl {
...
    public HelloResponseDocument sayHello(HelloRequestDocument firstName) {
      ...
      System.out.println("--> Generating Java Hello Component Response...");

      String name = firstName.getHelloRequest()==null||firstName.getHelloRequest().
        equals("")?"Friend":firstName.getHelloRequest(); 
		    HelloResponseDocument resp = HelloResponseDocument.Factory.newInstance(); 
		    resp.setHelloResponse("Hi " + name + "! " + "This is the Java component.\n");

      System.out.println("--> Java Hello Component Response: \n\t\t" + 
         resp.getHelloResponse());
      ...
   }
}
the following messages are written to the log:
11 Jun 2012 15:51:27,745 [hello1Connector_30] [INFO ] [] stdout - --> Generating Java Hello Component Response...
11 Jun 2012 15:51:27,808 [hello1Connector_30] [INFO ] [] stdout - --> Java Hello Component Response: 
		Hi Jim! This is the Java component.

TIBCO ActiveMatrix Logging

The TIBCO ActiveMatrix platform supports logging using the Log4J. We recommend you use the Simple Logging Facade for Java package to access log4j. In the following Hello World Java component implementation, the calls to System.out.println are replaced with sl4j method calls (logger.info) that log to a logger named HelloWorldLogger at the INFO log level:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
...
public class HelloWorldImpl extends AbstractHelloWorldImpl {
...
  final Logger logger = LoggerFactory.getLogger("HelloWorldLogger");
  ...
    public HelloResponseDocument sayHello(HelloRequestDocument firstName) {
      ...
      logger.info("--> Generating Java Hello Component Response...");

      String name = firstName.getHelloRequest()==null||firstName.getHelloRequest().
        equals("")?"Friend":firstName.getHelloRequest(); 
	    HelloResponseDocument resp = HelloResponseDocument.Factory.newInstance(); 
		resp.setHelloResponse("Hi " + name + "! " + "This is the Java component.\n");

      logger.info("--> Java Hello Component Response: \n\t\t" + resp.getHelloResponse());
      ...
   }
}
Note: By default messages longer than 2K are truncated. To configure the log service to log messages greater than 2K, see Log Service Property Reference in Administration.

To log messages on local debug nodes, in TIBCO Business Studio set the Log Level of a run or debug configuration to match the level in the logger method invocations. To specify where log messages are sent on remote nodes, in Administrator create a logging configuration with a logger named HelloWorldLogger for the Hello World application and assign level and appender properties, or accept the default logging configuration which is to use the logging configuration of the node on which the component is deployed.

When you log to HelloWorldLogger at the INFO level and create a run, debug, or logging configuration whose level is set to INFO, the following messages are written to the log:
11 Jun 2012 16:57:09,515 [hello1Connector_30] [INFO ] [jv.helloworld1.soa] HelloWorldLogger - --> Generating Java Hello Component Response...
11 Jun 2012 16:57:09,515 [hello1Connector_30] [INFO ] [jv.helloworld1.soa] HelloWorldLogger - --> Java Hello Component Response: 
		Hi Jim! This is the Java component.

Logging to a JMS Queue

Logging information can be sent to and retrieved from JMS queues. To send log entries to a JMS queue, set the appender type of a node or application's logging configuration to JMS Appender.

The following example shows how to retrieve log entries from the queue of a JMS Appender. The log entries consist of key-value pairs of the Base Event Format. For more information on Base Event Format, see Administration. For information on the APIs demonstrated in the following example, see TIBCO Enterprise Message Service User's Guide.

import javax.jms.MapMessage; 
...
public class TibjmsAsyncMsgConsumer implements MessageListener {
...
   public void start() {
    /* Create the JMS connection. */
     try {
       QueueConnectionFactory factory = new com.tibco.tibjms.TibjmsQueueConnectionFactory(
         serverUrl);
       connection = factory.createQueueConnection(userName, password);   
       session = connection.createQueueSession(false, javax.jms.Session.AUTO_ACKNOWLEDGE);

       /* Use createQueue() to enable receiving from dynamic queues.*/
      javax.jms.Queue queue = session.createQueue(queueName);
       /* Create a connection, session and consumer */
       queueReceiver = session.createConsumer(queue);
       queueReceiver.setMessageListener(this); 
       ...
      } 
   }
   public void onMessage(Message message) {
      /* Process message and handle exceptions */
      if (message instanceof MapMessage) {
      try {
        MapMessage mapMessage = (MapMessage) message;
        System.out.println("map message is: " + message.get("_cl.msg"));
        ...
      }
   }
}

Payload Data

The following example shows how to save payload data.

import java.util.List;
import java.util.UUID;
import javax.activation.MimetypesFileTypeMap; 
import org.apache.log4j.Logger;

 public class PayloadSample {
         
    private final static String PAYLOAD_FILE = "./payload.xml";
 
    public  void logPayload() {
      /** Prepare payload data */
      File payloadFile = new File(PAYLOAD_FILE);
      InputStream is = null;
      byte[] payloadBinary = null;
      try {
        is = new FileInputStream(payloadFile);
        payloadBinary = new byte[(int) payloadFile.length()];
        is.read(payloadBinary);
      } catch (FileNotFoundException e) {
        e.printStackTrace();
      } catch (IOException e) {
        e.printStackTrace();
      } finally{
        if (is != null)
          try {
            is.close();
          } catch (IOException e) {
            e.printStackTrace();
          }
      }
              
      /** Generate payload key */
      String payloadKey = UUID.randomUUID().toString(); 
                   
      /* Prepare log record. */
      HashMap<String, Object> logMap = new HashMap<String, Object>();
               
      logMap.put("_cl.msgId ", "dummyMessageId");              
      logMap.put("_cl.msg", "dummy message");
                 
      /*  construct payload array which can contain more 
          than one payload data for one log record. */
      @SuppressWarnings("rawtypes")
       List<Object> payloads = new ArrayList<Object>();
 
       /*  create one payload data. */
       HashMap<String, Object> payloadA = new HashMap<String, Object>();
                   
       /* Set payload key. These are required properties only if the user wants
         to know the payload key. If user does not specify this payload key,
         logging api will auto-generate one. But user won't be able to get the
         auto generated key via Logging API. */
       payloadA.put("_cl.payload.id", payloadKey);
                   
       /*  Set payload binary data. These are required properties. */
       payloadA.put("_cl.payload.data", payloadBinary);
                   
       /* Set payload data optional attributes. */         

       payloadA.put("_cl.payload.name", PAYLOAD_FILE);
       payloadA.put("_cl.payload.type", 
        new MimetypesFileTypeMap().getContentType(payloadFile));
       payloadA.put("_cl.payload.size", payloadFile.length());
       payloadA.put("_cl.payload.MD5", "This is MD5 value of payload binary data. ");
       payloadA.put("_cl.payload.TTL", "100");
                  
       /* Add one payload record into list. */
       payloads.add(payloadA);
                          
       /** Put payload key into log record */
       logMap.put("_cl.payloads", payloads);

       /** Log data via Log4j */
       Logger logger = Logger.getLogger(PayloadSample.class);
                   
       if (logger.isInfoEnabled()){
          logger.info(logMap);
       }
   }
}

The sample TIBCO_HOME/amx/version/samples/java/payload.zip shows how to retrieve and delete payload data.