monitor.v1: gopkg.in/spacemonkeygo/monitor.v1 Index | Examples | Files | Directories

package monitor

import "gopkg.in/spacemonkeygo/monitor.v1"

Package monitor is a flexible code instrumenting and data collection library.

With this package, it's easy to monitor and watch all sorts of data. A motivating example:

package main

import (
	"net/http"

	"gopkg.in/spacemonkeygo/monitor.v1"
)

var (
	mon = monitor.GetMonitors()
)

func FixSerenity() (err error) {
	defer mon.Task()(&err)

	if SerenityBroken() {
		err := CallKaylee()
		mon.Event("kaylee called")
		if err != nil {
			return err
		}
	}

	stowaway_count := StowawaysNeedingHiding()
	mon.Val("stowaway count", stowaway_count)
	err = HideStowaways(stowaway_count)
	if err != nil {
		return err
	}

	return nil
}

func Monitor() {
	go http.ListenAndServe(":8080", monitor.DefaultStore)
}

In this example, calling FixSerenity will cause the endpoint at http://localhost:8080/ to return all sorts of data, such as:

* How many times we've needed to fix the Serenity
  (the Task monitor infers the statistic name from the callstack)
* How many times we've succeeded
* How many times we've failed
* How long it's taken each time (min/max/avg/recent)
* How many times we needed to call Kaylee
* How many errors we've received (per error type!)
* Statistics on how many stowaways we usually have (min/max/avg/recent/etc)

To collect these statistics without the http server, you can call monitor.Stats like so

monitor.Stats(func(name string, val float64) {
	// do something with name, val
})

This package lets you easily instrument your code with all of these goodies and more!

Make sure to check out the trace subpackage for the Zipkin client extension. http://godoc.org/gopkg.in/spacemonkeygo/monitor.v1/trace

Index

Examples

Package Files

chained.go config.go datapoints.go doc.go environment.go environment_linux.go events.go group.go group_enabled.go helpers.go http.go monitor.go schedtrace_unsupported.go store.go tasks.go tasks_enabled.go values.go

Variables

var (
    // Package-level functions typically work on the DefaultStore. DefaultStore
    // functions as an HTTP handler, if serving statistics over HTTP sounds
    // interesting to you.
    DefaultStore = NewMonitorStore()

    CallerName             = trace.CallerName
    PackageName            = trace.PackageName
    AddIgnoredCallerPrefix = trace.AddIgnoredCallerPrefix
)
var Config = struct {
    DefaultCollectionFraction float64 `default:".1" usage:"The fraction of datapoints to collect"`
    DefaultCollectionMax      int     `default:"500" usage:"The max datapoints to collect"`
    MaxErrorLength            int     `default:"40" usage:"the max length for an error name"`
}{
    DefaultCollectionFraction: .1,
    DefaultCollectionMax:      500,
    MaxErrorLength:            40,
}

Config is a configuration struct meant to be used with

github.com/spacemonkeygo/flagfile/utils.Setup

but can be set independently.

func BoolAsFloat Uses

func BoolAsFloat(val bool) float64

BoolAsFloat converts a bool value into a float64 value, for easier datapoint usage.

func Collect Uses

func Collect(mon Monitor) map[string]float64

Collect takes something that implements the Monitor interface and returns a key/value map.

func Datapoints Uses

func Datapoints(reset bool, cb func(name string, data [][]float64, total uint64,
    clipped bool, fraction float64))

Datapoints calls cb with all the datasets registered on the default store.

func FdCount Uses

func FdCount() (count int, err error)

FdCount counts how many open file descriptors there are.

func FloatHash Uses

func FloatHash(data []byte) float64

FloatHash CRCs a byte array and converts the CRC into a float64, for easier datapoint usage.

func MonitorMap Uses

func MonitorMap(data map[string]float64, cb func(name string, val float64))

MonitorMap sends a map of keys and values to a callback.

func MonitorStruct Uses

func MonitorStruct(data interface{}, cb func(name string, val float64))

MonitorStruct uses reflection to walk the structure data and call cb with every field and value on the struct that's castable to float64.

func PrefixStats Uses

func PrefixStats(name string, obj Monitor, cb func(name string, val float64))

PrefixStats will call cb with all of the same calls obj would have, except every name is prefixed with name.

func ProcessCRC Uses

func ProcessCRC() (uint32, error)

func RegisterEnvironment Uses

func RegisterEnvironment()

RegisterEnvironment registers environment statistics on the default store.

func Running Uses

func Running(cb func(name string, current []*TaskCtx))

