metrics

package module
v0.0.0-...-02c7511 Latest Latest
Warning

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

Go to latest
Published: Apr 16, 2016 License: MIT Imports: 8 Imported by: 0

README

metrics Build Status GoDoc Coverage Status Go Report Card

Simple and extensible metrics instrumentation for your proxies. Collects useful and versatile metrics based on the analysis of duplex HTTP traffic and Go runtime stats.

Supports counters, gauges and histogram with 50, 75, 90, 95, 99 and 99.9 percentiles.

Uses codahale/metrics under the hood.

Reporters

Reporters are pluggable components that reads metric reports and tipically sends it to an data ingestor provider.

You can write and plug in your own reporter. See how to write reporters section.

Built-in supported reporters:

Meters

Meters are simple functions that reads HTTP request/response info and generates further counters, gauges or histograms based on it.

metrics package allows you to easily extend meter function in order to measure custom or new properies of the HTTP flow to cover your specific needs. See how to write meters section.

Default provided meters (listed as: description, measure type, metric name):

  • Total requests - counter - req.total.count
  • Total success responses - counter - res.status.ok.count
  • Total error responses - counter - res.status.error.count
  • Total bad responses - counter - res.status.bad.count
  • Total read requests - counter - req.reads.count
  • Total write requests - counter - req.writes.count
  • Response time in milliseconds - histogram - res.time.histogram
  • Response body size in KB - histogram - res.body.size.histogram
  • Request body size in KB - histogram - req.body.size.histogram

Installation

go get -u gopkg.in/vinxi/metrics.v0

API

See godoc reference.

Examples

Report metrics to InfluxDB
package main

import (
  "fmt"
  "gopkg.in/vinxi/metrics.v0"
  "gopkg.in/vinxi/metrics.v0/reporters/influx"
  "gopkg.in/vinxi/vinxi.v0"
)

const port = 3100

func main() {
  // Create a new vinxi proxy
  vs := vinxi.NewServer(vinxi.ServerOptions{Port: port})

  // Attach the metrics middleware
  config := influx.Config{
    URL:      "http://localhost:8086",
    Username: "root",
    Password: "root",
    Database: "metrics",
  }
  vs.Use(metrics.New(influx.New(config)))

  // Target server to forward
  vs.Forward("http://httpbin.org")

  fmt.Printf("Server listening on port: %d\n", port)
  err := vs.Listen()
  if err != nil {
    fmt.Errorf("Error: %s\n", err)
  }
}
Report metrics only for certain scenarios via multiplexer
package main

import (
  "fmt"
  "gopkg.in/vinxi/metrics.v0"
  "gopkg.in/vinxi/metrics.v0/reporters/influx"
  "gopkg.in/vinxi/mux.v0"
  "gopkg.in/vinxi/vinxi.v0"
)

const port = 3100

func main() {
  // Create a new vinxi proxy
  vs := vinxi.NewServer(vinxi.ServerOptions{Port: port})

  // InfluxDB reporter config
  config := influx.Config{
    URL:      "http://localhost:8086",
    Username: "root",
    Password: "root",
    Database: "metrics",
  }

  // Attach the metrics middleware via muxer
  mx := mux.If(mux.Method("GET", "POST"), mux.Path("/"))
  mx.Use(metrics.New(influx.New(config)))
  vs.Use(mx)

  // Target server to forward
  vs.Forward("http://httpbin.org")

  fmt.Printf("Server listening on port: %d\n", port)
  err := vs.Listen()
  if err != nil {
    fmt.Errorf("Error: %s\n", err)
  }
}

Writting reporters

metrics package allows you to write and plug in custom reporters in order to send data to third-party metrics and storage providers.

Reporters must implement the Reporter interface, which consists is a single method:

type Reporter interface {
  Report(metrics.Report) error
}

The metrics publisher will call the Report method passing the Report struct, which exports the fields Counters and Gauges.

Reporter example
import (
  "fmt"
  "gopkg.in/vinxi/metrics.v0"  
)

type MyCustomReporter struct {
  // reporter specific fields  
}

func (m *MyCustomReporter) Report(r metrics.Report) {
  // Print maps
  fmt.Printf("Counters: %#v \n", r.Counters)
  fmt.Printf("Gauges: %#v \n", r.Gauges)
  
  // Here you should usually map and transform the metrics report
  // into reporter specific data structures.
  data := mapReport(r)
    
  // Finally send the metrics, tipically via network to another server
  reporterClient.Send(data)
}

