xo

package module
v0.4.5 Latest Latest
Warning

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

Go to latest
Published: Feb 20, 2024 License: MIT Imports: 31 Imported by: 18

README

xo

Test GoDoc Release

A configuration, logging, reporting and tracing framework for Go applications.

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var Devel = os.Getenv("DEVEL") == "true" || Testing()

Devel is true when the program runs in development or testing mode.

View Source
var SinkFactory = func(name string) io.WriteCloser {

	reader, writer := io.Pipe()

	go Drain(name, reader)

	return writer
}

SinkFactory is the factory used by Sink() to create sinks.

View Source
var Stdout io.Writer = os.Stdout

Stdout is the original stdout.

Functions

func Abort added in v0.1.1

func Abort(err error)

Abort will abort with the supplied error.

func AbortIf added in v0.1.1

func AbortIf(err error)

AbortIf will only abort with the supplied error if present.

func Auto added in v0.3.0

func Auto(config Config) func()

Auto will automatically install logging, reporting and tracing components. The returned function should be deferred to catch panics and ensure flushing.

func Capture

func Capture(err error)

Capture will capture the error.

Example
// install
teardown := Debug(DebugConfig{
	NoReportContext:     true,
	NoReportLineNumbers: true,
})
defer teardown()

// capture error
Capture(F("some error"))

// report error
Reporter(SM{"foo": "bar"})(F("another error"))

// flush
time.Sleep(10 * time.Millisecond)
Output:

===== REPORT =====
ERROR
> some error (*xo.Err)
|   ExampleCapture (github.com/256dpi/xo): github.com/256dpi/xo/examples_test.go
|   main (main): _testmain.go
ERROR
• foo: bar
> another error (*xo.Err)
|   ExampleCapture (github.com/256dpi/xo): github.com/256dpi/xo/examples_test.go
|   main (main): _testmain.go

func CaptureSilent added in v0.3.2

func CaptureSilent(err error)

CaptureSilent will capture the error without printing it.

func Catch added in v0.2.3

func Catch(fn func() error) (err error)

Catch will call fn and recover any panic and return an error.

Note: If the built-in panic function has been called with nil, a call to Recover will discard that panic and continue execution.

func Crash added in v0.4.3

func Crash(err error)

Crash will panic with a formatted error.

func CrashIf added in v0.4.3

func CrashIf(err error)

CrashIf will only panic with a formatted error if an error is present.

func Debug

func Debug(config DebugConfig) func()

Debug will install logging, reporting and tracing components for debugging purposes. The returned function may be called to teardown all installed components.

func Drain added in v0.2.2

func Drain(name string, reader io.Reader)

Drain will read log lines from the reader and write them to Stdout.

func Drop added in v0.3.4

func Drop(err error, n int) error

Drop will drop the specified amount of frames from the error if possible.

func Eval added in v0.3.6

func Eval(key, value string) string

Eval will evaluate a rule found in value. If a value is formatted as "@file:foo" the contents of foo is loaded and returned. If a value is formatted as "@config:foo" the config foo is loaded and the value at the name key returned.

func F

func F(format string, args ...interface{}) error

F will format an error. This function can be used instead of errors.New() and fmt.Errorf().

func FilterSentryIntegrations

func FilterSentryIntegrations(drop ...string) func(i []sentry.Integration) []sentry.Integration

FilterSentryIntegrations will return a sentry integrations filter that will drop the named integrations.

func Get added in v0.2.4

func Get(key, fallback string) string

Get will get the specified environment variable and fallback to the specified value if it is missing or empty. The retrieved value is evaluated using Eval.

func GetGlobalTracer added in v0.3.5

func GetGlobalTracer() trace.Tracer

GetGlobalTracer will return the global xo tracer. It will cache the tracer to increase performance between calls.

func GetSpan

func GetSpan(ctx context.Context) trace.Span

GetSpan will return the first native span found in the provided context. It will return nil if no span has been found.

func HookReporting added in v0.2.6

func HookReporting(transport sentry.Transport) func()

HookReporting will set up error reporting using sentry. The returned function may be called to revert the previously configured client.

func HookTracing added in v0.2.6

func HookTracing(exporter exportTrace.SpanExporter, serviceName string, async bool) func()

