observability

package module
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Jun 25, 2026 License: MIT Imports: 15 Imported by: 0

README

togo

togo-framework/observability

marketplace pkg.go.dev MIT

App-internal observability for togo — request inspector, error tracking, log capture, health checks & metrics.

Install

togo install togo-framework/observability

A lightweight, app-internal Telescope / Pulse for togo: see every request, group your errors, capture structured logs, expose health endpoints, and read latency/error metrics — all from inside your app, no external service required.

What you get

  • Request inspector — middleware records method, path, status, duration and IP for every request.
  • Error trackingCaptureError groups exceptions by fingerprint into Issues (count, first/last seen); a panic-recovery middleware turns crashes into captured errors + a clean 500.
  • Log capture — a slog.Handler records structured logs, queryable by level.
  • Health — register readiness checks; serve /healthz (liveness) and /readyz (readiness → 503 when degraded).
  • Metrics — request count, error rate, p50/p95 latency, and slowest endpoints.

Everything lives in bounded in-memory ring buffers (with a seam for a durable store) and is exposed over a Go API + REST at /api/observability/*.

Usage

o, _ := observability.FromKernel(k)

// Inspect requests + capture panics.
router.Use(o.Middleware)
router.Use(o.Recover)

// Capture structured logs.
slog.SetDefault(slog.New(o.SlogHandler(slog.LevelInfo)))

// Capture handled errors with context.
if err := charge(ctx, order); err != nil {
    o.CaptureError(ctx, err, map[string]any{"order_id": order.ID})
}

// Readiness checks for your dependencies.
o.RegisterCheck("db",    func(ctx context.Context) error { return db.PingContext(ctx) })
o.RegisterCheck("cache", func(ctx context.Context) error { return cache.Ping(ctx) })

Read it back:

o.Requests()        // recent requests
o.Issues()          // error groups; o.Events(fingerprint) for the events
o.Logs("ERROR")     // captured logs, filtered by level
o.Health(ctx)       // ok | degraded + per-check status
o.Metrics()         // requests, error_rate, p50/p95, slowest endpoints

REST

Method Path Returns
GET /api/observability/requests recent requests
GET /api/observability/issues error groups
GET /api/observability/issues/{fp}/events events for an issue
GET /api/observability/logs?level=ERROR captured logs
GET /api/observability/metrics metrics summary
GET /api/observability/health health detail
GET /healthz · /readyz liveness · readiness (503 if degraded)

Configuration

No required env. Stores default to ~1000-entry ring buffers; replace the store seam with a durable backend for long retention or multi-instance aggregation.


Premium sponsors

ID8 Media  ·  One Studio

Support togo — become a sponsor.

Documentation

Overview

Package observability gives a togo app built-in request inspection, error tracking, structured-log capture, health checks and metrics — a lightweight, app-internal Telescope/Pulse for Go.

Everything is recorded into bounded in-memory ring buffers (with a pluggable seam for a durable store) and exposed over a Go API plus REST at /api/observability/* (+ /healthz, /readyz).

o, _ := observability.FromKernel(k)
router.Use(o.Middleware)              // record every request
router.Use(o.Recover)                 // capture panics as errors
slog.SetDefault(slog.New(o.SlogHandler(slog.LevelInfo)))
o.RegisterCheck("db", func(ctx context.Context) error { return db.PingContext(ctx) })

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type EndpointStat

type EndpointStat struct {
	Path  string  `json:"path"`
	AvgMS float64 `json:"avg_ms"`
	Count int     `json:"count"`
}

EndpointStat is per-path aggregate latency.

type ErrorEvent

type ErrorEvent struct {
	Fingerprint string         `json:"fingerprint"`
	Message     string         `json:"message"`
	Context     map[string]any `json:"context,omitempty"`
	Time        time.Time      `json:"time"`
}

ErrorEvent is a single captured error.

type HealthResult

type HealthResult struct {
	Status string            `json:"status"` // ok | degraded
	Checks map[string]string `json:"checks"`
}

HealthResult is the outcome of running the readiness checks.

type Issue

type Issue struct {
	Fingerprint string    `json:"fingerprint"`
	Title       string    `json:"title"`
	Level       string    `json:"level"`
	Count       int       `json:"count"`
	FirstSeen   time.Time `json:"first_seen"`
	LastSeen    time.Time `json:"last_seen"`
}

Issue is a group of error events sharing a fingerprint.

type LogRecord

type LogRecord struct {
	Level   string         `json:"level"`
	Message string         `json:"message"`
	Attrs   map[string]any `json:"attrs,omitempty"`
	Time    time.Time      `json:"time"`
}

LogRecord is one captured structured log line.

type Metrics

type Metrics struct {
	Requests  int            `json:"requests"`
	ErrorRate float64        `json:"error_rate"`
	P50MS     float64        `json:"p50_ms"`
	P95MS     float64        `json:"p95_ms"`
	Slowest   []EndpointStat `json:"slowest"`
}

Metrics is a rolling summary derived from observed requests.

type RequestRecord

type RequestRecord struct {
	ID         string    `json:"id"`
	Method     string    `json:"method"`
	Path       string    `json:"path"`
	Status     int       `json:"status"`
	DurationMS float64   `json:"duration_ms"`
	IP         string    `json:"ip"`
	Time       time.Time `json:"time"`
}

RequestRecord is one observed HTTP request.

type Service

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

Service is the observability runtime stored on the kernel (k.Get("observability")).

func FromKernel

func FromKernel(k *togo.Kernel) (*Service, bool)

FromKernel returns the observability Service.

func (*Service) CaptureError

func (s *Service) CaptureError(_ context.Context, err error, ctxData map[string]any)

CaptureError records an error, grouping by fingerprint into an Issue.

func (*Service) Events

func (s *Service) Events(fingerprint string) []ErrorEvent

Events returns the error events for an issue fingerprint.

func (*Service) Health

func (s *Service) Health(ctx context.Context) HealthResult

Health runs all registered checks; status is "degraded" if any fail.

func (*Service) Issues

func (s *Service) Issues() []Issue

Issues returns the error groups.

func (*Service) Logs

func (s *Service) Logs(level string) []LogRecord

Logs returns captured logs, optionally filtered by level (e.g. "ERROR").

func (*Service) Metrics

func (s *Service) Metrics() Metrics

Metrics computes request count, error rate, p50/p95 latency and slowest paths.

func (*Service) Middleware

func (s *Service) Middleware(next http.Handler) http.Handler

Middleware records every request (method, path, status, duration, IP).

func (*Service) Recover

func (s *Service) Recover(next http.Handler) http.Handler

Recover captures panics as errors and returns a 500.

func (*Service) RegisterCheck

func (s *Service) RegisterCheck(name string, fn func(ctx context.Context) error)

RegisterCheck adds a named readiness check.

func (*Service) Requests

func (s *Service) Requests() []RequestRecord

Requests returns recent observed requests (most recent last).

func (*Service) SlogHandler

func (s *Service) SlogHandler(level slog.Level) slog.Handler

SlogHandler returns a slog.Handler that captures records into the inspector. Compose it with a real handler via slog routing, or set it as the default.

Jump to

Keyboard shortcuts

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