Custom Connector for enabling logging from Mule ESB
Supercharge your Mule ESB logging with the Nodinite Custom Connector! Replace the standard Logger and Business Events shapes for a unified, scalable, and business-friendly logging experience—on-premise or in the cloud.
Supported versions:
- 3.9
- 3.8
- 3.7
- 3.6
For MuleSoft run-time 4 and later, use this guide as inspiration to build your own custom connector.
The Nodinite Custom Connector is a ready-to-use template that helps you get started with advanced logging in minutes.
Example: The Nodinite Custom Connector centralizes logging from multiple Mule ESB flows for streamlined monitoring and troubleshooting.

To enable logging from your Mule ESB flows, simply add the Nodinite Custom Connector (Prefixed Log ... in the examples). Use the Nodinite Custom Connector instead of the Logger or Business Events shapes for a consistent, future-proof approach.
Feature | Pros | Cons | Comment |
---|---|---|---|
Logger | Built in | - Limited options and hardcodes your solution - Hard to replace - Requires lots of code/configuration - Inconsistent logging quality - Log files (on-premise) waste disk space and must be managed - Long delays before data is visible in the cloud (sometimes >12 hours) - Configuration must change when moving from on-premise to cloud |
Requires a configured log appender |
Business Events | Built in | All cons as above, plus: - Requires Enterprise edition - Limited to provided key/values (no payload) |
Expensive and very limited options |
Nodinite Custom Connector | - Always logs the body - Consistent key/value (context properties) - Easy to replace with another logging solution - Faster time for logged events to be visible - All logic is within the custom connector and logging sub flow - Consistent quality is easier to achieve - Works equally on-premise and in the cloud, no code changes needed when migrating |
Requires adding the Log shape (custom connector) to all flows | Download our template and start using it instead of Logger and Business Events |
How do I get started with logging from Mule ESB using the Nodinite custom connector?
First, read the Asynchronous Logging user guide and install the Pickup Service.
Step 1: Download the Nodinite Custom Connector
Go to the Nodinite portal and download the ZIP file with the custom connector.
Step 2: Add Custom Connector to Anypoint Studio
Add the ZIP file to your Anypoint Studio project. The result should look like this:
Anypoint Studio 6
Example of Nodinite Custom Connector added to Anypoint Studio.
Anypoint Studio 7
Import the JAR package:
Step 3: Add Custom Connector to Flow
In your Mule ESB flows, add the Nodinite logging custom connector where needed (before/after transformation, exception handling, conditional flows, sub flows, etc.).
Step 4: Code for Target Destination
Logging is implemented as a generic, reusable sub flow:
Example of a logging sub flow.
The logging sub flow creates the JSON Log Event and posts it to a destination such as:
Destination | Pros | Cons | Comment |
---|---|---|---|
Log API | Available with Nodinite | - Not highly available - Connectivity required - Synchronous (not recommended for production) - Does not scale as well as queues/databases |
Great for POCs and initial testing. Avoid in production. |
ActiveMQ | - Free (Open Source) - Scales well - Supports fail-over clustering |
- Requires extra coding/configuration | Recommended |
AnypointMQ | - Scales well - Highly available |
- Requires enterprise subscription - More costly |
Not currently supported by Pickup Service. Contact support if needed. |
PostgreSQL | - Scales well | - Requires extra coding/configuration |
Choose the best destination for your needs. With this approach, you only need to change the destination in one place if requirements change.
Step 5: Configure Pickup Service
The Pickup Service fetches your JSON Log Events from the destination you coded for in the previous step.
Step 6: Verify and Fine-tune
Verify and fine-tune logging according to your business needs.
Tuning and Best Practices
Start small—implement the Custom Connector in a few Mule ESB flows before rolling it out everywhere.
The following event fields are mandatory; the rest are optional (set to null
or omit). Providing more details about the Log Event improves the end-user experience with Nodinite.
Mandatory | Data Type | Field | Value | Comment |
---|---|---|---|---|
string |
LogAgentValueId | 42 | Who (Log Agents) sent the data | |
string |
EndPointName | "INT101: Receive Hello World Log Events" | Name of Endpoint transport | |
string |
EndPointUri | "C:\DropArea\in" | URI for Endpoint transport | |
number |
EndPointDirection | 0 | Direction for Endpoint transport | |
number |
EndPointTypeId | 60 | Type of Endpoint transport | |
string |
OriginalMessageTypeName | "https://nodinite.com/Customers/1.0#Batch" | Message Type Name | |
string |
LogDateTime | "2018-05-03T13:37:00.123Z" | Client Log datetime (UTC format) |
See the Json Log Event user guide for full details.
Exception Handling
Add the custom connector to your exception handling and set the Log Status Code according to your business case. This provides user-friendly texts for the business.
Correlation
See the Mule ESB Correlation user guide.
Message Types
Providing the Message Type is mandatory.
Many Nodinite logging features depend on well-known Message Types. For example, when extracting values for Search Fields, Nodinite uses Search Field Expressions bound to named Message Types.
Tip
Provide unique names for message types to get the best logging experience with Nodinite.
Context Options
Nodinite offers a wide range of logging options. See the Context Options user guide for more information.
Repair and Resubmit
With Context Options, you can add properties to logged JSON Log Events that Nodinite can use for repairing and resubmitting messages. Build your Mule ESB flows to handle resubmitted messages.
Log Views
Involve your business and create role-based self-service Log Views. This reduces incidents and helps the business understand integration solutions.
Next Step
How to Add or manage Search Fields
How to Add or manage Log Views
Related Topics
- Logging
- Log Events
- What are Search Fields?
- What are Search Field Expressions?
- What are Message Types?
- What are Log Views?
Example flow configuration using the downloadable Nodinite custom connector
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:nodinite="http://www.mulesoft.org/schema/mule/nodinite" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:scripting="http://www.mulesoft.org/schema/mule/scripting" xmlns:file="http://www.mulesoft.org/schema/mule/file" xmlns:json="http://www.mulesoft.org/schema/mule/json" xmlns:batch="http://www.mulesoft.org/schema/mule/batch" xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/file http://www.mulesoft.org/schema/mule/file/current/mule-file.xsd
http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd
http://www.mulesoft.org/schema/mule/json http://www.mulesoft.org/schema/mule/json/current/mule-json.xsd
http://www.mulesoft.org/schema/mule/batch http://www.mulesoft.org/schema/mule/batch/current/mule-batch.xsd
http://www.mulesoft.org/schema/mule/scripting http://www.mulesoft.org/schema/mule/scripting/current/mule-scripting.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/nodinite http://www.mulesoft.org/schema/mule/nodinite/current/mule-nodinite.xsd">
<spring:beans>
<spring:bean class="int001.filemove.transform.NodiniteLoggerService" name="CreateLogEventBean"/>
</spring:beans>
<http:request-config name="Nodinite_HTTP_Request_Configuration" host="demo.nodinite.com" port="80" basePath="/LogAPI/api/" doc:name="HTTP Request Configuration"/>
<nodinite:config name="Nodinite__Configuration" doc:name="Nodinite: Configuration"/>
<flow name="int001.filemove.transformFlow">
<file:inbound-endpoint path="C:\Temp\mule\int001.filemove.transform\in\" responseTimeout="10000" doc:name="File"/>
<byte-array-to-string-transformer doc:name="Byte Array to String"/>
<scripting:component doc:name="Groovy - set up logging variables">
<scripting:script engine="Groovy"><![CDATA[sessionVars['correlationId'] = message.id;
message.correlationId = sessionVars['correlationId'];
sessionVars['nodiniteMessageTypeName'] = "MuleOrderBatch#1.0";
sessionVars['nodiniteLogText'] = "File Received";
sessionVars['nodiniteLogStatus'] = 0;
sessionVars['nodiniteEndPointDirection'] = 0;
sessionVars['nodiniteContextValues'] = [receivedFileName: flowVars['originalFilename']];
return payload;]]></scripting:script>
</scripting:component>
<logger message="Logging Correlation Id: #[sessionVars.correlationId]" level="INFO" doc:name="Logger"/>
<flow-ref name="int001.filemove.nodiniteloggingflow" doc:name="Log"/>
<choice doc:name="Choice">
<when expression="flowVars.originalFilename.endsWith('.json')">
<scripting:component doc:name="Update logging vars before looping">
<scripting:script engine="Groovy"><![CDATA[message.correlationId = sessionVars['correlationId'];
sessionVars['nodiniteMessageTypeName'] = "MuleOrderBatch#1.0";
sessionVars['nodiniteLogText'] = "Starting to debatch file";
sessionVars['nodiniteLogStatus'] = 0;
sessionVars['nodiniteEndPointDirection'] = 0;
sessionVars['nodiniteContextValues'] = [receivedFileName: flowVars['originalFilename']];
return payload;]]></scripting:script>
</scripting:component>
<flow-ref name="int001.filemove.nodiniteloggingflow" doc:name="Log Before Processing"/>
<json:object-to-json-transformer mimeType="application/json" doc:name="Object to JSON"/>
<json:json-to-object-transformer returnClass="java.util.List" doc:name="JSON to Object"/>
<foreach collection="#[payload]" doc:name="For Each">
<flow-ref name="int0int001.filemove.processSingleOrder" doc:name="processOrder"/>
</foreach>
</when>
<otherwise>
<scripting:component doc:name="Update logging variables">
<scripting:script engine="Groovy"><![CDATA[sessionVars['nodiniteMessageTypeName'] = "Unknown";
sessionVars['nodiniteLogText'] = "Message extension is wrong - should be JSON.";
sessionVars['nodiniteLogStatus'] = -1;
sessionVars['nodiniteEndPointDirection'] = 0;
sessionVars['nodiniteContextValues'] = [receivedFileName: "#[flowVars.originalFileName]"];
return payload;]]></scripting:script>
</scripting:component>
<flow-ref name="int001.filemove.nodiniteloggingflow" doc:name="Log error message"/>
<file:outbound-endpoint path="C:\Temp\mule\int001.filemove.transform\invalid\" outputPattern="#[flowVars.originalFilename]" responseTimeout="10000" doc:name="MoveToInvalidFolder"/>
</otherwise>
</choice>
</flow>
<sub-flow name="int0int001.filemove.processSingleOrder">
<set-variable variableName="currentOrderId" value="#[payload.OrderId]" doc:name="Variable"/>
<json:object-to-json-transformer doc:name="Object to JSON"/>
<scripting:component doc:name="Before processing">
<scripting:script engine="Groovy"><![CDATA[message.correlationId = sessionVars['correlationId'];
sessionVars['nodiniteMessageTypeName'] = "MuleOrder#1.0";
sessionVars['nodiniteLogText'] = "Starting to process order";
sessionVars['nodiniteLogStatus'] = 0;
sessionVars['nodiniteEndPointDirection'] = 0;
sessionVars['nodiniteContextValues'] = [receivedFileName: flowVars['originalFilename'], orderId: flowVars.currentOrderId.toString(), isGDPRData: "true"];
return payload;]]></scripting:script>
</scripting:component>
<flow-ref name="int001.filemove.nodiniteloggingflow" doc:name="Log single order"/>
<file:outbound-endpoint path="C:\Temp\mule\int001.filemove.transform\out" outputPattern="#[flowVars.currentOrderId].json" responseTimeout="10000" doc:name="File"/>
<scripting:component doc:name="After processing">
<scripting:script engine="Groovy"><![CDATA[message.correlationId = sessionVars['correlationId'];
sessionVars['nodiniteMessageTypeName'] = "MuleOrder#1.0";
sessionVars['nodiniteLogText'] = "Done processing order";
sessionVars['nodiniteLogStatus'] = 0;
sessionVars['nodiniteEndPointDirection'] = 1;
sessionVars['nodiniteContextValues'] = [receivedFileName: flowVars['originalFilename'], orderId: flowVars['currentOrderId'].toString(), outFullName: "C:\\Temp\\mule\\int001.filemove.transform\\out\\" + flowVars['currentOrderId'].toString() + ".json", outDirectory: "C:\\Temp\\mule\\int001.filemove.transform\\out\\", outFileName: flowVars['currentOrderId'].toString() + ".json"];
return payload;]]></scripting:script>
</scripting:component>
<flow-ref name="int001.filemove.nodiniteloggingflow" doc:name="Log done single order"/>
</sub-flow>
<sub-flow name="int001.filemove.nodiniteloggingflow">
<logger message="#[sessionVars.nodiniteLogText]" level="INFO" doc:name="Logger"/>
<set-variable variableName="payloadBeforeNodiniteLogEvent" value="#[payload]" doc:name="Variable"/>
<nodinite:create-log-event config-ref="Nodinite__Configuration" endPointName="int001.filemove.transformFlow" endpointUri="mule.developer" endPointDirection="#[sessionVars.nodiniteEndPointDirection]" originalMessageTypeName="#[sessionVars.nodiniteMessageTypeName]" logStatus="#[sessionVars.nodiniteLogStatus]" logText="#[sessionVars.nodiniteLogText]" payload="#[payload]" doc:name="Nodinite" processMachineName="roma.dev" processModuleName="int001.filemove.nodiniteloggingflow" processModuleType="Mule Flow" processName="int001.filemove.transformFlow">
<nodinite:context-properties ref="#[sessionVars.nodiniteContextValues]"/>
</nodinite:create-log-event>
<http:request config-ref="Nodinite_HTTP_Request_Configuration" path="logEvent/logEvent" method="POST" doc:name="HTTP">
<http:request-builder>
<http:header headerName="Content-Type" value="application/json"/>
</http:request-builder>
</http:request>
<set-payload value="#[flowVars.payloadBeforeNodiniteLogEvent]" doc:name="Set Payload"/>
</sub-flow>
</mule>