This documentation supports the 22.1 version of BMC Helix Innovation Studio.To view an earlier version, select the version from the Product version menu.

Enabling and downloading logs from BMC Helix Innovation Studio


BMC Helix Innovation Studio provides logging capabilities that you can use to track the activities and debug issues within the application. With BMC Helix Innovation Studio you can gather information to troubleshoot functional issues or errors that occur in a bundle and log them in a log file. The logs for each bundle are stored in a separate log file unique to that bundle. For example, logs for bundle A are stored in log file A, whereas logs for bundle B are stored in log file B.

BMC Helix Innovation Studio also allows multiple bundles to share the same log file name. For example, bundle A invokes a service from bundle B, the logs for the completed execution will be stored in multiple files. To avoid logs from being saved in multiple log files, BMC Helix Innovation Studio allows bundles to share the same log file name. The logs generated by these bundles are stored in same log file by specifying same log file name for each smart bundle.

As an administrator, you can enable bundle and server logs and download the log files to troubleshoot issues. To enable and download server logs, see Setting log files options.

To enable bundle logs

  1. Log in to BMC Helix Innovation Studio, navigate to the Administration tab.
  2. Click Logger Configuration, and select the required bundle.
    2102_Enable logging.png
  3. In the Logger Configuration Settings panel, enter the following details:

    Option

    Description

    fileName

    Specify the name of the log file.

    By default, name of your smart bundle is the name of the log file.

    level

    Specify the level of logging for smart bundle. The options are:

    • DEBUG
    • ERROR
    • FATAL
    • INFO
    • NOLOGERROR
    • NOLOGFATAL
    • TRACE
    • WARN

    The default level is ERROR.

  4. Click Save.
    For information about downloading bundle logs, see Setting log files options.
     

Important

  • If you use library services from an application, the library's logs are captured in the application's log file. These logs are generated based on the Logger Configuration Settings (File Name, Level) defined for the application.
    Capturing the library's logs in the application's log file allows you to maintain the log activities for the complete execution of the application in one single file.
    For example, a PTO application uses the Approval library to approve or reject the leave request of an employee. The logs for Approval library are stored in the log file for PTO application. The logs are generated based on the Logger Configuration Settings defined for PTO application.
  • The library's Logger Configuration Settings are used only if a REST API call is made to the library bundle with default-bundle-scope set to the library's bundle ID.
  • If default-bundle-scope is not set in REST API, then the logs are captured in arextension.log file.

Searching log files to track a single operation

An operation consists of several actions. For each operation, the logs are scattered across several files such as Process Log, API Log, SQL Log and so on. Any log file that is enabled contains the Operation Id parameter unique for all logs of an operation. To troubleshoot an application, you can search the Operation ID parameter in several log files and group the logs related to a single operation. 

Example

You want to troubleshoot why updating a request takes longer than expected. There are several rules and processes that run when a request is updated. After enabling the API, rule, process, and SQL debug logs, you can search for the Operation Id to identify the exact action that is causing the delay. 

You can set the Operation Id for an operation. If you have not set the Operation Id, the server generates the Operation Id.

How Operation ID works

  • The server tracks a single operation with the same Operation Id in different log files.
  • The server retains the Operation Id when the After Event rule executes.
  • The server generates a new Operation Id for a process that resumes after a wait state. 
  • The server generates a new Operation Id when a Timer Event rule is executed.
  • When a custom rule or process is executed in a Thread Local context and spawns a new thread, you can copy the Operation Id from the calling thread to the new thread. If the new thread is left blank, the server generates a new Operation Id. The ThreadLocalContext provides a method to set and get the Operation Id.

To set the Operation ID

In the REST API HTTP header, add the parameter operation-id and set the value to an alphanumeric string of 1 to 30 characters. You can use any standard Java algorithms to generate the Operation Id. If you want to use the same Operation Id for multiple API calls, you must set the Operation Id in the HTTP header for each call. 

Format of log messages

The following example shows the general format of the log messages:

<BUNDLE> <TID: xxx> <TENANT ID:xxx> <USER: xxx > /*date */ <<log level>> <<actual message>> 

For example:

