thoas / stats Goto Github PK
View Code? Open in Web Editor NEWA Go middleware that stores various information about your web application (response time, status code count, etc.)
License: MIT License
A Go middleware that stores various information about your web application (response time, status code count, etc.)
License: MIT License
the example of gin should be:
// StatMiddleware response time, status code count, etc.
func StatMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
beginning, _ := Stats.Begin(c.Writer)
c.Next()
Stats.EndWithStatus(beginning, c.Writer.Status())
}
}
the example of martini has same issue
if we look at https://github.com/thoas/stats/blob/master/recorder.go#L39 and take following scenario:
func (r *recorderResponseWriter) WriteHeader(code int) {
r.written = true
r.ResponseWriter.WriteHeader(code)
r.status = code
}
ref:
if I understood the issue correctly and if it really is a genuine issue, happy to make a PR
It would be great if you add support for Gin Gonic (https://github.com/gin-gonic/gin).
// Options are stats options.
type Options struct {
statusCode *int
size int
recorder ResponseWriter
}
Line 55 in ec540af
../../thoas/stats/options.go:55:4: o.saveResult undefined (type *Options has no field or method saveResult)
Hi,
I want to know it the result of stats.Data()
has a format supported by Prometheus.
Thanks
{
"pid": 27613,
"uptime": "2m7.358545583s",
"uptime_sec": 127.358545583,
"time": "2016-11-10 14:45:35.526270515 +0800 CST",
"unixtime": 1478760335,
"status_code_count": {
"200": 1
},
"total_status_code_count": {
"200": 17
},
"count": 1,
"total_count": 17,
"total_response_time": "78.531534ms",
"total_response_time_sec": 0.078531534,
"average_response_time": "4.619502ms",
"average_response_time_sec": 0.004619502
}
status_code_count and total_status_code_count code always 200, reivew the code , it is hard-coded. so I think the statecode should be depend on w.
func (mw *Stats) Begin(w http.ResponseWriter) (time.Time, ResponseWriter) {
start := time.Now()
writer := NewRecorderResponseWriter(w, 200)
return start, writer
}
Please add beego support too.
It would be appreciated
Hi
I'm observing what looks to be a bogus behavior of your middleware regarding the counting of HTTP responses status code. Given the following implementation with Negroni:
package main
import (
"encoding/json"
"fmt"
"net/http"
"time"
"github.com/gorilla/mux"
"github.com/thoas/stats"
"github.com/urfave/negroni"
)
func main() {
router := mux.NewRouter()
httpStats := stats.New()
router.HandleFunc("/a", handleA).
Methods("GET", "POST", "PUT")
router.HandleFunc("/b", handleB).
Methods("GET")
router.HandleFunc("/c", handleC).
Methods("GET")
router.HandleFunc("/stats", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
stats := httpStats.Data()
b, _ := json.Marshal(stats)
w.Write(b)
})
n := negroni.New()
n.UseHandler(router)
n.Use(httpStats)
http.ListenAndServe(":8000", n)
}
func handleA(rw http.ResponseWriter, r *http.Request) {
switch r.Method {
case "POST", "PUT":
time.Sleep(100 * time.Millisecond)
rw.WriteHeader(http.StatusCreated)
case "GET":
time.Sleep(10 * time.Millisecond)
}
fmt.Fprintf(rw, "A\n")
}
func handleB(rw http.ResponseWriter, r *http.Request) {
time.Sleep(50 * time.Millisecond)
fmt.Fprintf(rw, "B\n")
}
func handleC(rw http.ResponseWriter, r *http.Request) {
time.Sleep(10 * time.Millisecond)
fmt.Fprintf(rw, "C\n")
}
Sending the following HTTP requests...
$ curl -i -X POST localhost:8000/a
HTTP/1.1 201 Created
Date: Mon, 18 Dec 2017 15:16:25 GMT
Content-Length: 2
Content-Type: text/plain; charset=utf-8
A
$ curl -i -X POST localhost:8000/b
HTTP/1.1 405 Method Not Allowed
Date: Mon, 18 Dec 2017 15:16:32 GMT
Content-Length: 0
Content-Type: text/plain; charset=utf-8
$ curl -i localhost:8000/c
HTTP/1.1 200 OK
Date: Mon, 18 Dec 2017 15:16:40 GMT
Content-Length: 2
Content-Type: text/plain; charset=utf-8
C
$ curl -i localhost:8000/z
HTTP/1.1 404 Not Found
Content-Type: text/plain; charset=utf-8
X-Content-Type-Options: nosniff
Date: Mon, 18 Dec 2017 15:16:42 GMT
Content-Length: 19
404 page not found
...I expected the /stats
response total_status_code_count
value to be {"200":1,"201":1,"404":1,"405":1}
, but it's not:
$ curl localhost:8000/stats | jq .
{
"pid": 7201,
"uptime": "46.962268141s",
"uptime_sec": 46.962268141,
"time": "2017-12-18 16:16:55.098574 +0100 CET m=+46.963702150",
"unixtime": 1513610215,
"status_code_count": {},
"total_status_code_count": {
"200": 4
},
"count": 0,
"total_count": 4,
"total_response_time": "13.083µs",
"total_response_time_sec": 1.3083e-05,
"average_response_time": "3.27µs",
"average_response_time_sec": 3.27e-06
}
Am I doing something wrong?
I'm using your fine package in a small app thats a go module, when I did a go get -u I get the error:
options.go:55:4: o.saveResult undefined (type *Options has no field or method saveResult)
While this is not a problem, it would be advantageous if you could tag a release or - even better - use Git flow to ensure we can keep using your package as you develop.
The newly added Before(func(ResponseWriter)) from negroni.ResponseWriter is missing.
I'd like to see an example of using stats with go-chi.
Looks like if you integrate with expvar https://golang.org/pkg/expvar/ (just publish the metrics there) then it would be very cross-compatible with a variety of other metric libraries
Seems like @thoas never commented or did anything in this project since april.
Is it abandoned?
If yes, I'll continue it in my fork (https://github.com/caarlos0/stats)...
https://github.com/thoas/stats/blob/master/stats.go#L33
Why reset the ResponseCounts
every second? My team and I were using this value, banking on getting a total of status codes from this, but, after seeing this have switched to using the TotalResponseCounts
and diffing.
Though this method is protected by lock and create a new structure on every call, this structure still use the same instance of ResponseCounts. So it is possible that somebody would read this map in the same moment as EndWithStatus would write into it.
In go 1.6 it will cause a panic.
It would be good if we could have the middleware not to record stats for the configured route that displays the /stats results.
Presently, viewing the stats counts towards the stats and thus affects the timings and counts.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.