phos

package module
v0.0.2 Latest Latest
Warning

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

Go to latest
Published: Apr 15, 2026 License: GPL-3.0 Imports: 13 Imported by: 0

README

Phos

The Phos library is meant to be a simple-to-use, difficult-to-misuse tracing library.

Quickstart

import "github.com/johan-st/phos"

ctx, span := phos.NewSpan(ctx, "handler", slog.String("route", "/api"))
defer span.End()

phos.Attrs(ctx, slog.String("user", id))
phos.Event(ctx, "cache.hit")

Set a default exporter (optional), or use WithExporter on the request context:

restore := phos.SetExporter(myExporter)
defer restore()

ctx = phos.WithExporter(ctx, myExporter)

HTTP propagation (W3C Trace Context):

phos.InjectTraceContext(ctx, phos.HTTPHeaderCarrier{Header: resp.Header()})
ctx = phos.ExtractTraceContext(ctx, phos.HTTPHeaderCarrier{Header: req.Header})

References

https://www.w3.org/TR/trace-context

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 (or InSpan / InSpanE) and call Span.End exactly once per span; Span.End is idempotent. While a span is open, Span.Attrs, Span.Event, Span.Error, and Span.Fail are safe for concurrent use; after Span.End, further mutations are ignored.

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.

Propagation helpers InjectTraceContext and ExtractTraceContext work with any Carrier implementation, such as HTTPHeaderCarrier or MapCarrier.

Index

Examples

Constants

View Source
const (
	TraceParentHeader = "traceparent"
	TraceStateHeader  = "tracestate"
)

Variables

This section is empty.

Functions

func Attrs

func Attrs(ctx context.Context, attrs ...slog.Attr)

func Error

func Error(ctx context.Context, err error, attrs ...slog.Attr)

func Event

func Event(ctx context.Context, name string, attrs ...slog.Attr)

func ExtractTraceContext

func ExtractTraceContext(ctx context.Context, carrier Carrier) context.Context

func Fail

func Fail(ctx context.Context)

func InSpan

func InSpan(ctx context.Context, name string, fn func(context.Context), attrs ...slog.Attr)

func InSpanE

func InSpanE(ctx context.Context, name string, fn func(context.Context) error, attrs ...slog.Attr) error

func InjectTraceContext

func InjectTraceContext(ctx context.Context, carrier Carrier)

func RenderTrace

func RenderTrace(spans []Snapshot) string

RenderTrace renders one trace as a CLI-friendly timeline.

func RenderTraces

func RenderTraces(spans []Snapshot) string

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 WithExporter

func WithExporter(ctx context.Context, exp Exporter) context.Context

Types

type Carrier

type Carrier interface {
	Get(key string) (string, bool)
	Set(key string, value string)
	Keys() []string
}

type Exporter

type Exporter interface {
	Export(snapshot Snapshot)
}

type HTTPHeaderCarrier

type HTTPHeaderCarrier struct {
	Header http.Header
}

func (HTTPHeaderCarrier) Get

func (c HTTPHeaderCarrier) Get(key string) (string, bool)

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) Snapshot

func (e *InMemExportImporter) Snapshot() map[string]Snapshot

Snapshot returns a deep copy of all exported spans keyed by span ID.

type MapCarrier

type MapCarrier map[string]string

func (MapCarrier) Get

func (c MapCarrier) Get(key string) (string, bool)

func (MapCarrier) Keys

func (c MapCarrier) Keys() []string

func (MapCarrier) Set

func (c MapCarrier) Set(key string, value string)

type NoopExporter

type NoopExporter struct{}

func (*NoopExporter) Export

func (e *NoopExporter) Export(_ Snapshot)

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"`
	Failed    bool            `json:"failed"`
	Attrs     []slog.Attr     `json:"attrs"`
	Events    []SnapshotEvent `json:"events"`
	Errors    []SnapshotError `json:"errors"`
	Root      bool            `json:"root"`
}

type SnapshotError

type SnapshotError struct {
	Err   error       `json:"-"`
	Attrs []slog.Attr `json:"attrs"`
}

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"`
}

type Span

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

func NewSpan

func NewSpan(ctx context.Context, name string, attrs ...slog.Attr) (context.Context, *Span)
Example
package main

import (
	"context"
	"log/slog"

	"github.com/johan-st/phos"
)

func main() {
	ctx := context.Background()
	ctx, span := phos.NewSpan(ctx, "request", slog.String("method", "GET"))
	defer span.End()

	phos.Attrs(ctx, slog.String("user", "alice"))
	phos.Event(ctx, "authorized")

}

func (*Span) Attrs

func (s *Span) Attrs(attrs ...slog.Attr)

func (*Span) End

func (s *Span) End()

func (*Span) Error

func (s *Span) Error(err error, attrs ...slog.Attr)

func (*Span) Event

func (s *Span) Event(name string, attrs ...slog.Attr)

func (*Span) Fail

func (s *Span) Fail()

func (*Span) View

func (s *Span) View() Snapshot

type TraceParent

type TraceParent struct {
	Version string
	TraceID string
	Parent  string
	Flags   string
}

func ParseTraceParent

func ParseTraceParent(v string) (TraceParent, error)

func (TraceParent) String

func (t TraceParent) String() string

Directories

Path Synopsis
cmd
phos command

Jump to

Keyboard shortcuts

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