Writting meters

Meters are simple functions implementing the following function signature:

type MeterFunc func(*metrics.Info, *metrics.Metrics)
Meter example
package main

import (
  "fmt"
  "gopkg.in/vinxi/metrics.v0"
  "gopkg.in/vinxi/vinxi.v0"
)

const port = 3100

func main() {
  // Create a new vinxi proxy
  vs := vinxi.NewServer(vinxi.ServerOptions{Port: port})

  // Create a custom meter function the increases a counter
  // when the response status is 200
  myMeter := func(i *metrics.Info, m *metrics.Metrics) {
    if i.Status == 200 {
      m.Counter("res.success.total").Add()
    }
  }

  // Create a new metrics middleware
  m := metrics.New(reporter(collect))
  // Add the custom meter
  m.AddMeter(myMeter)
  // Attach the metrics middleware
  vs.Use(m)

  // Target server to forward
  vs.Forward("http://httpbin.org")

  fmt.Printf("Server listening on port: %d\n", port)
  err := vs.Listen()
  if err != nil {
    fmt.Errorf("Error: %s\n", err)
  }
}

// Simple stub reporter
type reporter func(metrics.Report) error

func (c reporter) Report(r metrics.Report) error {
  return c(r)
}

func collect(r metrics.Report) error {
  fmt.Printf("Gaudes: %#v\n", r.Gauges)
  fmt.Printf("Counters: %#v\n", r.Counters)
  return nil
}

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

Meters stores the built-in function meters used by default for metrics collection. You can define your custom meter functions via metrics.AddMeter() or metrics.SetMeters().

View Source
var PublishInterval = 15 * time.Second

PublishInterval defines the amount of time to wait between metrics publish cycles. Defaults to 15 seconds.

View Source
var RuntimeInterval = 10 * time.Second

RuntimeInterval the amount of time to wait between runtime metrics report cycles. Defaults to 10 seconds.

Functions

func MeterNumberOfRequests

func MeterNumberOfRequests(i *Info, m *Metrics)

MeterNumberOfRequests is used to register the total number of served requests.

func MeterRequestBodySize

func MeterRequestBodySize(i *Info, m *Metrics)

MeterRequestBodySize is used to measure the HTTP request body length. Data will be stored in a histogram.

func MeterRequestOperation

func MeterRequestOperation(i *Info, m *Metrics)

MeterRequestOperation is used to count the number of request by HTTP operation. Operation in inferred by HTTP verb:

- GET, HEAD = read operation - POST, PUT, PATCH, DELETE = write operation

func MeterResponseBodySize

func MeterResponseBodySize(i *Info, m *Metrics)

MeterResponseBodySize is used to measure the HTTP response body length. Data will be stored in a histogram.

func MeterResponseStatus

func MeterResponseStatus(i *Info, m *Metrics)

MeterResponseStatus is used to count the response status code by range (2xx, 4xx, 5xx).

func MeterResponseTime

func MeterResponseTime(i *Info, m *Metrics)

MeterResponseTime is used to measure the HTTP request/response time. Data will be stored in a histogram.

Types

type GaugeFunc

type GaugeFunc func(key string, val uint64)

GaugeFunc is an interface that implements the setting of a gauge value in a stats system. It should be expected that key will contain multiple parts separated by the '.' character in the form used by statsd (e.x. "mem.heap.alloc")

type Info

type Info struct {
	// Status stores the response HTTP status.
	Status int
	// BodyLength stores the response body length in bytes.
	BodyLength int64
	// TimeStart stores when the request was received by the server.
	TimeStart time.Time
	// TimeEnd stores when the response is written.
	TimeEnd time.Time
	// Header stores the response HTTP header.
	Header http.Header
	// Request points to the original http.Request instance.
	Request *http.Request
}

Info is used in meter functions to access to collected data from the response writer.

type Meter

type Meter struct {
	sync.Mutex
	// contains filtered or unexported fields
}

Meter provides a metrics instrumentation for vinxi Supports configurable metrics reporters and meters.

func New

func New(l ...Reporter) *Meter

New creates a new metrics meter middleware.

func (*Meter) AddMeter

func (m *Meter) AddMeter(meters ...MeterFunc)

AddMeter adds one or multiple meter functions.

func (*Meter) AddReporter

