metaverse / truss

Truss helps you build go-kit microservices without having to worry about writing or maintaining boilerplate code.
Other
737 stars 144 forks source link

how can I add zipkin-go with truss #276

Closed Allkoman closed 5 years ago

Allkoman commented 5 years ago

I don't know where should I add tracking module when I use truss and go-kit, I saw the TUTORIAL.md, the middlewares is TODO, can u help me with that, thx

zaquestion commented 5 years ago

I'll offer a brief explanation, as I'm pressed for time.

Essentially you'll want to use the endpoint middleware defined for zipkin https://github.com/go-kit/kit/blob/master/tracing/zipkin/endpoint.go#L16 ( or create your own if needed )

Generating the truss service will get you something like:

package handlers

import (
    "net/http"
    "os"

    pb "github.com/some/truss/service"
    "github.com/some/truss/service/service-service/svc"
)

// WrapEndpoints accepts the service's entire collection of endpoints, so that a
// set of middlewares can be wrapped around every middleware (e.g., access
// logging and instrumentation), and others wrapped selectively around some
// endpoints and not others (e.g., endpoints requiring authenticated access).
// Note that the final middleware wrapped will be the outermost middleware
// (i.e. applied first)
func WrapEndpoints(in svc.Endpoints) svc.Endpoints {
    // Pass a middleware you want applied to every endpoint.
    // optionally pass in endpoints by name that you want to be excluded
    // e.g.
    // in.WrapAllExcept(authMiddleware, "Status", "Ping")

    // Pass in a svc.LabeledMiddleware you want applied to every endpoint.
    // These middlewares get passed the endpoints name as their first argument when applied.
    // This can be used to write generic metric gathering middlewares that can
    // report the endpoint name for free.
    // github.com/metaverse/truss/_example/middlewares/labeledmiddlewares.go for examples.
    // in.WrapAllLabeledExcept(errorCounter(statsdCounter), "Status", "Ping")

    // How to apply a middleware to a single endpoint.
    // in.ExampleEndpoint = authMiddleware(in.ExampleEndpoint)

    return in
}

The simplest way to add a middleware is calling in.WrapAllExcept

import  "github.com/go-kit/kit/tracking/zipkin"

func WrapEndpoints(in svc.Endpoints) svc.Endpoints {
...
        var tracer *zipkin.Tracer // Actually initialize this
    in.WrapAllExcept(zipkin.TraceEndpoint(tracer, "name")) 
        // Basic example of wrapping the truss endpoints with the middleware but you're
        // now faced with the problem of getting the endpoint names out. This is a
        // common case for middlewares so truss provides another function which exposes
        // the endpoint name when wrapping middlewares
}

Instead you'll probably want to wrap the endpoint middleware to be a labelled middleware with in.WrapAllLabelledExcept

func WrapEndpoints(in svc.Endpoints) svc.Endpoints {
...
        var tracer *zipkin.Tracer // Actually initialize this
    in.WrapAllLabelledExcept(zipkinMiddleware(tracer))
}

func zipkinMiddleware(tracer *zipkin.Tracer) func(string, endpoint.Endpoint) endpoint.Endpoint {
    return func(name string, in endpoint.Endpoint) endpoint.Endpoint {
            return zipkin.TraceEndpoint(tracer, name)(in)
    }
}

Disclaimer: above probably needs to be tinkered with, just trying to get the concept out there.

Example labeled middlewares: https://github.com/metaverse/truss/blob/master/_example/middlewares/labeledmiddlewares.go

zaquestion commented 5 years ago

@Allkoman Let me know if you need any further clarification, gonna close this out.