Help us shape the future of Go! Take the 2026 Go Developer Survey

doctor

package
v0.20.0 Latest Latest
Warning

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

Go to latest
Published: Oct 27, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package doctor is `weft doctor` (plan B5): it asks a running Studio what it is and how it is wired, and prints one line per check. Every line reads one field of GET /api/meta (Lines is the table) — beside it, for the runtime check, the two environment variables the doctor's own shell can see (WEFT_ENV, WEFT_STUDIO_URL), and for the discovery check the discovery file this shell reads (Target.Discovery, the command's resolver's). The doctor computes nothing Studio does not serve: a second source of truth would drift.

The logic lives here, apart from the command wiring (cmd/weft), so the command stays a thin client of it.

Index

Examples

Constants

View Source
const Timeout = 5 * time.Second

Timeout bounds the one request the doctor makes: an unreachable or hung Studio is a clear first line, never a hang.

Variables

View Source
var ErrUnhealthy = errors.New("doctor: a check failed")

ErrUnhealthy is Run's error when any check failed: the command exits 1.

View Source
var Lines = []Line{
	{"studio", []string{"status", "weft_version", "studio_version"}},
	{"token", []string{"status", "auth_required"}},
	{"discovery", []string{"discovery_file", "db.path", "local:discovery"}},
	{"db", []string{"db.kind", "db.path", "db.size"}},
	{"content", []string{"content.ingest", "content.latest.run_id", "content.latest.mark", "content.latest.note", "content.latest.fix", "content.error"}},
	{"data", []string{"content.latest.started", "content.latest.weft_version", "content.latest.service", "weft_version"}},
	{"otlp", []string{"ingest_open", "capabilities"}},
	{"ingest", []string{"ingest.dropped", "ingest.accepted", "ingest.refused", "ingest.last_error", "ingest.last_at"}},
	{"runtimes", []string{"runtimes", "capabilities", "capabilities_off", "env:WEFT_ENV", "env:WEFT_STUDIO_URL"}},
	{"panel", []string{"panel_version", "studio_version"}},
	{"manifest", []string{"has_manifest", "manifest_check.source", "manifest_check.agents", "manifest_check.checked", "manifest_check.stale", "manifest_check.error"}},
}

Lines is the doctor's line table, in print order.

Functions

func Run

func Run(ctx context.Context, w io.Writer, t Target, getenv func(string) string) error

Run checks the Studio t names (t.Token "" sends none) and prints one line per check to w. getenv reads the doctor's own environment (the runtime check reports WEFT_ENV and WEFT_STUDIO_URL as this shell sees them). It returns ErrUnhealthy when a check failed — Studio not reachable, the token refused, a stale panel bundle — and nil otherwise; warnings (no runtime connected, content stripped, a stale weft.json, a discovery file naming another Studio) do not fail it.

Example

ExampleRun checks a Studio with nothing connected to it: one line per check, each read from its /api/meta. No discovery file names it (an embedded Studio writes none): that line warns. With the playground on and no runtime connected the runtimes line warns, and its continuation lines name the variables this shell lacks (WEFT_ENV, WEFT_STUDIO_URL).

package main

import (
	"context"
	"fmt"
	"net/http/httptest"
	"os"
	"path/filepath"
	"strings"

	"github.com/weftgo/weft/internal/doctor"
	"github.com/weftgo/weft/studio"
)

func main() {
	dir, _ := os.MkdirTemp("", "doctor")
	defer func() { _ = os.RemoveAll(dir) }()
	srv := studio.New(studio.Open(filepath.Join(dir, "weft.db")), studio.Playground(true))
	defer func() { _ = srv.Close() }()
	ts := httptest.NewServer(srv.Handler())
	defer ts.Close()

	var out strings.Builder
	err := doctor.Run(context.Background(), &out, doctor.Target{URL: ts.URL}, func(string) string { return "" })
	for _, line := range strings.Split(strings.TrimSpace(out.String()), "\n") {
		if f := strings.Fields(line); !strings.HasPrefix(line, " ") {
			fmt.Println(f[0], f[1])
		} else if strings.Contains(line, "WEFT_ENV is unset") {
			fmt.Println("  names WEFT_ENV")
		}
	}
	fmt.Println("err:", err)
}
Output:
ok studio
ok token
warn discovery
ok db
ok content
ok data
ok otlp
ok ingest
warn runtimes
  names WEFT_ENV
ok panel
ok manifest
err: <nil>

Types

type Discovery added in v0.20.0

type Discovery struct {
	// Off is WEFT_DISCOVERY=off in this shell: no file is read.
	Off bool
	// Path is the trusted file found, "" when none.
	Path string
	// URL, DB and PID are what the file names.
	URL, DB string
	PID     int
}

Discovery is the discovery file the doctor's shell reads (the resolver's view of it, read with internal/discovery's trust rules).

type Line

type Line struct {
	Label  string
	Fields []string
}

Line is one check the doctor prints: its label and the /api/meta fields (or "env:NAME" for a variable of the doctor's own shell, "local:discovery" for the discovery file it reads, or "status" for the meta response itself) it reads.

type Target added in v0.20.0

type Target struct {
	// URL is the Studio's root URL.
	URL string
	// Token is the bearer to send, "" for none.
	Token string
	// Discovery is the discovery file this shell reads.
	Discovery Discovery
}

Target is the Studio the doctor checks, found by cmd/weft's one resolver (--url, WEFT_STUDIO_URL, the discovery file, the default address), which names the source on stderr itself: the doctor's own lines do not repeat it.

Jump to

Keyboard shortcuts

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