Skip to content
/ stats Public

A Go middleware that stores various information about your web application (response time, status code count, etc.)

License

Notifications You must be signed in to change notification settings

thoas/stats

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

92 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Go stats handler

Build Status

stats is a net/http handler in golang reporting various metrics about your web application.

This middleware has been developed and required for the need of picfit, an image resizing server written in Go.

Compatibility

This handler supports the following frameworks at the moment:

We don't support your favorite Go framework? Send me a PR or create a new issue and I will implement it :)

Installation

  1. Make sure you have a Go language compiler >= 1.3 (required) and git installed.
  2. Make sure you have the following go system dependencies in your $PATH: bzr, svn, hg, git
  3. Ensure your GOPATH is properly set.
  4. Download it:
go get github.com/thoas/stats

Usage

Basic net/http

To use this handler directly with net/http, you need to call the middleware with the handler itself:

package main

import (
    "net/http"
    "github.com/thoas/stats"
)

func main() {
    h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "application/json")
        w.Write([]byte("{\"hello\": \"world\"}"))
    })

    handler := stats.New().Handler(h)
    http.ListenAndServe(":8080", handler)
}

Negroni

If you are using negroni you can implement the handler as a simple middleware in server.go:

package main

import (
    "net/http"
    "github.com/codegangsta/negroni"
    "github.com/thoas/stats"
    "encoding/json"
)

func main() {
    middleware := stats.New()

    mux := http.NewServeMux()

    mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "application/json")
        w.Write([]byte("{\"hello\": \"world\"}"))
    })

    mux.HandleFunc("/stats", func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "application/json")

        stats := middleware.Data()

        b, _ := json.Marshal(stats)

        w.Write(b)
    })

    n := negroni.Classic()
    n.Use(middleware)
    n.UseHandler(mux)
    n.Run(":3000")
}

HTTPRouter

If you are using HTTPRouter you need to call the middleware with the handler itself:

package main

import (
        "encoding/json"
        "github.com/julienschmidt/httprouter"
        "github.com/thoas/stats"
        "net/http"
)

func main() {
        router := httprouter.New()
        s := stats.New()
        router.GET("/stats", func(w http.ResponseWriter, _ *http.Request, _ httprouter.Params) {
                w.Header().Set("Content-Type", "application/json; charset=utf-8")
                s, err := json.Marshal(s.Data())
                if err != nil {
                        http.Error(w, err.Error(), http.StatusInternalServerError)
                }
                w.Write(s)
        })
        http.ListenAndServe(":8080", s.Handler(router))
}

Martini

If you are using martini, you can implement the handler as a wrapper of a Martini.Context in server.go:

package main

import (
    "encoding/json"
    "github.com/go-martini/martini"
    "github.com/thoas/stats"
    "net/http"
)

func main() {
    middleware := stats.New()

    m := martini.Classic()
    m.Get("/", func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "application/json")
        w.Write([]byte("{\"hello\": \"world\"}"))
    })
    m.Get("/stats", func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "application/json")

        stats := middleware.Data()

        b, _ := json.Marshal(stats)

        w.Write(b)
    })

    m.Use(func(c martini.Context, w http.ResponseWriter, r *http.Request) {
        beginning, recorder := middleware.Begin(w)

        c.Next()

        middleware.End(beginning, stats.WithRecorder(recorder))
    })
    m.Run()
}

Run it in a shell:

$ go run server.go

Then in another shell run:

$ curl http://localhost:3000/stats | python -m "json.tool"

Expect the following result:

{
    "total_response_time": "1.907382ms",
    "average_response_time": "86.699\u00b5s",
    "average_response_time_sec": 8.6699e-05,
    "count": 1,
    "pid": 99894,
    "status_code_count": {
        "200": 1
    },
    "time": "2015-03-06 17:23:27.000677896 +0100 CET",
    "total_count": 22,
    "total_response_time_sec": 0.0019073820000000002,
    "total_status_code_count": {
        "200": 22
    },
    "unixtime": 1425659007,
    "uptime": "4m14.502271612s",
    "uptime_sec": 254.502271612
}

See examples to test them.

Inspiration

Antoine Imbert is the original author of this middleware.

Originally developed for go-json-rest, it had been ported as a simple Golang handler by Florent Messa to be used in various frameworks.

This middleware implements a ticker which is launched every seconds to reset requests/sec and will implement new features in a near future :)

About

A Go middleware that stores various information about your web application (response time, status code count, etc.)

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published