iopipe

package module
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Jun 20, 2018 License: Apache-2.0 Imports: 24 Imported by: 9

README

IOpipe Agent for Go (beta)

Slack

This package provides analytics and distributed tracing for event-driven applications running on AWS Lambda.

Installation

Using go get:

go get https://github.com/iopipe/iopipe-go

Using dep:

dep ensure -add github.com/iopipe/iopipe-go

Usage

Set the IOPIPE_TOKEN environment variable to your project token,

import this library, instantiate an agent, and wrap your handler that you expose to AWS:

import (
	"github.com/aws/aws-lambda-go/lambda"
	"github.com/iopipe/iopipe-go"
)

var agent = iopipe.NewAgent(iopipe.Config{})

func hello() (string, error) {
	return "Hello ƛ!", nil
}

func main() {
	lambda.Start(agent.WrapHandler(hello))
}

The iopipe.Config struct offers further options for configuring how your function interacts with IOpipe, please refer to the godocfor more information.

Configuration

The following may be set via the iopipe.Config{} struct passed to the iopipe.NewAgent() initializer:

Token (*string: required)

Your IOpipe project token. If not supplied, the environment variable IOPIPE_TOKEN will be used if present. Find your project token

Debug (*bool: optional = false)

Debug mode will log all data sent to IOpipe servers. This is also a good way to evaluate the sort of data that IOpipe is receiving from your application. If not supplied, the environment variable IOPIPE_DEBUG will be used if present.

TimeoutWindow (*time.Duration: optional = 150)

By default, IOpipe will capture timeouts by exiting your function 150 milliseconds early from the AWS configured timeout, to allow time for reporting. You can disable this feature by setting timeout_window to 0 in your configuration. If not supplied, the environment variable IOPIPE_TIMEOUT_WINDOW will be used if present.

Enabled (*bool: optional = true)

Conditionally enable/disable the agent. The environment variable IOPIPE_ENABLED will also be checked.

Contexts

The IOpipe agent wraps the lambdacontext.LambdaContext. So instead of doing this:

import (
	"context"
	"fmt"

	"github.com/aws/aws-lambda-go/lambda"
)

func hello(ctx context.Context) (string, error) {
	context, _ := lambdacontext.FromContext(ctx)

	return fmt.Sprintf("My requestId is %s", context.AwsRequestID), nil
}

func main() {
	lambda.Start(agent.WrapHandler(hello))
}

You can do this:

import (
	"context"
	"fmt"

	"github.com/aws/aws-lambda-go/lambda"
	"github.com/iopipe/iopipe-go"
)

var agent = iopipe.NewAgent(iopipe.Config{})

func hello(ctx context.Context) (string, error) {
	context, _ := iopipe.FromContext(ctx)

	return fmt.Sprintf("My requestId is %s", context.AwsRequestID), nil
}

func main() {
	lambda.Start(agent.WrapHandler(hello))
}

And the lambdacontext.LambdaContext will be embedded in context. In addition to this, iopipe.FromContext() also attaches context.IOpipe which exposes methods to instrument your functions. See the sections below for examples.

Custom Metrics

You can log custom values in the data sent upstream to IOpipe using the following syntax:

import (
	"context"

	"github.com/aws/aws-lambda-go/lambda"
	"github.com/iopipe/iopipe-go"
)

var agent = iopipe.NewAgent(iopipe.Config{})

func hello(ctx context.Context) (string, error) {
	context, _ := iopipe.FromContext(ctx)

	// numerical (int, float) and string types supported for values
	context.IOpipe.Metric("my_metric", 42)

	return "Hello ƛ!", nil
}

func main() {
	lambda.Start(agent.WrapHandler(hello))
}

Metric key names are limited to 128 characters, and string values are limited to 1024 characters.

Labels

Invocation labels can be sent to IOpipe by calling the Label method with a string (limit of 128 characters):

import (
	"context"

	"github.com/aws/aws-lambda-go/lambda"
	"github.com/iopipe/iopipe-go"
)

var agent = iopipe.NewAgent(iopipe.Config{})

func hello(ctx context.Context) (string, error) {
	context, _ := iopipe.FromContext(ctx)

	// the name of the label must be a string
	context.IOpipe.Label("this-invocation-is-special")

	return "Hello ƛ!", nil
}

