Help us shape the future of Go! Take the 2026 Go Developer Survey

gomonitor

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Dec 22, 2016 License: MIT Imports: 4 Imported by: 2

README

Gin-Gomonitor

Build Status Coverage Status Go Report Card

Gin-Gomonitor is made specially for Gin Framework users who also want to use Go-Monitor. It was created by Go developers who needed Gin middleware for exposing metrics with Go-Monitor, which provides a simple and extensible way to build monitorizable long-term execution processes or daemons via HTTP. Gin-Gomonitor supports customized aspects and implements a simple counter aspect within the package ginmon.

Project Context and Features

When it comes to choosing a Go framework, there's a lot of confusion about what to use. The scene is very fragmented, and detailed comparisons of different frameworks are still somewhat rare. Meantime, how to handle dependencies and structure projects are big topics in the Go community.

We've liked using Gin for its speed, accessibility, and usefulness in developing microservice architectures. In creating Gin-Gomonitor, we wanted to take fuller advantage of Gin's capabilities and help other devs do likewise.

We implemented the following custom Aspects:

CounterAspect implements a counter for request per time.Duration, counting the sum of all and for each path independent counters.

RequestTimeAspect implements the measurement of request times including values for min, max, mean, stdev, p90, p95, p99.

See also our full example.

How Go-Monitor Is Different from Other Metric Libraries

Go-Monitor is easily extendable, does not need type casts to create JSON, and has useful metrics already defined. It exposes metrics as JSON to a metrics endpoint using a different TCP port.

Requirements

Gin-Gomonitor uses the following Go packages as dependencies:

Installation

Assuming you've installed Go and Gin, run this:

go get github.com/zalando/gin-gomonitor

Usage

This example shows you how to use Gin-Gomonitor. To try it out, use:

  go run example/main.go
Default Monitor with Custom Aspect

First define your Custom Aspect, so that it will be exposed in a special path /Custom:

type CustomAspect struct {
	CustomValue int
}

func (a *CustomAspect) GetStats() interface{} {
	return a.CustomValue
}

func (a *CustomAspect) Name() string {
	return "Custom"
}

func (a *CustomAspect) InRoot() bool {
	return false
}

Next, initialize the CounterAspect defined by Gin-Gomonitor and your own CustomAspect (defined above):

    router := gin.New()

    counterAspect := ginmon.NewCounterAspect()
    counterAspect.StartTimer(1 * time.Minute)

    anotherAspect := &CustomAspect{3}
    asps := []aspects.Aspect{counterAspect, anotherAspect}
    router.Use(ginmon.CounterHandler(counterAspect))

Finally, register the middleware to expose all metrics on TCP port 9000:

    router.Use(gomonitor.Metrics(9000, asps))
Testing

The page's counter metric will increment if you hit the page:

% curl http://localhost:9000/Counter
{
    "Counter": {
        "request_sum_per_minute": 0,
        "requests_per_minute": {},
        "request_codes_per_minute": {}
    }
}
% for i in {1..20}; do curl localhost:8080/ &>/dev/null ; curl localhost:8080/foo &>/dev/null ; done; sleep 3; curl http://localhost:9000/Counter
{
    "Counter": {
        "request_sum_per_minute": 40,
        "requests_per_minute": {
            "/": 20,
            "/foo": 20
        },
        "request_codes_per_minute": {
            "200": 20,
            "404": 20
        }
    }
}

The page custom metric will show three as defined:

% curl http://localhost:9000/Custom
{
  "Custom: 3
}

The regular metrics from go-monitor exposes Go process and build information:

% curl http://localhost:9000/
{
  "MemStats": {
    "Alloc": 1285680,
    "TotalAlloc": 1285680,
    "Sys": 4458744,
    "Lookups": 36,
    "Mallocs": 6216,
    "Frees": 0,
    "HeapAlloc": 1285680,
   ...
  "Runtime": {
    "GoVersion": "go1.5.1",
    "GoOs": "linux",
    "GoArch": "amd64",
    "CpuNum": 4,
    "GoroutineNum": 7,
    "Gomaxprocs": 4,
    "CgoCallNum": 1
  },
  "Time": {
    "StartTime": "2016-03-06T17:33:59.440088805+01:00",
    "RequestTime": "2016-03-06T17:48:55.245710327+01:00"
  }
}

You can also filter by sub-category:

% curl localhost:9000/Runtime
{
  "Runtime": {
    "GoVersion": "go1.5.1",
    "GoOs": "linux",
    "GoArch": "amd64",
    "CpuNum": 4,
    "GoroutineNum": 7,
    "Gomaxprocs": 4,
    "CgoCallNum": 1
  }
}

Contributing/TODO

We welcome contributions from the community—just submit a pull request. To help you get started, here are some items that we'd love help with:

  • Adding more custom metrics
    • time per request: average, p99, ..
    • number of requests: all, path, httpverb
    • <your idea>
  • the code base

Please use GitHub issues as your starting point for contributions, new ideas or bug reports.

Contact

Contributors

Thanks to:

  • <your name>

License

See LICENSE file.

Documentation

Overview

Package gomonitor is a Gin middleware, that exposes metrics to an http monitor endpoint. As base it uses https://gopkg.in/mcuadros/go-monitor.v1 to expose metrics. It supports custom metrics which are not triggered using the middleware context. If you want to add a page counter please see the example. You can even create your own aspects like defined in the https://gopkg.in/mcuadros/go-monitor.v1/aspects package.

Example:

   package main

   import (
   	"net/http"

   	"github.com/gin-gonic/gin"
   	"github.com/zalando/gin-gomonitor"
	"github.com/zalando/gin-gomonitor/aspects"
   	"gopkg.in/mcuadros/go-monitor.v1/aspects"
   )

   func main() {
   	router := gin.New()
   	counterAspect := &ginmon.CounterAspect{0}
   	asps := []aspects.Aspect{counterAspect}
   	// curl http://localhost:9000/Counter
   	router.Use(ginmon.CounterHandler(counterAspect))
   	// curl http://localhost:9000/
   	router.Use(gomonitor.Metrics(9000, asps))
   	// last middleware
   	router.Use(gin.Recovery())

   	// each request to all handlers like below will increment the Counter
   	router.GET("/", func(ctx *gin.Context) {
   		ctx.JSON(http.StatusOK, gin.H{"title": "Counter - Hello World"})
   	})

   	//..
   	router.Run(":8080")
   }

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Metrics

func Metrics(port int, asps []aspects.Aspect) gin.HandlerFunc

Metrics function exposes metrics of https://github.com/mcuadros/go-monitor package of your https://github.com/gin-gonic/gin based webapp. Metrics() get a port number as parameter to expose monitoring data to and a slice of aspects.Aspect defined by the user.

Example:

router := gin.New()
counterAspect := &ginmon.CounterAspect{0}
asps := []aspects.Aspect{counterAspect}
// curl http://localhost:9000/Counter
router.Use(ginmon.CounterHandler(counterAspect))
// curl http://localhost:9000/
router.Use(gomonitor.Metrics(9000, asps))
// last middleware
router.Use(gin.Recovery())

Types

This section is empty.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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