func (m *Meter) AddReporter(reporters ...Reporter)

AddReporter adds one or multiple metrics reporters.

func (*Meter) Publish

func (m *Meter) Publish()

Publish publishes the metrics snapshot report to the registered reporters.

func (*Meter) Register

func (m *Meter) Register(mw layer.Middleware)

Register registers the metrics middleware function.

func (*Meter) SetMeters

func (m *Meter) SetMeters(meters []MeterFunc)

SetMeters sets a new set of meter functions, replacing the existent ones.

func (*Meter) Start

func (m *Meter) Start()

Start starts a time ticker to publish metrics every certain amount of time. You should only call Start when you previously called Stop. Start is designed to be executed in its own goroutine.

func (*Meter) Stop

func (m *Meter) Stop()

Stop stops the publish goroutine.

type MeterFunc

type MeterFunc func(*Info, *Metrics)

MeterFunc represents the function interface to be implemented by metrics meter functions.

type Metrics

type Metrics struct {
	// Mutex provides synchronization for thead safety.
	sync.Mutex
	// contains filtered or unexported fields
}

Metrics is used to temporary store metrics data of multiple origins and nature. Provides a simple interface to write and read metric values.

Metrics is designed to be safety used by multiple goroutines.

func NewMetrics

func NewMetrics() *Metrics

NewMetrics creates a new metrics object for reporting.

func (*Metrics) Counter

func (m *Metrics) Counter(key string) metrics.Counter

Counter returns a counter metric by key. If the counter doesn't exists, it will be transparently created.

func (*Metrics) Guage

func (m *Metrics) Guage(key string) metrics.Gauge

Guage returns a gauge metric by key. If the gauge doesn't exists, it will be transparently created.

func (*Metrics) Histogram

func (m *Metrics) Histogram(key string) *metrics.Histogram

Histogram returns an histrogram by key. If the histogram doesn't exists, it will be transparently created.

func (*Metrics) Reset

func (m *Metrics) Reset()

Reset resets all the metrics (counters, gauges & histograms) to zero. You should collect them first with Snapshot(), otherwise the collected data will be lost.

func (*Metrics) Snapshot

func (m *Metrics) Snapshot() Report

Snapshot collects and returns a report of the existent counters and gauges metrics to be consumed by metrics publishers and listeners.

type Report

type Report struct {
	// Gauges stores metrics gauges values accesible by key.
	Gauges map[string]int64
	// Counters stores the metrics counters accesible by key.
	Counters map[string]uint64
}

Report is used to expose Counters and Gauges collected via Metrics.

type Reporter

type Reporter interface {
	Report(Report) error
}

Reporter represents the function interface to be implemented by metrics reporters. Metric reporters are responsable of reading, filtering and adapting metrics data. Also, reporters tipically sends the metrics to an external service.

type RuntimeCollector

type RuntimeCollector struct {
	// PauseTime represents the interval inbetween each set of stats output.
	// Defaults to 10 seconds.
	PauseTime time.Duration

	// EnableCPU determines whether CPU statisics will be output. Defaults to true.
	EnableCPU bool

	// EnableMem determines whether memory statistics will be output. Defaults to true.
	EnableMem bool

	// EnableGC determines whether garbage collection statistics will be output. EnableMem
	// must also be set to true for this to take affect. Defaults to true.
	EnableGC bool

	// Done, when closed, is used to signal RuntimeCollector that is should stop collecting
	// statistics and the Start function should return. If Done is set, upon shutdown
	// all gauges will be sent a final zero value to reset their values to 0.
	Done <-chan struct{}
	// contains filtered or unexported fields
}

RuntimeCollector implements the periodic grabbing of informational data from the runtime package and outputting the values to a GaugeFunc.

func NewRuntimeCollector

func NewRuntimeCollector(gaugeFunc GaugeFunc) *RuntimeCollector

NewRuntimeCollector creates a new RuntimeCollector that will periodically output statistics to gaugeFunc. It will also set the values of the exported fields to the described defaults. The values of the exported defaults can be changed at any point before Run is called.

func (*RuntimeCollector) Start

func (c *RuntimeCollector) Start()

Start gathers statistics from package runtime and outputs them to the configured GaugeFunc every PauseTime. This function will not return until Done has been closed (or never if Done is nil), therefore it should be called in its own goroutine.

Directories

Path Synopsis
_examples
mux
reporters

Jump to

Keyboard shortcuts

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