Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Tracing your money

mattheath
September 30, 2015

Tracing your money

At Mondo we’re building a new kind of bank in Go on a microservice platform, which has a huge number of benefits, at the cost of increased complexity. We use Phosphor, an open source system tracing tool built in Go, to track and diagnose problems in our platform. We'll cover how we developed and integrated this using the Context package, and how this enables system behaviour to be observed and monitored in high volume, low latency, distributed Go applications.

mattheath

September 30, 2015
Tweet

More Decks by mattheath

Other Decks in Programming

Transcript

  1. SOME
 API SERVICE ONE SERVICE TWO LOAD BALANCER HTTP API

    & ROUTING LAYER DATABASE DATABASE EXTERNAL PROVIDER
  2. PhosphorD Service A Trace Library goroutine chan UDP Service B

    Trace Library goroutine chan UDP PHOSPHOR HOST INSTANCES PUBLISH DASHBOARDS AGGREGATION PERSISTANCE NSQ
  3. PhosphorD Service A Trace Library goroutine chan UDP Service B

    Trace Library goroutine chan UDP PHOSPHOR HOST INSTANCES PUBLISH DASHBOARDS AGGREGATION PERSISTANCE NSQ
  4. PhosphorD Service A Trace Library goroutine chan UDP Service B

    Trace Library goroutine chan UDP PHOSPHOR HOST INSTANCES PUBLISH DASHBOARDS AGGREGATION PERSISTANCE NSQ
  5. PhosphorD Service A Trace Library goroutine chan UDP Service B

    Trace Library goroutine chan UDP PHOSPHOR HOST INSTANCES PUBLISH DASHBOARDS AGGREGATION PERSISTANCE NSQ
  6. package context type Context interface { Deadline() (deadline time.Time, ok

    bool) Done() <-chan struct{} Err() error Value(key interface{}) interface{} }
  7. package context type Context interface { Deadline() (deadline time.Time, ok

    bool) Done() <-chan struct{} Err() error Value(key interface{}) interface{} }
  8. package context type Context interface { Deadline() (deadline time.Time, ok

    bool) Done() <-chan struct{} Err() error Value(key interface{}) interface{} }
  9. type Client interface { Add(Call) Client // various other funcs

    Middleware() []ClientMiddleware SetMiddleware([]ClientMiddleware) AddMiddleware(ClientMiddleware) }
  10. ctx := context.Background() if v := req.Headers()["TraceID"]; v != ""

    { ctx = context.WithValue(ctx, "TraceID", v) }
  11. &Annotation{ Type: AnnotationType_SERVER_SEND, TraceId: "ffeae21f-c5c1-4...", ParentId: "31f4ebd0-a34b-4...", SpanId: "2c97d609-46ef-4...", Timestamp:

    microTime(time.Now()), Hostname: util.Hostname(), KeyValue: map[string]string{}, Payload: []byte{}, // extra fields }
  12. &Annotation{ Type: AnnotationType_SERVER_SEND, TraceId: "ffeae21f-c5c1-4...", ParentId: "31f4ebd0-a34b-4...", SpanId: "2c97d609-46ef-4...", Timestamp:

    microTime(time.Now()), Hostname: util.Hostname(), KeyValue: map[string]string{}, Payload: []byte{}, // extra fields }
  13. &Annotation{ Type: AnnotationType_SERVER_SEND, TraceId: "ffeae21f-c5c1-4...", ParentId: "31f4ebd0-a34b-4...", SpanId: "2c97d609-46ef-4...", Timestamp:

    microTime(time.Now()), Hostname: util.Hostname(), KeyValue: map[string]string{}, Payload: []byte{}, // extra fields }
  14. &Annotation{ Type: AnnotationType_SERVER_SEND, TraceId: "ffeae21f-c5c1-4...", ParentId: "31f4ebd0-a34b-4...", SpanId: "2c97d609-46ef-4...", Timestamp:

    microTime(time.Now()), Hostname: util.Hostname(), KeyValue: map[string]string{}, Payload: []byte{}, // extra fields }
  15. &Annotation{ Type: AnnotationType_ANNOTATION, TraceId: "ffeae21f-c5c1-4...", ParentId: "31f4ebd0-a34b-4...", SpanId: "2c97d609-46ef-4...", Timestamp:

    microTime(time.Now()), Hostname: util.Hostname(), KeyValue: map[string]string{}, Payload: []byte{}, // extra fields }
  16. &Annotation{ Type: AnnotationType_ANNOTATION, TraceId: "ffeae21f-c5c1-4...", ParentId: "31f4ebd0-a34b-4...", SpanId: "2c97d609-46ef-4...", Timestamp:

    microTime(time.Now()), Hostname: util.Hostname(), KeyValue: map[string]string{ "query": "SELECT xxx FROM...", }, Payload: results, // extra fields }
  17. PhosphorD Service A Trace Library goroutine chan UDP Service B

    Trace Library goroutine chan UDP PHOSPHOR HOST INSTANCES PUBLISH DASHBOARDS AGGREGATION PERSISTANCE NSQ
  18. listener, err := net.ListenUDP("udp", address) check(err) for { message :=

    make([]byte, packetSize) n, _, err := listener.ReadFrom(message) buf := bytes.NewBuffer(message[0:n]) writeToTransport(buf) }
  19. ch := make(chan []byte, 10000) for { message := make([]byte,

    packetSize) n, _, err := listener.ReadFrom(message) buf := bytes.NewBuffer(message[0:n]) select { case ch <- buf.Bytes(): // log.Infof("Wrote message to channel") default: // abort! // log.Infof("Dropped message") } }
  20. func (w *worker) loop() { var b []byte timeout :=

    time.NewTicker(bufferWindow) defer timeout.Stop() // Bonus points // Spin and forward on traces every time our // buffer fills, or when our time window elapses for { select { case b = <-w.ch: w.buf = append(w.buf, b) if len(w.buf) >= bufferSize { w.send() } case <-timeout.C: w.send() } } }
  21. PhosphorD Service A Trace Library goroutine chan UDP Service B

    Trace Library goroutine chan UDP PHOSPHOR HOST INSTANCES PUBLISH DASHBOARDS AGGREGATION PERSISTANCE NSQ
  22. log.Errorf(ctx, "Uh oh! %s", err.Error()) log.Warnf(ctx, "Uh oh! %s", err.Error())

    log.Infof(ctx, "Uh oh! %s", err.Error()) log.Debugf(ctx, "Uh oh! %s", err.Error())
  23. 44ac4b44-a874-4e60-8fe5-8d05229dbb49 127.0.0.1 - - [30/Sep/2015 05:38:15] "POST /oauth2/token HTTP/1.1" 200

    720 "" "Go 1.1 package http" 0. "{"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjaSI6Im9hdXRoY2xpZW50XzAwMDA5MGJ2RkdZRFJ5T2Z0UE9KSWYiLCJleHAiOjE0NDM2NTYyOTUsImlhdC AwMDA5MGJ2Rkg2Yk83dTFjM1RsdGgiLCJ1aSI6InVzZXJfMDAwMDkwYnZGRkRjUDRLSmxFa0xZWCIsInYiOiIxIn0.gGS_VD6tY7whmkVTZunsE- Fo8Si8fkUDOulCA8cbZxI","client_id":"oauthclient_000090bvFGYDRyOftPOJIf","expires_in": 21599,"refresh_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhaSI6InRva18wMDAwOTBidkZINmJPN3UxYzNUbHRoIiwiY2kiOiJvYXV0aGNsaWVudF8wMDAwOTBid DQzNjM0Njk1LCJ1aSI6InVzZXJfMDAwMDkwYnZGRkRjUDRLSmxFa0xZWCIsInYiOiIxIn0.rqWHmWWORQXoitn3HeJU743rMwB9pW7g3YJ96BGYSoE","token_type":"Bearer","us LYX"}" 44ac4b44-a874-4e60-8fe5-8d05229dbb49 1443634695745954288 [Debug] Bearer token recovered: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjaSI6Im9hdXRoY2xpZW50XzAwMDA5MGJ2RkdZRFJ5T2Z0UE9KSWYiLCJleHAiOjE0NDM2NTYyOTUsImlhdCI6MTQ0MzYzNDY5NSwi dTFjM1RsdGgiLCJ1aSI6InVzZXJfMDAwMDkwYnZGRkRjUDRLSmxFa0xZWCIsInYiOiIxIn0.gGS_VD6tY7whmkVTZunsE-Fo8Si8fkUDOulCA8cbZxI 44ac4b44-a874-4e60-8fe5-8d05229dbb49 1443634695746092845 [Debug] [Mercury:Client] Sending request to service.platform.authentication/read_a 44ac4b44-a874-4e60-8fe5-8d05229dbb49 1443634695761353836 [Debug] [Mercury:Client] Sending request to service.platform.permission/read… 44ac4b44-a874-4e60-8fe5-8d05229dbb49 1443634695762559395 [Debug] [Mercury:Client] Sending request to service.platform.permission/read… 44ac4b44-a874-4e60-8fe5-8d05229dbb49 1443634695762610999 [Debug] [Mercury:Client] Sending request to service.oauth2-client/read_client… 44ac4b44-a874-4e60-8fe5-8d05229dbb49 1443634695781366551 [Debug] [Mercury:Client] Sending request to service.api.card-activation/handlehttp