pax_global_header00006660000000000000000000000064142024604740014515gustar00rootroot0000000000000052 comment=ae5f240d00cd39ab8d9504de3c20c9635d2c3bbd envpprof-1.2.1/000077500000000000000000000000001420246047400133555ustar00rootroot00000000000000envpprof-1.2.1/LICENSE000066400000000000000000000020661420246047400143660ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2015 Matt Joiner Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. envpprof-1.2.1/README.md000066400000000000000000000046411420246047400146410ustar00rootroot00000000000000# envpprof [![pkg.go.dev badge](https://img.shields.io/badge/pkg.go.dev-reference-blue)](https://pkg.go.dev/github.com/anacrolix/envpprof) Allows run-time configuration of Go's pprof features and default HTTP mux using the environment variable `GOPPROF`. Import the package with `import _ "github.com/anacrolix/envpprof"`. `envpprof` has an `init` function that will run at process initialization that checks the value of the `GOPPROF` environment variable. The variable can contain a comma-separated list of values, for example `GOPPROF=http,block`. The supported keys are: Key | Effect --- | ------ http | Exposes the default HTTP muxer [`"net/http".DefaultServeMux`](https://pkg.go.dev/net/http?tab=doc#pkg-variables) to the first free TCP port after `6060` on `localhost`. The process PID, and location are logged automatically when this is enabled. `DefaultServeMux` is frequently the default location to expose status, and debugging endpoints, including those provided by [`net/http/pprof`](https://pkg.go.dev/net/http/pprof?tab=doc). Note that the `net/http/pprof` import is included with `envpprof`, and exposed on `DefaultServeMux`. cpu |Calls [`"runtime/pprof".StartCPUProfile`](https://pkg.go.dev/runtime/pprof?tab=doc#StartCPUProfile), writing to a temporary file in `$HOME/pprof` with the prefix `cpu`. The file is not removed after use. The name of the file is logged when this is enabled. [`envpprof.Stop`](https://pkg.go.dev/github.com/anacrolix/envpprof?tab=doc#Stop) should be deferred from `main` when this will be used, to ensure proper clean up. heap |This is similar to the `cpu` key, but writes heap profile information to a file prefixed with `heap`. The profile will not be written unless `Stop` is invoked. See `cpu` for more. block | This calls [`"runtime".SetBlockProfileRate(1)`](https://pkg.go.dev/runtime?tab=doc#SetBlockProfileRate) enabling the profiling of goroutine blocking events. Note that if `http` is enabled, this exposes the blocking profile at the HTTP path `/debug/pprof/block` per package [`net/http/pprof`](https://pkg.go.dev/net/http/pprof?tab=doc#pkg-overview). mutex | This calls [`"runtime".SetMutexProfileFraction(1)`](https://pkg.go.dev/runtime?tab=doc#SetMutexProfileFraction) enabling profiling of mutex contention events. Note that if `http` is enabled, this exposes the profile at the HTTP path `/debug/pprof/mutex` per package [`net/http/pprof`](https://pkg.go.dev/net/http/pprof?tab=doc#pkg-overview). envpprof-1.2.1/envpprof.go000066400000000000000000000057041420246047400155510ustar00rootroot00000000000000package envpprof import ( "expvar" "fmt" "io/ioutil" "net" "net/http" _ "net/http/pprof" "os" "path/filepath" "runtime" "runtime/pprof" "strings" "github.com/anacrolix/log" ) var ( pprofDir = filepath.Join(os.Getenv("HOME"), "pprof") heap bool ) func writeHeapProfile() { os.Mkdir(pprofDir, 0750) f, err := ioutil.TempFile(pprofDir, "heap") if err != nil { log.Printf("error creating heap profile file: %s", err) return } defer f.Close() pprof.WriteHeapProfile(f) log.Printf("wrote heap profile to %q", f.Name()) } // Stop ends CPU profiling, waiting for writes to complete. If heap profiling is enabled, it also // writes the heap profile to a file. Stop should be deferred from main if cpu or heap profiling // are to be used through envpprof. func Stop() { // Should we check if CPU profiling was initiated through this package? pprof.StopCPUProfile() if heap { // Can or should we do this concurrently with stopping CPU profiling? writeHeapProfile() } } func startHTTP(value string) { var l net.Listener if value == "" { for port := uint16(6061); port != 6060; port++ { var err error l, err = net.Listen("tcp", fmt.Sprintf("localhost:%d", port)) if err == nil { break } } if l == nil { log.Print("unable to create envpprof listener for http") return } } else { var addr string _, _, err := net.SplitHostPort(value) if err == nil { addr = value } else { addr = "localhost:" + value } l, err = net.Listen("tcp", addr) if err != nil { panic(err) } } log.Printf("(pid=%d) envpprof serving http://%s", os.Getpid(), l.Addr()) go func() { defer l.Close() log.Printf("error serving http on envpprof listener: %s", http.Serve(l, nil)) }() } func init() { expvar.Publish("numGoroutine", expvar.Func(func() interface{} { return runtime.NumGoroutine() })) _var := os.Getenv("GOPPROF") if _var == "" { return } for _, item := range strings.Split(os.Getenv("GOPPROF"), ",") { equalsPos := strings.IndexByte(item, '=') var key, value string if equalsPos < 0 { key = item } else { key = item[:equalsPos] value = item[equalsPos+1:] } switch key { case "http": startHTTP(value) case "cpu": os.Mkdir(pprofDir, 0750) f, err := ioutil.TempFile(pprofDir, "cpu") if err != nil { log.Printf("error creating cpu pprof file: %s", err) break } err = pprof.StartCPUProfile(f) if err != nil { log.Printf("error starting cpu profiling: %s", err) break } log.Printf("cpu profiling to file %q", f.Name()) case "block": // Taken from Safe Rate at // https://github.com/DataDog/go-profiler-notes/blob/main/guide/README.md#go-profilers. runtime.SetBlockProfileRate(10000) case "heap": heap = true case "mutex": // Taken from Safe Rate at // https://github.com/DataDog/go-profiler-notes/blob/main/guide/README.md#go-profilers. runtime.SetMutexProfileFraction(100) default: log.Printf("unexpected GOPPROF key %q", key) } } } envpprof-1.2.1/go.mod000066400000000000000000000004461420246047400144670ustar00rootroot00000000000000module github.com/anacrolix/envpprof go 1.12 require ( github.com/anacrolix/log v0.3.0 github.com/davecgh/go-spew v1.1.1 // indirect github.com/kr/pretty v0.1.0 // indirect github.com/stretchr/testify v1.4.0 // indirect gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect ) envpprof-1.2.1/go.sum000066400000000000000000000114631420246047400145150ustar00rootroot00000000000000github.com/RoaringBitmap/roaring v0.4.7/go.mod h1:8khRDP4HmeXns4xIj9oGrKSz7XTQiJx2zgh7AcNke4w= github.com/anacrolix/envpprof v0.0.0-20180404065416-323002cec2fa/go.mod h1:KgHhUaQMc8cC0+cEflSgCFNFbKwi5h54gqtVn8yhP7c= github.com/anacrolix/envpprof v1.0.0/go.mod h1:KgHhUaQMc8cC0+cEflSgCFNFbKwi5h54gqtVn8yhP7c= github.com/anacrolix/log v0.3.0 h1:Btxh7GkT4JYWvWJ1uKOwgobf+7q/1eFQaDdCUXCtssw= github.com/anacrolix/log v0.3.0/go.mod h1:lWvLTqzAnCWPJA08T2HCstZi0L1y2Wyvm3FJgwU9jwU= github.com/anacrolix/missinggo v1.1.2-0.20190815015349-b888af804467/go.mod h1:MBJu3Sk/k3ZfGYcS7z18gwfu72Ey/xopPFJJbTi5yIo= github.com/anacrolix/missinggo v1.2.1 h1:0IE3TqX5y5D0IxeMwTyIgqdDew4QrzcXaaEnJQyjHvw= github.com/anacrolix/missinggo v1.2.1/go.mod h1:J5cMhif8jPmFoC3+Uvob3OXXNIhOUikzMt+uUjeM21Y= github.com/anacrolix/missinggo/perf v1.0.0/go.mod h1:ljAFWkBuzkO12MQclXzZrosP5urunoLS0Cbvb4V0uMQ= github.com/anacrolix/tagflag v0.0.0-20180109131632-2146c8d41bf0/go.mod h1:1m2U/K6ZT+JZG0+bdMK6qauP49QT4wE5pmhJXOKKCHw= github.com/bradfitz/iter v0.0.0-20140124041915-454541ec3da2/go.mod h1:PyRFw1Lt2wKX4ZVSQ2mk+PeDa1rxyObEDlApuIsUKuo= github.com/bradfitz/iter v0.0.0-20190303215204-33e6a9893b0c h1:FUUopH4brHNO2kJoNN3pV+OBEYmgraLT/KHZrMM69r0= github.com/bradfitz/iter v0.0.0-20190303215204-33e6a9893b0c/go.mod h1:PyRFw1Lt2wKX4ZVSQ2mk+PeDa1rxyObEDlApuIsUKuo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustin/go-humanize v0.0.0-20180421182945-02af3965c54e/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= github.com/glycerine/goconvey v0.0.0-20180728074245-46e3a41ad493/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180124185431-e89373fe6b4a/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/huandu/xstrings v1.0.0 h1:pO2K/gKgKaat5LdpAhxhluX2GPQMaI3W5FUz/I/UnWk= github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo= github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46/go.mod h1:uAQ5PCi+MFsC7HjREoAz1BU+Mq60+05gifQSsHSDG/8= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/willf/bitset v1.1.9/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=