DecipherMiddleware

Logging within DataWeave Script

· 756 words · 4 minutes to read · ✍️ Pranav Davar
Categories: MuleSoft
Tags: DATAWEAVE Logging

With the release of Mule runtime 4.10 edge version, a new version of DataWeave, i.e. 2.10, is also released. One of the new features introduced in this release is DataWeave Logging Configuration. The feature facilitates the developer to have granular control over logging. This leads to faster development and debugging.

There might be a question: loggers are there; Why can’t we just put a log connector and log the variable or payload? What benefits do we get by logging within DataWeave? Where can I use this feature?

🔭 Let’s explore DataWeave examples of varying complexities.


👴🏼 Old way of debugging 🔗

Let’s consider simple Mule flow which outputs a hello world!, using a transform message.

--- config: theme: 'neutral' --- flowchart LR A["HTTP(s)"] --> B["Transform"]

DataWeave 🔗

Difficulty level | ⭐️⚝⚝⚝⚝

Print “hello world!”

%dw 2.0
output text/plain
---
"hello world!"

Output 🔗

"hello world!"

To analyze the value of payload in logs; the best way would be to add a logger after the transform message.

--- config: theme: 'neutral' --- flowchart LR A["HTTP(s)"] --> B["Transform"] --> C["Logger"]

Console Output 🔗

INFO  2025-10-07 23:50:57,309 [[MuleRuntime].uber.01: [dataweave-logs].dataweave-logsFlow.CPU_INTENSIVE @6198f22a] [processor: dataweave-logsFlow/processors/1; event: 5e704830-a3aa-11f0-bf2a-beeb1f9526e2] org.mule.runtime.core.internal.processor.LoggerMessageProcessor: hello world!

Pretty simple and easy 🫠… ❌ Not anymore, let’s increase the difficulty of the DataWeave script.

DataWeave 🔗

Difficulty level | ⭐️⭐️⚝⚝⚝

Factorial of a number

%dw 2.0
output application/json
---
(1 to payload.inp) reduce $ * $$

Input 🔗

{
    "inp": 5
}

Output 🔗

120

Considering the same flow, logger output will be as follows:

Console Output 🔗

INFO  2025-10-08 10:38:31,654 [[MuleRuntime].uber.07: [dataweave-logs].dataweave-logsFlow.CPU_INTENSIVE @1d9d48be] [processor: dataweave-logsFlow/processors/1; event: d569a3a0-a404-11f0-bf2a-beeb1f9526e2] org.mule.runtime.core.internal.processor.LoggerMessageProcessor: 120

Yuhhuuu!!! We did it, we got the factorial of the number printed in the logs, and the same has been sent to the calling API.

Now, if we need to know the value on each iteration of the reduce function, how are the values updated at every iteration? 🤔🤔🤔

If it were any other programming language, such as Java, Python, Go, etc. The print command would suffice for the needs. But in DataWeave, how do we do so?

We are still in the old way of debugging 😞. Let’s modify the code to get the desired outcome.

%dw 2.0
output application/json
---
(1 to payload.inp) reduce(it,acc=[1]) -> acc + acc[it-1]*it

Output 🔗

[
  1,
  1,
  2,
  6,
  24,
  120
]

Console Output 🔗

INFO  2025-10-08 11:12:32,863 [[MuleRuntime].uber.06: [dataweave-logs].dataweave-logsFlow.CPU_INTENSIVE @1bbba791] [processor: dataweave-logsFlow/processors/1; event: 961820f0-a409-11f0-bf2a-beeb1f9526e2] org.mule.runtime.core.internal.processor.LoggerMessageProcessor: [
  1,
  1,
  2,
  6,
  24,
  120
]

payload[-1] will be desired output sent to the client.

By doing this, we have significantly altered the dwl script and made it heavier, catering to the use case.

Simple task and complicated solution 😢😢😢

😎 New way of debugging 🔗

Starting with DataWeave 2.10, logging can be configured to control the verbosity of log messages using standard log levels: Debug, Info, Warn, and Error.

Let’s start with an example and remove the logger connector to make the flow simpler.

--- config: theme: 'neutral' --- flowchart LR A["HTTP(s)"] --> B["Transform"]

DataWeave 🔗

Difficulty level | ⭐️⚝⚝⚝⚝

Print “hello world!”

%dw 2.0
output text/plain
---
logInfo("hello world!")

Console Output 🔗

INFO  2025-10-08 19:27:55,625 [[MuleRuntime].uber.06: [dataweave-logs].dataweave-logsFlow.CPU_INTENSIVE @ae03158] [processor: ; event: ca3bdad0-a44e-11f0-bf2a-beeb1f9526e2] org.mule.weave.v2.model.service.DefaultLoggingService$: "hello world!"

Yeah!!! We did it…

Let’s look a little closer 🔎

Difference in packages used for logging 🔗

Logger Connector: org.mule.runtime.core.internal.processor.LoggerMessageProcessor

DataWeave: org.mule.weave.v2.model.service.DefaultLoggingService$

In above example, info level is used, for different log levels, different DataWeave logging functions are available.

DataWeave Logging Functions 🔗

logWith<T>(level: LogLevel, prefix: String, value: T): T
logDebug<T>(prefix: String = "", value: T): T
logInfo<T>(prefix: String = "", value: T): T
logWarn<T>(prefix: String = "", value: T): T
logError<T>(prefix: String = "", value: T): T
log<T>(prefix: String = "", value: T): T

More info on each function at official docs

Now let’s increase DataWeave complexity…

DataWeave 🔗

Difficulty level | ⭐️⭐️⚝⚝⚝

Factorial of a number

%dw 2.0
output application/json
---
(1 to payload.inp) reduce logInfo($ * $$)

Input 🔗

{
    "inp": 5
}

Output 🔗

120

Console Output 🔗

INFO  2025-10-08 20:16:32,412 [[MuleRuntime].uber.06: [dataweave-logs].dataweave-logsFlow.CPU_INTENSIVE @46ac5059] [processor: ; event: 94c8ac00-a455-11f0-bf2a-beeb1f9526e2] org.mule.weave.v2.model.service.DefaultLoggingService$: 2
INFO  2025-10-08 20:16:32,413 [[MuleRuntime].uber.06: [dataweave-logs].dataweave-logsFlow.CPU_INTENSIVE @46ac5059] [processor: ; event: 94c8ac00-a455-11f0-bf2a-beeb1f9526e2] org.mule.weave.v2.model.service.DefaultLoggingService$: 6
INFO  2025-10-08 20:16:32,413 [[MuleRuntime].uber.06: [dataweave-logs].dataweave-logsFlow.CPU_INTENSIVE @46ac5059] [processor: ; event: 94c8ac00-a455-11f0-bf2a-beeb1f9526e2] org.mule.weave.v2.model.service.DefaultLoggingService$: 24
INFO  2025-10-08 20:16:32,413 [[MuleRuntime].uber.06: [dataweave-logs].dataweave-logsFlow.CPU_INTENSIVE @46ac5059] [processor: ; event: 94c8ac00-a455-11f0-bf2a-beeb1f9526e2] org.mule.weave.v2.model.service.DefaultLoggingService$: 120

With the above log, we can infer that 4 times computation was performed, and the values were printed by the DataWeave logger. It helps in debugging script a lot.

The story doesn’t end here… Let’s make the script a little more complex… But Scope for this blog ends here… 😔😔😔

Part 2 🔗

Part 2 coming soon….


Please share your valuable feedback 😊😊😊…