Developer

Add Logging to your Android Application

Add logging to your native Android OData app, upload the log to the server, and view the logs.

Logging

Use logging features provided by supportability and logging libraries.

  • Logger Creation and Setup
    The Supportability framework provides advanced logging capabilities. Instantiate dedicated and custom logger objects using ClientLogManager’s getLogger method. The various SDK components use specific loggers internally.
    1. Add this statement to import the required classes from the namespaces:
      import com.sap.smp.client.supportability.*; 
    2. Query the default client log manager:
      // Get ClientLogManager instance 
      ClientLogManager logMan = Supportability.getInstance().getClientLogManager(this); 
      By default, loggers persist their logs in a local file system. If you need the logs to also appear in the console, you can override the default using the ClientLogManager’s setLogDestination API. The API expects values defined in an EnumSet of ClientLogDestination types, and therefore can be combined:
      // Gets it for every logger 
      logMan.setLogDestination(EnumSet.of(ClientLogDestination.CONSOLE, ClientLogDestination.FILESYSTEM));
    3. Set the log output destination and log level. Two log destinations are supported:
      • Console logs are displayed in Android Studio's debug console
      • FileSystem logs are persisted in the clients local storage
      ClientLogManager’s setLogLevel method allows setting of the global log level. The default log level is ERROR, which makes your logs less verbose; however, if you need more detailed log messages, you can lower the log level to Warning or Debug:
      // Set the desired log level on all the loggers
      logMan.setLogLevel(ClientLogLevel.DEBUG);
          
      // Set the desired log level for a particular logger // optional: default is ErrorClientLogLevel
      logManager.setLogLevel(ClientLogLevel.INFO, "LOGGER_PARSER");
      logManager.setLogLevel(ClientLogLevel.FATAL, "LOGGER_SERVER");
          
      // Set the log destination for a particular logger
      logManager.setLogDestination(EnumSet.of(ClientLogDestination.CONSOLE), "LOGGER_PARSER");
      
      To instantiate a custom logger, provide a unique ID to every particular custom logger. Reusing the same logger ID produces the same logger instance:
      // Instantiate a custom logger 
      ClientLogger customLogger = Supportability.getInstance().getClientLogManager(this).getLogger("LOGGER_PARSER");
    4. Log a warning using the newly created logger:
      customLogger.logWarning("Warning message goes here");
      In a real application, create a logger member variable, to use throughout the given implementation class.
  • Fine Tune Logger Settings

    The global setting applies for all existing logger instances, and provides default values for loggers to be created later. (If no global setting is made, the original defaults apply; Error for log level and File system for log destination.)

    Global settings can be overridden on a per logger basis, which is useful if you want to silence some components, while enabling logging for a group of selected loggers (for example, to identify issues in a specific part of the project, or focus on a small subset of components).
    // Set log level to DEBUG for this very logger
    logManager.setLogLevel(ClientLogLevel.DEBUG, "CustomLogger");
    
    // Do not persist logs, just display them in console window
    logManager.setLogDestination(EnumSet.of(ClientLogDestination.CONSOLE), "CustomLogger");
    
  • Client Log Levels
    The default log level setting is ERROR. The following log levels are supported:
    ClientLogLevel.FATAL > ClientLogLevel.ERROR > ClientLogLevel.WARNING > ClientLogLevel.INFO > ClientLogLevel.DEBUG.
    Lower levels automatically enable higher ones. For example, setting the log level to WARNING means that all WARNINGs, ERRORs and FATAL log messages are logged, while INFO and DEBUG messages are not:
    FATAL > ERROR > WARNING > INFO > DEBUG
    
    Setting the log level to FATAL silences all other log levels:
    FATAL > ERROR > WARNING > INFO > DEBUG
    
    Enabling the DEBUG log level is equivalent to enabling ALL log levels:
    FATAL > ERROR > WARNING > INFO > DEBUG
  • Retrieving Logs

    ClientLogManager provides APIs to retrieve the logs that have been produced by the app.

    Use iterateLogEntries to sequentially retrieve all logs with the specified and more critical level. Alternatively, use iterateLogEntriesForLogger(String loggerId, ClientLogLevel logLevel) to fetch logs for a given logger.

    Retrieve logs that are below a certain logLevel:
    Iterator<ClientLogEntry> logs = logMan.iterateLogEntriesForLogger(ClientLogLevel.ERROR);
    Or use this code for a custom logger:
    Iterator<ClientLogEntry> logs = logMan.iterateLogEntriesForLogger(”CustomLogger”, ClientLogLevel.ERROR);
    After getting the entries the user can read each ClientLogEntry. You can persist these entries by storing the Message and additional details, such as:

    Attribute

    Type

    Application

    String

    Date

    java.util.Date

    Location

    String

    Message

    String

    MessageType

    MessageType

    LogLevel

    ClientLogLevel

  • Client-side Log Persistence
    Since it is difficult to predict how many logs will be produced by an app, persisting them on the client is intentionally temporary. Logs are removed:
    • After being successfully uploaded to the server or
    • Once their expiation date is reached. By default log entries are purged after one week.
    • If the coded limit is reached: Logs are generated into various log files that are created as the logs are generated. If the sum of the logs reach a limit that can be modified by the API user, the oldest log file is deleted.
    The default settings for log file persistence are:
    • File age: 604800000 ms (7 days)
    • Max. file size: 102400 (100 KB)
    • Max. number of files: 10
    You can override these settings by adding the sap-supportability.properties file into your application’s assets folder with property values. For example:
    file_size=1000000
    file_count=10
    file_age=1209600000
    
  • Uploading Logs to the Server

    SAP Mobile Platform Server supports uploading of client log files. Access is controlled by the security configuration associated with the given application. Therefore, prior to uploading logs, the Server Administer must set the appropriate settings. See http://help.sap.com/saphelp_smp307svr/helpdata/en/e6/46aa8668a64efb94ec30e198a0b009/content.htm (or perform a Web search for “SMP” “Defining Client Log and Trace Policies”). Additionally, the application connection ID must be passed as a “X-SMP-APPCID” header field.

    The following code attempts to upload client logs to SAP Mobile Platform Server. You must supply a valid SAP Mobile Platform Server log upload URL in the form “http(s)://host:port/clientlogs”, and the client log policy must be configured to accept log uploads on the Management Cockpit. See http://help.sap.com/saphelp_smp307svr/helpdata/en/e6/46aa8668a64efb94ec30e198a0b009/content.htm for details.
    HttpConversationManager convMan = new HttpConversationManager(this);
    IHttpConversation conv = convMan.create(logURL); // logURL is assembled beforehand
    conv.addHeader(HEADER_SMP_APPCID, <appCId>); // appcid or connection ID is coming from onboarding
    					
    SupportabilityUploaderImpl uploader = new SupportabilityUploaderImpl(conv, this);
    logMan.uploadClientLogs(uploader, new UploadListener() {
    public void onUploadSuccess() {		
    	Log.i(LOG_TAG, "Log Upload Successful");
    	}
    
    	public void onUploadFailure(UploadResult result) {
    		Log.e(LOG_TAG, "Log Upload Failed: " + result.getResponseStatusCode() + ", " + result.getHint());
    	}
    });
    
    The above code uses the uploader provided by the HttpConversation library.
  • Viewing Logs on the Server

    Logs that are successfully uploaded to the server can be viewed and filtered to analyze and troubleshoot issues. See : http://help.sap.com/saphelp_smp307svr/helpdata/en/81/540a14ddb04e00a73ddaaa10c7260f/content.htm