Skip to content

Logging in Workflows and Services

Overview

Logging in Martini lets you track workflow and service execution, capture business events, and diagnose issues in real-time. By adding logger functions to your workflows and services, you can monitor application behavior, validate data transformations, and maintain audit trails without external tools.

What You Will Learn

  • Add and place logger functions in workflows and services
  • Configure logger inputs and names
  • Choose logger functions and levels for common scenarios
  • Test, secure, and troubleshoot logging

When To Use This

Use logging when you need to:

  • Debug execution flow and trace runtime paths
  • Monitor business decisions and rule evaluations
  • Track data transformations and validation failures
  • Audit external integrations and API calls
  • Diagnose errors and production incidents — see Server Admin UI Logs to monitor logs

Prerequisites

Before adding logging to your workflows and services, ensure you have:

Adding Loggers to Workflows and Services

Workflows and services use the same logger functions but differ in how you add them to your canvas or editor. This section covers the methods for adding logger functions to both workflows and services in Martini Designer.

Logger Guidance

For help selecting the appropriate logger function and understanding log levels, see Logger Functions and Martini Log Levels.

Adding Loggers to Workflows

Method 1: Drag from Functions View

  1. Open the Functions view and look for the "Logger" category, or search for "Logger" to see available logging functions.
  2. Drag your desired logger function (e.g., info( message )) onto the Workflow Designer canvas.

Method 2: Quick Add via Edge (Content Assist)

  1. Drag an edge from any node and drop it onto a blank area of the Workflow Designer canvas.
  2. In the popup, type "Logger" to see available logger functions (prefixed with LoggerMethods).
  3. Double-click your chosen function or press to select it.

Expected result: The logger function appears as an Invoke Function Node displaying the logger function name, ready for property mapping and connection to other nodes.

Adding Loggers to Services

Method 1: Drag from Functions View

  1. Open the Functions view and look for the "Logger" category, or search for "Logger" to see available logging functions.
  2. Drag your desired logger function (e.g., info( message )) onto the Service Editor canvas.

Method 2: Add Button (Toolbar)

  1. Click the Add button on the Service Editor toolbar and select Function .
  2. Search for "Logger" to see all available logger functions.
  3. Select your desired log type and press to add it to your service.

Method 3: Quick Add (Keyboard Shortcut)

  1. Ensure the service editor is active by clicking the canvas.
  2. Press (period key) to trigger the content assist or press + to search for a function.
  3. Search for your desired logger function and double-click or press to add it.

Expected result: The logger function appears as a function step, ready for configuration and integration with your service logic.

Logger Input Properties

Once you've added a logger function to your workflow or service, configure its input properties to control what gets logged and how it appears in your log files.

Property Example Value Description
message "Processing user request for ID: ${userId}" The text content to log
loggerName "com.mycompany.userservice" Text identifier for the logger
throwable ${exceptionObject} The exception object to include in the log with stack trace

Testing Your Logger Implementation

After configuring your logger function input properties, verify that logging works correctly.

  1. Click the Run button from the Workflow Designer or Service Editor toolbar.
  2. Check the log output in the Console view.

Expected result: Your log message appears in the Console view with the correct log level, timestamp, and content. If your logger is in a Fork Node/Step, ensure the execution path reaches the logger node/step.

Logging Output

Logger functions write to both console output AND log files unless configured otherwise. For information about log file management and configuration, see Log Files in Martini.

Implementing Logging Strategies

Strategic placement of loggers throughout your workflows and services helps you trace execution flow, validate business logic, and diagnose issues efficiently. This section covers patterns for different logging scenarios.

Entry Point Logging

Add an INFO-level logger at the beginning of workflows and services to record when execution starts and capture initial context.

1
2
3
4
// Example invocations
info("Process started: ${processName} - RequestID: ${requestId}")

info(message: "User action: ${userId} performing ${action}", loggerName: "com.mycompany.service")

Entry point logging creates an audit trail of all executions and provides essential context for troubleshooting. Include request identifiers, user information, and business operation names to correlate related log entries.

