trace

package module
v1.1.15 Latest Latest
Warning

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

Go to latest
Published: Apr 7, 2021 License: Apache-2.0 Imports: 24 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 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 GetFields

func GetFields(err error) map[string]interface{}

GetFields returns any fields that have been added to the error message

func IsAccessDenied

func IsAccessDenied(err 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

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

IsNotFound returns whether this error is of NotFoundError type

func IsNotImplemented

func IsNotImplemented(e error) bool

IsNotImplemented returns whether this error is of NotImplementedError 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 IsTerminal

func IsTerminal(w io.Writer) bool

IsTerminal checks whether writer is a terminal

func IsTrustError

func IsTrustError(e error) bool

IsTrustError returns if this is a trust error

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 ReadError

func ReadError(statusCode int, respBytes []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 SetDebug

func SetDebug(enabled bool)

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

func Unwrap

func Unwrap(err error) error

Unwrap returns the original error the given error wraps

func UserMessage

func UserMessage(err error) string

UserMessage returns user-friendly part of the error

func UserMessageWithFields

func UserMessageWithFields(err error) string

UserMessageWithFields returns user-friendly error with key-pairs as part of the message

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

func (*ConnectionProblemError) Unwrap

func (c *ConnectionProblemError) Unwrap() error

Unwrap returns the wrapped error if any

type DebugReporter

type DebugReporter interface {
	// DebugReport formats an error for display
	DebugReport() string
}

DebugReporter formats an error for display

type Error

type Error interface {
	error
	ErrorWrapper
	DebugReporter
	UserMessager

	// 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{}) *TraceErr

	// AddField adds additional field information to the error
	AddField(key string, value interface{}) *TraceErr

	// AddFields adds a map of additional fields to the error
	AddFields(fields map[string]interface{}) *TraceErr

	// GetFields returns any fields that have been added to the error
	GetFields() map[string]interface{}
}

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

Error handlers can use Unwrap() to retrieve error from the wrapper, or errors.Is()/As() to compare it to another value.

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 LimitExceeded

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

LimitExceeded returns whether new instance of LimitExceededError

func NotFound

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

NotFound returns new instance of not found error

func NotImplemented

func NotImplemented(message string, args ...interface{}) Error

NotImplemented returns a new instance of NotImplementedError

func OAuth2

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

OAuth2 returns new instance of OAuth2Error

func Retry

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

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

func Trust

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

Trust returns new instance of TrustError

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 ErrorWrapper

type ErrorWrapper interface {
	// OrigError returns the wrapped error
	OrigError() error
}

ErrorWrapper wraps another error

type Fields

type Fields map[string]interface{}

Fields maps arbitrary keys to values inside an error

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 NotImplementedError

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

NotImplementedError defines an error condition to describe the result of a call to an unimplemented API

func (*NotImplementedError) Error

func (e *NotImplementedError) Error() string

Error returns log friendly description of an error

func (*NotImplementedError) IsNotImplementedError

func (e *NotImplementedError) IsNotImplementedError() bool

IsNotImplementedError indicates that this error is of NotImplementedError type

func (*NotImplementedError) OrigError

func (e *NotImplementedError) OrigError() error

OrigError returns original error

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 specifies the original error
	Err json.RawMessage `json:"error,omitempty"`
	// Traces lists the stack traces at the moment the error was recorded
	Traces `json:"traces,omitempty"`
	// Message specifies the optional user-facing message
	Message string `json:"message,omitempty"`
	// Messages is a list of user messages added to this error.
	Messages []string `json:"messages,omitempty"`
	// Fields is a list of key-value-pairs that can be wrapped with the error to give additional context
	Fields map[string]interface{} `json:"fields,omitempty"`
}

RawTrace describes the error trace on the wire

func (*RawTrace) Error

func (r *RawTrace) Error() string

Error returns the error message this trace describes. Implements error

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)

func (*RetryError) Unwrap

func (c *RetryError) Unwrap() error

Unwrap returns the wrapped error if any

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
	// EnableColors enables colored output
	EnableColors bool
	// FormatCaller is a function to return (part) of source file path for output.
	// Defaults to filePathAndLine() if unspecified
	FormatCaller func() (caller string)
}

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 = internal.Trace

type TraceErr

type TraceErr struct {
	// Err is the underlying error that TraceErr wraps
	Err error `json:"error"`
	// Traces is a slice of stack trace entries for the error
	Traces `json:"traces,omitempty"`
	// Message is an optional message that can be wrapped with the original error.
	//
	// This field is obsolete, replaced by messages list below.
	Message string `json:"message,omitempty"`
	// Messages is a list of user messages added to this error.
	Messages []string `json:"messages,omitempty"`
	// Fields is a list of key-value-pairs that can be wrapped with the error to give additional context
	Fields map[string]interface{} `json:"fields,omitempty"`
}

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

func (*TraceErr) AddField

func (e *TraceErr) AddField(k string, v interface{}) *TraceErr

AddField adds a single field to the error wrapper as context for the error

func (*TraceErr) AddFields

func (e *TraceErr) AddFields(fields map[string]interface{}) *TraceErr

AddFields adds the given map of fields to the error being reported

func (*TraceErr) AddUserMessage

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

AddUserMessage adds user-friendly message describing the error nature

func (*TraceErr) DebugReport

func (e *TraceErr) DebugReport() string

DebugReport returns developer-friendly error report

func (*TraceErr) Error

func (e *TraceErr) Error() string

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

func (*TraceErr) GetFields

func (e *TraceErr) GetFields() map[string]interface{}

func (*TraceErr) GoString

func (e *TraceErr) GoString() string

GoString formats this trace object for use with with the "%#v" format string

func (*TraceErr) MarshalJSON

func (r *TraceErr) MarshalJSON() ([]byte, error)

MarshalJSON marshals this error as JSON-encoded payload

func (*TraceErr) OrigError

func (e *TraceErr) OrigError() error

OrigError returns original wrapped error

func (*TraceErr) Unwrap

func (e *TraceErr) Unwrap() error

Unwrap returns the error this TraceErr wraps. The returned error may also wrap another one, Unwrap doesn't recursively get the inner-most error like OrigError does.

func (*TraceErr) UserMessage

func (e *TraceErr) UserMessage() string

UserMessage returns user-friendly error message

type Traces

type Traces = internal.Traces

type TrustError

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

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)

func (*TrustError) Unwrap

func (t *TrustError) Unwrap() error

Unwrap returns the wrapped error if any

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

type UserMessager

type UserMessager interface {
	// UserMessage returns the user message associated with the error if any
	UserMessage() string
}

UserMessager returns a user message associated with the error

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
y or Y : Canonical URL