Introduction

Application logging and error handling are critical parts of log management and help a business run smoothly. If you don’t have any proper logging records, it is difficult to identify the events, making troubleshooting a long and time-consuming process.

Generally, developers use different logging practises to log the events, but in case of a mishap, it is a default to find the required data that is helpful for troubleshooting. This again requires a long process of additional coding or debugging to derive the relevant data.

To overcome the above scenarios, we have developed a framework for service utility service error handling. This essentially standardises the message logging and exception handling scenarios in any kind of MuleSoft API. The out-of-box utility service minimises developer efforts by 10-15%.

What is Utility Service?

Utility Service is a framework that logs messages with all the required information that would be helpful for troubleshooting. It has the capability to log the message in different formats.

Services offered by Utility Service

  • It supports different log formats.
  • Maintains one transaction across different layers (system, process, and experience). Using this, one can easily track the transaction from start to finish.
  • No additional formatting or logging is required, and it is easily publishable to data aggregation platforms like Splunk, ELK, and others.
  • It calculates the latency from start to end across layers, which is useful to monitor the performance of the application.
  • Request level details can be tracked using RequestID and FunctionalID params. The RequestID will be unique for different layers.
  • Additionally, it supports up to 10 context keys to log any other information.
  • It will propagate the actual error details to the consumer, even in the case of an API-led approach.
  • One can easily configure it to log the original and errored payloads.
  • Logs the source and target names, which are helpful for the triage team.

Different formats are supported by Utility Service

  • JSON
  • XML
  • CSV

Setting up the Utility Service

Using the Runnable Jar

1. Download the Utility Service Jar.

2. Include the Utility Service library in the Maven local repository using the below command.

mvn install:install-file -Dfile=\\co-utility-service-v1-1.0.0-mule-application.jar -DgroupId=com.co -DartifactId=co-utility-service-v1 -Dversion=1.0.0 -Dpackaging=jar -DgeneratePom=true

3. Add the below dependency to your mule project pom.xml

<dependency>
                   <groupId>com.co</groupId>
                   <artifactId>co-utility-service-v1</artifactId>
                   <version>1.0.0</version>
 </dependency>

4. Import “co-utility-service.xml” from the utility service into your project global elements and use the utility service for logging and error handling.

Code snippet

<import doc:name=“Import” doc:id=“6dfee7a7-d89a-499b-a4c6-4e24e28d1dd5” file=“co-utility-service.xml” />

Using Utility Service for Error Handling

The utility service is simply used by calling the flows defined using Flow Reference. From here, it automatically handles the errors and logs the transaction in the specified format.

Prerequisite properties to configure

PropertyUsageSupported valuesExample
app.sysnameApplication NameAnyco-utility-service
app.versionApplication VersionAnyV1
app.sourceSource NameAnySFTP
app.targetTarget NameAnySalesforce
app.log.originalPayloadLogs the original payload from the source if set to truetrue/false   Default – falsetrue
app.log.erroredPayloadLogs the errored-out payload in case of error if set to truetrue/false   Default – falsetrue
app.log.formatLogs the message in the specified formatjson/xml/csv   Default – jsonjson

The Utility Service logs the below information

Log Fieldsusage
serverNameName of the server where application hosted
appNameName of the Application
appVersionApplication Version
environmentEnvironment of the application
sourceSource Name
targetTarget Name
transactionIdTransaction Id
transactionStateTransaction state
requestIdRequest Id
executionStateExecution State
serviceResourceEnd point called
serviceMethodMethod of the resource
payloadPayload
logTimeStampCurrent Time Stamp
logMessageLogs the Message provided
functionalIdAny unique ID from the Request
contextKey1 .. contextKey10Any additional details for logging
logLevelLog Level
latencyTotal time is taken for the process
errorAtThe component at which the error has occurred
errorCodeThe Response Status code in error cases default is 500
errorTypeType of the error Ex: “Internal Server Error”
errorMessageThe appropriate error message

Global Error Handler

The globalErrorHandler flow logs the error details in the event of any errors. This flow works on “On Error Propagate” as well as “On Error Continue”. It logs the error messages in different formats like JSON, XML, and CSV.

Steps to configure

  • Drag and drop ‘On Error Continue’ or ‘On Error Propagate’ based on the requirement.
  • Drag and drop the flow reference inside the error handling.
  • Select the globalErrorHandler as a flow name from the drop-down.
  • Configure app.log.erroredPayload property to log the errored-out payload if required.
  • Configure log format and other properties as per requirements.

The globalErrorHandler logs the root cause of the error.

Suppose the error occurs at the system layer; the same error will be propagated back to the process and application layers.

Snippet of globalErrorHandler

The globalErrorHandler set the actual error status code in the httpStatus variable. The same variable can be used in the HTTP response header to propagate the error status.

Sample error log

{
    "serverName": "LAPTOP-KALVA",
    "appName": "demo-sample-papi",
    "appVersion": "v1",
    "environment": "dev",
    "transactionId": "5da88430-08f8-11ed-bd7c-d20f0c30c779",
    "transactionState": "Transaction_Error",
    "requestId": "66870726-279b-45dc-8270-a48b165a2740",
    "executionState": "Error",
    "serviceResource": "/papi/orders",
    "serviceMethod": "GET",
    "payload": "{\n  \"orderId\": 987456321,\n  \"customerId\": \"12934\",\n  \"items\": [\n    \"ABB-123\",\n    \"ACC-452\"\n  ]\n}",
    "logTimeStamp": "2022-07-21T18:53:54+0530",
    "functionalId": 123,
    "contextKey1": "test",
    "logLevel": "Error",
    "latency": 1118,
    "errorAt": "demo-sample-sapi-flow/processors/4 @ demo-sample-sapi:demo-sample-sapi.xml:24 (Request)",
    "errorCode": 404,
    "errorType": "Not Found",
    "errorMessage": "No listener for endpoint: /test11111111"
}