Running calls cb with lists of currently running tasks by name.

func RuntimeInternals Uses

func RuntimeInternals() (rv struct{})

RuntimeInternals parses a scheduler trace line into an InternalStats struct. Not supported yet with Go 1.4.

func SanitizeName Uses

func SanitizeName(name string) string

SanitizeName cleans a stat or datapoint name to be representable in a wide range of data collection software.

func Stats Uses

func Stats(cb func(name string, val float64))

Stats calls cb with all the statistics registered on the default store.

type ChainedMonitor Uses

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

ChainedMonitor is a monitor that simply wraps another monitor, while allowing for atomic monitor changing.

func NewChainedMonitor Uses

func NewChainedMonitor() *ChainedMonitor

NewChainedMonitor returns a ChainedMonitor

func (*ChainedMonitor) Set Uses

func (c *ChainedMonitor) Set(other Monitor)

Set replaces the ChainedMonitor's existing monitor with other

func (*ChainedMonitor) Stats Uses

func (c *ChainedMonitor) Stats(cb func(name string, val float64))

Stats conforms to the Monitor interface, and passes the call to the chained monitor.

type DataCollection Uses

type DataCollection interface {
    // Datapoints calls cb with stored datasets. If reset is true, Datapoints
    // should clear its stores. cb is called with the name of the dataset,
    // len(data) datapoints, where a datapoint is a vector of scalars, the total
    // number of datapoints actually seen (which will be >= len(data)), whether
    // or not some datapoints got clipped and the data collector had to revert to
    // stream random sampling, and the fraction of data points collectoed.
    Datapoints(reset bool, cb func(name string, data [][]float64, total uint64,
        clipped bool, fraction float64))
}

DataCollection is the basic key/vector interface. Anything that implements the DataCollection interface can be connected to the monitor system for later processing.

type DatapointCollector Uses

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

DatapointCollector collects a set of datapoints

func NewDatapointCollector Uses

func NewDatapointCollector(collection_fraction float64, collection_max int) *DatapointCollector

NewDatapointCollector makes a new DatapointCollector that will collect collection_fraction of all datapoints, and will start clipping data once collection_max has been reached without getting drained.

You probably want to create a new DatapointCollector using MonitorGroup.Data instead.

func (*DatapointCollector) Add Uses

func (d *DatapointCollector) Add(val ...float64)

Add adds new datapoints to the collector. A datapoint is an n-dimensional vector. There should be one argument for each scalar in the vector.

func (*DatapointCollector) Datapoints Uses

func (d *DatapointCollector) Datapoints(reset bool, cb func(name string,
    data [][]float64, total uint64, clipped bool, fraction float64))

Datapoints returns all of the saved datapoints and any statistics about the dataset retained to cb. If reset is true, the collector will be reset and the datapoints will be drained from the collector. Datapoints conforms to the DataCollection interface.

type EventMonitor Uses

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

EventMonitor keeps track of the number of times an event happened

func NewEventMonitor Uses

func NewEventMonitor() *EventMonitor

NewEventMonitor makes a new event monitor. You probably want to create a new EventMonitor using MonitorGroup.Event instead.

func (*EventMonitor) Add Uses

func (e *EventMonitor) Add()

Add indicates that the given event happened again

func (*EventMonitor) Stats Uses

func (e *EventMonitor) Stats(cb func(name string, val float64))

Stats conforms to the Monitor interface

type IntValueMonitor Uses

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

IntValueMonitor is faster than ValueMonitor when you don't want to deal with floating-point ops

func NewIntValueMonitor Uses

func NewIntValueMonitor() *IntValueMonitor

NewIntValueMonitor returns a new IntValueMonitor. You probably want to create a new IntValueMonitor through MonitorGroup.IntVal instead.

func (*IntValueMonitor) Add Uses

func (v *IntValueMonitor) Add(val int64)

Add adds a value to the IntValueMonitor

func (*IntValueMonitor) Stats Uses

func (v *IntValueMonitor) Stats(cb func(name string, val float64))

Stats conforms to the Monitor interface

type Monitor Uses

type Monitor interface {
    Stats(cb func(name string, val float64))
}

Monitor is the basic key/value interface. Anything that implements the Monitor interface can be connected to the monitor system for later processing.

type MonitorFunc Uses

type MonitorFunc func(cb func(name string, val float64))

MonitorFunc assists in Monitor interface instances

func (MonitorFunc) Stats Uses

func (f MonitorFunc) Stats(cb func(name string, val float64))

Stats just calls f with the given cb

