How to Diagnose Application Issues Quickly Using IBM Cloud App Configuration

4 min read

Use IBM Cloud App Configuration to quickly diagnose and identify issues in your application by utilizing the feature management capability to control the application traces

Detailed traces play a major role in debugging applications, but these traces may become expensive. For optimal usage, debug traces are enabled only on an as-needed basis. Feature management systems like IBM Cloud App Configuration help to control the traces for an entire application or a specific user, group or device.

Feature management helps developers get control over the software and increase productivity. It helps to tweak the user experience by targeting rules for a defined set of features. 

App Configuration is a centralized feature management and configuration service hosted on IBM Cloud, and it provides a wide variety of capabilities to control your feature rollout.

Log and trace Management

Logs and traces provide a glimpse of the current state within a running system. While logs provide error reporting and tracking, the purpose of traces is to provide a program’s flow and data progression. Traces can also represent a user’s journey through the software. Adding logs or traces is not an automatic process, but it can be achieved if the development team has a meticulous development process and it needs continuous tuning. 

The memory usage of an application increases based on the number of times the application code logs. They can also adversely impact performance and responsiveness of the application. For optimal performance, debug traces are not enabled by default in the application.

Detailed traces will only be enabled to debug and identify the root cause of an incident when an incident happens or when a specific customer faces an issue in using the application. The application can log at various levels, such as info, error, warn, debug etc. While info and error are always logged, debug is enabled only on an as-needed basis.

The benefits and challenges of traces

Traces are handy to track the end-to-end flow of a system. They are, essentially, a representation of logs with more detail.

The following are just a few of the benefits of traces:

  • Get the end-to-end flow of a system.
  • Understand a user’s journey through the system.
  • Identify errors and debug faster.
  • Identify the root cause of an issue.

While traces help, they also pose challenges to the application maintenance.  The following are the challenges of having traces in the application:

  • Traces consume more storage space.
  • Traces can be expensive in terms of application memory consumption based on the amount of traces logged and also in terms of performance (responsiveness) as the application will be bogged down in generating them.
  • Too many trace statements can slow the analysis of issues due to an overload of information that may not be relevant.
  • Enabling traces on the fly can be challenging, too, and will most likely require a new build and deployment.

How to control traces using feature management

All the challenges mentioned above can be solved when the feature flags are used to control traces. Let’s integrate IBM Cloud App Configuration into an application to control the traces being enabled. 

The sample used in this blog is based on the Shopper’s Delight sample app. An update to control trace management using feature flags is available here.

Control trace levels using feature flags

The Shopper’s Delight website is a Node.js application that uses the bunyan library for logging. The default logging level enabled is “info,” which prints only the necessary information of the application. The logging level is controlled by a feature flag “log-level” defined in IBM Cloud App Configuration. 

The “log-level” feature flag has the default disabled value as “info” and default enabled value as “debug.”  When this feature flag is enabled, the application receives the update to the feature flag and updates the logging level as “debug” on the fly. This helps to identify the root cause of any issue just by toggling the feature flag. This also eliminates any need for a new deployment of the application to update the log level.

The below code snippet helps to listen to the log-level feature updates and update the application logging level accordingly:

client.emitter.on('configurationUpdate', () => {
  acLogLevelFeature = client.getFeature('log-level');
  const logEntityId="appadminuser";
  acLogDebugLevel = acLogLevelFeature.getCurrentValue(logEntityId);
  log.level(acLogDebugLevel);
  log.info("application log level is " + acLogDebugLevel);
});

When the log feature flag is enabled, detailed traces are displayed in the application console:

When the log feature flag is enabled, detailed traces are displayed in the application console:

Controlling traces for specific users using segmentation

During a customer incident, it is important to understand the end-to-end flow of events for a specific user. At this time, the entire application should log the traces in “info” level except for the user who is facing the issue. Assigning rules to the feature flag helps achieve this.

User identification/categorization is done using segmentation. A segment named “User Filter” is defined, and it helps to identify the user. Target the feature flag “log-level” with this segment and override the value to be “debug.” Update the default enabled value also to be “info” so that based on the targeted rules, the application can update the log levels:

User identification/categorization is done using segmentation. A segment named “User Filter” is defined, and it helps to identify the user. Target the feature flag “log-level” with this segment and override the value to be “debug.” Update the default enabled value also to be “info” so that based on the targeted rules, the application can update the log levels:

When the application is run with any other user, the default enabled value is applied so the application runs with “info”-level debugging. When the segmentation rule evaluates to “true”  — in this case, when the user’s email id contains “alice” — the logging level is set to “debug.” Adding the below code in logincheck method modifies the logging level as per the user logged in:

    const entityAttributesForLogs = {
      user: userDetails.email,
    };
    acLogDebugLevel = acLogLevelFeature.getCurrentValue(userDetails.email, entityAttributesForLogs );
    log.level(acLogDebugLevel);

When user alice@example.com logs in, the log level is “debug” and the application captures more event details:

When user alice@example.com logs in, the log level is “debug” and the application captures more event details:

Summary

This article shows how to use IBM Cloud App Configuration to quickly diagnose and identify issues in your application by using the feature management capability to control the application traces.  It explains how feature flags can be used to enable traces for the entire application or to enable the restricted traces for a specific user to understand the user journey. The same principle can be extended to your microservices, API implementation or any kind of software to gather traces.

Resources

Be the first to hear about news, product updates, and innovation from IBM Cloud