Decision Point and Business Logic Logging

Add DEBUG-level loggers after condition checks, business rule evaluations, and calculations to track decision flow and verify logic correctness.

1
2
3
4
5
6
// Example invocations
debug("Condition evaluation: ${condition} = ${result}")

debug(message: "Business rule '${ruleName}' evaluated: ${result}", loggerName: "com.mycompany.rules")

debug(message: "Calculation '${calculationType}': ${formula} = ${result}")

Decision point logging helps you understand why workflows take specific paths and validates that business rules execute as expected. Use descriptive rule names and include both inputs and outputs for complete context.

Data Transformation Logging

Add DEBUG-level loggers before and after data transformations to track how data changes through your pipeline. Use WARN-level loggers for validation failures.

1
2
3
4
// Example invocations
debug("Data transformed: Input=${inputData} Output=${transformedData}")

warn(message: "Validation failed for ${fieldName}: ${validationMessage}", loggerName: "com.mycompany.validation")

Data transformation logging reveals unexpected data changes, helps diagnose transformation errors, and validates that data mappings work correctly. Include both original and transformed values to quickly spot issues.

Integration and External Service Logging

Add INFO-level loggers around external service calls and API requests to track integration health and diagnose connection issues. Use DEBUG-level loggers for detailed database operation information (row counts, payloads, query timing) that is useful for troubleshooting but too verbose for production INFO logs.

1
2
3
4
5
6
// Example invocations
info("External service call: ${serviceName} - Request: ${request}")
info(message: "External service response: ${serviceName} - Response: ${response}", loggerName: "com.mycompany.integration")

// Database operation example
debug(message: "Database operation: ${operation} on table ${tableName} - Rows affected: ${rowCount}")

Integration logging provides visibility into external dependencies, helps diagnose timeout or connectivity issues, and maintains an audit trail of data exchanges. Include service names, operation types, and response details for complete traceability.

Completion Logging

Add INFO-level loggers at workflow and service completion points to record successful execution and capture performance metrics.

1
2
3
// Example invocations
info("Process completed: ${processName} - Duration: ${duration}ms")
info(message: "Order processed successfully: OrderID=${orderId} - Total=${orderTotal}", loggerName: "com.mycompany.orders")

Completion logging confirms successful execution, provides performance baselines, and helps correlate entry and exit points for the same execution. Include duration metrics and business outcomes to measure operational success.

Error Logging with Exceptions

Add ERROR-level loggers in exception handlers and error paths, using the throwable property to capture complete stack traces and exception details.

1
2
3
4
// Example invocations (include throwable for stack traces)
error(message: "Failed to process customer record - CustomerID: ${customerId}", throwable: exception)

error(message: "Database connection failed - Host: ${dbHost}, Port: ${dbPort}", throwable: connectionException)

Error logging with exceptions provides complete diagnostic information including stack traces, root causes, and contextual data. Always include relevant identifiers (customer IDs, transaction IDs) to help trace the error back to specific business operations.

Mapping Exceptions in Workflows

To include exception details in error logs from workflows, configure a Try Catch Node connected to an error logger function:

  1. Add a Try/Catch node to your workflow where you want to handle errors.
  2. Add an error logger function
  3. Connect the Catch edge handle of the Try/Catch node to the error logger function node.

Your workflow structure should look like this:

1
[ ... ] ---> [ Try/Catch Node ] ---Catch---> [ Error Logger Function Node ] ---> [ ... ]

Configuring the Exception Mapping:

  1. Click the expand button on the error logger function node to open the Data Mapper Panel.
  2. On the left side, locate the $exception model in the available properties.
  3. Expand the $exception model to reveal the realException property.
  4. Map $exception.realException to the throwable input property of the error logger function.

Map the Real Exception

Always map $exception.realException to the throwable property, not $exception itself. The realException property contains the actual underlying java.lang.Throwable object, while $exception is a wrapper model.

Example mapping for error( message, throwable ):