func main() {
	lambda.Start(agent.WrapHandler(hello))
}
Reporting Errors

The IOpipe agent will automatically recover, trace and re-panic any unhandled panics in your function. If you want to trace errors in your case, you can use the .Error(err) method. This will add the error to the current report.

import (
	"context"

	"github.com/aws/aws-lambda-go/lambda"
	"github.com/iopipe/iopipe-go"
)

var agent = iopipe.NewAgent(iopipe.Config{})

func hello(ctx context.Context) (string, error) {
	context, _ := iopipe.FromContext(ctx)

	thing, err := doSomething()

	if err != nil {
	  context.IOpipe.Error(err)
	}

	return "Hello ƛ!", nil
}

func main() {
	lambda.Start(agent.WrapHandler(hello))
}

It is important to note that a report is sent to IOpipe when Error() is called. So you should only record exceptions this way for failure states. For caught exceptions that are not a failure state, it is recommended to use custom metrics.

You also don't need to use Error() if the error is being returned as the second return value of the function. IOpipe will add that error to the report for you automatically.

Running Tests

The tests use Convey, so make sure that is installed:

go get github.com/smartystreets/goconvey

We use dep for package dependencies, to installed them:

dep ensure

To run the tests:

go test -v

Contributing

Please refer to our code of conduct. Please follow it in all your interactions with the project.

License

Apache 2.0

Documentation

Index

Constants

View Source
const (
	// VERSION is the version of the IOpipe agent
	VERSION = "0.1.1"

	// RUNTIME is the runtime of the IOpipe agent
	RUNTIME = "go"
)
View Source
const HookPostInvoke = "post:invoke"

HookPostInvoke is a hook run after an invocation

View Source
const HookPostReport = "post:report"

HookPostReport is a hook run after reporting

View Source
const HookPostSetup = "post:setup"

HookPostSetup is a hook run after agent setup

View Source
const HookPreInvoke = "pre:invoke"

HookPreInvoke is a hook run before an invocation

View Source
const HookPreReport = "pre:report"

HookPreReport is a hook run before reporting

View Source
const HookPreSetup = "pre:setup"

HookPreSetup is ahook run before agent setup

Variables

This section is empty.

Functions

func False

func False() *bool

False returns a pointer to false

func NewContext

func NewContext(parent context.Context, cw *ContextWrapper) context.Context

NewContext returns a new Context that contains the IOpipe context wrapper

func True

func True() *bool

True returns a pointer to true

Types

type Agent

type Agent struct {
	*Config
	// contains filtered or unexported fields
}

Agent is the IOpipe instance

func NewAgent

func NewAgent(config Config) *Agent

NewAgent returns a new IOpipe instance with config

func (*Agent) WrapHandler

func (a *Agent) WrapHandler(handler interface{}) interface{}

WrapHandler wraps the handler with the IOpipe agent

type Config

type Config struct {
	Debug               *bool
	Enabled             *bool
	PluginInstantiators []PluginInstantiator
	Reporter            Reporter
	TimeoutWindow       *time.Duration
	Token               *string
}

Config is the config object passed to agent initialization

type ContextWrapper

type ContextWrapper struct {
	*lambdacontext.LambdaContext
	IOpipe *HandlerWrapper
}

ContextWrapper wraps the AWS lambda context

func FromContext

func FromContext(ctx context.Context) (*ContextWrapper, bool)

FromContext returns the context wrapper stored in ctx

func NewContextWrapper

func NewContextWrapper(ctx *lambdacontext.LambdaContext, handler *HandlerWrapper) *ContextWrapper

NewContextWrapper returns a new context wrapper

type CustomMetric

type CustomMetric struct {
	Name string      `json:"name"`
	S    interface{} `json:"s"`
	N    interface{} `json:"n"`
}

CustomMetric is a custom metric

type HandlerWrapper

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

HandlerWrapper is the IOpipe handler wrapper

func NewHandlerWrapper

func NewHandlerWrapper(handler interface{}, agent *Agent) *HandlerWrapper

NewHandlerWrapper creates a new IOpipe handler wrapper

func (*HandlerWrapper) Error

