obs

package
v0.15.0 Latest Latest
Warning

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

Go to latest
Published: Jul 13, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package obs provides observability primitives for the deepwork application.

Design: T5-TS-OBS-DESIGN.md r2 | CAP-TSOBS-C1 ContextPropagation Philosophy: Single-path context.Context propagation. No goroutine-local. No middleware.

Index

Constants

This section is empty.

Variables

View Source
var OnFailed = func(msg string) {
	panic(msg)
}

OnFailed is the failure handler for contract assertions. Default: panic. Override in tests to collect failures without crashing.

obs.OnFailed = func(msg string) { t.Fatal(msg) }
View Source
var R = &Registry{
	counters:   make(map[string]*Counter),
	gauges:     make(map[string]*Gauge),
	histograms: make(map[string]*Histogram),
}

Functions

func DefaultBuckets

func DefaultBuckets() []float64

DefaultBuckets returns the default histogram bucket boundaries.

func DropCancel

func DropCancel(ctx context.Context) context.Context

DropCancel preserves all ctx values (TID/STG) while disconnecting from the parent's cancel/deadline signal. Use at lifecycle boundaries where a child operation must outlive the parent request.

Resource ownership discipline: DropCancel only preserves obs metadata. After calling DropCancel, you MUST NOT reuse parent-owned request-scoped resources (DB tx, HTTP streams, deadlines). Independently acquire what you need:

baseCtx := obs.DropCancel(ctx)
childCtx, cancel := context.WithTimeout(baseCtx, ownTimeout)
defer cancel()

Requires Go 1.21+.

func Go

func Go(ctx context.Context, fn func(context.Context))

Go launches a goroutine with ctx propagation. This is a spawn boundary guard: it ensures the goroutine receives the context (forgetting ctx = compile error).

Zero recover: panics in fn are fatal (DDC-I-14). Business layer may add defer/recover explicitly outside obs.Go if isolation is needed, but obs does not make that choice for you.

func Init

func Init(level Level, out io.Writer)

Init initializes the obs subsystem. Idempotent: repeated calls update level/output. Must be called before the first log entry. Defaults: INFO level, os.Stderr output.

func NewRED

func NewRED(ns string) (requests, errors *Counter, duration *Histogram)

NewRED creates the RED (Rate/Error/Duration) metric triple for a namespace.

func NoError

func NoError(err error, format string, args ...any)

NoError asserts that err is nil. Panics with formatted message + error. Use when an error indicates a bug, not an expected failure.

func NotNil

func NotNil(v any, name string)

NotNil asserts that v is not nil. Panics with descriptive message. Primary use: ValidateDeps in observe.go files.

func ResetForTest

func ResetForTest()

ResetForTest clears all registered metrics. Only for use in tests.

func SetLevel

func SetLevel(l Level)

SetLevel sets the global minimum log level. Thread-safe.

func SetModuleLevel

func SetModuleLevel(mod string, l Level)

SetModuleLevel sets a module-specific level that overrides the global level.

func SetOutput

func SetOutput(w io.Writer)

SetOutput sets the log output destination.

func Since

func Since(start time.Time) float64

Since returns elapsed seconds since start, as float64. Convenience for Histogram.Observe:

start := time.Now()
defer h.Observe(obs.Since(start))

func Stage

func Stage(ctx context.Context) string

Stage reads the STG from context. Returns "" if not set.

func Trace

func Trace(ctx context.Context) string

Trace reads the TID from context. Returns "" if not set.

func True

func True(condition bool, format string, args ...any)

True asserts a condition. Panics with formatted message if false. Use for internal invariants, never for external input validation.

func True1

func True1[T1 any](condition bool, format string, arg1 T1)

True1 is a generic specialization of True for single-arg formatting. Avoids interface{} boxing overhead on hot paths.

func True2

func True2[T1, T2 any](condition bool, format string, arg1 T1, arg2 T2)

True2 is a generic specialization of True for two-arg formatting.

func Unreachable

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

Unreachable marks code paths that should never execute. If reached, it indicates a logic error.

func WithStage

func WithStage(ctx context.Context, stg string) context.Context

WithStage injects a business stage coordinate into the context. STG format: "{subsystem}/{phase}", e.g. "council/round/scatter". Call when entering a new business phase. Immutable per ctx — creates new ctx.

func WithTrace

func WithTrace(ctx context.Context, tid string) context.Context

WithTrace injects a Trace ID into the context. TID identifies an execution context (not a business entity). Call once at trace boundary: HTTP handler entry, CLI command start, goroutine spawn with new trace.

func WritePrometheus

func WritePrometheus(w io.Writer)

WritePrometheus writes all registered metrics in Prometheus text exposition format.

Types

type Counter

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

Counter is a monotonically increasing counter. Thread-safe via atomic.

func NewCounter

func NewCounter(name string) *Counter

NewCounter creates and registers a Counter. Idempotent: returns existing if name already registered.

func (*Counter) Add

func (c *Counter) Add(n uint64)

func (*Counter) Inc

func (c *Counter) Inc()

func (*Counter) Name

func (c *Counter) Name() string

func (*Counter) Value

func (c *Counter) Value() uint64

type Entry

