periskop

package module
v0.0.0-...-c5603b2 Latest Latest
Warning

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

Go to latest
Published: May 12, 2022 License: Apache-2.0 Imports: 13 Imported by: 5

README

periskop-go

Build Status

Periskop requires collecting and aggregating exceptions on the client side, as well as exposing them via an HTTP endpoint using a well defined format.

This library provides low level collection and rendering capabilities

Usage

go get github.com/periskop-dev/periskop-go
Example
package main

import (
	"encoding/json"
	"net/http"

	"github.com/periskop-dev/periskop-go"
)

func faultyJSONParser() error {
	var dat map[string]interface{}
	// will return "unexpected end of JSON input"
	return json.Unmarshal([]byte(`{"id":`), &dat)
}

func main() {
	c := periskop.NewErrorCollector()

	// Without context
	c.ReportError(faultyJSONParser())

	// Optionally pass Severity of an error (supported by all report methods)
	c.ReportWithSeverity(faultyJSONParser(), periskop.SeverityInfo)

	// With HTTP context
	body := "some body"
	c.ReportWithHTTPContext(faultyJSONParser(), &periskop.HTTPContext{
		RequestMethod:  "GET",
		RequestURL:     "http://example.com",
		RequestHeaders: map[string]string{"Cache-Control": "no-cache"},
		RequestBody:    &body, // optional request body, nil if not present
	})

	// With http.Request
	req, err := http.NewRequest("GET", "http://example.com", nil)
	c.ReportWithHTTPRequest(err, req)

	// With a full error report
	c.Report(periskop.ErrorReport{
		Err:      err,
		Severity: SeverityWarning,
		HTTPCtx: &periskop.HTTPContext{
			RequestMethod:  "GET",
			RequestURL:     "http://example.com",
			RequestHeaders: map[string]string{"Cache-Control": "no-cache"},
			RequestBody:    &body,
		},
		ErrKey: "json-parsing", // Overrides the errors aggregation key (see more info below)
	})

	// With a full error report, but with http.Request instead of HTTP context
	c.Report(periskop.ErrorReport{
		Err:         err,
		Severity:    SeverityWarning,
		HTTPRequest: req,
		ErrKey:      "json-parsing",
	})

	// Call the exporter and HTTP handler to expose the
	// errors in /-/exceptions endpoints
	e := periskop.NewErrorExporter(&c)
	h := periskop.NewHandler(e)
	http.Handle("/-/exceptions", h)
	http.ListenAndServe(":8080", nil)
}
Custom aggregation for reported errors

By default errors are aggregated by their stack trace and error message. This might cause that errors that are the same (but with different message) are treated as different in Periskop:

*url.Error@efdca928 -> Get "http://example": dial tcp 10.10.10.1:10100: i/o timeout
*url.Error@824c748e -> Get "http://example": dial tcp 10.10.10.2:10100: i/o timeout

To avoid that, you can manually group errors specifying the error key that you want to use:

func main() {
	c := periskop.NewErrorCollector()
	req, err := http.NewRequest("GET", "http://example.com", nil)
	c.Report(periskop.ErrorReport{
		Err:         err,
		HTTPRequest: req,
		ErrKey:      "example-request-error",
	})
}
Using push gateway

You can also use pushgateway in case you want to push your metrics instead of using pull method. Use only in case you really need it (e.g a batch job) as it would degrade the performance of your application. In the following example, we assume that we deployed an instance of periskop-pushgateway on http://localhost:6767:

package main

import (
	"encoding/json"
	"github.com/periskop-dev/periskop-go"
)

func faultyJSONParser() error {
	var dat map[string]interface{}
	// will return "unexpected end of JSON input"
	return json.Unmarshal([]byte(`{"id":`), &dat)
}

func reportAndPush(c *periskop.ErrorCollector, e *periskop.ErrorExporter, err error) error {
  c.ReportError(err)
  return e.PushToGateway("http://localhost:6767")
}

func main() {
	c := periskop.NewErrorCollector()
	e := periskop.NewErrorExporter(&c)

	reportAndPush(&c, &e, faultyJSONParser())
}

Contributing

Please see CONTRIBUTING.md

Documentation

Index

Constants

View Source
const (
	SeverityInfo    Severity = "info"
	SeverityWarning Severity = "warning"
	SeverityError   Severity = "error"
	MaxTraces       int      = 4
	MaxErrors       int      = 10
)

Variables

This section is empty.

Functions

func NewHandler

func NewHandler(e ErrorExporter) http.Handler

