outrig

package module
v0.9.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 11, 2025 License: Apache-2.0 Imports: 19 Imported by: 13

README

Outrig

Outrig Logo

Outrig is an open-source observability tool for Go development. It provides real-time log search, goroutine monitoring, variable tracking, and runtime metrics to help you debug and understand your applications.

Outrig runs 100% locally. No data ever leaves your machine.

It is currently available for macOS and Linux.

Outrig in action

Go Reference Go Report Card Go Version

Features

  • Real-time Log Viewing: Stream and search logs from your Go application in real-time
  • Goroutine Monitoring: Track and inspect goroutines, including custom naming
  • Variable Watching: Monitor variables and counters in your application
  • Runtime Hooks: Execute hooks in your running application (coming soon)
  • Minimal Integration: Integrate into your Go application in seconds
  • Docker Integration: See Using Docker in the Outrig Docs

How It Works

Outrig consists of two main components that work together:

  1. SDK Client: A lightweight Go library that you import into your application. It collects logs, goroutine information, and other runtime data from your application and sends it to the Outrig Monitor. API Docs

  2. Outrig Monitor: A standalone server that receives data from your application, processes it, and provides a web-based dashboard for real-time monitoring and debugging.

Installation

For macOS:

brew install --cask outrigdev/outrig/outrig

This installs a system tray application. After installation, you'll need to launch the Outrig application from your Applications folder or Spotlight to start the server. Once you run the application the first time, the outrig CLI tool will be available in your path.

For Linux:

# Quick installation script (installs to ~/.local/bin)
curl -sf https://outrig.run/install.sh | sh

Alternatively, you can download .dmg, .deb, .rpm, or .tar.gz packages directly from our GitHub releases page.

For Nix users:

# Install using the flake
nix profile install github:outrigdev/outrig

For developers interested in building from source, see BUILD.md. If you've already cloned the repository, you can build and install with:

# Build from source and install to ~/.local/bin
task install

Usage

The simplest way to try Outrig is by running your main.go using the Outrig CLI:

outrig run main.go

The outrig run command takes all the same arguments as go run (as it is implemented as a thin wrapper around go run). Under the hood outrig run instruments your code to work with the Outrig monitor, giving you log searching, a full goroutine viewer, and runtime stats out of the box.

Integration using the SDK

You can also integrate Outrig by adding a single import to your Go application's main file:

// Add this import to your main Go file:
import _ "github.com/outrigdev/outrig/autoinit"

// That's it! Your app will appear in Outrig when run
Running the Outrig Monitor

macOS

The Outrig Monitor is managed through the system tray application. After installation, launch the Outrig app from your Applications folder or Spotlight. The monitor will start automatically and you'll see the Outrig icon in your system tray.

Linux

To start the Outrig Monitor, run the following command in your terminal:

outrig server

To stop the monitor, use Ctrl+C in the terminal where the monitor is running. Note that future versions will include systemd support to run the monitor as a background service.

To verify the monitor is running correctly, navigate to http://localhost:5005 and you should see the Outrig dashboard.

Key Features

Logs

Outrig captures and displays logs from your Go application in real-time out of the box by capturing stdout/stderr.

// Logs are automatically captured from stdout and stderr
fmt.Println("This will be captured by Outrig")
log.Printf("Standard Go logging is captured too")

Features:

  • Real-time log streaming
  • Instant type-ahead progressive searching
  • Advanced search and filtering capabilities (exact match, fuzzy search, regexp, tags, ANDs, and ORs)
  • Follow mode to automatically track latest logs
Watches