type Entry struct {
	L   string         `json:"l"`
	T   string         `json:"t"`
	TID string         `json:"tid,omitempty"`
	STG string         `json:"stg,omitempty"`
	Mod string         `json:"mod"`
	Msg string         `json:"msg"`
	F   string         `json:"f,omitempty"`
	Ext map[string]any `json:"ext,omitempty"`
}

Entry is the fixed-schema log record. 7 core fields + ext map. Reserved keys (l/t/tid/stg/mod/msg/f) must not appear in Ext.

func RecentEntries

func RecentEntries(level string, limit int, since time.Time) []Entry

RecentEntries 从全局 ring buffer 中查询最近的日志条目。 参数说明同 Ring.RecentEntries。

type Gauge

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

Gauge is a value that can go up and down. Thread-safe via atomic.

func NewGauge

func NewGauge(name string) *Gauge

NewGauge creates and registers a Gauge. Idempotent.

func (*Gauge) Add

func (g *Gauge) Add(n int64)

func (*Gauge) Name

func (g *Gauge) Name() string

func (*Gauge) Set

func (g *Gauge) Set(v int64)

func (*Gauge) Sub

func (g *Gauge) Sub(n int64)

func (*Gauge) Value

func (g *Gauge) Value() int64

type Histogram

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

Histogram records observations into pre-defined buckets. Thread-safe via mutex. Acceptable for desktop app concurrency levels. Performance flip trigger: profiler confirms >1% CPU or observable mutex contention.

func NewHistogram

func NewHistogram(name string, buckets []float64) *Histogram

NewHistogram creates and registers a Histogram. Idempotent.

func (*Histogram) Name

func (h *Histogram) Name() string

func (*Histogram) Observe

func (h *Histogram) Observe(v float64)

type Level

type Level int

Level represents log severity.

const (
	DEBUG Level = iota
	INFO
	WARN
	ERROR
)

func (Level) String

func (l Level) String() string

type LogCoalescer

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

LogCoalescer is for high-frequency observational logs, such as polling or heartbeat paths. It emits the first event, emits immediately when the caller's fingerprint changes, and otherwise emits at most once per window with a count of suppressed duplicate observations.

func NewLogCoalescer

func NewLogCoalescer(window time.Duration) *LogCoalescer

NewLogCoalescer creates a coalescer with a minimum emit window. A non-positive window falls back to 30s so callers cannot accidentally create a noisy logger.

func (*LogCoalescer) Info

func (c *LogCoalescer) Info(ctx context.Context, logger Logger, key, fingerprint, msg string, args ...any)

Info emits an INFO log according to the coalescing policy.

key is the stable identity of the event stream and is intentionally not logged by the coalescer; callers should pass any safe identity fields explicitly in args. fingerprint is the semantic state. When fingerprint changes, the event is emitted immediately even if the window has not elapsed.

type Logger

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

Logger is a module-scoped logger. Create with Module(). All log methods require context.Context to extract TID/STG.

func Module

func Module(mod string) Logger

Module creates a Logger for the named module. Convention: mod must match the package directory name.

func (Logger) Debug

func (l Logger) Debug(ctx context.Context, msg string, args ...any)

Debug logs at DEBUG level. Use for non-error branch diagnostics.

func (Logger) Error

func (l Logger) Error(ctx context.Context, msg string, args ...any)

Error logs at ERROR level with automatic file:line capture. Use for failures that break core functionality.

func (Logger) Info

func (l Logger) Info(ctx context.Context, msg string, args ...any)

Info logs at INFO level. Use for key success milestones and deliberate skip events.

func (Logger) Warn

func (l Logger) Warn(ctx context.Context, msg string, args ...any)

Warn logs at WARN level with automatic file:line capture. Use for degraded-but-not-crashed scenarios.

type Registry

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

Registry is the global metric registration point.

type Ring

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

Ring 是固定容量的循环缓冲区,保存最近的日志条目。 线程安全,使用 sync.RWMutex 保护并发访问。

func NewRing

func NewRing(capacity int) *Ring

NewRing 创建一个指定容量的 Ring。capacity 必须 > 0,否则 panic。

func (*Ring) Push

func (r *Ring) Push(e Entry)

Push 将一条日志条目写入 ring buffer。 当 buffer 已满时,最旧的条目被覆盖。

func (*Ring) RecentEntries

func (r *Ring) RecentEntries(level string, limit int, since time.Time) []Entry

RecentEntries 返回满足过滤条件的条目,按时间倒序排列(最新在前)。

  • level: 空字符串表示不过滤级别;否则只返回 l == level 的条目
  • limit: ≤ 0 表示不限数量
  • since: 零值表示不过滤时间;否则只返回 T >= since 的条目

func (*Ring) Stats

func (r *Ring) Stats() RingStats

Stats 返回 ring buffer 的统计信息。

type RingStats

type RingStats struct {
	Count      int    `json:"count"`
	Capacity   int    `json:"capacity"`
	OldestTime string `json:"oldest_time"`
}

RingStats 描述 ring buffer 的当前状态。

func GlobalRingStats

func GlobalRingStats() RingStats

GlobalRingStats 返回全局 ring buffer 的统计信息。

Jump to

Keyboard shortcuts

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