Documentation
¶
Overview ¶
Package phos provides lightweight request-scoped tracing with optional export, W3C Trace Context propagation, and CLI-oriented trace rendering.
Spans are stored in context: use NewSpan and call Span.End exactly once per span; Span.End is idempotent. While a span is open, Span.Attrs, Span.Event, and Span.Error are safe for concurrent use; after Span.End, further mutations are ignored. Span.Fail records a terminal error and ends the span.
Use WithExporter to attach an Exporter to a context (e.g. per request). Use SetExporter for a process-wide default when no context exporter is set. SetExporter uses an internal read-write lock so it is safe to call concurrently with NewSpan and span completion.
Once a span ends it is no longer returned by SpanFromContext. Helper calls such as Attrs, Event, Error, and Fail therefore become no-ops when a context only carries an ended span.
Call DrainAndClose to start shutdown admission control. While draining, new root spans return no-op spans but child spans on still-open local parents are still allowed. Call WaitForClosed before process exit to wait until all open local span trees have closed.
Propagation helpers InjectTraceContext and ExtractTraceContext work with any Carrier implementation, such as HTTPHeaderCarrier or MapCarrier.
Index ¶
- Constants
- func Attrs(ctx context.Context, attrs ...slog.Attr)
- func DrainAndClose(ctx context.Context)
- func Error(ctx context.Context, err error, attrs ...slog.Attr)
- func Event(ctx context.Context, name string, attrs ...slog.Attr)
- func ExtractTraceContext(ctx context.Context, carrier Carrier) context.Context
- func Fail(ctx context.Context, err error, attrs ...slog.Attr)
- func InjectTraceContext(ctx context.Context, carrier Carrier)
- func RenderTrace(spans []Snapshot) string
- func RenderTraces(spans []Snapshot) string
- func SetExporter(exp Exporter) func()
- func WaitForClosed()
- func WithExporter(ctx context.Context, exp Exporter) context.Context
- type Carrier
- type Exporter
- type HTTPHeaderCarrier
- type InMemExportImporter
- type MapCarrier
- type NoopExporter
- type Snapshot
- type SnapshotError
- type SnapshotEvent
- type SnapshotLink
- type Span
- type SpanKind
- type SpanOption
- type TraceParent
Examples ¶
Constants ¶
const ( TraceParentHeader = "traceparent" TraceStateHeader = "tracestate" )
Variables ¶
This section is empty.
Functions ¶
func Attrs ¶
Attrs records attributes in the span. Attributes are key-value pairs that describe the span.
func DrainAndClose ¶ added in v0.0.3
DrainAndClose begins shutdown admission control without blocking.
Once draining has started, new root spans return noop spans while child spans on still-open local parents are allowed. If ctx is canceled before all open roots end naturally, Phos closes the remaining trees bottom-up and records the event "phos.Shutdown timeout reached" on affected spans.
func Error ¶
Error records an error in the span. An error is a terminal, timestamped occurrence in the span.
func Event ¶
Event records an event in the span. An event is a non-terminal, timestamped occurrence in the span.
func ExtractTraceContext ¶
func InjectTraceContext ¶
func RenderTrace ¶
RenderTrace renders one trace as a CLI-friendly timeline.
func RenderTraces ¶
RenderTraces renders all spans grouped by trace in a CLI-friendly timeline.
func SetExporter ¶
func SetExporter(exp Exporter) func()
SetExporter replaces the package-level exporter and returns a restore function for callers that need to put the previous exporter back. It is safe for concurrent use with NewSpan and span completion.
func WaitForClosed ¶ added in v0.0.3
func WaitForClosed()
WaitForClosed blocks until Phos reaches the closed state.
Types ¶
type Exporter ¶
type Exporter interface {
Export(snapshot Snapshot)
}
Exporter receives completed span snapshots.
Export must be safe for concurrent use. Phos considers export complete when Export returns, so exporters should avoid blocking indefinitely. Any exporter-specific buffering or shutdown coordination is owned by the exporter implementation, not Phos.
type HTTPHeaderCarrier ¶
func (HTTPHeaderCarrier) Get ¶
func (c HTTPHeaderCarrier) Get(key string) string
func (HTTPHeaderCarrier) Keys ¶
func (c HTTPHeaderCarrier) Keys() []string
func (HTTPHeaderCarrier) Set ¶
func (c HTTPHeaderCarrier) Set(key string, value string)
type InMemExportImporter ¶
type InMemExportImporter struct {
// contains filtered or unexported fields
}
func NewInMemExportImporter ¶
func NewInMemExportImporter() *InMemExportImporter
func (*InMemExportImporter) Export ¶
func (e *InMemExportImporter) Export(data Snapshot)
func (*InMemExportImporter) Spans ¶ added in v0.0.3
func (e *InMemExportImporter) Spans() map[string]Snapshot
Spans returns a deep copy of all exported spans keyed by span ID.
type MapCarrier ¶
func (MapCarrier) Get ¶
func (c MapCarrier) Get(key string) string
func (MapCarrier) Keys ¶
func (c MapCarrier) Keys() []string
func (MapCarrier) Set ¶
func (c MapCarrier) Set(key string, value string)
type Snapshot ¶
type Snapshot struct {
ID string `json:"id"`
Name string `json:"name"`
ParentID string `json:"parent_id"`
TraceID string `json:"trace_id"`
TimeStart time.Time `json:"time_start"`
TimeEnd time.Time `json:"time_end"`
Kind SpanKind `json:"kind"`
Failed bool `json:"failed"`
Attrs []slog.Attr `json:"attrs"`
Links []SnapshotLink `json:"links"`
Events []SnapshotEvent `json:"events"`
Errors []SnapshotError `json:"errors"`
}
func (Snapshot) MarshalJSON ¶ added in v0.0.3
type SnapshotError ¶
func (SnapshotError) MarshalJSON ¶
func (e SnapshotError) MarshalJSON() ([]byte, error)
type SnapshotEvent ¶
type SnapshotEvent struct {
Time time.Time `json:"time"`
Name string `json:"name"`
Attrs []slog.Attr `json:"attrs"`
}
func (SnapshotEvent) MarshalJSON ¶ added in v0.0.3
func (e SnapshotEvent) MarshalJSON() ([]byte, error)
type SnapshotLink ¶ added in v0.0.3
type SnapshotLink struct {
TraceID string `json:"trace_id"`
SpanID string `json:"span_id"`
Attrs []slog.Attr `json:"attrs"`
}
func (SnapshotLink) MarshalJSON ¶ added in v0.0.3
func (l SnapshotLink) MarshalJSON() ([]byte, error)
type Span ¶
type Span struct {
// contains filtered or unexported fields
}
func NewSpan ¶
Example ¶
package main
import (
"context"
"log/slog"
"github.com/johan-st/phos"
)
func main() {
ctx := context.Background()
ctx, span := phos.NewSpan(ctx, "request", phos.WithAttrs(slog.String("method", "GET")))
defer span.End()
phos.Attrs(ctx, slog.String("user", "alice"))
phos.Event(ctx, "authorized")
}
Output:
func SpanFromContext ¶ added in v0.0.3
SpanFromContext returns the active span for the given context. If the context does not have an active span, nil is returned.
type SpanOption ¶ added in v0.0.3
type SpanOption func(*spanConfig)
func WithAttrs ¶ added in v0.0.3
func WithAttrs(attrs ...slog.Attr) SpanOption
func WithKind ¶ added in v0.0.3
func WithKind(kind SpanKind) SpanOption
type TraceParent ¶
func ParseTraceParent ¶
func ParseTraceParent(v string) (TraceParent, error)
func (TraceParent) String ¶
func (t TraceParent) String() string