apptracer
is multiple trace system wrapper for Stackdriver Trace, AWS X-Ray and LightStep.
import (
"github.com/evalphobia/apptracer"
"github.com/evalphobia/apptracer/platform/localdebug"
"github.com/evalphobia/apptracer/platform/lightstep"
"github.com/evalphobia/apptracer/platform/opencensus/datadog"
"github.com/evalphobia/apptracer/platform/opencensus/xray"
"github.com/evalphobia/apptracer/platform/opencensus/stackdriver"
)
// global singleton tracer.
var tracer *apptracer.AppTracer
// Init initializes trace setting.
func Init() {
// init tracer
tracer = apptracer.New(apptracer.Config{
Enable: true,
ServiceName: "my-cool-app",
Version: "v0.0.1",
Environment: "stage",
})
// add localdebug trace (show trace data on the given Logger).
if isDebug() {
localCli := localdebug.NewClient(localdebug.Config{
Logger: nil, // when it's nil, default std.err logger is set.
})
tracer.AddClient(localCli)
}
// add LightStep
lsCli := lightstep.NewClient(lightstep.Config{
AccessToken: "<LightStep access token>",
ServiceName: "stage-my-cool-app",
})
tracer.AddClient(lsCli)
// add opencensus trace
{
// datadog (installed agent is needed)
ddExp, err := datadog.NewExporter(context.Background(), "my-cool-app")
if err != nil {
panic(err)
}
// stackdriver trace
projectID := "test-morikawa"
sdExp, err := stackdriver.NewExporter(context.Background(), stackdriver.Config{
// auth setting
PrivateKey: "<GCP private key>",
Email: "<GCP email address>",
// Filename: "/path/to/pem.json",
}, "<GCP projectID>")
if err != nil {
panic(err)
}
// aws xray trace
xrayExp, err := xray.NewExporter(context.Background())
ocCli := opencensus.NewClient(ddExp, sdExp, xrayExp)
opencensus.SetSamplingRate(1) // 100%
tracer.AddClient(ocCli)
}
tracer.Flush()
}
func MainFunction(ctx context.Context, r *http.Request) {
// Before use tracer and get span, you have to call Init() to initialzed tracer.
// defer tracer.Close()
defer tracer.Flush()
span := tracer.Trace(ctx).NewRootSpanFromRequest(r)
defer func(){
span.SetResponse(200).Finish()
// debug print for localdebug client
// span.OutputSummary()
}()
childFunction1(ctx)
childFunction2(ctx)
childFunction3(ctx)
}
func childFunction1(ctx context.Context) {
defer tracer.Trace(ctx).NewChildSpan("childFunction1").Finish()
// ... process something
}
// get user data
func childFunction2(ctx context.Context) error {
var user string
var err error
span := tracer.Trace(ctx).NewChildSpan("childFunction2")
defer func(){
span.SetUser(user).SetError(err).Finish()
}()
user, err = getUserName()
if err != nil {
return err
}
// process something ...
return nil
}
// exec sql
func childFunction3(ctx context.Context) error {
var sql string
span := tracer.Trace(ctx).NewChildSpan("childFunction3")
defer func(){
span.SetSQL(sql).Finish()
}()
sql = "SELECT * FROM users"
users, err = execSQL(sql)
if err != nil {
return err
}
// process something ...
return nil
}
- OpenCensus
- Datadog trace
- Google Stackdriver trace
- New Relic
- AWS X-Ray
- Datadog trace
- LightStep
- Supports microservices tracing
- Supports other platforms
One code for multiple tracing platforms!
- Compare and PoC tracing platforms .
- Multiple platforms with different sampling rates.