1
2
3
4
| Available Properties | Mapping Lines | Error Logger Input Properties |
|----------------------|---------------|-------------------------------|
| $exception           |               | message                       |
| +--realException     | ------------> | throwable                     |

Mapping Exceptions in Services

To include exception details in error logs from services, configure a Block Step with a catch block containing an error logger function:

  1. Add a Block step to your service and set its type to either Try Catch or Try Catch Finally.
  2. Add an error logger function inside the Catch block step.

Your service structure should look like this:

1
2
3
4
5
6
...
Block Step
+-- Try 
+-- Catch 
    +-- Error Logger Function Step 
...

Configuring the Exception Mapping:

  1. Double-click the error logger function step to open the Data Mapper Panel.
  2. On the left side, locate the $gloopException model in the available properties.
  3. Expand the $gloopException model to reveal the realException property.
  4. Map $gloopException.realException to the throwable input property of the error logger function.

Map the Real Exception

Always map $gloopException.realException to the throwable property, not $gloopException itself. The realException property contains the actual underlying java.lang.Throwable object, while $gloopException is a wrapper model.

Example mapping for error( message, throwable ):

1
2
3
4
| Available Properties | Mapping Lines | Error Logger Input Properties |
|----------------------|---------------|-------------------------------|
| $gloopException      |               | message                       |
| +--realException     | ------------> | throwable                     |

Writing Meaningful Log Messages

Effective log messages provide actionable context that helps you quickly diagnose issues and understand system behavior. Structure your messages to include operation type, relevant identifiers, and state information.

Poor Message: Vague without context

1
"Database error"

Good Message: Specific with actionable context

1
"Failed to insert customer record - CustomerID: ${customerId}, Table: customers, Error: ${ex.message}"

Avoid vague messages such as "Error occurred" or "Processing data" that provide little debugging value.

Structured Logging

Use structured logging formats (for example, JSON) to enable automated analysis and easier ingestion by log management tools. See Fish Tagging for structured logging patterns and field tagging.

Using Custom Logger Names

Custom logger names help organize logs by component, module, or business domain, making it easier to filter and analyze specific areas of your application.

Functions that don't accept a loggerName use the default logger Martini. For component-level filtering or separate level controls, set loggerName to a meaningful, stable name:

1
2
3
4
5
// Reverse-domain (recommended for multi-team/org)
loggerName: "com.mycompany.orders.processing"

// Component-based (shorter; good for single apps)
loggerName: "orders.processing"

After defining custom logger names, configure them in your Martini log configuration to control log levels and output formats independently for each component. See Martini Log Files for configuration details.

Security Considerations for Logging

Logging can inadvertently expose sensitive data if not configured carefully. Follow these security practices to protect user privacy and comply with data regulations.

Data to Never Log:

  • Passwords, API keys, authentication tokens, or security credentials
  • Credit card numbers, CVV codes, or banking information
  • Personal identification numbers
  • Encryption keys or salts

Safe Logging Practices:

Use generic identifiers instead of sensitive data:

1
2
3
4
5
// Safe: Uses non-sensitive identifier
"User login attempt: userId=${userId}"

// Unsafe: Logs password
"Login: username=${username}, password=${password}"

Sanitize user input before logging to prevent log injection attacks where malicious users insert fake log entries. Consider data retention policies and compliance requirements that may restrict what you can log and how long you can retain logs.

Troubleshooting

Common logging issues in workflows and services often relate to execution flow, property mapping, or configuration problems.

Problem Detection Cause Fix Context
Workflow logger not executing Expected error message not displaying in logs Node not connected properly or Fork Node Condition not met Connect logger node to workflow execution path Workflows
Service logger step skipped Expected error message not displaying in logs Step condition not met or Step disabled Check step execution conditions and logic flow Services
Missing workflow context in logs Generic log messages without workflow data Properties not mapped correctly Map workflow properties to logger message parameter Workflows
Service variables not accessible Logger shows undefined or null values Variable scope or timing issues Ensure variables are initialized before logger step Services

Helpful Resources