func (hw *HandlerWrapper) Error(err error)

Error adds an error to the report

func (*HandlerWrapper) Invoke

func (hw *HandlerWrapper) Invoke(ctx context.Context, payload interface{}) (response interface{}, err error)

Invoke invokes the wrapped handler, handling panics and timeouts

func (*HandlerWrapper) Label

func (hw *HandlerWrapper) Label(name string)

Label adds a label to the report

func (*HandlerWrapper) Metric

func (hw *HandlerWrapper) Metric(name string, value interface{})

Metric adds a custom metric to the report

type InvocationError

type InvocationError struct {
	Message    string                  `json:"message"`
	Name       string                  `json:"name"`
	StackTrace []*panicErrorStackFrame `json:"-"`
	Stack      string                  `json:"stack"`
}

InvocationError is an invocation error caught by the agent

func NewInvocationError

func NewInvocationError(err error) *InvocationError

NewInvocationError returns an new InvocationError

func NewPanicInvocationError

func NewPanicInvocationError(err interface{}) *InvocationError

NewPanicInvocationError returns a new panic InvocationError

func (*InvocationError) Error

func (h *InvocationError) Error() string

type LoggerPluginConfig

type LoggerPluginConfig struct {
	Key string
}

LoggerPluginConfig is the logger plugin configuration

type Plugin

type Plugin interface {
	Meta() *PluginMeta
	Name() string
	Version() string
	Homepage() string
	Enabled() bool

	// Hook methods
	PreSetup(*Agent)
	PostSetup(*Agent)
	PreInvoke(context.Context, interface{})
	PostInvoke(context.Context, interface{})
	PreReport(*Report)
	PostReport(*Report)
}

Plugin is the interface a plugin should implement

type PluginInstantiator

type PluginInstantiator func() Plugin

PluginInstantiator is the function that initializes the plugin

func LoggerPlugin

func LoggerPlugin(config LoggerPluginConfig) PluginInstantiator

LoggerPlugin loads the logger plugin

func TestPlugin

func TestPlugin(config TestPluginConfig) PluginInstantiator

TestPlugin returns a test plugin

type PluginMeta

type PluginMeta struct {
	Name     string `json:"name"`
	Version  string `json:"version"`
	Homepage string `json:"homepage"`
	Enabled  bool   `json:"enabled"`
}

PluginMeta is meta data about the plugin

type Report

type Report struct {
	ClientID      string             `json:"client_id"`
	InstallMethod string             `json:"installMethod"`
	Duration      int                `json:"duration"`
	ProcessID     string             `json:"processId"`
	Timestamp     int                `json:"timestamp"`
	TimestampEnd  int                `json:"timestampEnd"`
	AWS           *ReportAWS         `json:"aws"`
	Disk          *ReportDisk        `json:"disk"`
	Environment   *ReportEnvironment `json:"environment"`
	ColdStart     bool               `json:"coldstart"`
	Errors        interface{}        `json:"errors"`
	CustomMetrics []CustomMetric     `json:"custom_metrics"`

	Labels  []string      `json:"labels"`
	Plugins []interface{} `json:"plugins"`
	// contains filtered or unexported fields
}

Report contains an IOpipe report

func NewReport

func NewReport(handler *HandlerWrapper) *Report

NewReport instantiates a new IOpipe report

type ReportAWS

type ReportAWS struct {
	FunctionName             string `json:"functionName"`
	FunctionVersion          string `json:"functionVersion"`
	AWSRequestID             string `json:"awsRequestId"`
	InvokedFunctionArn       string `json:"invokedFunctionArn"`
	LogGroupName             string `json:"logGroupName"`
	LogStreamName            string `json:"logStreamName"`
	MemoryLimitInMB          int    `json:"memoryLimitInMB"`
	GetRemainingTimeInMillis int    `json:"getRemainingTimeInMillis"`
	TraceID                  string `json:"traceId"`
}

ReportAWS contains AWS invocation details

type ReportDisk

type ReportDisk struct {
	TotalMiB       float64 `json:"totalMiB"`
	UsedMiB        float64 `json:"usedMiB"`
	UsedPercentage float64 `json:"usedPercentage"`
}

