Logging

The QuickBooks Online Java SDK includes the Simple Logging Façade for Java (SLF4J) utility that serves as an abstract layer for various logging frameworks, such as, log4j, java.util.logging, and logback. You can plug in the desired logging framework at deployment time. This page describes steps on how to set up the SLF4J logger in your QuickBooks Online project. By default the SDK includes the slf4j-api.jar required for any SLF4J implementation.

1. Bind with logging framework.

SLF4J uses a static binding. This means there is one JAR file for each supported logging framework. Depending on the logging framework you choose to use, you must include the corresponding SLF4J binding JAR file to the lib directory, in your development project.

Download the required SLF4J binding JAR files from the SLF4J download site.The following table lists JAR files corresponding to each logging framework that must be included:

Logging framework Required JARs
log4J version 1.2 log4j.jar, slf4j-log4j12-1.6.4.jar
java.util.logging slf4j-jdk14-1.6.4.jar
logback logback-core-1.0.3.jar/logback-classic-1.0.3.jar

Note

Note

Do not include more than one implementation JAR file in the class path. If more than one are included, the app may exhibit unexpected behavior.

To switch logging frameworks, replace slf4j bindings in your class path. For example, to switch from java.util.logging to log4j, replace slf4j-jdk12-1.6.4.jar with slf4j-log4j12-1.6.4.jar in the path.

If no binding JAR is found in the class path, SLF4J errors with Failed to load class “org.slf4j.impl.StaticLoggerBinder”. For more information, see SLF4J warning and error messages.

2. Configure logging framework.

By default, a logging framework has the rootlogger configured with the logger level. You can change the logger level, set the appender in the rootLogger and have rootLogger log messages. You can also set up the SDK or your app to log messages. However, the appender (output of log messages) is always defined in the rootLogger.

The following table describes the log levels:

Log level Description
NONE Results in no log event being created regardless of the configuration.
TRACE Creates a TRACE event in the logging system.
DEBUG Generates debug messages in the logging system.
INFO Generates informational messages in the logging system.
WARN Generates warning messages in the logging system.
ERROR Generates error messages in the logging system.

Note

Note

To capture Request and Response logs, the SDK logger must be set to DEBUG level.

3. Configure log4J framework.

SDK Logs

Configure the appender and logger level in the log4j.properties file. In the following code sample, the logger level for the SDK (com.intuit.platform) is set to DEBUG and this overrides the logger level of rootLogger. Appender STDOUT is defined in the rootLogger:

1
2
3
4
5
6
7
8
9
log4j.rootLogger=INFO, STDOUT

#This code sets SDK logger at level ERROR and overrides the rootLogger level.
log4j.logger.com.intuit.platform=DEBUG

#This appender will log messages to the console.
log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender
log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout
log4j.appender.STDOUT.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
Application logs

To obtain logs from your app, you can add one or more loggers within required java files of your development project. Following steps define how to capture logs from your app:

  1. Create app logger in required Java file. In the following code sample, a logger by name myClass is instantiated in the Entry.java file:

1
2
//File Entry.java
org.slf4j.Logger logger=org.slf4j.LoggerFactory.getLogger("myClass");
  1. Set the logger properties in the log4j.properties file. In the following code sample, DEBUG is set as log level for myClass logger created in Step a:

1
2
3
#File log4j.properties
#This code sets myClass logger at level DEBUG and overrides the rootLogger level.
log4j.logger.myClass=DEBUG

4. Configure logback framework

SDK logs

Configure the appender and logger level in the logback.xml file. In the following code sample, the logger level for the SDK (com.intuit.platform) is set to DEBUG and this overrides the logger level of rootLogger. Appender STDOUT is defined in the rootLogger.

1
2
3
4
5
6
7
8
9
<!-- This code sets rootLogger at level INFO and appender as STDOUT. -->
   <root level="INFO">
      <appender-ref ref="STDOUT" />
   </root>