type MonitorGroup Uses

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

MonitorGroup is a collection of named Monitor interfaces and DataCollector interfaces. They are automatically created by various calls on the MonitorGroup

func GetMonitors Uses

func GetMonitors() *MonitorGroup

GetMonitors creates a MonitorGroup with an automatic per-package name on the default store.

func GetMonitorsNamed Uses

func GetMonitorsNamed(name string) *MonitorGroup

GetMonitorsNamed creates a named MonitorGroup on the default store.

func NewMonitorGroup Uses

func NewMonitorGroup(name string) *MonitorGroup

NewMonitorGroup makes a new MonitorGroup unattached to anything.

func (*MonitorGroup) Chain Uses

func (self *MonitorGroup) Chain(name string, other Monitor)

Chain creates a ChainedMonitor by the given name if one doesn't exist and sets the Monitor other to it.

func (*MonitorGroup) Data Uses

func (self *MonitorGroup) Data(name string, val ...float64)

Data takes a name, makes a DataCollector if one doesn't exist, and adds a datapoint to it.

func (*MonitorGroup) DataTask Uses

func (self *MonitorGroup) DataTask() func(*error)

DataTask works just like Task, but automatically makes datapoints about the task in question. It's a hybrid of Data and Task.

func (*MonitorGroup) Datapoints Uses

func (g *MonitorGroup) Datapoints(reset bool, cb func(name string,
    data [][]float64, total uint64, clipped bool, fraction float64))

Datapoints conforms to the DataCollection interface. Datapoints aggregates all datasets attached to this group.

func (*MonitorGroup) Event Uses

func (self *MonitorGroup) Event(name string)

Event simply calls EventNamed after adding a prefix to the name based on the caller.

func (*MonitorGroup) EventNamed Uses

func (self *MonitorGroup) EventNamed(name string)

EventNamed creates an EventMonitor by the given name if one doesn't exist and adds an event to it.

func (*MonitorGroup) IntVal Uses

func (self *MonitorGroup) IntVal(name string, val int64)

IntVal is faster than Val when you don't want to deal with floating point ops.

func (*MonitorGroup) Running Uses

func (g *MonitorGroup) Running(cb func(name string, current []*TaskCtx))

Running collects lists of all running tasks by name

func (*MonitorGroup) Stats Uses

func (g *MonitorGroup) Stats(cb func(name string, val float64))

Stats conforms to the Monitor interface. Stats aggregates all statistics attatched to this group.

func (*MonitorGroup) Task Uses

func (self *MonitorGroup) Task() func(*error)

Task allows you to monitor a specific function. Task automatically chooses a name for you based on the callstack and creates a TaskMonitor for you by that name if one doesn't already exist. If you'd like to pick your own metric name (and improve performance), use TaskNamed. Please see the example.

N.B.: Error types are best tracked when you're using Space Monkey's hierarchical error package: http://github.com/spacemonkeygo/errors

Code:

mon := GetMonitors()
myfunc := func() (err error) {
    defer mon.Task()(&err)
    // do some work
    // maybe return an error
    return nil
}
myfunc()

func (*MonitorGroup) TaskNamed Uses

func (self *MonitorGroup) TaskNamed(name string) func(*error)

TaskNamed works just like Task without any automatic name selection

func (*MonitorGroup) TracedTask Uses

func (self *MonitorGroup) TracedTask(ctx *context.Context) func(*error)

TracedTask creates a Task and also uses gopkg.in/spacemonkeygo/monitor.v1/trace's Trace function to Trace the given function. Currently only uses the default tracing SpanManager

func (*MonitorGroup) Val Uses

func (self *MonitorGroup) Val(name string, val float64)

Val creates a ValueMonitor by the given name if one doesn't exist and adds a value to it.

type MonitorStore Uses

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

MonitorStore is a collection of package-level MonitorGroups. There is typically only one MonitorStore per process, the DefaultStore.

func NewMonitorStore Uses

func NewMonitorStore() *MonitorStore

NewMonitorStore creates a new MonitorStore

func (*MonitorStore) Datapoints Uses

func (s *MonitorStore) Datapoints(reset bool, cb func(name string,
    data [][]float64, total uint64, clipped bool, fraction float64))

Datapoints conforms to the DataCollection interface

func (*MonitorStore) GetMonitors Uses

func (s *MonitorStore) GetMonitors() *MonitorGroup

GetMonitorsNamed finds or creates a MonitorGroup using automatic name selection

func (*MonitorStore) GetMonitorsNamed Uses