HookTracing will hook tracing using the provided span exporter. The returned function may be called to revert the previously configured provider.

func Intercept

func Intercept() func()

Intercept will replace os.Stdout with a logging sink named "STDOUT". It will also redirect the output of the log package to a logging sink named "LOG". The returned function can be called to restore the original state.

func IsSafe

func IsSafe(err error) bool

IsSafe can be used to check if an error has been wrapped using SW. It will also detect further wrapped safe errors.

func Load added in v0.2.5

func Load(v Var) string

Load will return the value of the provided environment variable. The loaded value is evaluated using Eval.

func NumberCleaner

func NumberCleaner(fullNumber bool) func([]string) []string

NumberCleaner will return a function that replaces number-like URL segments with a "#". If fullNumber is true it will only replace if the whole segment is a number instead of just the first character.

Note: BSON ObjectIDs start with a number until 2055.

func Panic added in v0.2.1

func Panic(err error)

Panic will panic with the provided error.

func PanicIf added in v0.3.4

func PanicIf(err error)

PanicIf will only panic if the supplied error is present.

func Recover added in v0.2.1

func Recover(fn func(error))

Recover will recover any panic and call fn if an error has been recovered.

Note: If the built-in panic function has been called with nil, a call to Recover will discard that panic and continue execution.

func Reporter

func Reporter(tags SM) func(error)

Reporter will return a capture function that adds the provided tags.

func ResetGlobalTracer added in v0.3.5

func ResetGlobalTracer()

ResetGlobalTracer will reset the global tracer cache.

func Resume added in v0.1.1

func Resume(fn func(error))

Resume will recover an earlier call to Abort or AbortIf and call fn if an error has been recovered. It will not recover direct calls to the built-in panic function.

Note: If the built-in panic function has been called with nil, a call to Resume will discard that panic and continue execution.

func RootHandler

func RootHandler(cleaners ...func([]string) []string) func(http.Handler) http.Handler

RootHandler is the middleware used to create the root trace span for incoming HTTP requests.

func Run

func Run(ctx context.Context, fn func(ctx *Context) error) error

Run will run the provided function and automatically handle tracing, error handling and panic recovering.

Example
// get context
ctx := context.Background()

// divide positive
res, err := Div(ctx, 10, 2)
fmt.Printf("div: %d, %v\n", res, err)

// divide negative
res, err = Div(ctx, 10, -2)
fmt.Printf("div: %d, %v\n", res, err)

// divide zero
res, err = Div(ctx, 10, 0)
fmt.Printf("div: %d, %v\n", res, err)
Output:

div: 5, <nil>
div: 0, xo.Div: negative division
div: 0, xo.Div: PANIC: runtime error: integer divide by zero

func SF

func SF(format string, args ...interface{}) error

SF is a short-hand function to format a safe error.

func SW

func SW(err error) error

SW wraps an error and marks it as safe. Wrapped errors are safe to be presented to the client if appropriate.

func Sink

func Sink(name string) io.WriteCloser

Sink will return a new named logging sink.

Example
// intercept
reset := Intercept()
defer reset()

// builtin fmt
fmt.Println("foo", "bar")
fmt.Printf("%d %d\n", 7, 42)
time.Sleep(10 * time.Millisecond)

// builtin logger
log.SetFlags(0)
log.Println("foo", "bar")
log.Printf("%d %d", 7, 42)
time.Sleep(10 * time.Millisecond)

// custom logger
sink := Sink("FOO")
logger := log.New(sink, "", 0)
logger.Println("foo", "bar")
logger.Printf("%d %d", 7, 42)
time.Sleep(10 * time.Millisecond)
Output:

===== STDOUT =====
foo bar
7 42
===== LOG =====
foo bar
7 42
===== FOO =====
foo bar
7 42

func SortNodes

func SortNodes(nodes []*VNode)

SortNodes will sort the specified nodes.

func StartSpan

func StartSpan(ctx context.Context, name string) (context.Context, trace.Span)

StartSpan will start a native span using the globally configured tracer. It will continue any span found in the provided context or start a new span with the specified name if absent.

func Test

func Test(fn func(tester *Tester))

Test will temporarily intercept and collect logging, tracing and reporting data for testing purposes. Standard logging is not intercepted to prevent messing with test output.

func Testing added in v0.3.0

func Testing() bool

Testing will return true if the program is likely being tested.

func Tunnel added in v0.3.8

func Tunnel(limit int64, verify func(*http.Request, string, *url.URL) bool, reporter func(error)) http.Handler

Tunnel returns a handler that forwards received Sentry envelopes to the endpoint specified by the DSN received in the envelopes. The optional verify callback may set to verify received DSNs. This handler can be used together with the sentry tunnel feature to relay browser errors via a custom endpoint.

func VerifyDSN added in v0.3.8

func VerifyDSN(list ...string) func(*http.Request, string, *url.URL) bool

VerifyDSN will require the submitted DNS to match one of the provided DSNs.

func W

func W(err error) error

W will wrap an error. The error is not wrapped if the parent error already captured the caller.

func WF

func WF(err error, format string, args ...interface{}) error

WF will wrap and error with a formatted message. This function can be used instead of wrapping with fmt.Errorf().

func WS added in v0.3.4

func WS(err error, skip int) error

WS will wrap an error. The error is not wrapped if the parent error already captured the caller. If the error is wrapped the specified amount of frames is skipped.

func WalkTrace

func WalkTrace(node *VNode, fn func(node *VNode) bool) bool

WalkTrace will walk the specified trace.

Types

type BaseErr added in v0.1.1

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

BaseErr represents the base of an error chain. It cannot directly be used as an error value. Instead, the caller uses Wrap() to get a new wrapped error or Self() to get the identity error.

func BF added in v0.1.1

func BF(format string, args ...interface{}) BaseErr

BF formats and returns a new base error.

func BW added in v0.1.1

func BW(err error) BaseErr

BW wraps and returns a new base error.

func (*BaseErr) Is added in v0.1.1

func (b *BaseErr) Is(err error) bool

Is returns whether the provided error is a descendant.

func (*BaseErr) Self added in v0.1.1

func (b *BaseErr) Self() error

Self will return the identity error.

func (*BaseErr) Wrap added in v0.1.1

func (b *BaseErr) Wrap() error

Wrap wraps and returns an error value.

func (*BaseErr) WrapF added in v0.3.0

func (b *BaseErr) WrapF(format string, args ...interface{}) error

WrapF wraps, formats and returns an error value.

type Caller

type Caller struct {
	Short string
	Full  string
	File  string
	Line  int
	Stack []uintptr
}

Caller describes a caller.

func GetCaller

func GetCaller(skip, limit int) Caller

GetCaller returns information on the caller.

func (*Caller) Analyze added in v0.3.4

func (c *Caller) Analyze()

Analyze will fill Short, Full, File and Line from the first stack frame.

func (*Caller) Drop added in v0.3.4

func (c *Caller) Drop(n int)

Drop will drop the specified amount of frames from the caller.

func (Caller) Format

func (c Caller) Format(s fmt.State, verb rune)

Format will format the caller.

%s   short name
%q   "short name"
%v   full name
%+v  stack trace

func (Caller) Includes

func (c Caller) Includes(cc Caller, ignore int) bool

Includes returns whether the receiver fully includes the provided caller. Ignore can be set to ignore n bottom frames. Two adjacent callers will have the same stack except for the last frame which represents the call site.

func (Caller) Print

func (c Caller) Print(out io.Writer)

Print will print the stack to the provided writer.

func (Caller) String

func (c Caller) String() string

String will format the caller as a string.

type Config

type Config struct {
	// The Sentry DSN.
	SentryDSN string

	// The OTLP endpoint URL.
	OTLPEndpointURL string

	// The trace service name.
	TraceServiceName string

	// ReportOutput for writing errors.
	//
	// Default: os.Stderr.
	ReportOutput io.Writer

	// The debug config.
	DebugConfig DebugConfig
}

Config is used to configure xo.

type Context

type Context struct {
	context.Context

	// The caller.
	Caller Caller

	// The span.
	Span Span
}

Context is used by Run to track execution.

func (*Context) Attach

func (c *Context) Attach(event string, attributes M)

Attach will add the provided event to the span.

func (*Context) Log

func (c *Context) Log(format string, args ...interface{})

Log will attach a log event to the span.

func (*Context) Rename

func (c *Context) Rename(name string)

Rename will set a new name on the span.

func (*Context) Tag

func (c *Context) Tag(key string, value interface{})

Tag will add the provided attribute to the span.

type DebugConfig added in v0.2.4

type DebugConfig struct {
	// Whether to omit interception.
	//
	// Default: false.
	NoIntercept bool

	// The output for traces.
	//
	// Default: Sink("TRACE").
	TraceOutput io.Writer

	// The trace resolution.
	//
	// Default: 1ns.
	TraceResolution time.Duration

	// The trace width.
	//
	// Default: 80.
	TraceWidth int

	// Whether to include trace attributes.
	TraceAttributes bool

	// The output for reports.
	//
	// Default: Sink("REPORT").
	ReportOutput io.Writer

	// Whether to omit report context data.
	NoReportContext bool

	// Whether to omit file paths from report stack traces.
	NoReportPaths bool

	// Whether to omit line numbers from report stack traces.
	NoReportLineNumbers bool
}

DebugConfig is used to configure xo for debugging.

func (*DebugConfig) Ensure added in v0.2.4

func (c *DebugConfig) Ensure()

Ensure will ensure defaults.

type Debugger

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

Debugger is a virtual logging, tracing and reporting provider for debugging purposes.

func NewDebugger

func NewDebugger(config DebugConfig) *Debugger

NewDebugger will create and return a new debugger.

func (*Debugger) Report added in v0.3.0

func (d *Debugger) Report(event *sentry.Event)

Report will report the specified event.

func (*Debugger) SentryTransport

func (d *Debugger) SentryTransport() sentry.Transport

SentryTransport will return a sentry transport that print received events.

func (*Debugger) SpanExporter added in v0.2.4

func (d *Debugger) SpanExporter() trace.SpanExporter

SpanExporter will return a span exporter that prints received spans.

type Err

type Err struct {
	Err    error
	Msg    string
	Caller Caller
}

Err is the error returned by F(), W(), WS() and WF().

func (*Err) Error

func (e *Err) Error() string

Error will return the error string.

func (*Err) Format

func (e *Err) Format(s fmt.State, verb rune)

Format will format the error.

%s   message
%q   "message"
%v   caller: message
%+v  err
     message
     caller

func (*Err) StackTrace

func (e *Err) StackTrace() []uintptr

StackTrace will return the stack trace (for sentry compatibility).

func (*Err) Unwrap

func (e *Err) Unwrap() error

Unwrap will return the wrapped error, if any.

type M

type M = map[string]interface{}

M is a shorthand for a generic map.

type SM

type SM = map[string]string

SM is a shorthand for a string map.

type SafeErr

type SafeErr struct {
	Err
}

SafeErr wraps Err to indicate presentation safety.

func AsSafe

func AsSafe(err error) *SafeErr

AsSafe will return the safe error from an error chain.

type SentryTransport

type SentryTransport func(*sentry.Event)

SentryTransport is a functional sentry transport.

func (SentryTransport) Configure

func (t SentryTransport) Configure(sentry.ClientOptions)

Configure implements the sentry.Transport interface.

func (SentryTransport) Flush

func (t SentryTransport) Flush(time.Duration) bool

Flush implements the sentry.Transport interface.

func (SentryTransport) SendEvent

func (t SentryTransport) SendEvent(event *sentry.Event)

SendEvent implements the sentry.Transport interface.

type Span

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

Span is the underlying span used for tracing.

func NewSpan added in v0.2.0

func NewSpan(ctx context.Context, span trace.Span) Span

NewSpan will create and return a new span from the provided context and native span. The context should already carry the native span.

func SmartTrace added in v0.2.0

func SmartTrace(ctx context.Context) (context.Context, Span)

SmartTrace calls Trace with the callers short name.

func Trace

func Trace(ctx context.Context, name string) (context.Context, Span)

Trace is used to trace a function call. It will start a new span based on the history in the provided context. It will return a new span and context that contains the created spans native span.

Example
// install
teardown := Debug(DebugConfig{
	TraceResolution: 100 * time.Millisecond,
})
defer teardown()

// get context
ctx := context.Background()

// trace one
func() {
	ctx, span := Trace(ctx, "One")
	defer span.End()

	time.Sleep(100 * time.Millisecond)

	// trace two
	func() {
		ctx, span := Trace(ctx, "Two")
		span.Log("hello world")
		defer span.End()

		time.Sleep(100 * time.Millisecond)

		// trace three
		func() {
			_, span := Trace(ctx, "Three")
			span.Tag("foo", "bar")
			defer span.End()

			time.Sleep(100 * time.Millisecond)
		}()
	}()

	// trace four
	func() {
		ctx, span := Trace(ctx, "Four")
		span.Record(F("fatal"))
		defer span.End()

		// trace five
		func() {
			_, span := Trace(ctx, "Five")
			span.Tag("baz", 42)
			defer span.End()

			time.Sleep(100 * time.Millisecond)
		}()

		time.Sleep(100 * time.Millisecond)
	}()
}()

// flush
time.Sleep(10 * time.Millisecond)
Output:

===== TRACE =====
> One            ├──────────────────────────────────────────────────────────────────────────────┤   500ms
|   Two                          ├──────────────────────────────┤                                   200ms
|   :log                         •                                                                  100ms
|     Three                                      ├──────────────┤                                   100ms
|   Four                                                         ├──────────────────────────────┤   200ms
|   :exception                                                   •                                  300ms
|     Five                                                       ├──────────────┤                   100ms

func (Span) Attach

func (s Span) Attach(event string, attributes M)

Attach will add the provided event to the span.

func (Span) Context added in v0.2.0

func (s Span) Context() context.Context

Context will return the context carrying the native span.

func (Span) End

func (s Span) End()

End will end the span.

func (Span) Log

func (s Span) Log(format string, args ...interface{})

Log will attach a log event to the span.

func (Span) Native

func (s Span) Native() trace.Span

Native will return the underlying native span.

func (Span) Record

func (s Span) Record(err error)

Record will attach an error event to the span.

func (Span) Rename

func (s Span) Rename(name string)

Rename will set a new name on the span.

func (Span) Tag

func (s Span) Tag(key string, value interface{})

Tag will add the provided attribute to the span.

type SpanExporter added in v0.2.4

type SpanExporter func(trace.ReadOnlySpan) error

SpanExporter is a functional span exporter.

func (SpanExporter) ExportSpans added in v0.2.4

func (s SpanExporter) ExportSpans(_ context.Context, spans []trace.ReadOnlySpan) error

ExportSpans implements the trace.SpanExporter interface.

func (SpanExporter) Shutdown added in v0.2.4

func (s SpanExporter) Shutdown(context.Context) error

Shutdown implements the trace.SpanExporter interface.

type Tester

type Tester struct {
	// The collected spans.
	Spans []VSpan

	// The collected reports.
	Reports []VReport

	// The collected sinks.
	Sinks map[string]*VSink
}

Tester is a virtual logging, tracing and reporting provider for testing purposes.

func (*Tester) ReducedReports

func (t *Tester) ReducedReports(includeFrames bool) []VReport

ReducedReports will return a copy of the report list with reduced information. This representation can be used in tests for easy direct comparison.

func (*Tester) ReducedSpans

func (t *Tester) ReducedSpans(resolution time.Duration) []VSpan

ReducedSpans will return a copy of the span list with reduced information. This representation can be used in tests for easy direct comparison.

func (*Tester) Reset

func (t *Tester) Reset()

Reset collected spans, reports and sinks.

func (*Tester) SentryTransport

func (t *Tester) SentryTransport() sentry.Transport

SentryTransport will return a sentry transport that collects events.

func (*Tester) SinkFactory

func (t *Tester) SinkFactory() func(name string) io.WriteCloser

SinkFactory will return a sink factory that returns buffer sinks.

func (*Tester) SpanExporter added in v0.2.4

func (t *Tester) SpanExporter() trace.SpanExporter

SpanExporter will return a span exporter that collects spans.

type Tracer added in v0.2.0

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

Tracer manages a span stack that can be used with fat contexts. Rather than branching of the context for every function call, a span is pushed onto the tracers stack to trace execution.

Code that uses Trace or native opentelemetry APIs will automatically discover the stack and branch of its tail if no previous branch has been detected.

