xo

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 3, 2020 License: MIT Imports: 24 Imported by: 18

README

xo

Build Status Coverage Status GoDoc Release Go Report Card

A logging, reporting and tracing framework for Go applications.

Documentation

Index

Examples

Constants

This section is empty.

Variables

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

	reader, writer := io.Pipe()

	go Forward(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 Capture

func Capture(err error)

Capture will capture the error.

Example
// install
teardown := Debug(Config{
	NoEventContext:     true,
	NoEventLineNumbers: true,
})
defer teardown()

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

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

===== EVENT =====
Level: error
Exceptions:
- some error (*xo.Err)
  > ExampleCapture (github.com/256dpi/xo): github.com/256dpi/xo/examples_test.go
  > main (main): _testmain.go

func Debug

func Debug(config Config) func()

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

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 Forward

func Forward(name string, reader io.Reader)

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

func GetSpan

func GetSpan(ctx context.Context) trace.Span

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

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 NumberCleaner

func NumberCleaner(segments []string) []string

NumberCleaner will replace number URL segments with a "#".

func Reporter

func Reporter(tags SM) func(error)

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

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) (err error)

Run will run the provided function and automatically handle tracking, 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 SetupReporting

func SetupReporting(transport sentry.Transport) func()

SetupReporting will setup error reporting using sentry. The returned function may be called to teardown the component.

func SetupTracing

func SetupTracing(syncer export.SpanSyncer) func()

SetupTracing will setup tracing using the provided span syncer. The returned function may be called to teardown the component.

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 configured tracer. It will continue any span found in the context or start a new one if absent.

func Test

func Test(fn func(tester *Tester))

Test will temporarily intercept and collect logging, tracing and reporting data for testing purposes.

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 WalkTrace

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

WalkTrace will walk the specified trace.

Types

type BufferSink

type BufferSink struct {
	*bytes.Buffer
}

BufferSink wraps a bytes buffer.

func (*BufferSink) Close

func (s *BufferSink) Close() error

Close implements the io.Closer interface.

type Caller

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

Caller describes a caller.

func GetCaller

func GetCaller(skip int) Caller

GetCaller returns information on 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 {
	// 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 omit trace attributes.
	NoTraceAttributes bool

	// The output for events.
	//
	// Default: Sink("EVENT").
	EventOutput io.Writer

	// Whether to omit event context data.
	NoEventContext bool

	// Whether to omit file paths from event stack traces.
	NoEventPaths bool

	// Whether to omit line numbers from event stack traces.
	NoEventLineNumbers bool
}

Config is used to configure xo.

func (*Config) Ensure

func (c *Config) Ensure()

Ensure will ensure defaults.

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 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 Config) *Debugger

NewDebugger will create and return a new debugger.

func (*Debugger) SentryTransport

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

SentryTransport will return a sentry transport that print received events.

func (*Debugger) SpanSyncer

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

SpanSyncer will return a span syncer that prints received spans.

type Err

type Err struct {
	Err    error
	Msg    string
	Caller Caller
}

Err is the error returned by F(), W() 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 short-hand for a generic map.

type SM

type SM = map[string]string

SM is a short-hand for a string map.

type SafeErr

type SafeErr struct {
	Err
}

SafeErr wraps an 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 AutoTrack

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

AutoTrack calls Track with the callers short name.

func Track

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

Track is used to mark and annotate a function call. It will automatically wrap the context with a child from the span history found in the provided context. If no span history was found it will start a new span.

If the function finds a trace in the context and its root span matches the span from the context it will create a child from the traces tail. If not it considers the span history to have diverged from the trace.

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

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

// track
ctx1, span1 := Track(ctx, "One")
time.Sleep(100 * time.Millisecond)
ctx2, span2 := Track(ctx1, "Two")
span2.Log("hello world")
time.Sleep(100 * time.Millisecond)
_, span3 := Track(ctx2, "Three")
span3.Tag("foo", "bar")
time.Sleep(100 * time.Millisecond)
span3.End()
span2.End()
ctx4, span4 := Track(ctx1, "Four")
span4.Record(F("fatal"))
time.Sleep(100 * time.Millisecond)
_, span5 := Track(ctx4, "Five")
span5.Tag("baz", 42)
time.Sleep(100 * time.Millisecond)
span5.End()
span4.End()
span1.End()

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

===== TRACE =====
One         ├──────────────────────────────────────────────────────────────────────────────┤   500ms
  Two                       ├──────────────────────────────┤                                   200ms
  :log                      •                                                                  100ms
    Three                                   ├──────────────┤                                   100ms
  Four                                                      ├──────────────────────────────┤   200ms
  :error                                                    •                                  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) 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 SpanSyncer

type SpanSyncer func(*trace.SpanData)

SpanSyncer is a functional span exporter.

func (SpanSyncer) ExportSpan

func (s SpanSyncer) ExportSpan(_ context.Context, span *trace.SpanData)

ExportSpan implements the trace.SpanSyncer interface.

type Tester

type Tester struct {
	// Whether events should be cleaned.
	//
	// Default: true.
	CleanEvents bool

	// The collected spans.
	Spans []VSpan

	// The collected reports.
	Reports []VReport

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

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

func (*Tester) ReducedReports

func (t *Tester) ReducedReports() []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) SpanSyncer

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

SpanSyncer will return a span syncer that collects spans.

type Trace

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

Trace implements 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 stack to track execution.

Code that uses Track will automatically discover the stack and branch of its tail if no previous branch has been detected. Other opentracing compatible code would not be able to find the stack and would use the root span instead. This can be prevented by ensuring a branch using the Branch function.

func CreateTrace

func CreateTrace(ctx context.Context, name string) (*Trace, context.Context)

CreateTrace returns a new trace that will use the span found in the provided context as its root or start a new one. The returned context is the provided context wrapped with the new span and trace.

func GetTrace

func GetTrace(ctx context.Context) *Trace

GetTrace will return the trace from the context or nil if absent.

func (*Trace) Attach

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

Attach will add the provided event to the tail.

func (*Trace) End

func (t *Trace) End()

End will end all stacked spans and the root span.

func (*Trace) Log

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

Log will attach a log event to the tail.

func (*Trace) Pop

func (t *Trace) Pop()

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

func (*Trace) Push

func (t *Trace) Push(name string)

Push will add a new span to the trace.

func (*Trace) Record

func (t *Trace) Record(err error)

Record will attach an error event to the tail.

func (*Trace) Rename

func (t *Trace) Rename(name string)

Rename will set a new name on the tail.

func (*Trace) Root

func (t *Trace) Root() Span

Root will return the root of the span stack.

func (*Trace) Tag

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

Tag will add the provided attribute to the tail.

func (*Trace) Tail

func (t *Trace) 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       SM
	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 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.SpanData) VSpan

ConvertSpan will convert a raw span to a virtual span.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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