-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add local debug, Stackdriver trace and AWS X-Ray client
- Loading branch information
1 parent
6abcb1a
commit eb211f0
Showing
21 changed files
with
1,257 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,3 +12,5 @@ | |
|
||
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 | ||
.glide/ | ||
|
||
.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,172 @@ | ||
# apptracer | ||
Multiple trace system wrapper for Stackdriver Trace asd AWS X-Ray | ||
apptracer | ||
---- | ||
|
||
[![GoDoc][1]][2] [![License: MIT][3]][4] [![Release][5]][6] [![Build Status][7]][8] [![Co decov Coverage][11]][12] [![Go Report Card][13]][14] [![Downloads][15]][16] | ||
|
||
[1]: https://godoc.org/github.com/evalphobia/apptracer?status.svg | ||
[2]: https://godoc.org/github.com/evalphobia/apptracer | ||
[3]: https://img.shields.io/badge/License-MIT-blue.svg | ||
[4]: LICENSE.md | ||
[5]: https://img.shields.io/github/release/evalphobia/apptracer.svg | ||
[6]: https://github.com/evalphobia/apptracer/releases/latest | ||
[7]: https://travis-ci.org/evalphobia/apptracer.svg?branch=master | ||
[8]: https://travis-ci.org/evalphobia/apptracer | ||
[9]: https://coveralls.io/repos/evalphobia/apptracer/badge.svg?branch=master&service=github | ||
[10]: https://coveralls.io/github/evalphobia/apptracer?branch=master | ||
[11]: https://codecov.io/github/evalphobia/apptracer/coverage.svg?branch=master | ||
[12]: https://codecov.io/github/evalphobia/apptracer?branch=master | ||
[13]: https://goreportcard.com/badge/github.com/evalphobia/apptracer | ||
[14]: https://goreportcard.com/report/github.com/evalphobia/apptracer | ||
[15]: https://img.shields.io/github/downloads/evalphobia/apptracer/total.svg?maxAge=1800 | ||
[16]: https://github.com/evalphobia/apptracer/releases | ||
[17]: https://img.shields.io/github/stars/evalphobia/apptracer.svg | ||
[18]: https://github.com/evalphobia/apptracer/stargazers | ||
|
||
`apptracer` is multiple trace system wrapper for Stackdriver Trace and AWS X-Ray. | ||
|
||
# Usage | ||
|
||
```go | ||
import ( | ||
"github.com/evalphobia/apptracer" | ||
"github.com/evalphobia/apptracer/platform/localdebug" | ||
"github.com/evalphobia/apptracer/platform/stackdriver" | ||
"github.com/evalphobia/apptracer/platform/xray" | ||
) | ||
|
||
// 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 stackdriver trace | ||
sdCli = stackdriver.NewClient(stackdriver.Config{ | ||
// auth setting | ||
PrivateKey: "<GCP private key>", | ||
Email: "<GCP email address>", | ||
// Filename: "/path/to/pem.json", // | ||
|
||
// sampling setting | ||
SamplingFraction: 0.5, // sampling rate => 50% | ||
SamplingQPS: 100.0, // max late => 100 req/s | ||
|
||
// stackdriver trace can only filter by URI(name), | ||
// so adding prefix can make difference between other service or environment in same projectID. | ||
Prefix: "stage-my-cool-app", | ||
}, "<GCP projectID>") | ||
tracer.AddClient(sdCli) | ||
|
||
// add aws xray trace | ||
xrayCli := xray.NewClient(xray.Config{ | ||
AccessKey: "<AWS access key>", | ||
SecretKey: "<AWS secret key>", | ||
Region: "<AWS region>", | ||
|
||
// sampling setting | ||
SamplingFraction: 0.5, | ||
SamplingQPS: 10.0, | ||
|
||
// client sends span data on each checkpoint, | ||
CheckpointSize: 10, | ||
CheckpointInterval: 1*time.Second, | ||
}) | ||
tracer.AddClient(xrayCli) | ||
} | ||
|
||
func MainFunction(ctx context.Context, r *http.Request) { | ||
// Before use tracer and get span, you have to call Init() to initialzed tracer. | ||
|
||
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 | ||
} | ||
``` | ||
|
||
## Supported Platform | ||
|
||
- Google Stackdriver trace | ||
- AWS X-Ray | ||
|
||
## TODO | ||
|
||
- Supports microservices tracing | ||
- Supports other platforms | ||
- New Relic | ||
- LightStep | ||
|
||
# Whats For? | ||
|
||
One code for multiple tracing platforms! | ||
|
||
- Compare and PoC tracing platforms . | ||
- Multiple platforms with different sampling rates. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package apptracer | ||
|
||
import ( | ||
"golang.org/x/net/context" | ||
|
||
"github.com/evalphobia/apptracer/platform" | ||
) | ||
|
||
// AppTracer has multiple tracing platform clients | ||
// to send tracing activity to the platforms. | ||
type AppTracer struct { | ||
Config | ||
ClientList []PlatformClient | ||
} | ||
|
||
// New returns initialized AppTracer. | ||
func New(conf Config) *AppTracer { | ||
return &AppTracer{ | ||
Config: conf, | ||
} | ||
} | ||
|
||
// AddClient adds PlatformClient into ClientList. | ||
func (a *AppTracer) AddClient(c PlatformClient) { | ||
a.ClientList = append(a.ClientList, c) | ||
} | ||
|
||
// Trace creates *TraceWrapper from context. | ||
// TraceWrapper contains platform clients and generates span data for the platforms. | ||
// TraceWrapper is cached in the context and you can get same TraceWrapper | ||
// when pass the same context. | ||
func (a *AppTracer) Trace(ctx context.Context) *TraceWrapper { | ||
switch { | ||
case !a.Config.Enable, | ||
ctx == nil: | ||
return &TraceWrapper{} | ||
} | ||
|
||
t, ok := ctx.Value(traceKey{}).(*TraceWrapper) | ||
if ok { | ||
return t | ||
} | ||
|
||
t = &TraceWrapper{ | ||
traceList: make([]platform.Trace, 0, len(a.ClientList)), | ||
defaultLabels: a.Config.DefaultLabels, | ||
serviceName: a.Config.ServiceName, | ||
version: a.Config.Version, | ||
environment: a.Config.Environment, | ||
} | ||
for _, cli := range a.ClientList { | ||
tr, err := cli.NewTrace(ctx) | ||
if err == nil { | ||
t.traceList = append(t.traceList, tr) | ||
} | ||
} | ||
t.ctx = context.WithValue(ctx, traceKey{}, t) | ||
return t | ||
} | ||
|
||
type traceKey struct{} // used to get TraceWrapper from context. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package apptracer | ||
|
||
// Config contains tracing settings. | ||
type Config struct { | ||
// Only if Enable is true then tracing data sends to tracing platform. | ||
Enable bool | ||
// DefaultLabels sets labels into every tracing data(span). | ||
DefaultLabels []Label | ||
// ServiceName is your application name. | ||
ServiceName string | ||
// Version is your application version. | ||
Version string | ||
// Environment is your application version. (e.g. dev, stage, prod) | ||
Environment string | ||
} | ||
|
||
// Label has key-value pair data for labeling. | ||
type Label struct { | ||
Key string | ||
Value string | ||
} | ||
|
||
// NewLabel creates Label. | ||
func NewLabel(key, value string) Label { | ||
return Label{key, value} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package localdebug | ||
|
||
import ( | ||
"log" | ||
"os" | ||
|
||
"golang.org/x/net/context" | ||
|
||
"github.com/evalphobia/apptracer/platform" | ||
) | ||
|
||
// Client is struct of local debugging client for tracing. | ||
type Client struct { | ||
conf Config | ||
} | ||
|
||
// NewClient returns initialized *Client. | ||
func NewClient(conf Config) *Client { | ||
if conf.Logger == nil { | ||
conf.Logger = log.New(os.Stderr, "", log.LstdFlags) | ||
} | ||
|
||
return &Client{ | ||
conf: conf, | ||
} | ||
} | ||
|
||
func (c *Client) NewTrace(ctx context.Context) (platform.Trace, error) { | ||
return &Trace{ | ||
logger: c.conf.Logger, | ||
}, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package localdebug | ||
|
||
import "log" | ||
|
||
type Config struct { | ||
Logger *log.Logger | ||
} |
Oops, something went wrong.