๐ tracer - Awesome Go Library for Performance
Simple, lightweight tracing.
Detailed Description of tracer
๐งถ tracer
Dead simple, lightweight tracing.
๐ก Idea
The tracer provides API to trace execution flow.
func Do(ctx context.Context) {
defer tracer.Fetch(ctx).Start().Stop()
// do some heavy job
}
A full description of the idea is available here.
๐ Motivation
At Avito, we use the Jaeger - a distributed tracing platform. It is handy in most cases, but at production, we also use sampling. So, what is a problem, you say?
I had 0.02% requests with a write: broken pipe
error and it was difficult to find the appropriate one in
the Sentry which also has trace related to it in the Jaeger.
For that reason, I wrote the simple solution to handle this specific case and found the bottleneck in our code quickly.
๐คผโโ๏ธ How to
import (
"context"
"io"
"net/http"
"time"
"github.com/kamilsk/tracer"
)
func InjectTracer(handler http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
req = req.WithContext(tracer.Inject(req.Context(), make([]*tracer.Call, 0, 10)))
handler.ServeHTTP(rw, req)
})
}
func Handle(rw http.ResponseWriter, req *http.Request) {
ctx, cancel := context.WithTimeout(req.Context(), time.Second)
defer cancel()
call := tracer.Fetch(req.Context()).Start(req.Header.Get("X-Request-Id"))
defer call.Stop()
...
call.Checkpoint("serialize")
data, err := FetchData(ctx, req.Body)
if err != nil {
http.Error(rw, err.Error(), http.StatusInternalServerError)
return
}
call.Checkpoint("store")
if err := StoreIntoDatabase(ctx, data); err != nil {
http.Error(rw,
http.StatusText(http.StatusInternalServerError),
http.StatusInternalServerError)
return
}
rw.WriteHeader(http.StatusOK)
}
func FetchData(ctx context.Context, r io.Reader) (Data, error) {
defer tracer.Fetch(ctx).Start().Stop()
// fetch a data into a struct
}
func StoreIntoDatabase(ctx context.Context, data Data) error {
defer tracer.Fetch(ctx).Start().Stop()
// store the data into a database
}
Output:
allocates at call stack: 0, detailed call stack:
call Handle [ca7a87c4-58d0-4fdf-857c-ef49fc3bf271]: 14.038083ms, allocates: 2
checkpoint [serialize]: 1.163587ms
checkpoint [store]: 2.436265ms
call FetchData: 1.192829ms, allocates: 0
call StoreIntoDatabase: 10.428663ms, allocates: 0
๐งฉ Integration
The library uses SemVer for versioning, and it is not BC-safe through major releases. You can use go modules to manage its version.
$ go get github.com/kamilsk/tracer@latest
made with โค๏ธ for everyone