Documentation
¶
Overview ¶
Package treqs provides tracing for individual HTTP requests.
Incoming requests pass through the Tracer handler. If the request contains valid key & action headers (X-Treqs-Key & X-Treqs-Action) the runtime tracer is enabled for the life of the request. While the tracer is enabled an exclusive lock is held so that only the single request is traced. All other requests hold a shared lock.
To use treqs wrap the application http.Handler with a Tracer.
var handler http.Handler // ... tracer := &treqs.Tracer{ Key: "secret-treqs-key", Handler: handler, }
Trace a request by adding the action & key headers.
var req *http.Request // ... req.Header.Set("X-Treqs-Action", "trace") req.Header.Set("X-Treqs-Key", "secret-treqs-key") res, _ := http.DefaultClient.Do(req)
Download the trace data for the last request with the action, key, and ID headers.
traceID := res.Header.Get("X-Treqs-Id") req, _ = http.NewRequest("GET", req.URL.String(), nil) req.Header.Set("X-Treqs-Action", "read") req.Header.Set("X-Treqs-Id", traceID) req.Header.Set("X-Treqs-Key", "secret-treqs-key") var file *os.File // ... res, _ := http.DefaultClient.Do(req) io.Copy(file, res.Body)
The "treqs" command can be used instead to issue a traced request and writes the contents to stdout.
$ go get -u github.com/benburkert/treqs/cmd/treqs $ treqs -url http://localhost -key secret-treqs-key > trace.out $ go tools trace treqs trace.out
Goroutines that live outside of HTTP server may be captured in trace data. The Exclude method prevents functions from inclusion in the trace.
tracer := &treqs.Tracer{ Key: "secret-treqs-key", Handler: app, } go http.ListenAndServe(addr, tracer) for := range time.NewTicker(30*time.Second) { tracer.Exclude(app.Compact) }
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Tracer ¶
Tracer is a http.Handler for enabling runtime tracing on a wrapped http.Handler. The handler supports three actions: trace, read, & reset.
Example ¶
piHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { rounds, err := strconv.Atoi(r.FormValue("rounds")) if err != nil { rounds = 50000 } ch := make(chan float64) for k := float64(1); k <= float64(rounds); k++ { go func(k float64) { ch <- (-4) * math.Pow(-1, k) / (2 * k * (2*k + 1) * (2*k + 2)) }(k) } pi := 3.0 for k := 1; k <= rounds; k++ { pi += <-ch } w.Write([]byte(fmt.Sprintf("π to the 10th digit is ~%.10f\n", pi))) }) srv := httptest.NewServer(&Tracer{ Key: "treqs", Handler: piHandler, }) req, err := http.NewRequest("GET", srv.URL, nil) if err != nil { panic(err) } req.Header.Set("X-Treqs-Key", "treqs") req.Header.Set("X-Treqs-Action", "trace") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } io.Copy(os.Stdout, res.Body) traceID := res.Header.Get("X-Treqs-Id") if traceID == "" { panic("missing X-Treqs-Id header") } if req, err = http.NewRequest("GET", srv.URL, nil); err != nil { panic(err) } req.Header.Set("X-Treqs-Key", "treqs") req.Header.Set("X-Treqs-Action", "read") req.Header.Set("X-Treqs-ID", traceID) if res, err = http.DefaultClient.Do(req); err != nil { panic(err) } if res.StatusCode != http.StatusOK { panic("unexpected response: " + res.Status) } file, err := os.Create("pi.trace") if err != nil { panic(err) } if _, err := io.Copy(file, res.Body); err != nil { panic(err) }
Output: