{"id":13563825,"url":"https://github.com/jtolio/gls","last_synced_at":"2025-04-13T05:00:09.938Z","repository":{"id":11777089,"uuid":"14315701","full_name":"jtolio/gls","owner":"jtolio","description":"Goroutine local storage","archived":false,"fork":false,"pushed_at":"2022-08-12T02:32:01.000Z","size":18,"stargazers_count":673,"open_issues_count":4,"forks_count":51,"subscribers_count":24,"default_branch":"master","last_synced_at":"2025-04-10T00:03:26.080Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/jtolio.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}},"created_at":"2013-11-11T22:41:18.000Z","updated_at":"2025-04-03T06:09:31.000Z","dependencies_parsed_at":"2022-07-07T22:12:20.076Z","dependency_job_id":null,"html_url":"https://github.com/jtolio/gls","commit_stats":null,"previous_names":["jtolds/gls"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jtolio%2Fgls","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jtolio%2Fgls/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jtolio%2Fgls/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jtolio%2Fgls/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jtolio","download_url":"https://codeload.github.com/jtolio/gls/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248368710,"owners_count":21092437,"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-01T13:01:23.648Z","updated_at":"2025-04-13T05:00:09.882Z","avatar_url":"https://github.com/jtolio.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"gls\n===\n\nGoroutine local storage\n\n### IMPORTANT NOTE ###\n\nIt is my duty to point you to https://blog.golang.org/context, which is how \nGoogle solves all of the problems you'd perhaps consider using this package\nfor at scale. \n\nOne downside to Google's approach is that *all* of your functions must have\na new first argument, but after clearing that hurdle everything else is much\nbetter.\n\nIf you aren't interested in this warning, read on.\n\n### Huhwaht? Why? ###\n\nEvery so often, a thread shows up on the\n[golang-nuts](https://groups.google.com/d/forum/golang-nuts) asking for some\nform of goroutine-local-storage, or some kind of goroutine id, or some kind of\ncontext. There are a few valid use cases for goroutine-local-storage, one of\nthe most prominent being log line context. One poster was interested in being\nable to log an HTTP request context id in every log line in the same goroutine\nas the incoming HTTP request, without having to change every library and\nfunction call he was interested in logging.\n\nThis would be pretty useful. Provided that you could get some kind of\ngoroutine-local-storage, you could call\n[log.SetOutput](http://golang.org/pkg/log/#SetOutput) with your own logging\nwriter that checks goroutine-local-storage for some context information and\nadds that context to your log lines.\n\nBut alas, Andrew Gerrand's typically diplomatic answer to the question of\ngoroutine-local variables was:\n\n\u003e We wouldn't even be having this discussion if thread local storage wasn't\n\u003e useful. But every feature comes at a cost, and in my opinion the cost of\n\u003e threadlocals far outweighs their benefits. They're just not a good fit for\n\u003e Go.\n\nSo, yeah, that makes sense. That's a pretty good reason for why the language\nwon't support a specific and (relatively) unuseful feature that requires some\nruntime changes, just for the sake of a little bit of log improvement.\n\nBut does Go require runtime changes?\n\n### How it works ###\n\nGo has pretty fantastic introspective and reflective features, but one thing Go\ndoesn't give you is any kind of access to the stack pointer, or frame pointer,\nor goroutine id, or anything contextual about your current stack. It gives you\naccess to your list of callers, but only along with program counters, which are\nfixed at compile time.\n\nBut it does give you the stack.\n\nSo, we define 16 special functions and embed base-16 tags into the stack using\nthe call order of those 16 functions. Then, we can read our tags back out of\nthe stack looking at the callers list.\n\nWe then use these tags as an index into a traditional map for implementing\nthis library.\n\n### What are people saying? ###\n\n\"Wow, that's horrifying.\"\n\n\"This is the most terrible thing I have seen in a very long time.\"\n\n\"Where is it getting a context from? Is this serializing all the requests? \nWhat the heck is the client being bound to? What are these tags? Why does he \nneed callers? Oh god no. No no no.\"\n\n### Docs ###\n\nPlease see the docs at http://godoc.org/github.com/jtolds/gls\n\n### Related ###\n\nIf you're okay relying on the string format of the current runtime stacktrace \nincluding a unique goroutine id (not guaranteed by the spec or anything, but \nvery unlikely to change within a Go release), you might be able to squeeze \nout a bit more performance by using this similar library, inspired by some \ncode Brad Fitzpatrick wrote for debugging his HTTP/2 library: \nhttps://github.com/tylerb/gls (in contrast, jtolds/gls doesn't require \nany knowledge of the string format of the runtime stacktrace, which \nprobably adds unnecessary overhead).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjtolio%2Fgls","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjtolio%2Fgls","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjtolio%2Fgls/lists"}