func (ca *CounterAspect) StartTimer(d time.Duration) {
	timer := time.Tick(d)
	go func() {
		for {
			select {
			case tup := <-ca.inc:
				ca.increment(tup)
			case <-timer:
				ca.reset()
			}
		}
	}()
}
StartTimer will call a forever loop in a goroutine to calculate
metrics for measurements every d ticks. The parameter of this
function should normally be 1 * time.Minute, if not it will expose
unintuive JSON keys (requests_per_minute and
request_sum_per_minute).
package ginmon
import (
	"time"
	"github.com/gin-gonic/gin"
)
func CounterHandler(ca *CounterAspect) gin.HandlerFunc {
	return func(ctx *gin.Context) {
		ctx.Next()
		ca.inc <- tuple{
			path: ctx.Request.URL.Path,
			code: ctx.Writer.Status(),
		}
	}
}
type tuple struct {
	path string
	code int
}
type CounterAspect struct {
	inc                  chan tuple
	internalRequestsSum  int
	internalRequests     map[string]int
	internalRequestCodes map[int]int
	RequestsSum          int            `json:"request_sum_per_minute"`
	Requests             map[string]int `json:"requests_per_minute"`
	RequestCodes         map[int]int    `json:"request_codes_per_minute"`
}
func NewCounterAspect() *CounterAspect {
	ca := &CounterAspect{}
	ca.inc = make(chan tuple)
	ca.internalRequestsSum = 0
	ca.internalRequests = make(map[string]int, 0)
	ca.internalRequestCodes = make(map[int]int, 0)
	return ca
}