trace

package module
Version: v0.0.0-...-0bd1364 Latest Latest
Warning

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

Go to latest
Published: Nov 18, 2017 License: Apache-2.0 Imports: 21 Imported by: 0

README

Trace

GoDoc

Package for error handling and error reporting

Read more here:

http://gravitational.com/blog/golang_error_handling/

Capture file, line and function

import (
     "github.com/gravitational/trace"
)

func someFunc() error {
   return trace.Wrap(err)
}


func main() {
  err := someFunc()
  fmt.Println(err.Error()) // prints file, line and function
}
Emit structured logs to Elastic search using udpbeat

Add trace's document template to your ElasticSearch cluster

curl -XPUT 'http://localhost:9200/_template/trace' -d@udbbeat/template.json

Start udpbeat UDP logs collector and emitter

go get github.com/gravitational/udpbeat
udpbeat

Hook up logger to UDP collector

In your code, attach a logrus hook to use udpbeat:


import (
   "github.com/gravitational/trace"
   log "github.com/sirupsen/logrus"
)

func main() {
   hook, err := trace.NewUDPHook()
   if err != nil {
       log.Fatalf(err)
   }
   log.SetHook(hook)
}

Done! You will get structured logs capturing output, log and error message. You can edit udpbeat/template.json to modify emitted fields to whatever makes sense to your app.

Documentation

Overview

Package trace implements utility functions for capturing logs

Package trace implements utility functions for capturing debugging information about file and line in error reports and logs.

Index

Constants

View Source
const (
	// FileField is a field with code file added to structured traces
	FileField = "file"
	// FunctionField is a field with function name
	FunctionField = "func"
	// LevelField returns logging level as set by logrus
	LevelField = "level"
	// Component is a field that represents component - e.g. service or
	// function
	Component = "trace.component"
	// ComponentFields is a fields component
	ComponentFields = "trace.fields"
	// DefaultComponentPadding is a default padding for component field
	DefaultComponentPadding = 11
	// DefaultLevelPadding is a default padding for level field
	DefaultLevelPadding = 4
)
View Source
const (
	// UDPDefaultAddr is a default address to emit logs to
	UDPDefaultAddr = "127.0.0.1:5000"
	// UDPDefaultNet is a default network
	UDPDefaultNet = "udp"
)

Variables

This section is empty.

Functions

func AccessDenied

func AccessDenied(message string, args ...interface{}) error

AccessDenied returns new instance of AccessDeniedError

func AlreadyExists

func AlreadyExists(message string, args ...interface{}) error

AlreadyExists returns a new instance of AlreadyExists error

func BadParameter

func BadParameter(message string, args ...interface{}) error

BadParameter returns a new instance of BadParameterError

func CompareFailed

func CompareFailed(message string, args ...interface{}) error

CompareFailed returns new instance of CompareFailedError

func ConnectionProblem

func ConnectionProblem(err error, message string, args ...interface{}) error

ConnectionProblem returns new instance of ConnectionProblemError

func ConvertSystemError

func ConvertSystemError(err error) error

ConvertSystemError converts system error to appropriate trace error if it is possible, otherwise, returns original error

func DebugReport

func DebugReport(err error) string

DebugReport returns debug report with all known information about the error including stack trace if it was captured

func ErrorToCode

func ErrorToCode(err error) int

ErrorToCode returns an appropriate HTTP status code based on the provided error type

func Errorf

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

Errorf is similar to fmt.Errorf except that it captures more information about the origin of error, such as callee, line number and function that simplifies debugging

func Fatalf

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

Fatalf - If debug is false Fatalf calls Errorf. If debug is true Fatalf calls panic

func IsAccessDenied

func IsAccessDenied(e error) bool

IsAccessDenied detects if this error is of AccessDeniedError type

func IsAggregate

func IsAggregate(err error) bool

IsAggregate returns whether this error of Aggregate error type

func IsAlreadyExists

func IsAlreadyExists(e error) bool

IsAlreadyExists returns whether this is error indicating that object already exists

func IsBadParameter

func IsBadParameter(e error) bool

IsBadParameter returns whether this error is of BadParameterType

func IsCompareFailed

func IsCompareFailed(e error) bool

IsCompareFailed detects if this error is of CompareFailed type

func IsConnectionProblem

func IsConnectionProblem(e error) bool

IsConnectionProblem returns whether this error is of ConnectionProblemError

func IsDebug

func IsDebug() bool

IsDebug returns true if debug mode is on, false otherwize

func IsEOF

func IsEOF(e error) bool

IsEOF returns true if the passed error is io.EOF

func IsLimitExceeded

func IsLimitExceeded(e error) bool

IsLimitExceeded detects if this error is of LimitExceededError

func IsNotFound

func IsNotFound(e error) bool