<BUNDLE><TID: 0000000033> <TENANT ID: TNGAABDUC2YGIAO78IS4O6M82T3SUZ> <USER:admin>  /* Wed Mar 15 2017 16:59:36.459 */ DEBUG trackExpenses : Debug Level Is Enabled
<BUNDLE><TID: 0000000033> <TENANT ID: TNGAABDUC2YGIAO78IS4O6M82T3SUZ> <USER:admin>  /* Wed Mar 15 2017 16:59:36.462 */ TRACE trackExpenses: For Expense exception amount is 5000

Example of Operation Id in an API log

<API > <OpId: IDGG5K5KB1HMPAOD1EK2OD1EK28A9Z> <TID: 0000000001> <RPC ID: 0000000000> <Queue: Admin     > <Client-RPC: 390600   > <USER: Remedy Application Service                   > <Tenant-ID: 0                                            > <Overlay-Group: 0         > /* Fri Sep 15 2017 11:22:55.2270 */ +GLEWF   ARGetListEntryWithFields -- schema BundleDeploy:BundleRegistry from Unidentified Client (protocol 19) at IP address null using INTERNAL // :q:0.0s null
<API > <OpId: IDGG5K5KB1HMPAOD1EK2OD1EK28A9Z> <TID: 0000000001> <RPC ID: 0000000000> <Queue: Admin     > <Client-RPC: 390600   > <USER: Remedy Application Service                   > <Tenant-ID: 0                                            > <Overlay-Group: 0         > /* Fri Sep 15 2017 11:22:55.2390 */ -GLEWF            OK
<API > <OpId: IDGG5K5KB1HMPAOD1EK2OD1EK28A9Z> <TID: 0000000392> <RPC ID: 0000000000> <Queue: Admin     > <Client-RPC: 390600   > <USER: Remedy Application Service                   > <Tenant-ID: 0                                            > <Overlay-Group: 0         > /* Fri Sep 15 2017 11:22:55.2940 */ +GLEWF   ARGetListEntryWithFields -- schema BundleDeploy:BundleRegistry from Unidentified Client (protocol 19) at IP address null using INTERNAL // :q:0.0s null
<API > <OpId: IDGG5K5KB1HMPAOD1EK2OD1EK28A9Z> <TID: 0000000392> <RPC ID: 0000000000> <Queue: Admin     > <Client-RPC: 390600   > <USER: Remedy Application Service                   > <Tenant-ID: 0                                            > <Overlay-Group: 0         > /* Fri Sep 15 2017 11:22:55.2940 */ -GLEWF            OK
<API > <OpId: IDGG5K5KB1HMPAOD1EK2OD1EK28A9Z> <TID: 0000000001> <RPC ID: 0000000000> <Queue: Admin     > <Client-RPC: 390600   > <USER: Remedy Application Service                   > <Tenant-ID: 0                                            > <Overlay-Group: 0         > /* Fri Sep 15 2017 11:22:56.8780 */ +GLEWF   ARGetListEntryWithFields -- schema BundleDeploy:BundleRegistry from Unidentified Client (protocol 19) at IP address null using INTERNAL // :q:0.0s null

Using Logger service

BMC Helix Innovation Studio provides a Logger service (com.bmc.arsys.rx.services.common.Logger) to add logs in their server-side code. For example, an administrator can add logs in service classes or REST resources.

The following example shows how to get the Logger and use the Logger to log messages:

import com.bmc.arsys.rx.application.common.ServiceLocator;
import com.bmc.arsys.rx.services.common.Logger;

public class TaskService implements Service {
    public TaskResult createTask(Task task) {
        Logger logger = ServiceLocator.getLogger();
       if (logger.isDebugEnabled()) {
            logger.debug(String.format("the task name is %s, assigned to %s", task.getName(), task.getAssignee());
        }

        RecordInstance recordInstance = convertToRecordInstance(task);
       try{
            ServiceLocator.getRecordService().createRecordInstance(recordInstance);
            logger.info(String.format("task %s is created", task.getId()));
        } catch (RxException ex) {
            logger.error(ex);
            throw ex;
        }
    }
}

Related topic

Enabling-browser-logging-in-an-application