trace

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Apr 22, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package trace captures request-lifecycle events (start, end, downstream calls, logs) into an in-memory ring buffer and fans them out to subscribers such as the dashboard. It is the data plane under /__nexus/events.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Middleware

func Middleware(bus *Bus, service, endpoint, transport string) gin.HandlerFunc

Middleware emits request.start and request.end events bracketing the handler chain, and stashes a *Span and the bus in gin.Context so Record() can attach downstream events to the same trace.

func Record

func Record(c *gin.Context, name string, start time.Time, err error)

Record attaches a downstream event (DB call, MQ publish, external HTTP, etc.) to the current request's trace. Typical use:

start := time.Now()
err := db.Query(...)
trace.Record(c, "db.users.get", start, err)

Types

type Bus

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

Bus is a bounded ring buffer + pub/sub. Slow subscribers drop events rather than block producers — the request path must never be held up by a stalled UI.

func BusFrom

func BusFrom(c *gin.Context) (*Bus, bool)

func BusFromCtx

func BusFromCtx(ctx context.Context) (*Bus, bool)

BusFromCtx returns the Bus from context, if the trace middleware stashed one.

func NewBus

func NewBus(capacity int) *Bus

func (*Bus) Publish

func (b *Bus) Publish(e Event)

func (*Bus) Subscribe

func (b *Bus) Subscribe(sinceID int64, buffer int) ([]Event, <-chan Event, func())

Subscribe atomically captures the backlog (events with ID > sinceID) and registers a channel for future events. Doing both under one lock guarantees a reconnecting client sees every event exactly once — no gap, no duplicate.

type Event

type Event struct {
	ID         int64          `json:"id"`
	TraceID    string         `json:"traceId"`
	Kind       Kind           `json:"kind"`
	Service    string         `json:"service,omitempty"`
	Endpoint   string         `json:"endpoint,omitempty"`
	Transport  string         `json:"transport,omitempty"`
	Method     string         `json:"method,omitempty"`
	Path       string         `json:"path,omitempty"`
	Status     int            `json:"status,omitempty"`
	DurationMs int64          `json:"durationMs,omitempty"`
	Message    string         `json:"message,omitempty"`
	Error      string         `json:"error,omitempty"`
	Timestamp  time.Time      `json:"timestamp"`
	Meta       map[string]any `json:"meta,omitempty"`
}

type Kind

type Kind string
const (
	KindRequestStart Kind = "request.start"
	KindRequestEnd   Kind = "request.end"
	KindDownstream   Kind = "downstream"
	KindLog          Kind = "log"
)

type Span

type Span struct {
	TraceID  string
	Service  string
	Endpoint string
	Start    time.Time
}

func SpanFrom

func SpanFrom(c *gin.Context) (*Span, bool)

func SpanFromCtx

func SpanFromCtx(ctx context.Context) (*Span, bool)

SpanFromCtx reads the current request's Span from any context.Context. Use this from code paths that don't have a *gin.Context — GraphQL resolvers (via p.Context), GORM callbacks, downstream HTTP clients.

Jump to

Keyboard shortcuts

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