VOOZH about

URL: https://deepwiki.com/hypervel/telescope/2.3.7-command-watcher

⇱ Command Watcher | hypervel/telescope | DeepWiki


Loading...
Last indexed: 7 February 2026 (146f77)
Menu

Command Watcher

Purpose and Scope

The Command Watcher monitors console command execution in Hyperf applications, capturing command names, exit codes, arguments, and options for debugging and auditing purposes. This page documents the CommandWatcher class implementation, its registration with the event system, data capture mechanisms, and configuration options.

For monitoring scheduled tasks that run commands, see Schedule Watcher. For the base watcher pattern that all watchers implement, see Watcher Overview and Base Pattern.

Overview

The CommandWatcher is one of five Infrastructure Watchers that monitor application execution contexts. It operates by listening to the AfterExecuteCommand event dispatched by Hyperf's command system after each console command completes. The watcher extracts command metadata and submits it to the Telescope core for storage and later analysis.

Unlike most watchers that track operations during execution, the Command Watcher specifically records information after command completion, ensuring it captures the final exit code and has access to the complete execution context.

Sources: src/Watchers/CommandWatcher.php1-56

Class Structure and Dependencies


The CommandWatcher extends the abstract Watcher base class, inheriting the options array populated from configuration. It depends on three key collaborators: Hyperf's EventDispatcherInterface for event registration, the AfterExecuteCommand event for command execution notifications, and the Telescope facade for entry recording.

Sources: src/Watchers/CommandWatcher.php1-56

Registration and Event Binding

The watcher registers during system bootstrap via the register() method, which is invoked by the TelescopeServiceProvider when initializing all enabled watchers.


The registration process src/Watchers/CommandWatcher.php19-23 retrieves the PSR-14 EventDispatcherInterface from the container and registers the recordCommand() method as a listener for the AfterExecuteCommand event class. This creates a binding that will invoke the watcher every time any console command completes execution.

Sources: src/Watchers/CommandWatcher.php16-23

Command Recording Lifecycle

When a console command executes, the following sequence occurs:


The recording process src/Watchers/CommandWatcher.php28-41 follows these steps:

  1. Event Reception: The recordCommand() method receives an AfterExecuteCommand event containing the executed Command instance
  2. Recording Check: Calls Telescope::isRecording() to verify recording is enabled for the current context
  3. Ignore Filter: Calls shouldIgnore() to check if the command name matches the ignore list
  4. Data Extraction: Uses closure binding to access protected command properties (exitCode, input)
  5. Entry Creation: Constructs an IncomingEntry with command metadata
  6. Entry Recording: Submits the entry to Telescope::recordCommand() for queueing and eventual storage

Sources: src/Watchers/CommandWatcher.php25-41

Data Capture Structure

The Command Watcher captures four fields of command execution data:

FieldTypeDescriptionSource
commandstringThe command name (e.g., migrate, cache:clear)Command::getName()
exit_codeintThe exit status code (0 for success, non-zero for errors)Command::$exitCode (protected)
argumentsarrayPositional arguments passed to the commandInputInterface::getArguments()
optionsarrayNamed options/flags passed to the commandInputInterface::getOptions()

Accessing Protected Properties

The watcher uses a sophisticated technique to access protected properties of the Command instance src/Watchers/CommandWatcher.php37-39:


This pattern creates a closure that accesses $this->exitCode and $this->input, then binds the closure to the $command object using call(). This temporarily changes the closure's $this context to the command instance, allowing access to its protected properties without reflection or making them public.

Entry Type Classification

Commands are recorded with entry type EntryType::COMMAND and stored in the telescope_entries table with JSON-encoded content containing all four captured fields.

Sources: src/Watchers/CommandWatcher.php35-40

Ignore List Configuration

The Command Watcher implements filtering to prevent recording of specific commands that would create noise or cause recursion issues.


Default Ignored Commands

The watcher automatically ignores two commands src/Watchers/CommandWatcher.php48-54:

  • schedule:run: The Hyperf command scheduler's execution command
  • crontab:run: The crontab execution command

These are ignored to prevent excessive entries from scheduled task runners. Individual scheduled tasks are captured by the Schedule Watcher instead.

Configuration Options

The ignore list is configurable via config/telescope.php:


User-defined ignores from $this->options['ignore'] are merged with the default ignores src/Watchers/CommandWatcher.php48-54 This allows applications to exclude commands that are:

  • High-frequency maintenance commands
  • Internal tooling that doesn't need monitoring
  • Commands that trigger recursive Telescope operations

Sources: src/Watchers/CommandWatcher.php43-55

Entry Storage and Retrieval

Command entries follow Telescope's standard storage pipeline:


After recording, command entries:

  1. Are queued in the context-scoped ENTRIES_QUEUE
  2. Undergo batch filtering via configured filterBatchUsing callbacks
  3. Are persisted to the telescope_entries table with type command
  4. Can be retrieved via the Telescope UI at /telescope/commands
  5. Are serialized to JSON via EntryResult for API responses

The EntryResult class src/EntryResult.php1-80 provides JSON serialization of stored entries, including the command content fields captured by the watcher.

Sources: src/Watchers/CommandWatcher.php35-40 src/EntryResult.php1-80

Integration with Hyperf Event System

The Command Watcher leverages Hyperf's PSR-14 event system for loose coupling with the command execution infrastructure:


This event-driven architecture provides several benefits:

  • Non-invasive: Command execution code doesn't need to know about Telescope
  • Configurable: The watcher can be enabled/disabled without changing command code
  • Extensible: Multiple listeners can observe command execution events
  • Framework-aligned: Uses Hyperf's standard event dispatching mechanism

The AfterExecuteCommand event is dispatched by Hyperf's command kernel after any command completes, providing a consistent interception point for all console operations.

Sources: src/Watchers/CommandWatcher.php19-23

Performance Considerations

The Command Watcher has minimal performance impact:

  • Post-execution timing: Recording occurs after command completion, not during execution
  • Selective recording: The ignore list prevents recording of high-frequency commands
  • Context-aware: Respects the SHOULD_RECORD context flag for conditional monitoring
  • Deferred storage: Entries are queued and stored asynchronously after command completion

For long-running commands, the watcher adds negligible overhead since data extraction happens once at completion rather than continuously during execution.

Sources: src/Watchers/CommandWatcher.php28-41