NewHandler receives a Periskop Error Exporter and returns a handler with the exported errors in json format

Types

type ErrorCollector

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

ErrorCollector collects all the aggregated errors

func NewErrorCollector

func NewErrorCollector() ErrorCollector

NewErrorCollector creates a new ErrorCollector

func (*ErrorCollector) Report

func (c *ErrorCollector) Report(report ErrorReport)

Report adds an error report to map of aggregated errors. Severity defaults to Error when missing.

func (*ErrorCollector) ReportError

func (c *ErrorCollector) ReportError(err error)

ReportError adds an error with severity Error to map of aggregated errors

func (*ErrorCollector) ReportErrorWithContext

func (c *ErrorCollector) ReportErrorWithContext(errWithContext ErrorWithContext, severity Severity, errKey string)

ReportErrorWithContext adds a manually generated ErrorWithContext to map of aggregated errors

func (*ErrorCollector) ReportWithHTTPContext

func (c *ErrorCollector) ReportWithHTTPContext(err error, httpCtx *HTTPContext)

ReportWithHTTPContext adds an error with severity Error (with HTTPContext) to map of aggregated errors

func (*ErrorCollector) ReportWithHTTPContextAndSeverity

func (c *ErrorCollector) ReportWithHTTPContextAndSeverity(err error, severity Severity, httpCtx *HTTPContext)

ReportWithHTTPContextAndSeverity adds an error with given severity (with HTTPContext) to map of aggregated errors

func (*ErrorCollector) ReportWithHTTPRequest

func (c *ErrorCollector) ReportWithHTTPRequest(err error, r *http.Request)

ReportWithHTTPRequest adds and error with severity Error (with HTTPContext from http.Request) to map of aggregated errors

func (*ErrorCollector) ReportWithHTTPRequestAndSeverity

func (c *ErrorCollector) ReportWithHTTPRequestAndSeverity(err error, severity Severity, r *http.Request)

ReportWithHTTPRequestAndSeverity adds and error with given severity (with HTTPContext from http.Request) to map of aggregated errors

func (*ErrorCollector) ReportWithSeverity

func (c *ErrorCollector) ReportWithSeverity(err error, severity Severity)

ReportWithSeverity adds an error with given severity to map of aggregated errors

type ErrorExporter

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

ErrorExporter exposes collected errors

func NewErrorExporter

func NewErrorExporter(collector *ErrorCollector) ErrorExporter

NewErrorExporter creates a new ErrorExporter

func (*ErrorExporter) Export

func (e *ErrorExporter) Export() (string, error)

Export exports all collected errors in json format

func (*ErrorExporter) PushToGateway

func (e *ErrorExporter) PushToGateway(addr string) error

PushToGateway pushes all collected errors to the pushgateway specified by `addr`

type ErrorInstance

type ErrorInstance struct {
	Class      string         `json:"class"`
	Message    string         `json:"message"`
	Stacktrace []string       `json:"stacktrace"`
	Cause      *ErrorInstance `json:"cause"`
}

func NewCustomErrorInstance

func NewCustomErrorInstance(errMsg string, errType string, stacktrace []string) ErrorInstance

NewCustomErrorInstance allows to create a custom error instance without specifying a Go error

type ErrorReport

type ErrorReport struct {
	Err         error
	Severity    Severity
	HTTPRequest *http.Request
	HTTPCtx     *HTTPContext
	ErrKey      string
}

ErrorReport represents a report of a single error

type ErrorWithContext

type ErrorWithContext struct {
	Error       ErrorInstance `json:"error"`
	UUID        uuid.UUID     `json:"uuid"`
	Timestamp   time.Time     `json:"timestamp"`
	Severity    Severity      `json:"severity"`
	HTTPContext *HTTPContext  `json:"http_context"`
}

func NewErrorWithContext

func NewErrorWithContext(errInstance ErrorInstance, severity Severity, httpCtx *HTTPContext) ErrorWithContext

type HTTPContext

type HTTPContext struct {
	RequestMethod  string            `json:"request_method"`
	RequestURL     string            `json:"request_url"`
	RequestHeaders map[string]string `json:"request_headers"`
	RequestBody    *string           `json:"request_body"`
}

HTTPContext holds info of the HTTP context when an error is produced

type Severity

type Severity string

Severity is the definition of different severities

Directories

Path Synopsis
Package errors provides errors that have stack-traces.
Package errors provides errors that have stack-traces.

Jump to

Keyboard shortcuts

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