IsNotFound returns whether this error is of NotFoundError type

func IsOAuth2

func IsOAuth2(e error) bool

IsOAuth2 returns if this is a OAuth2-related error

func IsRetryError

func IsRetryError(e error) bool

IsRetryError returns whether this error is of ConnectionProblemError

func IsTrustError

func IsTrustError(e error) bool

IsTrustError returns if this is a trust error

func LimitExceeded

func LimitExceeded(message string, args ...interface{}) error

LimitExceeded returns whether new instance of LimitExceededError

func NewAggregate

func NewAggregate(errs ...error) error

NewAggregate creates a new aggregate instance from the specified list of errors

func NewAggregateFromChannel

func NewAggregateFromChannel(errCh chan error, ctx context.Context) error

NewAggregateFromChannel creates a new aggregate instance from the provided errors channel.

A context.Context can be passed in so the caller has the ability to cancel the operation. If this is not desired, simply pass context.Background().

func NotFound

func NotFound(message string, args ...interface{}) error

NotFound returns new instance of not found error

func ReadError

func ReadError(statusCode int, re []byte) error

ReadError converts http error to internal error type based on HTTP response code and HTTP body contents if status code does not indicate error, it will return nil

func Retry

func Retry(err error, message string, args ...interface{}) error

Retry return new instance of RetryError which indicates a transient error type

func SetDebug

func SetDebug(enabled bool)

SetDebug turns on/off debugging mode, that causes Fatalf to panic

func Unwrap

func Unwrap(err error) error

Unwrap unwraps error to it's original error

func UserMessage

func UserMessage(err error) string

UserMessage returns user-friendly part of the error

func WriteError

func WriteError(w http.ResponseWriter, err error)

WriteError sets up HTTP error response and writes it to writer w

Types

type AccessDeniedError

type AccessDeniedError struct {
	Message string `json:"message"`
}

AccessDeniedError indicates denied access

func (*AccessDeniedError) Error

func (e *AccessDeniedError) Error() string

Error is debug - friendly error message

func (*AccessDeniedError) IsAccessDeniedError

func (e *AccessDeniedError) IsAccessDeniedError() bool

IsAccessDeniedError indicates that this error is of AccessDeniedError type

func (*AccessDeniedError) OrigError

func (e *AccessDeniedError) OrigError() error

OrigError returns original error (in this case this is the error itself)

type Aggregate

type Aggregate interface {
	error
	// Errors obtains the list of errors this aggregate combines
	Errors() []error
}

Aggregate interface combines several errors into one error

type AlreadyExistsError

type AlreadyExistsError struct {
	Message string `json:"message"`
}

AlreadyExistsError indicates that there's a duplicate object that already exists in the storage/system

func (*AlreadyExistsError) Error

func (n *AlreadyExistsError) Error() string

Error returns log friendly description of an error

func (AlreadyExistsError) IsAlreadyExistsError

func (AlreadyExistsError) IsAlreadyExistsError() bool

IsAlreadyExistsError indicates that this error of the AlreadyExistsError type

func (*AlreadyExistsError) OrigError

func (e *AlreadyExistsError) OrigError() error

OrigError returns original error (in this case this is the error itself)

type BadParameterError

type BadParameterError struct {
	Message string `json:"message"`
}

BadParameterError indicates that something is wrong with passed parameter to API method

func (*BadParameterError) Error

func (b *BadParameterError) Error() string

Error returns log friendly description of an error

func (*BadParameterError) IsBadParameterError

func (b *BadParameterError) IsBadParameterError() bool

IsBadParameterError indicates that this error is of BadParameterError type

func (*BadParameterError) OrigError

func (b *BadParameterError) OrigError() error

OrigError returns original error (in this case this is the error itself)

type CompareFailedError

type CompareFailedError struct {
	// Message is user-friendly error message
	Message string `json:"message"`
}

CompareFailedError indicates a failed comparison (e.g. bad password or hash)

func (*CompareFailedError) Error

func (e *CompareFailedError) Error() string

Error is debug - friendly message

func (*CompareFailedError) IsCompareFailedError

func (e *CompareFailedError) IsCompareFailedError() bool

IsCompareFailedError indicates that this is CompareFailedError

func (*CompareFailedError) OrigError

func (e *CompareFailedError) OrigError() error

OrigError returns original error (in this case this is the error itself)

type ConnectionProblemError

type ConnectionProblemError struct {
	Message string `json:"message"`
	Err     error  `json:"-"`
}

ConnectionProblemError indicates a network related problem

func (*ConnectionProblemError) Error

func (c *ConnectionProblemError) Error() string

Error is debug - friendly error message

func (*ConnectionProblemError) IsConnectionProblemError

func (c *ConnectionProblemError) IsConnectionProblemError() bool

