{"id":13469999,"url":"https://github.com/thoas/stats","last_synced_at":"2025-05-15T04:08:20.822Z","repository":{"id":28223536,"uuid":"31727930","full_name":"thoas/stats","owner":"thoas","description":"A Go middleware that stores various information about your web application (response time, status code count, etc.)","archived":false,"fork":false,"pushed_at":"2022-12-12T15:43:00.000Z","size":3552,"stargazers_count":593,"open_issues_count":8,"forks_count":50,"subscribers_count":16,"default_branch":"master","last_synced_at":"2025-04-14T05:57:01.704Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thoas.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-03-05T18:02:50.000Z","updated_at":"2025-03-04T10:45:00.000Z","dependencies_parsed_at":"2023-01-14T08:22:54.584Z","dependency_job_id":null,"html_url":"https://github.com/thoas/stats","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thoas%2Fstats","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thoas%2Fstats/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thoas%2Fstats/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thoas%2Fstats/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thoas","download_url":"https://codeload.github.com/thoas/stats/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254270656,"owners_count":22042860,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T16:00:21.195Z","updated_at":"2025-05-15T04:08:15.810Z","avatar_url":"https://github.com/thoas.png","language":"Go","readme":"Go stats handler\n================\n\n.. image:: https://secure.travis-ci.org/thoas/stats.svg?branch=master\n    :alt: Build Status\n    :target: http://travis-ci.org/thoas/stats\n\nstats is a ``net/http`` handler in golang reporting various metrics about\nyour web application.\n\nThis middleware has been developed and required for the need of picfit_,\nan image resizing server written in Go.\n\nCompatibility\n-------------\n\nThis handler supports the following frameworks at the moment:\n\n* `negroni`_\n* `martini`_\n* `gocraft/web \u003chttps://github.com/gocraft/web\u003e`_\n* `Gin \u003chttps://github.com/gin-gonic/gin\u003e`_\n* `Goji \u003chttps://github.com/zenazn/goji\u003e`_\n* `Beego \u003chttps://github.com/astaxie/beego\u003e`_\n* `HTTPRouter \u003chttps://github.com/julienschmidt/httprouter\u003e`_\n\nWe don't support your favorite Go framework? Send me a PR or\ncreate a new `issue \u003chttps://github.com/thoas/stats/issues\u003e`_ and\nI will implement it :)\n\nInstallation\n------------\n\n1. Make sure you have a Go language compiler \u003e= 1.3 (required) and git installed.\n2. Make sure you have the following go system dependencies in your $PATH: bzr, svn, hg, git\n3. Ensure your GOPATH_ is properly set.\n4. Download it:\n\n::\n\n    go get github.com/thoas/stats\n\n\nUsage\n-----\n\nBasic net/http\n..............\n\nTo use this handler directly with ``net/http``, you need to call the\nmiddleware with the handler itself:\n\n.. code-block:: go\n\n    package main\n\n    import (\n        \"net/http\"\n        \"github.com/thoas/stats\"\n    )\n\n    func main() {\n        h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n            w.Header().Set(\"Content-Type\", \"application/json\")\n            w.Write([]byte(\"{\\\"hello\\\": \\\"world\\\"}\"))\n        })\n\n        handler := stats.New().Handler(h)\n        http.ListenAndServe(\":8080\", handler)\n    }\n\nNegroni\n.......\n\nIf you are using negroni_ you can implement the handler as\na simple middleware in ``server.go``:\n\n.. code-block:: go\n\n    package main\n\n    import (\n        \"net/http\"\n        \"github.com/codegangsta/negroni\"\n        \"github.com/thoas/stats\"\n        \"encoding/json\"\n    )\n\n    func main() {\n        middleware := stats.New()\n\n        mux := http.NewServeMux()\n\n        mux.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n            w.Header().Set(\"Content-Type\", \"application/json\")\n            w.Write([]byte(\"{\\\"hello\\\": \\\"world\\\"}\"))\n        })\n\n        mux.HandleFunc(\"/stats\", func(w http.ResponseWriter, r *http.Request) {\n            w.Header().Set(\"Content-Type\", \"application/json\")\n\n            stats := middleware.Data()\n\n            b, _ := json.Marshal(stats)\n\n            w.Write(b)\n        })\n\n        n := negroni.Classic()\n        n.Use(middleware)\n        n.UseHandler(mux)\n        n.Run(\":3000\")\n    }\n\nHTTPRouter\n.......\n\nIf you are using HTTPRouter_ you need to call the middleware with the handler itself:\n\n.. code-block:: go\n    \n    package main                                                                          \n\n    import (\n            \"encoding/json\"\n            \"github.com/julienschmidt/httprouter\"\n            \"github.com/thoas/stats\"\n            \"net/http\"\n    )\n    \n    func main() {\n            router := httprouter.New()\n            s := stats.New()\n            router.GET(\"/stats\", func(w http.ResponseWriter, _ *http.Request, _ httprouter.Params) {\n                    w.Header().Set(\"Content-Type\", \"application/json; charset=utf-8\")\n                    s, err := json.Marshal(s.Data())\n                    if err != nil {\n                            http.Error(w, err.Error(), http.StatusInternalServerError)\n                    }\n                    w.Write(s)\n            })\n            http.ListenAndServe(\":8080\", s.Handler(router))\n    }\n    \n    \nMartini\n.......\n\nIf you are using martini_, you can implement the handler as a wrapper of\na ``Martini.Context`` in ``server.go``:\n\n\n.. code-block:: go\n\n    package main\n\n    import (\n        \"encoding/json\"\n        \"github.com/go-martini/martini\"\n        \"github.com/thoas/stats\"\n        \"net/http\"\n    )\n\n    func main() {\n        middleware := stats.New()\n\n        m := martini.Classic()\n        m.Get(\"/\", func(w http.ResponseWriter, r *http.Request) {\n            w.Header().Set(\"Content-Type\", \"application/json\")\n            w.Write([]byte(\"{\\\"hello\\\": \\\"world\\\"}\"))\n        })\n        m.Get(\"/stats\", func(w http.ResponseWriter, r *http.Request) {\n            w.Header().Set(\"Content-Type\", \"application/json\")\n\n            stats := middleware.Data()\n\n            b, _ := json.Marshal(stats)\n\n            w.Write(b)\n        })\n\n        m.Use(func(c martini.Context, w http.ResponseWriter, r *http.Request) {\n            beginning, recorder := middleware.Begin(w)\n\n            c.Next()\n\n            middleware.End(beginning, stats.WithRecorder(recorder))\n        })\n        m.Run()\n    }\n\nRun it in a shell:\n\n::\n\n    $ go run server.go\n\nThen in another shell run:\n\n::\n\n    $ curl http://localhost:3000/stats | python -m \"json.tool\"\n\nExpect the following result:\n\n.. code-block:: json\n\n    {\n        \"total_response_time\": \"1.907382ms\",\n        \"average_response_time\": \"86.699\\u00b5s\",\n        \"average_response_time_sec\": 8.6699e-05,\n        \"count\": 1,\n        \"pid\": 99894,\n        \"status_code_count\": {\n            \"200\": 1\n        },\n        \"time\": \"2015-03-06 17:23:27.000677896 +0100 CET\",\n        \"total_count\": 22,\n        \"total_response_time_sec\": 0.0019073820000000002,\n        \"total_status_code_count\": {\n            \"200\": 22\n        },\n        \"unixtime\": 1425659007,\n        \"uptime\": \"4m14.502271612s\",\n        \"uptime_sec\": 254.502271612\n    }\n\nSee `examples \u003chttps://github.com/thoas/stats/blob/master/examples\u003e`_ to\ntest them.\n\n\nInspiration\n-----------\n\n`Antoine Imbert \u003chttps://github.com/ant0ine\u003e`_ is the original author\nof this middleware.\n\nOriginally developed for `go-json-rest \u003chttps://github.com/ant0ine/go-json-rest\u003e`_,\nit had been ported as a simple Golang handler by `Florent Messa \u003chttps://github.com/thoas\u003e`_\nto be used in various frameworks.\n\nThis middleware implements a ticker which is launched every seconds to\nreset requests/sec and will implement new features in a near future :)\n\n.. _GOPATH: http://golang.org/doc/code.html#GOPATH\n.. _StatusMiddleware: https://github.com/ant0ine/go-json-rest/blob/master/rest/status.go\n.. _go-json-rest: https://github.com/ant0ine/go-json-rest\n.. _negroni: https://github.com/codegangsta/negroni\n.. _martini: https://github.com/go-martini/martini\n.. _picfit: https://github.com/thoas/picfit\n.. _HTTPRouter: https://github.com/julienschmidt/httprouter\n","funding_links":[],"categories":["Go","Web Frameworks","Web框架","Libraries for creating HTTP middlewares","中间件### 中间件","中间件","XML"],"sub_categories":["Middlewares","中间件","创建http中间件的代码库","Fail injection","中間件"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthoas%2Fstats","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthoas%2Fstats","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthoas%2Fstats/lists"}