spectator

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

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

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

README

Build Status

Spectator-go

⚠ Experimental

Simple library for instrumenting code to record dimensional time series.

Description

This implements a basic Spectator library for instrumenting golang applications, sending metrics to an Atlas aggregator service OR exposing metrics via an endpoint handler.

Instrumenting Code

Implemented to Send Metrics
package main

import (
	"github.com/Netflix/spectator-go"
	"strconv"
	"time"
)

type Server struct {
	registry       *spectator.Registry
	requestCountId *spectator.Id
	requestLatency *spectator.Timer
	responseSizes  *spectator.DistributionSummary
}

type Request struct {
	country string
}

type Response struct {
	status int
	size   int64
}

func (s *Server) Handle(request *Request) (res *Response) {
	clock := s.registry.Clock()
	start := clock.Now()

	// initialize res
	res = &Response{200, 64}

	// Update the counter id with dimensions based on the request. The
	// counter will then be looked up in the registry which should be
	// fairly cheap, such as lookup of id object in a map
	// However, it is more expensive than having a local variable set
	// to the counter.
	cntId := s.requestCountId.WithTag("country", request.country).WithTag("status", strconv.Itoa(res.status))
	s.registry.CounterWithId(cntId).Increment()

	// ...
	s.requestLatency.Record(clock.Now().Sub(start))
	s.responseSizes.Record(res.size)
	return
}

func newServer(registry *spectator.Registry) *Server {
	return &Server{
		registry,
		registry.NewId("server.requestCount", nil),
		registry.Timer("server.requestLatency", nil),
		registry.DistributionSummary("server.responseSizes", nil),
	}
}

func getNextRequest() *Request {
	// ...
	return &Request{"US"}
}

func main() {
	commonTags := map[string]string{"nf.app": "example", "nf.region": "us-west-1"}
	config := &spectator.Config{Frequency: 5 * time.Second, Timeout: 1 * time.Second,
		Uri: "http://example.org/api/v1/publish", CommonTags: commonTags}
	registry := spectator.NewRegistry(config)

	// optionally set custom logger (needs to implement Debugf, Infof, Errorf)
	// registry.SetLogger(logger)
	registry.Start()
	defer registry.Stop()

	// collect memory and file descriptor metrics
	spectator.CollectRuntimeMetrics(registry)

	server := newServer(registry)

	for i := 1; i < 3; i++ {
		// get a request
		req := getNextRequest()
		server.Handle(req)
	}
}

Implemented to Expose an Endpoint to Scrape Metrics
package main

import (
	"fmt"
	"net/http"
	"os"
	"time"

	"github.com/Netflix/spectator-go"
)