IsConnectionProblemError indicates that this error is of ConnectionProblemError type

func (*ConnectionProblemError) OrigError

func (c *ConnectionProblemError) OrigError() error

OrigError returns original error (in this case this is the error itself)

type Error

type Error interface {
	error
	// OrigError returns original error wrapped in this error
	OrigError() error
	// AddMessage adds formatted user-facing message
	// to the error, depends on the implementation,
	// usually works as fmt.Sprintf(formatArg, rest...)
	// but implementations can choose another way, e.g. treat
	// arguments as structured args
	AddUserMessage(formatArg interface{}, rest ...interface{})

	// UserMessage returns user-friendly error message
	UserMessage() string

	// DebugReport returns develeoper-friendly error report
	DebugReport() string
}

Error is an interface that helps to adapt usage of trace in the code When applications define new error types, they can implement the interface So error handlers can use OrigError() to retrieve error from the wrapper

func OAuth2

func OAuth2(code, message string, query url.Values) Error

OAuth2 returns new instance of OAuth2Error

func Wrap

func Wrap(err error, args ...interface{}) Error

Wrap takes the original error and wraps it into the Trace struct memorizing the context of the error.

func WrapWithMessage

func WrapWithMessage(err error, message interface{}, args ...interface{}) Error

WrapWithMessage wraps the original error into Error and adds user message if any

type Frame

type Frame struct {
	Time    time.Time              `json:"time"`
	Type    string                 `json:"type"`
	Entry   map[string]interface{} `json:"entry"`
	Message string                 `json:"message"`
	Level   string                 `json:"level"`
}

type JSONFormatter

type JSONFormatter struct {
	log.JSONFormatter
}

JSONFormatter implements logrus.Formatter interface and adds file and line properties to JSON entries

func (*JSONFormatter) Format

func (j *JSONFormatter) Format(e *log.Entry) ([]byte, error)

Format implements logrus.Formatter interface

type LimitExceededError

type LimitExceededError struct {
	Message string `json:"message"`
}

LimitExceededError indicates rate limit or connection limit problem

func (*LimitExceededError) Error

func (c *LimitExceededError) Error() string

Error is debug - friendly error message

func (*LimitExceededError) IsLimitExceededError

func (c *LimitExceededError) IsLimitExceededError() bool

IsLimitExceededError indicates that this error is of ConnectionProblem

func (*LimitExceededError) OrigError

func (c *LimitExceededError) OrigError() error

OrigError returns original error (in this case this is the error itself)

type NotFoundError

type NotFoundError struct {
	Message string `json:"message"`
}

NotFoundError indicates that object has not been found

func (*NotFoundError) Error

func (e *NotFoundError) Error() string

Error returns log friendly description of an error

func (*NotFoundError) IsNotFoundError

func (e *NotFoundError) IsNotFoundError() bool

IsNotFoundError returns true to indicate that is NotFoundError

func (*NotFoundError) OrigError

func (e *NotFoundError) OrigError() error

OrigError returns original error (in this case this is the error itself)

type OAuth2Error

type OAuth2Error struct {
	Code    string     `json:"code"`
	Message string     `json:"message"`
	Query   url.Values `json:"query"`
}

OAuth2Error defined an error used in OpenID Connect Flow (OIDC)

func (*OAuth2Error) Error

func (o *OAuth2Error) Error() string

Error returns log friendly description of an error

func (*OAuth2Error) IsOAuth2Error

func (o *OAuth2Error) IsOAuth2Error() bool

IsOAuth2Error returns whether this error of OAuth2Error type

type RawTrace

type RawTrace struct {
	Err     json.RawMessage `json:"error"`
	Traces  `json:"traces"`
	Message string `json:"message"`
}

type RetryError

type RetryError struct {
	Message string `json:"message"`
	Err     error  `json:"-"`
}

RetryError indicates a transient error type

func (*RetryError) Error

func (c *RetryError) Error() string

Error is debug-friendly error message

func (*RetryError) IsRetryError

func (c *RetryError) IsRetryError() bool

IsRetryError indicates that this error is of RetryError type

func (*RetryError) OrigError

func (c *RetryError) OrigError() error

OrigError returns original error (in this case this is the error itself)

type TextFormatter

type TextFormatter struct {
	// DisableTimestamp disables timestamp output (useful when outputting to
	// systemd logs)
	DisableTimestamp bool
	// ComponentPadding is a padding to pick when displaying
	// and formatting component field, defaults to DefaultComponentPadding
	ComponentPadding int
}

TextFormatter is logrus-compatible formatter and adds file and line details to every logged entry.

func (*TextFormatter) Format

func (tf *TextFormatter) Format(e *log.Entry) (data []byte, err error)

Format implements logrus.Formatter interface and adds file and line