func CreateTracer added in v0.2.0

func CreateTracer(ctx context.Context, name string) (*Tracer, context.Context)

CreateTracer returns a new tracer that will use the span found in the provided context to start a new one with the provided name. The returned context is the provided context wrapped with the new native span and tracer.

func GetTracer added in v0.2.0

func GetTracer(ctx context.Context) *Tracer

GetTracer will return the tracer from the context or nil if absent.

func NewTracer added in v0.2.0

func NewTracer(ctx context.Context) (*Tracer, context.Context)

NewTracer returns a new tracer that will use the native span found in the context as its root. The returned context is the provided context wrapped with the tracer.

func (*Tracer) Attach added in v0.2.0

func (t *Tracer) Attach(event string, attributes M)

Attach will add the provided event to the tail span.

func (*Tracer) End added in v0.2.0

func (t *Tracer) End()

End will end all stacked spans and the root span.

func (*Tracer) Log added in v0.2.0

func (t *Tracer) Log(format string, args ...interface{})

Log will attach a log event to the tail span.

func (*Tracer) Pop added in v0.2.0

func (t *Tracer) Pop()

Pop ends and removes the last pushed span. This call is usually deferred right after a push.

func (*Tracer) Push added in v0.2.0

func (t *Tracer) Push(name string)

Push will add a new span onto the stack.

func (*Tracer) Record added in v0.2.0

func (t *Tracer) Record(err error)

Record will attach an error event to the tail span.

func (*Tracer) Rename added in v0.2.0

func (t *Tracer) Rename(name string)

Rename will set a new name on the tail span.

func (*Tracer) Root added in v0.2.0

func (t *Tracer) Root() Span

Root will return the root of the span stack.

func (*Tracer) SmartPush added in v0.2.0

func (t *Tracer) SmartPush()

SmartPush will call Push() with callers short name.

func (*Tracer) Tag added in v0.2.0

func (t *Tracer) Tag(key string, value interface{})

Tag will add the provided attribute to the tail span.

func (*Tracer) Tail added in v0.2.0

func (t *Tracer) Tail() Span

Tail returns the tail or root of the span stack.

type VEvent

type VEvent struct {
	Name       string
	Time       time.Time
	Attributes M
}

VEvent is a virtual span event.

type VException

type VException struct {
	Type   string
	Value  string
	Module string
	Frames []VFrame
}

VException is a virtual report exception.

type VFrame

type VFrame struct {
	Func   string
	Module string
	File   string
	Path   string
	Line   int
}

VFrame is a virtual exception frame.

type VNode

type VNode struct {
	Span     VSpan
	Parent   *VNode
	Children []*VNode
	Depth    int
}

VNode is a virtual trace node.

func BuildTraces

func BuildTraces(list []VSpan) []*VNode

BuildTraces will assemble traces from a list of spans.

type VReport

type VReport struct {
	ID         string
	Level      string
	Time       time.Time
	Context    M
	Tags       M
	Exceptions []VException
}

VReport is a virtual report.

func ConvertReport

func ConvertReport(event *sentry.Event) VReport

ConvertReport will convert a raw event to virtual report.

type VSink added in v0.3.6

type VSink struct {
	String string
}

VSink provides a virtual string buffer.

func (*VSink) Close added in v0.3.6

func (s *VSink) Close() error

Close implements the io.Closer interface.

func (*VSink) Write added in v0.3.6

func (s *VSink) Write(p []byte) (n int, err error)

Write implements the io.Writer interface.

type VSpan

type VSpan struct {
	ID         string
	Trace      string
	Parent     string
	Name       string
	Start      time.Time
	End        time.Time
	Duration   time.Duration
	Attributes M
	Events     []VEvent
}

VSpan is a virtual span.

func ConvertSpan

func ConvertSpan(data trace.ReadOnlySpan) VSpan

ConvertSpan will convert a raw span to a virtual span.

type Var added in v0.2.5

type Var struct {
	// Then name of the variable e.g. "SOME_VAR".
	Name string

	// Whether providing a value is required.
	Require bool

	// The main default value.
	Main string

	// The development default value.
	Devel string
}

Var defines an environment variable.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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