func main() {
	// setting no Uri in the registry config switchs to internal publish
	commonTags := map[string]string{"nf.app": "example", "nf.region": "us-west-1"}
	config := &spectator.Config{Frequency: 5 * time.Second, Timeout: 1 * time.Second,
		CommonTags: commonTags}
	registry := spectator.NewRegistry(config)

	// optionally set custom logger (needs to implement Debugf, Infof, Errorf)
	// registry.SetLogger(logger)
	registry.Start()
	defer registry.Stop()

	// collect memory and file descriptor metrics
	spectator.CollectRuntimeMetrics(registry)

	// attach spectators handler to your server to scrape metrics
	router := http.NewServeMux()
	handlerfunc := spectator.HttpHandler(registry)
	router.HandleFunc("/spectator/metrics", handlerfunc)

	httpServer := &http.Server{
		Addr:    ":3000",
		Handler: router,
	}
	fmt.Println("Server starting up")
	if err := httpServer.ListenAndServe(); err != http.ErrServerClosed {
		fmt.Println(err.Error())
		os.Exit(1)
	}
	fmt.Println("Server shutdown")
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CollectMemStats

func CollectMemStats(registry *Registry)

Collect memory stats https://golang.org/pkg/runtime/#MemStats

func CollectRuntimeMetrics

func CollectRuntimeMetrics(registry *Registry)

Starts the collection of memory and file handle metrics

func CollectSysStats

func CollectSysStats(registry *Registry)

Collects system stats: current/max file handles, number of goroutines

func Convert

func Convert(r *Registry) map[string]Metric

func HttpHandler

func HttpHandler(registry *Registry) http.HandlerFunc

Types

type Clock

type Clock interface {
	Now() time.Time
	Nanos() int64
}

type Config

type Config struct {
	Frequency  time.Duration     `json:"frequency"`
	Timeout    time.Duration     `json:"timeout"`
	Uri        string            `json:"uri"`
	BatchSize  int               `json:"batch_size"`
	CommonTags map[string]string `json:"common_tags"`
	Log        Logger
	IsEnabled  func() bool
}

type Counter

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

func NewCounter

func NewCounter(id *Id) *Counter

func (*Counter) Add

func (c *Counter) Add(delta int64)

func (*Counter) AddFloat

func (c *Counter) AddFloat(delta float64)

func (*Counter) Count

func (c *Counter) Count() float64

func (*Counter) Increment

func (c *Counter) Increment()

func (*Counter) Measure

func (c *Counter) Measure() []Measurement

func (*Counter) MeterId

func (c *Counter) MeterId() *Id

type DefaultLogger

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

func (*DefaultLogger) Debugf

func (l *DefaultLogger) Debugf(format string, v ...interface{})

func (*DefaultLogger) Errorf

func (l *DefaultLogger) Errorf(format string, v ...interface{})

func (*DefaultLogger) Infof

func (l *DefaultLogger) Infof(format string, v ...interface{})

type DistributionSummary

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

func NewDistributionSummary

func NewDistributionSummary(id *Id) *DistributionSummary

func (*DistributionSummary) Count

func (d *DistributionSummary) Count() int64

func (*DistributionSummary) Measure

func (d *DistributionSummary) Measure() []Measurement

func (*DistributionSummary) MeterId

func (d *DistributionSummary) MeterId() *Id

func (*DistributionSummary) Record

func (d *DistributionSummary) Record(amount int64)

func (*DistributionSummary) TotalAmount

func (d *DistributionSummary) TotalAmount() int64

type Gauge

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

func NewGauge

func NewGauge(id *Id) *Gauge

func (*Gauge) Get

func (g *Gauge) Get() float64

func (*Gauge) Measure

func (g *Gauge) Measure() []Measurement

func (*Gauge) MeterId

func (g *Gauge) MeterId() *Id

func (*Gauge) Set

func (g *Gauge) Set(value float64)

type HttpClient

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

func NewHttpClient

func NewHttpClient(registry *Registry, timeout time.Duration) *HttpClient

func (*HttpClient) PostJson

func (h *HttpClient) PostJson(uri string, jsonBytes []byte) (statusCode int, err error)

type Id

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

func NewId

func NewId(name string, tags map[string]string) *Id

func (*Id) Name

func (id *Id) Name() string

func (*Id) String

func (id *Id) String() string

func (*Id) Tags

func (id *Id) Tags() map[string]string

func (*Id) WithDefaultStat

func (id *Id) WithDefaultStat(stat string) *Id

func (*Id) WithStat

func (id *Id) WithStat(stat string) *Id

func (*Id) WithTag

func (id *Id) WithTag(key string, value string) *Id

func (*Id) WithTags

func (id *Id) WithTags(tags map[string]string) *Id

type Logger

type Logger interface {
	Debugf(format string, v ...interface{})
	Infof(format string, v ...interface{})
	Errorf(format string, v ...interface{})
}

type ManualClock

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

func (*ManualClock) Nanos

func (c *ManualClock) Nanos() int64

func (*ManualClock) Now

func (c *ManualClock) Now() time.Time

func (*ManualClock) SetFromDuration

func (c *ManualClock) SetFromDuration(duration time.Duration)

func (*ManualClock) SetNanos

func (c *ManualClock) SetNanos(nanos int64)

type Measurement

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

func NewMeasurement

func NewMeasurement(id *Id, Value float64) Measurement

func (Measurement) Id

func (m Measurement) Id() *Id

func (Measurement) String

func (m Measurement) String() string

func (Measurement) Value

func (m Measurement) Value() float64

type Meter

type Meter interface {
	MeterId() *Id
	Measure() []Measurement
}

type MeterFactoryFun

type MeterFactoryFun func() Meter

type Metric

type Metric struct {
	Kind   string     `json:"kind"`
	Values []TopValue `json:"values"`
}

type MonotonicCounter

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

func NewMonotonicCounter

func NewMonotonicCounter(registry *Registry, name string, tags map[string]string) *MonotonicCounter

func NewMonotonicCounterWithId

func NewMonotonicCounterWithId(registry *Registry, id *Id) *MonotonicCounter

func (*MonotonicCounter) Count

func (c *MonotonicCounter) Count() int64

func (*MonotonicCounter) Set

func (c *MonotonicCounter) Set(amount int64)

type Registry

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

func NewRegistry

func NewRegistry(config *Config) *Registry

func NewRegistryConfiguredBy

func NewRegistryConfiguredBy(filePath string) (*Registry, error)

func (*Registry) Clock

func (r *Registry) Clock() Clock

func (*Registry) Counter

func (r *Registry) Counter(name string, tags map[string]string) *Counter

func (*Registry) CounterWithId

func (r *Registry) CounterWithId(id *Id) *Counter

func (*Registry) DistributionSummary

func (r *Registry) DistributionSummary(name string, tags map[string]string) *DistributionSummary

func (*Registry) DistributionSummaryWithId

func (r *Registry) DistributionSummaryWithId(id *Id) *DistributionSummary

func (*Registry) Gauge

func (r *Registry) Gauge(name string, tags map[string]string) *Gauge

func (*Registry) GaugeWithId

func (r *Registry) GaugeWithId(id *Id) *Gauge

func (*Registry) GetExport

func (r *Registry) GetExport() map[string]Metric

func (*Registry) Measurements

func (r *Registry) Measurements() []Measurement

func (*Registry) Meters

func (r *Registry) Meters() []Meter

func (*Registry) NewId

func (r *Registry) NewId(name string, tags map[string]string) *Id

func (*Registry) NewMeter

func (r *Registry) NewMeter(id *Id, meterFactory MeterFactoryFun) Meter

func (*Registry) SetExport

func (r *Registry) SetExport(e map[string]Metric)

func (*Registry) SetLogger

func (r *Registry) SetLogger(logger Logger)

func (*Registry) Start

func (r *Registry) Start() error

func (*Registry) Stop

func (r *Registry) Stop()

func (*Registry) Timer

func (r *Registry) Timer(name string, tags map[string]string) *Timer

func (*Registry) TimerWithId

func (r *Registry) TimerWithId(id *Id) *Timer

type SystemClock

type SystemClock struct{}

func (*SystemClock) Nanos

func (c *SystemClock) Nanos() int64

func (*SystemClock) Now

func (c *SystemClock) Now() time.Time

type Tag

type Tag struct {
	Key   string `json:"key"`
	Value string `json:"value"`
}

type Timer

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

func NewTimer

func NewTimer(id *Id) *Timer

func (*Timer) Count

func (t *Timer) Count() int64

func (*Timer) Measure

func (t *Timer) Measure() []Measurement

func (*Timer) MeterId

func (t *Timer) MeterId() *Id

func (*Timer) Record

func (t *Timer) Record(amount time.Duration)

func (*Timer) TotalTime

func (t *Timer) TotalTime() time.Duration

type TopValue

type TopValue struct {
	Tags   []Tag    `json:"tags"`
	Values []*Value `json:"values"`
}

type Value

type Value struct {
	V int   `json:"v"`
	T int64 `json:"t"`
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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