{"id":13526831,"url":"https://github.com/mitchellh/go-server-timing","last_synced_at":"2025-04-01T08:30:28.624Z","repository":{"id":29296167,"uuid":"121197542","full_name":"mitchellh/go-server-timing","owner":"mitchellh","description":"Go (golang) library for creating and consuming HTTP Server-Timing headers","archived":true,"fork":false,"pushed_at":"2023-12-08T11:37:45.000Z","size":118,"stargazers_count":862,"open_issues_count":9,"forks_count":38,"subscribers_count":18,"default_branch":"master","last_synced_at":"2024-08-02T06:23:22.844Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://gist.github.com/mitchellh/90029601268e59a29e64e55bab1c5bdc","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/mitchellh.png","metadata":{"files":{"readme":"README.md","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,"governance":null,"roadmap":null,"authors":null}},"created_at":"2018-02-12T03:56:02.000Z","updated_at":"2024-07-22T20:45:31.000Z","dependencies_parsed_at":"2024-01-08T16:21:01.570Z","dependency_job_id":null,"html_url":"https://github.com/mitchellh/go-server-timing","commit_stats":{"total_commits":33,"total_committers":10,"mean_commits":3.3,"dds":"0.36363636363636365","last_synced_commit":"feb680ab92c20d57c527399b842e1941bde888c3"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitchellh%2Fgo-server-timing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitchellh%2Fgo-server-timing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitchellh%2Fgo-server-timing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitchellh%2Fgo-server-timing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mitchellh","download_url":"https://codeload.github.com/mitchellh/go-server-timing/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":222709936,"owners_count":17026767,"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-08-01T06:01:35.632Z","updated_at":"2024-11-02T11:31:43.108Z","avatar_url":"https://github.com/mitchellh.png","language":"Go","readme":"# HTTP Server-Timing for Go\n[![Godoc](https://godoc.org/github.com/mitchellh/go-server-timing?status.svg)](https://godoc.org/github.com/mitchellh/go-server-timing)\n\nThis is a library including middleware for using\n[HTTP Server-Timing](https://www.w3.org/TR/server-timing) with Go. This header\nallows a server to send timing information from the backend, such as database\naccess time, file reads, etc. The timing information can be then be inspected\nin the standard browser developer tools:\n\n![Server Timing Example](https://raw.githubusercontent.com/mitchellh/go-server-timing/master/example/screenshot.png)\n\n## Features\n\n  * Middleware for injecting the server timing struct into the request `Context`\n    and writing the `Server-Timing` header.\n\n  * Concurrency-safe structures for easily recording timings of multiple\n    concurrency tasks.\n\n  * Parse `Server-Timing` headers as a client.\n\n  * Note: No browser properly supports sending the Server-Timing header as\n    an [HTTP Trailer](https://tools.ietf.org/html/rfc7230#section-4.4) so\n\tthe Middleware only supports a normal header currently.\n\n## Browser Support\n\nBrowser support is required to **view** server timings easily. Because server\ntimings are sent as an HTTP header, there is no negative impact to sending\nthe header to unsupported browsers.\n\n  * Either **Chrome 65 or higher** or **Firefox 71 or higher** is required\n    to properly display server timings in the devtools.\n\n  * IE, Opera, and others are unknown at this time.\n\n## Usage\n\nExample usage is shown below. A fully runnable example is available in\nthe `example/` directory.\n\n```go\nfunc main() {\n\t// Our handler. In a real application this might be your root router,\n\t// or some subset of your router. Wrapping this ensures that all routes\n\t// handled by this handler have access to the server timing header struct.\n\tvar h http.Handler = http.HandlerFunc(handler)\n\n\t// Wrap our handler with the server timing middleware\n\th = servertiming.Middleware(h, nil)\n\n\t// Start!\n\thttp.ListenAndServe(\":8080\", h)\n}\n\nfunc handler(w http.ResponseWriter, r *http.Request) {\n\t// Get our timing header builder from the context\n\ttiming := servertiming.FromContext(r.Context())\n\n\t// Imagine your handler performs some tasks in a goroutine, such as\n\t// accessing some remote service. timing is concurrency safe so we can\n\t// record how long that takes. Let's simulate making 5 concurrent requests\n\t// to various servicse.\n\tvar wg sync.WaitGroup\n\tfor i := 0; i \u003c 5; i++ {\n\t\twg.Add(1)\n\t\tname := fmt.Sprintf(\"service-%d\", i)\n\t\tgo func(name string) {\n\t\t\t// This creats a new metric and starts the timer. The Stop is\n\t\t\t// deferred so when the function exits it'll record the duration.\n\t\t\tdefer timing.NewMetric(name).Start().Stop()\n\t\t\ttime.Sleep(random(25, 75))\n\t\t\twg.Done()\n\t\t}(name)\n\t}\n\n\t// Imagine this is just some blocking code in your main handler such\n\t// as a SQL query. Let's record that.\n\tm := timing.NewMetric(\"sql\").WithDesc(\"SQL query\").Start()\n\ttime.Sleep(random(20, 50))\n\tm.Stop()\n\n\t// Wait for the goroutine to end\n\twg.Wait()\n\n\t// You could continue recording more metrics, but let's just return now\n\tw.WriteHeader(200)\n\tw.Write([]byte(\"Done. Check your browser inspector timing details.\"))\n}\n\nfunc random(min, max int) time.Duration {\n\treturn (time.Duration(rand.Intn(max-min) + min)) * time.Millisecond\n}\n```\n","funding_links":[],"categories":["Web Frameworks","Web框架","Go","中间件### 中间件","中间件","Actual middlewares"],"sub_categories":["Middlewares","中间件","版本控制`版本控制相关库`","Fail injection"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmitchellh%2Fgo-server-timing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmitchellh%2Fgo-server-timing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmitchellh%2Fgo-server-timing/lists"}