Skip to main content

Traceflow

Traceflow is a unified logging system that provides contextual logging across workflows, activities, and console commands. It automatically routes messages to the appropriate target based on the execution context.

Overview

Traceflow allows you to log messages using a single API (traceflow()) that automatically adapts to different execution contexts:
  • Workflows: Messages are stored in the database as traceflow_logs
  • Activities: Messages are stored in the database and linked to the parent workflow
  • Console Commands: Messages are displayed in the terminal with progress bar integration
  • Default: Messages are written to Laravel’s log files

Basic Usage

Use the traceflow() helper function to log messages:
traceflow()->info('Processing started');
traceflow()->success('Operation completed successfully');
traceflow()->warn('Warning: Resource limit approaching');
traceflow()->error('Error occurred', $exception);

Available Methods

info(string $message, ?array $context = null)

Log an informational message:
traceflow()->info('Starting import process');
traceflow()->info('Processing batch', [
    'batch_size' => 100,
    'resource_type' => 'orders',
]);

success(string $message, ?array $context = null)

Log a success message:
traceflow()->success('Import completed successfully');
traceflow()->success('Order processed', ['order_id' => $order->id]);

warn(string $message, ?array $context = null)

Log a warning message:
traceflow()->warn('Rate limit approaching');
traceflow()->warn('Unusual data detected', ['data' => $unusualData]);

error(string $message, ?Throwable $exception = null)

Log an error message. Optionally include an exception:
try {
    // Some operation
} catch (Exception $e) {
    traceflow()->error('Failed to process order', $e);
}

throw(string $message, Throwable $exception)

Log an error and re-throw the exception:
try {
    // Some operation
} catch (Exception $e) {
    traceflow()->throw('Critical error occurred', $e);
    // Exception is re-thrown after logging
}

raw(mixed $message)

Log raw data without formatting:
traceflow()->raw(['key' => 'value', 'data' => $complexObject]);

incrementProcessedCount(int $amount = 1)

Increment the processed count for progress tracking:
foreach ($items as $item) {
    processItem($item);
    traceflow()->incrementProcessedCount();
}

incrementFailureCount()

Increment the failure count for tracking:
try {
    processItem($item);
    traceflow()->incrementProcessedCount();
} catch (Exception $e) {
    traceflow()->incrementFailureCount();
    traceflow()->error('Failed to process item', $e);
}

Targets

Traceflow automatically routes messages to different targets based on the execution context:

WorkflowTarget

When used in workflows, messages are stored in the traceflow_logs table:
class ImportDataWorkflow extends Workflow
{
    public function execute()
    {
        traceflow()->info('Starting import'); // Stored in database
        // ...
    }
}

ActivityTarget

When used in activities, messages are stored in the database and linked to the parent workflow:
class ProcessOrderActivity extends Activity
{
    public function execute(Order $order)
    {
        traceflow()->info('Processing order'); // Stored with activity context
        // ...
    }
}

CommandTarget

When used in console commands, messages are displayed in the terminal:
class ImportCommand extends BaseCommand
{
    public function handle()
    {
        $this->setTotalCount(100);
        
        foreach ($items as $item) {
            traceflow()->info('Processing item'); // Shown in terminal
            traceflow()->incrementProcessedCount(); // Advances progress bar
        }
    }
}
Note: In commands with active progress bars, info() messages are displayed as hints below the progress bar to avoid creating new lines.

LogTarget

When no specific target is set, messages are written to Laravel’s log files:
// Used as fallback when no workflow/activity/command context exists
traceflow()->info('General log message'); // Written to storage/logs/laravel.log

Usage Examples

In Workflows

class ImportOrdersWorkflow extends Workflow
{
    public function execute()
    {
        traceflow()->info('Starting order import');
        $this->setTotalCount(Order::count());
        
        Order::chunk(100, function ($orders) {
            foreach ($orders as $order) {
                yield ActivityStub::make(ProcessOrderActivity::class, $order);
                $this->incrementProgress();
            }
        });
        
        traceflow()->success('Import completed');
    }
}

In Activities

class ProcessOrderActivity extends Activity
{
    public function execute(Order $order)
    {
        traceflow()->info('Processing order', ['order_id' => $order->id]);
        
        try {
            $this->processOrder($order);
            traceflow()->incrementProcessedCount();
            traceflow()->success('Order processed successfully');
        } catch (Exception $e) {
            traceflow()->incrementFailureCount();
            traceflow()->error('Failed to process order', $e);
            throw $e;
        }
    }
}

In Console Commands

class ImportCommand extends BaseCommand
{
    public function handle()
    {
        $items = Item::all();
        $this->setTotalCount($items->count(), 'Importing items...');
        
        foreach ($items as $item) {
            traceflow()->info("Processing item: {$item->name}");
            
            try {
                $this->importItem($item);
                traceflow()->incrementProcessedCount();
            } catch (Exception $e) {
                traceflow()->incrementFailureCount();
                traceflow()->error("Failed to import item: {$item->name}", $e);
            }
        }
        
        traceflow()->success('Import completed');
    }
}

Context Data

All methods accept optional context data that is stored with the log entry:
traceflow()->info('Processing order', [
    'order_id' => $order->id,
    'customer_id' => $order->customer_id,
    'amount' => $order->total,
    'timestamp' => now(),
]);
In workflows and activities, this context is stored in the traceflow_logs table and can be viewed in the workflow detail page.

Progress Tracking

Traceflow integrates with progress tracking in workflows and commands:
  • Workflows: incrementProcessedCount() updates the workflow’s processed_count
  • Activities: incrementProcessedCount() updates the parent workflow’s processed_count
  • Commands: incrementProcessedCount() advances the progress bar (if active)

Best Practices

  1. Use descriptive messages: Include relevant information in your log messages
  2. Include context: Pass context data for better debugging
  3. Track progress: Use incrementProcessedCount() for long-running operations
  4. Handle errors: Always log errors with exceptions for full stack traces
  5. Use appropriate levels: Use info() for general messages, warn() for warnings, error() for errors

Configuration

The default target can be configured in config/core.php:
'traceflow' => [
    'default_target' => \Inly\Core\Services\Traceflow\Targets\LogTarget::class,
],