func (s *MonitorStore) GetMonitorsNamed(group_name string) *MonitorGroup

GetMonitorsNamed finds or creates a MonitorGroup by the given group name

func (*MonitorStore) RegisterEnvironment Uses

func (store *MonitorStore) RegisterEnvironment()

RegisterEnvironment configures the MonitorStore receiver to understand all sorts of process environment statistics, such as memory statistics, process uptime, file descriptor use, goroutine use, runtime internals, Rusage stats, etc.

func (*MonitorStore) Running Uses

func (s *MonitorStore) Running(cb func(name string, current []*TaskCtx))

Running collects lists of all running tasks by name

func (*MonitorStore) ServeHTTP Uses

func (s *MonitorStore) ServeHTTP(w http.ResponseWriter, req *http.Request)

ServeHTTP dumps all of the MonitorStore's keys and values to the requester. This method allows a MonitorStore to be registered as an HTTP handler.

func (*MonitorStore) Stats Uses

func (s *MonitorStore) Stats(cb func(name string, val float64))

Stats conforms to the Monitor interface

type RunningTasksCollector Uses

type RunningTasksCollector interface {
    Running(cb func(name string, current []*TaskCtx))
}

RunningTasksCollector keeps track of tasks that are currently in process.

type TaskCtx Uses

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

TaskCtx keeps track of a task as it is running.

func (TaskCtx) ElapsedTime Uses

func (t TaskCtx) ElapsedTime() time.Duration

func (*TaskCtx) Finish Uses

func (c *TaskCtx) Finish(err_ref *error, rec interface{})

Finish records a successful task completion. You must pass a pointer to the named error return value (or nil if there isn't one) and the result of recover() out of the method that was deferred for this to work right. Finish will re-panic any recovered panics (provided it wasn't a nil panic) after bookkeeping.

type TaskMonitor Uses

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

TaskMonitor is a type for keeping track of tasks. A TaskMonitor will keep track of the current number of tasks, the highwater number (the maximum amount of concurrent tasks), the total started, the total completed, the total that returned without error, the average/min/max/most recent amount of time the task took to succeed/fail/both, the number of different kinds of errors the task had, and how many times the task had a panic.

N.B.: Error types are best tracked when you're using Space Monkey's hierarchical error package: http://github.com/spacemonkeygo/errors

func NewTaskMonitor Uses

func NewTaskMonitor() *TaskMonitor

NewTaskMonitor returns a new TaskMonitor. You probably want to create a TaskMonitor using MonitorGroup.Task instead.

func (*TaskMonitor) NewContext Uses

func (t *TaskMonitor) NewContext() *TaskCtx

NewContext creates a new context that is watching a live task. See Start or MonitorGroup.Task

func (*TaskMonitor) Running Uses

func (t *TaskMonitor) Running() (rv []*TaskCtx)

Running returns a list of tasks that are currently running. Each TaskCtx can tell how long it's been since the task was started, though keep in mind that the task might finish between calling (*TaskMonitor).Running() and (*TaskCtx).ElapsedTime()

func (*TaskMonitor) Start Uses

func (t *TaskMonitor) Start() func(*error)

Start is a helper method for watching a task in a less error-prone way. Managing a task context yourself is tricky to get right - recover only works in deferred methods. Call out of a method that was deferred and it no longer works! See the example.

Code:

task := NewTaskMonitor()
myfunc := func() (err error) {
    defer task.Start()(&err)
    // do some work
    // maybe return an error
    return nil
}
myfunc()

func (*TaskMonitor) Stats Uses

func (t *TaskMonitor) Stats(cb func(name string, val float64))

Stats conforms to the Monitor interface

type ValueMonitor Uses

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

ValueMonitor keeps track of the highs and lows and averages and most recent versions of some value

func NewValueMonitor Uses

func NewValueMonitor() *ValueMonitor

NewValueMonitor creates a new ValueMonitor. You probably want to create a new ValueMonitor through MonitorGroup.Val instead.

func (*ValueMonitor) Add Uses

func (v *ValueMonitor) Add(val float64)

Add adds a value to the ValueMonitor

func (*ValueMonitor) Stats Uses

func (v *ValueMonitor) Stats(cb func(name string, val float64))

Stats conforms to the Monitor interface

Directories

PathSynopsis
tracePackage trace is a distributed tracing and Zipkin client library for Go.
trace/gen-go/scribe
trace/gen-go/zipkin
utils
utils/sched

Package monitor imports 21 packages (graph). Updated 2016-07-16. Refresh now. Tools for package owners.