Watches Viewer

The Watches tab lets you monitor custom values inside your running application—from simple counters to complex data structures. Once you integrate the Outrig SDK, you can watch internal maps update in real-time, see configuration values after parsing, track job queues, or monitor any application state you define. Values display as formatted JSON or Go's %#v output, updating every second so you can spot issues like memory leaks or stuck processes immediately. Unlike traditional metrics tools that only handle numbers, watches can display entire structs, maps, or any Go type, giving you a window into your application's actual runtime state. Search by name, tags, or even within the watched values themselves to quickly find what you're monitoring.

Getting Started

When you select the Watches tab for a running application, the viewer displays all active watches you've defined in your code. If no watches are found, you'll see helpful examples and documentation for adding watches to your application.

Core Features

Real-Time Value Updates

The Watches Viewer provides live monitoring with automatic updates:

  • Live Updates: Watch values update every second automatically (indicated by the green auto-refresh light)
  • Current Values: See the most recent value for each watch
  • Timestamp Indicators: Green dots show when each watch was last updated
  • Auto-Refresh Control: Toggle automatic updates on/off as needed

Watch Information Display

Each watch entry shows comprehensive information:

Header Information

  • Watch Name: The name you assigned when creating the watch
  • Data Type: The Go type of the watched value (e.g., int, string, struct)
  • Timestamp Dot: Green indicator showing when the value was last updated
  • Tags: Custom tags assigned to the watch (displayed with # prefix)

Value Display

  • Formatted Values: Values are displayed according to their format type
  • JSON Format: Pretty-printed JSON for structured data
  • Go Format: Go's native formatting for complex types
  • String Format: Simple string representation
  • Error Display: Clear error messages if watch collection fails

Additional Metadata

  • Length/Capacity: For slices, arrays, and maps, shows length and capacity information
  • Performance Warnings: Alerts for watches that take too long to collect (>2ms)
  • Copy Functionality: Click to copy any watch value to clipboard

Watch Types and Formats

The viewer supports different watch collection methods:

Push Watches

Values you manually push from your code:

pusher := outrig.NewWatch("user.profile").ForPush()
pusher.Push(user)

Poll Watches

Values collected automatically via functions:

outrig.NewWatch("cache.size").PollFunc(func() int {
    return len(myCache)
})

Atomic Watches

Direct monitoring of atomic values:

var counter atomic.Int64
outrig.NewWatch("requests.count").PollAtomic(&counter)

Synchronized Watches

Thread-safe value monitoring:

outrig.NewWatch("app.state").PollSync(&mu, &appState)

Watch Status Indicators

Watches display various status tags to help you understand their state:

  • Counter: Indicates this watch tracks incremental values
  • Invalid: Watch has an invalid configuration
  • Unregistered: Watch was removed but still appears in results
  • Watch Type: Shows the collection method (push, poll, atomic, etc.)

Powerful Search and Filtering

Text Search

The search bar provides instant filtering across all watch information:

# Search by watch name
cache

# Search by value content
"user123"

# Search by data type
$type:int

# Use field-specific searches
$name:counter
$val:error
$type:string

The search supports all of Outrig's advanced operators including regex, fuzzy matching, and exclusions.

Search Fields

Target specific parts of watch data:

  • $name - Watch name
  • $val - Watch value (the actual value content)
  • $type - Data type of the watch
  • No field specified - Searches across name, type, and value

Watch Pinning

Pin important watches to keep them at the top of the list:

  • Pin Button: Click the pin icon to pin/unpin watches
  • Persistent: Pinned watches are saved and restored between sessions
  • Visual Indicator: Pinned watches show a filled pin icon and "Pinned" label
  • Sorted Display: Pinned watches appear first, then unpinned watches alphabetically

Auto-Refresh and Manual Control

Auto-Refresh (Green Light)

  • Enabled by Default: Watches update automatically every second
  • Visual Indicator: Green light shows auto-refresh is active
  • Toggle Control: Click to enable/disable automatic updates
  • Smart Updates: Only updates when the application is running

Manual Refresh

  • Refresh Button: Force an immediate update of all watch values
  • Search Integration: Refresh respects current search filters
  • Error Recovery: Use manual refresh if auto-refresh encounters issues

Adding Watches to Your Application

Basic Watch Creation

All watches start with the NewWatch() function and support method chaining:

// Basic counter
outrig.NewWatch("request.count").PollFunc(getRequestCount)

// With tags and formatting
outrig.NewWatch("user.data").
    WithTags("user", "profile").
    AsJSON().
    PollFunc(getUserData)

Watch Configuration Options

Tags

Add searchable tags to organize watches:

outrig.NewWatch("metric").WithTags("performance", "critical")

Formatters

Control how values are displayed:

// Force JSON formatting
outrig.NewWatch("data").AsJSON().PollFunc(getData)

// Force Go formatting
outrig.NewWatch("status").AsGoFmt().PollFunc(getStatus)

// Use as counter (shows incremental changes)
outrig.NewWatch("requests").AsCounter().PollFunc(getCount)

Collection Methods

Push Values

For values you control when to update:

pusher := outrig.NewWatch("current.user").ForPush()
// Later in your code...
pusher.Push(currentUser)

Poll Functions

For values that should be collected automatically:

outrig.NewWatch("active.connections").PollFunc(func() int {
    return connectionPool.ActiveCount()
})

Atomic Values

For thread-safe atomic variables:

var requestCount atomic.Int64
outrig.NewWatch("requests.total").PollAtomic(&requestCount)

Synchronized Values

For values that need mutex protection:

var mu sync.Mutex
var appState AppState
outrig.NewWatch("app.state").PollSync(&mu, &appState)

Navigation and Controls

Keyboard Shortcuts

  • PageUp / PageDown - Scroll through watches list
  • / in search bar - Open search history
  • Enter in search bar - Save current search to history
  • Escape - Clear search or close search history

Display Controls

  • Auto-Refresh Toggle: Enable/disable automatic value updates
  • Manual Refresh: Force immediate update of all values
  • Pin Controls: Pin important watches to the top
  • Add Watch Button: Quick access to watch creation examples (when no search is active)

Understanding Watch Performance

Performance Indicators

  • Poll Duration: Watches that take >2ms to collect show a warning
  • Update Frequency: All watches are polled every second by default
  • Error States: Failed watch collections show clear error messages

Best Practices

  • Lightweight Functions: Keep poll functions fast and simple
  • Avoid Heavy Computation: Don't perform expensive operations in watch functions
  • Use Appropriate Types: Choose the right collection method for your data
  • Meaningful Names: Use descriptive names that make searches effective

Debugging Workflows

Monitoring Application State

  1. Create watches for key application variables
  2. Use tags to group related watches
  3. Pin critical watches to keep them visible
  4. Monitor for unexpected value changes

Performance Analysis

  1. Watch performance counters and metrics
  2. Use counter-type watches for rates and totals
  3. Monitor resource usage (memory, connections, etc.)
  4. Look for watches with long poll durations

Error Investigation

  1. Watch error counters and status variables
  2. Use search to find watches with error values
  3. Monitor state transitions during problem periods
  4. Track recovery metrics and health indicators

Development and Testing

  1. Watch test-specific variables during development
  2. Monitor feature flags and configuration values
  3. Track user session data and request patterns
  4. Use temporary watches for debugging specific issues

Tips for Effective Watch Usage

Organizing Watches

  • Use consistent naming conventions (e.g., module.metric)
  • Apply meaningful tags for grouping and searching
  • Pin the most important watches for quick access
  • Use descriptive names that explain what you're monitoring

Search Strategies

  • Start with broad terms like module names
  • Use field-specific searches to find specific data types
  • Combine searches: cache $type:int for integer cache metrics
  • Use exclusions to filter out noise: -error

Value Monitoring

  • Watch both current values and rates of change
  • Use counter watches for cumulative metrics
  • Monitor both success and error conditions
  • Track timing and performance metrics

The Watches Viewer provides deep insight into your application's runtime behavior, making it easy to monitor custom metrics, debug issues, and understand how your application performs under different conditions.