<!-- This code sets SDK logger at level DEBUG and overrides the rootLogger level. -->
   <logger name="com.intuit.platform">
      <level value="DEBUG"/>
   </logger>
Application logs

To obtain logs from your app, you can add one or more loggers within required java files of your development project. Following steps define how to capture logs from your app:

  1. Create app logger in the required Java files. In the following code sample, a logger named myClass is instantiated in the Entry.java file:

1
2
//File Entry.java
org.slf4j.Logger logger=org.slf4j.LoggerFactory.getLogger("myClass");
  1. Set the logger properties in the logback.xml file. In the following code sample, INFO is set as log level for the myClass logger created in Step a:

1
2
3
4
<!-- This code sets myClass logger at level INFO and overrides the rootLogger level. -->
<logger name="myClass">
   <level value="INFO"/>
</logger>

5. java.util.logging Framework

SDK logs

Following steps define how to capture logs from the SDK:

  1. Define the logging.properties file path in the required Java file. The logger obtains properties set in the logging.properties file. In the following code sample, the getResourceAsStream() method is set to look at root of source files for logging.properties:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
//File Entry.java

try {
   InputStream is = Logger.class.getResourceAsStream("/logging.properties"); //location is root of source files
      LogManager manager = LogManager.getLogManager();
      manager.readConfiguration(is);
      is.close();
   } catch (Exception e) {
      try {
      LogManager.getLogManager().readConfiguration();
      } catch (Exception e1) {
         // If the configuration can't be read, print a stack trace as a tombstone and continue
         e1.printStackTrace();
      }

b. Define the handler and configure the appender and logger level in the logging.properties file. The logger level of the handler must be set to ALL. In the following code sample, the logger level for the SDK (com.intuit.platform) is set to FINE and this overrides the logger level of rootLogger. Appender STDOUT is defined in the rootLogger:

1
2
3
4
5
6
7
#This code sets rootLogger at level INFO and appender as STDOUT.
.level = INFO

#This code sets SDK logger at level FINE and overrides the rootLogger level.
com.intuit.platform.level = FINE
handlers = java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level = ALL

Note

Note

To capture debug logs from the SDK when using the Java.util.logging framework, the logger must be set to level FINE.

Application logs

To obtain logs from your app, you can add one or more loggers within the required java files of your development project. The following steps define how to capture logs from your app:

  1. Define the logging.properties file path in the required Java file. The logger obtains properties set in the logging.properties file. In the following code sample, the getResourceAsStream() method is set to look at root of source files for logging.properties:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
//File Entry.java

try {
   InputStream is = Logger.class.getResourceAsStream("/logging.properties"); //location is root of source files
   LogManager manager = LogManager.getLogManager();
   manager.readConfiguration(is);
   is.close();
} catch (Exception e) {
   try {
      LogManager.getLogManager().readConfiguration();
   } catch (Exception e1) {
      // If the configuration can't be read, print a stack trace as a tombstone and continue
      e1.printStackTrace();
   }
  1. Create the app logger in the required Java file. In the following code sample, a logger named myClass is instantiated in the Entry.java file:

1
2
//File Entry.java
org.slf4j.Logger logger=org.slf4j.LoggerFactory.getLogger("myClass");
  1. Set the logger properties in the logging.properties file. The properties file must be placed in the path defined in Step a. In the following code sample, INFO is set as log level for the myClass logger created in Step b:

1
myClass.level = INFO
Log message format

In SLF4J, the printing methods, such as debug(), info(), warn(), and error() in the Logger interface, accept only messages of type String instead of object. The following code sample shows the format for a single replacement in a log message:

1
logger.info("File Input Stream {}", fileInputStream);

The following code shows the format for multiple string replacements:

1
logger.debug("Inside getRequestToken Consumer Key and Secret: {} {}", new Object[]{consumerkey ,consumersecret});

For more information on accepted log types, see SLF4J API.