Easily monitor variables in your application. Outrig can display structures (JSON or %#v output) and numeric values (easy graphing and historical data viewing coming soon). Values are collected automatically every second (except for push-based watches).

// Basic watch using a function
outrig.NewWatch("counter").PollFunc(func() int {
    return myCounter
})

// Watch with mutex protection
var mu sync.Mutex
var counter int
outrig.NewWatch("sync-counter").PollSync(&mu, &counter)

// Watch an atomic value
var atomicCounter atomic.Int64
outrig.NewWatch("atomic-counter").PollAtomic(&atomicCounter)

// Push values directly from your code
pusher := outrig.NewWatch("requests").ForPush()
pusher.Push(42)
// Later...
pusher.Push(43)

// Chained configuration with tags and formatting
outrig.NewWatch("api-response").
    WithTags("api", "performance").
    AsJSON().
    PollFunc(func() interface{} {
        return app.GetAPIStats()
    })

// Use as a counter (incremental values)
outrig.NewWatch("request-count").
    WithTags("performance").
    AsCounter().
    PollFunc(getRequestCount)
Goroutine Monitoring

Outrig captures your goroutine stack traces every second for easy search/viewing. You can optionally name and tag your goroutines for easier inspecting.

When using the outrig run CLI, you can name any goroutine in your own module by using a special comment above the go keyword. This will override the system generated name for the goroutine in the outrig viewer.

//outrig name="worker-thread"
go func() {
	...
}()

Alternatively you can use the SDK to give your goroutines names and tags:

outrig.Go("worker-pool-1").WithTags("worker").Run(func() {
    // Goroutine code...
})
Runtime Stats

Outrig gathers runtime stats every second. Including:

  • Memory usage breakdown with visual charts
  • CPU usage monitoring
  • Goroutine count tracking
  • Heap memory allocation statistics
  • Garbage collection cycle monitoring
  • Process information display (PID, uptime, etc.)
  • Go runtime version and environment details

Architecture

The Outrig codebase is organized into three main components:

  1. Client SDK (outrig.go and pkg/): A lightweight Go library that integrates with your application. It collects logs, goroutine information, and other runtime data and sends it to the Outrig Monitor.

  2. Monitor (server/): A standalone Go server that receives data from your application, processes it, and exposes it via an RPC API. The monitor efficiently stores and indexes the data for quick searching and retrieval. It has a separate go.mod file so its dependencies don't pollute the SDK.

  3. Frontend (frontend/): A React TypeScript application that communicates with the monitor via WebSocket using RPC calls. It provides a user-friendly interface for monitoring and debugging your application in real-time. It is built and embedded into the Outrig Monitor.

Data Flow
  1. Your Go application imports the Outrig SDK and initializes it with the autoinit package or an explicit call to outrig.Init()
  2. The SDK collects logs, goroutine information, and other runtime data
  3. This data is sent to the Outrig Monitor via a local domain socket
  4. The monitor server processes and stores the data
  5. Go to http://localhost:5005 to view and interact with your data
Performance
  • Minimal overhead by design — When disconnected, the SDK enters standby mode, suspends collection, and performs only a brief periodic check for reconnection.
  • Disable in Production — A build flag (+no_outrig) can completely disable SDK at compile time
Security
  • No open ports — Your program doesn't expose extra HTTP servers or ports. It attempts to make a domain socket connection to the Outrig Monitor. If the domain socket is not found or is not active, the SDK will remain in standby mode
  • Secure by default — All connections stay on localhost (unless you explicitly configure it otherwise); no application data leaves your machine
Telemetry

To help understand how many people are using Outrig, help prioritize new features, and find/fix bugs we collect minimal anonymous telemetry from the Outrig Monitor. It can be disabled on the CLI by running outrig server --no-telemetry. Note that the SDK does not send any telemetry.

Development

For information on building from source, setting up a development environment, and contributing to Outrig, see BUILD.md.

Contributing

Please read CONTRIBUTING.md for details on our code of conduct and the process for submitting pull requests.

License

This project is licensed under the Apache 2.0 License - see the LICENSE file for details.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AppDone

func AppDone()

AppDone signals that the application is done This should be deferred in the program's main function

func DefaultConfig

func DefaultConfig() *config.Config

DefaultConfig returns the default configuration

func Disable

func Disable(disconnect bool)

Disable disables Outrig

func Enable

func Enable()

Enable enables Outrig

func Enabled

func Enabled() bool

func GetAppRunId

func GetAppRunId() string

GetAppRunId returns the unique identifier for the current application run

func Init

func Init(appName string, cfgParam *config.Config) (bool, error)

Init initializes Outrig, returns (enabled, error)

func Log added in v0.4.2

func Log(str string)

Log sends a simple string message to the Outrig logger

func Logf added in v0.4.2

func Logf(format string, args ...any)

Logf sends a formatted message to the Outrig logger

func MakeLogStream added in v0.5.0

func MakeLogStream(name string) io.Writer

MakeLogStream creates an io.Writer that sends written data as log lines to Outrig The name parameter specifies the source of the logs This log stream will never block your code for I/O. When Outrig is disabled, it discards the data after a simple atomic.Bool check (nanoseconds). When Outrig is enabled it uses a non-blocking write to a buffered channel.

func OrigStderr

func OrigStderr() *os.File

OrigStderr returns the original stderr stream that was captured during initialization

func OrigStdout

func OrigStdout() *os.File

OrigStdout returns the original stdout stream that was captured during initialization

func OutrigVersion added in v0.2.0

func OutrigVersion() string

semver

func Shutdown

func Shutdown()

Shutdown shuts down Outrig

Types

type Config

type Config = config.Config

Re-export ds.Config so callers can use "outrig.Config"

type GoRoutine added in v0.5.2

type GoRoutine struct {
	// contains filtered or unexported fields
}

func CurrentGR added in v0.5.2

func CurrentGR() *GoRoutine

CurrentGR returns a GoRoutine for the current goroutine. If the goroutine is already registered, it returns the existing declaration. Otherwise, it creates a new one and registers it.

func Go added in v0.5.2

func Go(name string) *GoRoutine

func SetGoRoutineName

func SetGoRoutineName(name string) *GoRoutine

SetGoRoutineName sets a name for the current goroutine

func (*GoRoutine) Run added in v0.5.2

func (g *GoRoutine) Run(fn func())

func (*GoRoutine) WithGroup added in v0.9.0

func (g *GoRoutine) WithGroup(group string) *GoRoutine

func (*GoRoutine) WithName added in v0.5.2

func (g *GoRoutine) WithName(name string) *GoRoutine

func (*GoRoutine) WithPkg added in v0.7.4

func (g *GoRoutine) WithPkg(pkg string) *GoRoutine

func (*GoRoutine) WithTags added in v0.5.2

func (g *GoRoutine) WithTags(tags ...string) *GoRoutine

func (*GoRoutine) WithoutRecover added in v0.5.2

func (g *GoRoutine) WithoutRecover() *GoRoutine

type Pusher added in v0.5.0

type Pusher struct {
	// contains filtered or unexported fields
}

func (*Pusher) Push added in v0.5.0

func (p *Pusher) Push(val any)

func (*Pusher) Unregister added in v0.5.0

func (p *Pusher) Unregister()

Unregister unregisters the pusher's watch from the watch collector

type Watch added in v0.5.0

type Watch struct {
	// contains filtered or unexported fields
}

func NewWatch added in v0.5.0

func NewWatch(name string) *Watch

func (*Watch) AsCounter added in v0.5.0

func (w *Watch) AsCounter() *Watch

func (*Watch) AsGoFmt added in v0.5.0

func (w *Watch) AsGoFmt() *Watch

func (*Watch) AsJSON added in v0.5.0

func (w *Watch) AsJSON() *Watch

func (*Watch) AsStringer added in v0.5.0

func (w *Watch) AsStringer() *Watch

func (*Watch) ForPush added in v0.5.0

func (w *Watch) ForPush() *Pusher

func (*Watch) PollAtomic added in v0.5.0

func (w *Watch) PollAtomic(val any) *Watch

PollAtomic sets up an atomic-based watch that reads values from atomic variables. This method is optimized for monitoring values that are updated using atomic operations.

The val parameter must be:

  • A non-nil pointer
  • A pointer to one of the following types:
  • sync/atomic package types (atomic.Bool, atomic.Int32, atomic.Int64, etc.)
  • Primitive types that support atomic operations (int32, int64, uint32, uint64, uintptr)
  • unsafe.Pointer

Example:

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

func (*Watch) PollFunc added in v0.5.0

func (w *Watch) PollFunc(fn any) *Watch

PollFunc sets up a function-based watch that periodically calls the provided function to retrieve its current value. The provided function must take no arguments and must return exactly one value (of any type).

Requirements for fn:

  • Non-nil function
  • Zero arguments
  • Exactly one return value

Example:

outrig.NewWatch("counter").PollFunc(func() int { return myCounter })

func (*Watch) PollSync added in v0.5.0

func (w *Watch) PollSync(lock sync.Locker, val any) *Watch

PollSync sets up a synchronization-based watch to monitor values protected by a mutex or other locker. It's intended for values updated concurrently, ensuring thread-safe access during polling.

Requirements:

  • lock: A non-nil sync.Locker (e.g., *sync.Mutex, *sync.RWMutex)
  • val: A non-nil pointer to the value being watched

Example:

var mu sync.Mutex
var counter int
outrig.NewWatch("sync-counter").PollSync(&mu, &counter)

func (*Watch) Static added in v0.7.0

func (w *Watch) Static(val any) *Watch

Static sets up a static watch that holds a constant value. The value is set once when the watch is created and never changes. This is useful for configuration values, URLs, or other constants that you want to monitor but don't need to poll.

Example:

outrig.NewWatch("game-url").Static("http://localhost:8080")

func (*Watch) Unregister added in v0.5.0

func (w *Watch) Unregister()

Unregister unregisters the watch from the watch collector

func (*Watch) WithTags added in v0.5.0

func (w *Watch) WithTags(tags ...string) *Watch

WithTags adds tags to the watch. Tags can be specified with or without a "#" prefix, which will be stripped if present. Empty, duplicate tags are removed, and all tags are trimmed.

Directories

Path Synopsis
Package autoinit provides automatic initialization of Outrig when imported.
Package autoinit provides automatic initialization of Outrig when imported.
pkg
collector/loginitex
Package loginitex provides external process-based log capture functionality
Package loginitex provides external process-based log capture functionality
ds
Package ds provides data structures, types, and constants used over the wire between the SDK and the server
Package ds provides data structures, types, and constants used over the wire between the SDK and the server
ioutrig
internal outrig package (used to get around circular references for internal outrig SDK calls)
internal outrig package (used to get around circular references for internal outrig SDK calls)
server module

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL