Initial draft of READMEs for each package.
Peter Bourgon
8 years ago
23 | 23 | |
24 | 24 | ## Component status |
25 | 25 | |
26 | - API stability — adopted | |
27 | - `package metrics` — [implemented](https://github.com/go-kit/kit/tree/master/metrics) | |
28 | - `package server` — [implemented](https://github.com/go-kit/kit/tree/master/server) | |
29 | - `package transport` — [implemented](https://github.com/go-kit/kit/tree/master/transport) | |
30 | - `package log` — [implemented](https://github.com/go-kit/kit/tree/master/log) | |
31 | - `package tracing` — [prototyping](Https://github.com/go-kit/kit/tree/master/tracing) | |
26 | - [API stability](https://github.com/go-kit/kit/blob/master/rfc/rfc007-api-stability.md) — **adopted** | |
27 | - [`package metrics`](https://github.com/go-kit/kit/tree/master/metrics) — **implemented** | |
28 | - [`package server`](https://github.com/go-kit/kit/tree/master/server) — **implemented** | |
29 | - [`package transport`](https://github.com/go-kit/kit/tree/master/transport) — **implemented** | |
30 | - [`package log`](https://github.com/go-kit/kit/tree/master/log) — **implemented** | |
31 | - [`package tracing`](https://github.com/go-kit/kit/tree/master/tracing) — prototyping | |
32 | 32 | - `package client` — pending |
33 | 33 | - Service discovery — pending |
34 | 34 |
0 | # addsvc | |
1 | ||
2 | addsvc is an example service, used to illustrate the mechanics of gokit. | |
3 | It exposes simple functionality on a variety of transports and endpoints. | |
4 | ||
5 | ## Server | |
6 | ||
7 | To build and run addsvc, | |
8 | ||
9 | ``` | |
10 | $ go install | |
11 | $ addsvc | |
12 | ``` | |
13 | ||
14 | ## Client | |
15 | ||
16 | TODO |
0 | # package log | |
1 | ||
2 | `package log` is an opinionated package for logging in your service. | |
3 | It provides a minimal interface for structured logging, which may be wrapped to encode conventions, enforce type-safety, etc. | |
4 | It can used for both typical application log events, and log-structured data streams. | |
5 | ||
6 | ## Rationale | |
7 | ||
8 | TODO | |
9 | ||
10 | ## Usage | |
11 | ||
12 | Typical application logging. | |
13 | ||
14 | ```go | |
15 | import "github.com/go-kit/kit/log" | |
16 | ||
17 | func main() { | |
18 | logger := log.NewPrefixLogger(os.Stderr) | |
19 | logger.Log("question", "what is the meaning of life?", "answer", 42) | |
20 | } | |
21 | ``` | |
22 | ||
23 | Contextual logging. | |
24 | ||
25 | ```go | |
26 | func handle(logger log.Logger, req *Request) { | |
27 | logger = log.With(logger, "txid", req.TransactionID, "query", req.Query) | |
28 | logger.Log() | |
29 | ||
30 | answer, err := process(logger, req.Query) | |
31 | if err != nil { | |
32 | logger.Log("err", err) | |
33 | return | |
34 | } | |
35 | ||
36 | logger.Log("answer", answer) | |
37 | } | |
38 | ``` | |
39 | ||
40 | Redirect stdlib log to gokit logger. | |
41 | ||
42 | ```go | |
43 | import ( | |
44 | "os" | |
45 | stdlog "log" | |
46 | kitlog "github.com/go-kit/kit/log" | |
47 | ) | |
48 | ||
49 | func main() { | |
50 | logger := kitlog.NewJSONLogger(os.Stdout) | |
51 | stdlog.SetOutput(kitlog.NewStdlibAdapter(logger)) | |
52 | } | |
53 | ```⏎ |
8 | 8 | |
9 | 9 | // StdlibWriter implements io.Writer by invoking the stdlib log.Printf. It's |
10 | 10 | // designed to be passed to a gokit logger as the writer, for cases where it's |
11 | // desirable to pipe all log output to the same, canonical destination. | |
11 | // necessary to redirect all gokit log output to the stdlib logger. | |
12 | // | |
13 | // If you have any choice in the matter, you shouldn't use this. Prefer to | |
14 | // redirect the stdlib log to the gokit logger via NewStdlibAdapter. | |
12 | 15 | type StdlibWriter struct{} |
13 | 16 | |
14 | 17 | // Write implements io.Writer. |
0 | # package metrics | |
1 | ||
2 | `package metrics` is an opinionated package for instrumenting your service. | |
3 | It provides a set of uniform interfaces for **[counters][]**, **[gauges][]**, and **[histograms][]**. | |
4 | It provides adapters to popular metrics packages, like **[expvar][]**, **[statsd][]**, and **[Prometheus][]**. | |
5 | ||
6 | [counters]: http://prometheus.io/docs/concepts/metric_types/#counter | |
7 | [gauges]: http://prometheus.io/docs/concepts/metric_types/#gauge | |
8 | [histogram]: http://prometheus.io/docs/concepts/metric_types/#histogram | |
9 | [expvar]: https://golang.org/pkg/expvar | |
10 | [statsd]: https://github.com/etsy/statsd | |
11 | [Prometheus]: http://prometheus.io | |
12 | ||
13 | ## Rationale | |
14 | ||
15 | TODO | |
16 | ||
17 | ## Usage | |
18 | ||
19 | A simple counter, exported via expvar. | |
20 | ||
21 | ```go | |
22 | import "github.com/go-kit/kit/metrics/expvar" | |
23 | ||
24 | func main() { | |
25 | myCount := expvar.NewCounter("my_count") | |
26 | myCount.Add(1) | |
27 | } | |
28 | ``` | |
29 | ||
30 | A histogram for request duration, exported via a Prometheus summary with | |
31 | dynamically-computed quantiles. | |
32 | ||
33 | ```go | |
34 | import ( | |
35 | stdprometheus "github.com/prometheus/client_golang/prometheus" | |
36 | ||
37 | "github.com/go-kit/kit/metrics" | |
38 | "github.com/go-kit/kit/metrics/prometheus" | |
39 | "github.com/go-kit/kit/metrics/statsd" | |
40 | ) | |
41 | ||
42 | var requestDuration = prometheus.NewSummary(stdprometheus.SummaryOpts{ | |
43 | Namespace: "myservice", | |
44 | Subsystem: "api", | |
45 | Name: "request_duration_nanoseconds_count", | |
46 | Help: "Total time spent serving requests.", | |
47 | }, []string{}) | |
48 | ||
49 | func handleRequest() { | |
50 | defer func(begin time.Time) { requestDuration.Observe(time.Since(begin)) }(time.Now()) | |
51 | // handle request | |
52 | } | |
53 | ``` |
0 | # package server | |
1 | ||
2 | `package server` is a very small package that collects interfaces used by services. | |
3 | Most server-side functionality is actually implemented in surrounding packages. | |
4 | ||
5 | # Rationale | |
6 | ||
7 | TODO | |
8 | ||
9 | # Usage | |
10 | ||
11 | As currently defined, you shouldn't need to use `package server` directly. | |
12 | Other go-kit components integrate on `package server` interfaces. |
0 | # package tracing | |
1 | ||
2 | `package tracing` provides [Dapper-style][dapper] request tracing to services. | |
3 | An implementations exists for [Zipkin][]; [Appdash][] support is planned. | |
4 | ||
5 | [dapper]: http://research.google.com/pubs/pub36356.html | |
6 | [Zipkin]: https://blog.twitter.com/2012/distributed-systems-tracing-with-zipkin | |
7 | [Appdash]: https://sourcegraph.com/blog/117580140734 | |
8 | ||
9 | ## Rationale | |
10 | ||
11 | TODO | |
12 | ||
13 | ## Usage | |
14 | ||
15 | Wrap a [server.Endpoint][] so that it emits traces to a Zipkin collector. | |
16 | ||
17 | [server.Endpoint]: http://godoc.org/github.com/go-kit/kit/server#Endpoint | |
18 | ||
19 | ```go | |
20 | func main() { | |
21 | var ( | |
22 | myHost = "instance01.addsvc.internal.net" | |
23 | myMethod = "ADD" | |
24 | scribeHost = "scribe.internal.net" | |
25 | timeout = 50 * time.Millisecond | |
26 | batchSize = 100 | |
27 | batchInterval = 3 * time.Second | |
28 | ) | |
29 | ||
30 | spanFunc := zipkin.NewSpanFunc(myHost, myMethod) | |
31 | collector, _ := zipkin.NewScribeCollector(scribeHost, timeout, batchSize, batchInterval) | |
32 | ||
33 | var e server.Endpoint | |
34 | e = makeEndpoint() // for your service | |
35 | e = zipkin.AnnotateEndpoint(spanFunc, collector) | |
36 | ||
37 | serve(e) | |
38 | } | |
39 | ``` |
0 | # package transport | |
1 | ||
2 | `package transport` defines interfaces for service transports and codecs. | |
3 | It also provides implementations for transports and codecs that aren't already well-defined by other packages. | |
4 | The most common use case for `package transport` is probably to bind a gokit [server.Endpoint][] with a stdlib [http.Handler][], via gokit's [http.Binding][]. | |
5 | Refer to the [addsvc][] example service to see how to make [Thrift][] or [gRPC][] transport bindings. | |
6 | ||
7 | [server.Endpoint]: https://godoc.org/github.com/go-kit/kit/server/#Endpoint | |
8 | [http.Handler]: https://golang.org/pkg/net/http/#Handler | |
9 | [http.Binding]: https://godoc.org/github.com/go-kit/kit/transport/http/#Binding | |
10 | [addsvc]: https://github.com/go-kit/kit/blob/319c1c7129a146b541bbbaf18e2502bf32c603c5/addsvc/main.go | |
11 | [Thrift]: https://github.com/go-kit/kit/blob/319c1c7129a146b541bbbaf18e2502bf32c603c5/addsvc/main.go#L142-192 | |
12 | [gRPC]: https://github.com/go-kit/kit/blob/319c1c7129a146b541bbbaf18e2502bf32c603c5/addsvc/main.go#L102-119 | |
13 | ||
14 | ## Rationale | |
15 | ||
16 | TODO | |
17 | ||
18 | ## Usage | |
19 | ||
20 | Bind a gokit [server.Endpoint][] with a stdlib [http.Handler][]. | |
21 | ||
22 | ```go | |
23 | import ( | |
24 | "net/http" | |
25 | "reflect" | |
26 | ||
27 | "golang.org/x/net/context" | |
28 | ||
29 | jsoncodec "github.com/go-kit/kit/transport/codec/json" | |
30 | httptransport "github.com/go-kit/kit/transport/http" | |
31 | ) | |
32 | ||
33 | type request struct{} | |
34 | ||
35 | func main() { | |
36 | var ( | |
37 | ctx = context.Background() | |
38 | requestType = reflect.TypeOf(request{}) | |
39 | codec = jsoncodec.New() | |
40 | e = makeEndpoint() | |
41 | before = []httptransport.BeforeFunc{} | |
42 | after = []httptransport.AfterFunc{} | |
43 | ) | |
44 | handler := httptransport.NewBinding(ctx, requestType, codec, e, before, after) | |
45 | mux := http.NewServeMux() | |
46 | mux.Handle("/path", handler) | |
47 | http.ListenAndServe(":8080", mux) | |
48 | } | |
49 | ``` |