type Trace

type Trace struct {
	// Path is a full file path
	Path string `json:"path"`
	// Func is a function name
	Func string `json:"func"`
	// Line is a code line number
	Line int `json:"line"`
}

Trace stores structured trace entry, including file line and path

func (*Trace) String

func (t *Trace) String() string

String returns debug-friendly representation of this trace

type TraceErr

type TraceErr struct {
	Err     error `json:"error"`
	Traces  `json:"traces"`
	Message string `json:"message,omitemtpy"`
}

TraceErr contains error message and some additional information about the error origin

func (*TraceErr) AddUserMessage

func (e *TraceErr) AddUserMessage(formatArg interface{}, rest ...interface{})

AddUserMessage adds user-friendly message describing the error nature

func (*TraceErr) DebugReport

func (e *TraceErr) DebugReport() string

DebugReport returns develeoper-friendly error report

func (*TraceErr) Error

func (e *TraceErr) Error() string

Error returns user-friendly error message when not in debug mode

func (*TraceErr) OrigError

func (e *TraceErr) OrigError() error

OrigError returns original wrapped error

func (*TraceErr) UserMessage

func (e *TraceErr) UserMessage() string

UserMessage returns user-friendly error message

type Traces

type Traces []Trace

Traces is a list of trace entries

func (Traces) Func

func (s Traces) Func() string

Func returns first function in trace list

func (Traces) FuncName

func (s Traces) FuncName() string

Func returns just function name

func (Traces) Loc

func (s Traces) Loc() string

Loc points to file/line location in the code

func (Traces) SetTraces

func (s Traces) SetTraces(traces ...Trace)

SetTraces adds new traces to the list

func (Traces) String

func (s Traces) String() string

String returns debug-friendly representaton of trace stack

type TrustError

type TrustError struct {
	// Err is original error
	Err     error `json:"error"`
	Message string
}

TrustError indicates trust-related validation error (e.g. untrusted cert)

func (*TrustError) Error

func (t *TrustError) Error() string

Error returns log-friendly error description

func (*TrustError) IsTrustError

func (*TrustError) IsTrustError() bool

IsTrustError indicates that this error is of TrustError type

func (*TrustError) OrigError

func (t *TrustError) OrigError() error

OrigError returns original error (in this case this is the error itself)

type UDPHook

type UDPHook struct {
	Clock clockwork.Clock
	// contains filtered or unexported fields
}

func NewUDPHook

func NewUDPHook(opts ...UDPOptionSetter) (*UDPHook, error)

NewUDPHook returns logrus-compatible hook that sends data to UDP socket

func (*UDPHook) Fire

func (elk *UDPHook) Fire(e *log.Entry) error

Fire fires the event to the ELK beat

func (*UDPHook) Levels

func (elk *UDPHook) Levels() []log.Level

Levels returns logging levels supported by logrus

type UDPOptionSetter

type UDPOptionSetter func(f *UDPHook)

UDPOptionSetter represents functional arguments passed to ELKHook

Directories

Path Synopsis
Package trail integrates trace errors with GRPC Example server that sends the GRPC error and attaches metadata: func (s *server) Echo(ctx context.Context, message *gw.StringMessage) (*gw.StringMessage, error) { trace.SetDebug(true) // to tell trace to start attaching metadata // Send sends metadata via grpc header and converts error to GRPC compatible one return nil, trail.Send(ctx, trace.AccessDenied("missing authorization")) } Example client reading error and trace debug info: var header metadata.MD r, err := c.Echo(context.Background(), &gw.StringMessage{Value: message}, grpc.Header(&header)) if err != nil { // FromGRPC reads error, converts it back to trace error and attaches debug metadata // like stack trace of the error origin back to the error err = trail.FromGRPC(err, header) / // this line will log original trace of the error log.Errorf("error saying echo: %v", trace.DebugReport(err)) return }
Package trail integrates trace errors with GRPC Example server that sends the GRPC error and attaches metadata: func (s *server) Echo(ctx context.Context, message *gw.StringMessage) (*gw.StringMessage, error) { trace.SetDebug(true) // to tell trace to start attaching metadata // Send sends metadata via grpc header and converts error to GRPC compatible one return nil, trail.Send(ctx, trace.AccessDenied("missing authorization")) } Example client reading error and trace debug info: var header metadata.MD r, err := c.Echo(context.Background(), &gw.StringMessage{Value: message}, grpc.Header(&header)) if err != nil { // FromGRPC reads error, converts it back to trace error and attaches debug metadata // like stack trace of the error origin back to the error err = trail.FromGRPC(err, header) / // this line will log original trace of the error log.Errorf("error saying echo: %v", trace.DebugReport(err)) return }

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
t or T : Toggle theme light dark auto
y or Y : Canonical URL