ReportDisk contains disk usage information

type ReportEnvironment

type ReportEnvironment struct {
	Agent   *ReportEnvironmentAgent   `json:"agent"`
	Host    *ReportEnvironmentHost    `json:"host"`
	OS      *ReportEnvironmentOS      `json:"os"`
	Runtime *ReportEnvironmentRuntime `json:"runtime"`
}

ReportEnvironment contains environment information

type ReportEnvironmentAgent

type ReportEnvironmentAgent struct {
	Runtime  string `json:"runtime"`
	Version  string `json:"version"`
	LoadTime int    `json:"load_time"`
}

ReportEnvironmentAgent contains information about the IOpipe agent

type ReportEnvironmentHost

type ReportEnvironmentHost struct {
	BootID string `json:"boot_id"`
}

ReportEnvironmentHost contains host information

type ReportEnvironmentOS

type ReportEnvironmentOS struct {
	FreeMem  uint64                    `json:"freemem"`
	Hostname string                    `json:"hostname"`
	TotalMem uint64                    `json:"totalmem"`
	UsedMem  uint64                    `json:"usedmem"`
	CPUs     []ReportEnvironmentOSCPU  `json:"cpus"`
	Linux    *ReportEnvironmentOSLinux `json:"linux"`
}

ReportEnvironmentOS contains operating system information

type ReportEnvironmentOSCPU

type ReportEnvironmentOSCPU struct {
	Times ReportEnvironmentOSCPUTimes `json:"times"`
}

ReportEnvironmentOSCPU contains cpu information

type ReportEnvironmentOSCPUTimes

type ReportEnvironmentOSCPUTimes struct {
	Idle uint64 `json:"idle"`
	Irq  uint64 `json:"irq"`
	Nice uint64 `json:"nice"`
	Sys  uint64 `json:"sys"`
	User uint64 `json:"user"`
}

ReportEnvironmentOSCPUTimes contains cpu times

type ReportEnvironmentOSLinux

type ReportEnvironmentOSLinux struct {
	PID *ReportEnvironmentOSLinuxPID `json:"pid"`
}

ReportEnvironmentOSLinux contains linux system information

type ReportEnvironmentOSLinuxPID

type ReportEnvironmentOSLinuxPID struct {
	Self *ReportEnvironmentOSLinuxPIDSelf `json:"self"`
}

ReportEnvironmentOSLinuxPID contains linux process information

type ReportEnvironmentOSLinuxPIDSelf

type ReportEnvironmentOSLinuxPIDSelf struct {
	Stat      *ReportEnvironmentOSLinuxPIDSelfStat   `json:"stat"`
	StatStart *ReportEnvironmentOSLinuxPIDSelfStat   `json:"stat_start"`
	Status    *ReportEnvironmentOSLinuxPIDSelfStatus `json:"status"`
}

ReportEnvironmentOSLinuxPIDSelf contains current process information

type ReportEnvironmentOSLinuxPIDSelfStat

type ReportEnvironmentOSLinuxPIDSelfStat struct {
	Cstime uint64 `json:"cstime"`
	Cutime uint64 `json:"cutime"`
	Stime  uint64 `json:"stime"`
	Utime  uint64 `json:"utime"`
}

ReportEnvironmentOSLinuxPIDSelfStat contains process stats

type ReportEnvironmentOSLinuxPIDSelfStatus

type ReportEnvironmentOSLinuxPIDSelfStatus struct {
	FDSize  int32  `json:"FDSize"`
	Threads int32  `json:"Threads"`
	VMRSS   uint64 `json:"VmRSS"`
}

ReportEnvironmentOSLinuxPIDSelfStatus contains process status

type ReportEnvironmentRuntime

type ReportEnvironmentRuntime struct {
	Name    string `json:"name"`
	Version string `json:"version"`
}

ReportEnvironmentRuntime contains runtime information

type Reporter

type Reporter func(report *Report) error

Reporter is the reporter interface

type TestPluginConfig

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

TestPluginConfig is a test plugin config

type UUID

type UUID [16]byte

UUID is a universally unique identifier

func (UUID) String

func (uuid UUID) String() string

String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx , or "" if uuid is invalid.

Jump to

Keyboard shortcuts

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