Flow Studio
Emitting Custom Logs
Executors emit custom logs via ctx.Observability.Logger. Use structured logging patterns — pass data as named arguments, not string concatenation. Entries appear in the Observer Panel Logs tab and are shipped to Loki.
Basic Usage
public override async Task<NodeExecutionResult> ExecuteAsync(
NodeExecutionContext ctx, CancellationToken ct)
{
var logger = ctx.Observability.Logger;
logger.LogInformation("Processing payment for order {OrderId}, amount {Amount}",
orderId, amount);
try
{
var result = await _paymentService.ProcessAsync(orderId, amount, ct);
logger.LogInformation("Payment processed successfully. TransactionId: {TxId}",
result.TransactionId);
return NodeExecutionResult.Success(result);
}
catch (PaymentDeclinedException ex)
{
logger.LogWarning("Payment declined for order {OrderId}: {Reason}",
orderId, ex.Reason);
return NodeExecutionResult.Fail("Payment declined: " + ex.Reason);
}
catch (Exception ex)
{
logger.LogError(ex, "Unexpected error processing payment for order {OrderId}", orderId);
throw; // Let BaseNodeExecutor handle retry logic
}
}
Do and Don't
| Do | Don't |
|---|---|
logger.LogInformation("Order {Id}", orderId) | logger.LogInformation($"Order {orderId}") (string interpolation — loses structure) |
| Log milestones and key values | Log every loop iteration at Info (use Debug/Trace) |
Log exceptions with LogError(ex, ...) | Log exception.Message only — log the full exception object |
| Use ctx.Observability.Logger | Inject ILogger<T> directly into the executor constructor |
| Redact PII before logging | Log raw email addresses, phone numbers, or payment details |
Structured Fields Are Automatically Included
// When you call:
logger.LogInformation("Payment processed. TxId: {TxId}", txId);
// The resulting Loki entry contains:
{
"message" : "Payment processed. TxId: ABC123",
"TxId" : "ABC123", // ← named argument becomes a field
"nodeId" : "node-payment", // ← added by INodeLogger
"executionId": "exec-abc-123", // ← added by INodeLogger
"tenantId" : "tenant-001", // ← added by INodeLogger
"traceId" : "3d7f..." // ← added by INodeLogger
}
PII in logs: Do not log customer names, email addresses, phone numbers, national ID numbers, or payment card details. Use reference IDs (orderId, customerId) in log messages. If you need PII for debugging, use the encrypted audit log API instead.