How to do it...

These steps cover writing and running your application:

  1. From your Terminal or console application, create a new directory called ~/projects/go-programming-cookbook/chapter11/metrics and navigate to it.
  2. Run the following command:
$ go mod init github.com/PacktPublishing/Go-Programming-Cookbook-Second-Edition/chapter11/metrics

You should see a file called go.mod that contains the following content:

module github.com/PacktPublishing/Go-Programming-Cookbook-Second-Edition/chapter11/metrics    
  1. Copy the tests from ~/projects/go-programming-cookbook-original/chapter11/metrics, or use this as an opportunity to write some of your own code!
  2. Create a file called handler.go with the following content:
        package metrics

import (
"net/http"
"time"

metrics "github.com/rcrowley/go-metrics"
)

// CounterHandler will update a counter each time it's called
func CounterHandler(w http.ResponseWriter, r *http.Request) {
c := metrics.GetOrRegisterCounter("counterhandler.counter",
nil)
c.Inc(1)

w.WriteHeader(http.StatusOK)
w.Write([]byte("success"))
}

// TimerHandler records the duration required to compelete
func TimerHandler(w http.ResponseWriter, r *http.Request) {
currt := time.Now()
t := metrics.GetOrRegisterTimer("timerhandler.timer", nil)

w.WriteHeader(http.StatusOK)
w.Write([]byte("success"))
t.UpdateSince(currt)
}
  1. Create a file called report.go with the following content:
        package metrics

import (
"net/http"

gometrics "github.com/rcrowley/go-metrics"
)

// ReportHandler will emit the current metrics in json format
func ReportHandler(w http.ResponseWriter, r *http.Request) {

w.WriteHeader(http.StatusOK)

t := gometrics.GetOrRegisterTimer(
"reporthandler.writemetrics", nil)
t.Time(func() {
gometrics.WriteJSONOnce(gometrics.DefaultRegistry, w)
})
}
  1. Create a new directory named example and navigate to it.
  2. Create a file named main.go :
        package main

import (
"net/http"

"github.com/PacktPublishing/
Go-Programming-Cookbook-Second-Edition/
chapter11/metrics"
)

func main() {
// handler to populate metrics
http.HandleFunc("/counter", metrics.CounterHandler)
http.HandleFunc("/timer", metrics.TimerHandler)
http.HandleFunc("/report", metrics.ReportHandler)
fmt.Println("listening on :8080")
panic(http.ListenAndServe(":8080", nil))
}
  1. Run go run main.go. Alternatively, you may also run the following command:
$ go build
$ ./example

You should now see the following output:

$ go run main.go
listening on :8080
  1. Run the following commands from a separate shell:
$ curl localhost:8080/counter 
success

$ curl localhost:8080/timer
success

$ curl localhost:8080/report
{"counterhandler.counter":{"count":1},
"reporthandler.writemetrics": {"15m.rate":0,"1m.rate":0,"5m.rate":0,"75%":0,"95%":0,"99%":0,"99.9%":0,"count":0,"max":0,"mean":0,"mean.rate":0,"median":0,"min":0,"stddev":0},"timerhandler.timer":{"15m.rate":0.0011080303990206543,"1m.rate":0.015991117074135343,"5m.rate":0.0033057092356765017,"75%":60485,"95%":60485,"99%":60485,"99.9%":60485,"count":1,"max":60485,"mean":60485,"mean.rate":1.1334543719787356,"median":60485,"min":60485,"stddev":0}}
  1. Try hitting all the endpoints a few more times to see how they change.
  2. The go.mod file may be updated and the go.sum file should now be present in the top-level recipe directory.
  3. If you copied or wrote your own tests, go up one directory and run go test. Ensure that all the tests pass.