Skip to content
This repository was archived by the owner on Dec 5, 2023. It is now read-only.

Commit fae2a75

Browse files
Merge pull request #30 from microservices-demo/enhancement/opentracing
Enhancement/opentracing
2 parents 1d394b6 + 6bc65ab commit fae2a75

File tree

7 files changed

+257
-33
lines changed

7 files changed

+257
-33
lines changed

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,24 @@ curl http://localhost:8080/register
8585
```bash
8686
make dockertravisbuild
8787
```
88+
89+
## Test Zipkin
90+
91+
To test with Zipkin
92+
93+
```
94+
make
95+
docker-compose -f docker-compose-zipkin.yml build
96+
docker-compose -f docker-compose-zipkin.yml up
97+
```
98+
It takes about 10 seconds to seed data
99+
100+
you should see it at:
101+
[http://localhost:9411/](http://localhost:9411)
102+
103+
be sure to hit the "Find Traces" button. You may need to reload the page.
104+
105+
when done you can run:
106+
```
107+
docker-compose -f docker-compose-zipkin.yml down
108+
```

api/endpoints.go

Lines changed: 63 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ package api
66

77
import (
88
"github.com/go-kit/kit/endpoint"
9+
"github.com/go-kit/kit/tracing/opentracing"
910
"github.com/microservices-demo/user/db"
1011
"github.com/microservices-demo/user/users"
12+
stdopentracing "github.com/opentracing/opentracing-go"
1113
"golang.org/x/net/context"
1214
)
1315

@@ -27,24 +29,28 @@ type Endpoints struct {
2729

2830
// MakeEndpoints returns an Endpoints structure, where each endpoint is
2931
// backed by the given service.
30-
func MakeEndpoints(s Service) Endpoints {
32+
func MakeEndpoints(s Service, tracer stdopentracing.Tracer) Endpoints {
3133
return Endpoints{
32-
LoginEndpoint: MakeLoginEndpoint(s),
33-
RegisterEndpoint: MakeRegisterEndpoint(s),
34-
HealthEndpoint: MakeHealthEndpoint(s),
35-
UserGetEndpoint: MakeUserGetEndpoint(s),
36-
UserPostEndpoint: MakeUserPostEndpoint(s),
37-
AddressGetEndpoint: MakeAddressGetEndpoint(s),
38-
AddressPostEndpoint: MakeAddressPostEndpoint(s),
39-
CardGetEndpoint: MakeCardGetEndpoint(s),
40-
DeleteEndpoint: MakeDeleteEndpoint(s),
41-
CardPostEndpoint: MakeCardPostEndpoint(s),
34+
LoginEndpoint: opentracing.TraceServer(tracer, "GET /login")(MakeLoginEndpoint(s)),
35+
RegisterEndpoint: opentracing.TraceServer(tracer, "POST /register")(MakeRegisterEndpoint(s)),
36+
HealthEndpoint: opentracing.TraceServer(tracer, "GET /health")(MakeHealthEndpoint(s)),
37+
UserGetEndpoint: opentracing.TraceServer(tracer, "GET /customers")(MakeUserGetEndpoint(s)),
38+
UserPostEndpoint: opentracing.TraceServer(tracer, "POST /customers")(MakeUserPostEndpoint(s)),
39+
AddressGetEndpoint: opentracing.TraceServer(tracer, "GET /addresses")(MakeAddressGetEndpoint(s)),
40+
AddressPostEndpoint: opentracing.TraceServer(tracer, "POST /addresses")(MakeAddressPostEndpoint(s)),
41+
CardGetEndpoint: opentracing.TraceServer(tracer, "GET /cards")(MakeCardGetEndpoint(s)),
42+
DeleteEndpoint: opentracing.TraceServer(tracer, "DELETE /")(MakeDeleteEndpoint(s)),
43+
CardPostEndpoint: opentracing.TraceServer(tracer, "POST /cards")(MakeCardPostEndpoint(s)),
4244
}
4345
}
4446

4547
// MakeLoginEndpoint returns an endpoint via the given service.
4648
func MakeLoginEndpoint(s Service) endpoint.Endpoint {
4749
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
50+
var span stdopentracing.Span
51+
span, ctx = stdopentracing.StartSpanFromContext(ctx, "login user")
52+
span.SetTag("service", "user")
53+
defer span.Finish()
4854
req := request.(loginRequest)
4955
u, err := s.Login(req.Username, req.Password)
5056
return userResponse{User: u}, err
@@ -54,6 +60,10 @@ func MakeLoginEndpoint(s Service) endpoint.Endpoint {
5460
// MakeRegisterEndpoint returns an endpoint via the given service.
5561
func MakeRegisterEndpoint(s Service) endpoint.Endpoint {
5662
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
63+
var span stdopentracing.Span
64+
span, ctx = stdopentracing.StartSpanFromContext(ctx, "register user")
65+
span.SetTag("service", "user")
66+
defer span.Finish()
5767
req := request.(registerRequest)
5868
id, err := s.Register(req.Username, req.Password, req.Email, req.FirstName, req.LastName)
5969
return postResponse{ID: id}, err
@@ -63,8 +73,16 @@ func MakeRegisterEndpoint(s Service) endpoint.Endpoint {
6373
// MakeUserGetEndpoint returns an endpoint via the given service.
6474
func MakeUserGetEndpoint(s Service) endpoint.Endpoint {
6575
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
76+
var span stdopentracing.Span
77+
span, ctx = stdopentracing.StartSpanFromContext(ctx, "get users")
78+
span.SetTag("service", "user")
79+
defer span.Finish()
80+
6681
req := request.(GetRequest)
82+
83+
userspan := stdopentracing.StartSpan("users from db", stdopentracing.ChildOf(span.Context()))
6784
usrs, err := s.GetUsers(req.ID)
85+
userspan.Finish()
6886
if req.ID == "" {
6987
return EmbedStruct{usersResponse{Users: usrs}}, err
7088
}
@@ -78,7 +96,9 @@ func MakeUserGetEndpoint(s Service) endpoint.Endpoint {
7896
return users.User{}, err
7997
}
8098
user := usrs[0]
99+
attrspan := stdopentracing.StartSpan("attributes from db", stdopentracing.ChildOf(span.Context()))
81100
db.GetUserAttributes(&user)
101+
attrspan.Finish()
82102
if req.Attr == "addresses" {
83103
return EmbedStruct{addressesResponse{Addresses: user.Addresses}}, err
84104
}
@@ -92,6 +112,10 @@ func MakeUserGetEndpoint(s Service) endpoint.Endpoint {
92112
// MakeUserPostEndpoint returns an endpoint via the given service.
93113
func MakeUserPostEndpoint(s Service) endpoint.Endpoint {
94114
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
115+
var span stdopentracing.Span
116+
span, ctx = stdopentracing.StartSpanFromContext(ctx, "post user")
117+
span.SetTag("service", "user")
118+
defer span.Finish()
95119
req := request.(users.User)
96120
id, err := s.PostUser(req)
97121
return postResponse{ID: id}, err
@@ -101,8 +125,14 @@ func MakeUserPostEndpoint(s Service) endpoint.Endpoint {
101125
// MakeAddressGetEndpoint returns an endpoint via the given service.
102126
func MakeAddressGetEndpoint(s Service) endpoint.Endpoint {
103127
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
128+
var span stdopentracing.Span
129+
span, ctx = stdopentracing.StartSpanFromContext(ctx, "get users")
130+
span.SetTag("service", "user")
131+
defer span.Finish()
104132
req := request.(GetRequest)
133+
addrspan := stdopentracing.StartSpan("addresses from db", stdopentracing.ChildOf(span.Context()))
105134
adds, err := s.GetAddresses(req.ID)
135+
addrspan.Finish()
106136
if req.ID == "" {
107137
return EmbedStruct{addressesResponse{Addresses: adds}}, err
108138
}
@@ -116,6 +146,10 @@ func MakeAddressGetEndpoint(s Service) endpoint.Endpoint {
116146
// MakeAddressPostEndpoint returns an endpoint via the given service.
117147
func MakeAddressPostEndpoint(s Service) endpoint.Endpoint {
118148
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
149+
var span stdopentracing.Span
150+
span, ctx = stdopentracing.StartSpanFromContext(ctx, "post address")
151+
span.SetTag("service", "user")
152+
defer span.Finish()
119153
req := request.(addressPostRequest)
120154
id, err := s.PostAddress(req.Address, req.UserID)
121155
return postResponse{ID: id}, err
@@ -125,8 +159,14 @@ func MakeAddressPostEndpoint(s Service) endpoint.Endpoint {
125159
// MakeUserGetEndpoint returns an endpoint via the given service.
126160
func MakeCardGetEndpoint(s Service) endpoint.Endpoint {
127161
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
162+
var span stdopentracing.Span
163+
span, ctx = stdopentracing.StartSpanFromContext(ctx, "get cards")
164+
span.SetTag("service", "user")
165+
defer span.Finish()
128166
req := request.(GetRequest)
167+
cardspan := stdopentracing.StartSpan("addresses from db", stdopentracing.ChildOf(span.Context()))
129168
cards, err := s.GetCards(req.ID)
169+
cardspan.Finish()
130170
if req.ID == "" {
131171
return EmbedStruct{cardsResponse{Cards: cards}}, err
132172
}
@@ -140,6 +180,10 @@ func MakeCardGetEndpoint(s Service) endpoint.Endpoint {
140180
// MakeCardPostEndpoint returns an endpoint via the given service.
141181
func MakeCardPostEndpoint(s Service) endpoint.Endpoint {
142182
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
183+
var span stdopentracing.Span
184+
span, ctx = stdopentracing.StartSpanFromContext(ctx, "post card")
185+
span.SetTag("service", "user")
186+
defer span.Finish()
143187
req := request.(cardPostRequest)
144188
id, err := s.PostCard(req.Card, req.UserID)
145189
return postResponse{ID: id}, err
@@ -149,6 +193,10 @@ func MakeCardPostEndpoint(s Service) endpoint.Endpoint {
149193
// MakeLoginEndpoint returns an endpoint via the given service.
150194
func MakeDeleteEndpoint(s Service) endpoint.Endpoint {
151195
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
196+
var span stdopentracing.Span
197+
span, ctx = stdopentracing.StartSpanFromContext(ctx, "delete entity")
198+
span.SetTag("service", "user")
199+
defer span.Finish()
152200
req := request.(deleteRequest)
153201
err = s.Delete(req.Entity, req.ID)
154202
if err == nil {
@@ -161,6 +209,10 @@ func MakeDeleteEndpoint(s Service) endpoint.Endpoint {
161209
// MakeHealthEndpoint returns current health of the given service.
162210
func MakeHealthEndpoint(s Service) endpoint.Endpoint {
163211
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
212+
var span stdopentracing.Span
213+
span, ctx = stdopentracing.StartSpanFromContext(ctx, "health check")
214+
span.SetTag("service", "user")
215+
defer span.Finish()
164216
health := s.Health()
165217
return healthResponse{Health: health}, nil
166218
}

api/transport.go

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ import (
1010
"strings"
1111

1212
"github.com/go-kit/kit/log"
13+
"github.com/go-kit/kit/tracing/opentracing"
1314
httptransport "github.com/go-kit/kit/transport/http"
1415
"github.com/gorilla/mux"
1516
"github.com/microservices-demo/user/users"
17+
stdopentracing "github.com/opentracing/opentracing-go"
1618
"github.com/prometheus/client_golang/prometheus/promhttp"
1719
"golang.org/x/net/context"
1820
)
@@ -22,7 +24,7 @@ var (
2224
)
2325

2426
// MakeHTTPHandler mounts the endpoints into a REST-y HTTP handler.
25-
func MakeHTTPHandler(ctx context.Context, e Endpoints, logger log.Logger) http.Handler {
27+
func MakeHTTPHandler(ctx context.Context, e Endpoints, logger log.Logger, tracer stdopentracing.Tracer) http.Handler {
2628
r := mux.NewRouter().StrictSlash(false)
2729
options := []httptransport.ServerOption{
2830
httptransport.ServerErrorLogger(logger),
@@ -38,70 +40,70 @@ func MakeHTTPHandler(ctx context.Context, e Endpoints, logger log.Logger) http.H
3840
e.LoginEndpoint,
3941
decodeLoginRequest,
4042
encodeResponse,
41-
options...,
43+
append(options, httptransport.ServerBefore(opentracing.FromHTTPRequest(tracer, "GET /login", logger)))...,
4244
))
4345
r.Methods("POST").Path("/register").Handler(httptransport.NewServer(
4446
ctx,
4547
e.RegisterEndpoint,
4648
decodeRegisterRequest,
4749
encodeResponse,
48-
options...,
50+
append(options, httptransport.ServerBefore(opentracing.FromHTTPRequest(tracer, "POST /register", logger)))...,
4951
))
5052
r.Methods("GET").PathPrefix("/customers").Handler(httptransport.NewServer(
5153
ctx,
5254
e.UserGetEndpoint,
5355
decodeGetRequest,
5456
encodeResponse,
55-
options...,
57+
append(options, httptransport.ServerBefore(opentracing.FromHTTPRequest(tracer, "GET /customers", logger)))...,
5658
))
5759
r.Methods("GET").PathPrefix("/cards").Handler(httptransport.NewServer(
5860
ctx,
5961
e.CardGetEndpoint,
6062
decodeGetRequest,
6163
encodeResponse,
62-
options...,
64+
append(options, httptransport.ServerBefore(opentracing.FromHTTPRequest(tracer, "GET /cards", logger)))...,
6365
))
6466
r.Methods("GET").PathPrefix("/addresses").Handler(httptransport.NewServer(
6567
ctx,
6668
e.AddressGetEndpoint,
6769
decodeGetRequest,
6870
encodeResponse,
69-
options...,
71+
append(options, httptransport.ServerBefore(opentracing.FromHTTPRequest(tracer, "GET /addresses", logger)))...,
7072
))
7173
r.Methods("POST").Path("/customers").Handler(httptransport.NewServer(
7274
ctx,
7375
e.UserPostEndpoint,
7476
decodeUserRequest,
7577
encodeResponse,
76-
options...,
78+
append(options, httptransport.ServerBefore(opentracing.FromHTTPRequest(tracer, "POST /customers", logger)))...,
7779
))
7880
r.Methods("POST").Path("/addresses").Handler(httptransport.NewServer(
7981
ctx,
8082
e.AddressPostEndpoint,
8183
decodeAddressRequest,
8284
encodeResponse,
83-
options...,
85+
append(options, httptransport.ServerBefore(opentracing.FromHTTPRequest(tracer, "POST /addresses", logger)))...,
8486
))
8587
r.Methods("POST").Path("/cards").Handler(httptransport.NewServer(
8688
ctx,
8789
e.CardPostEndpoint,
8890
decodeCardRequest,
8991
encodeResponse,
90-
options...,
92+
append(options, httptransport.ServerBefore(opentracing.FromHTTPRequest(tracer, "POST /cards", logger)))...,
9193
))
9294
r.Methods("DELETE").PathPrefix("/").Handler(httptransport.NewServer(
9395
ctx,
9496
e.DeleteEndpoint,
9597
decodeDeleteRequest,
9698
encodeResponse,
97-
options...,
99+
append(options, httptransport.ServerBefore(opentracing.FromHTTPRequest(tracer, "DELETE /", logger)))...,
98100
))
99101
r.Methods("GET").PathPrefix("/health").Handler(httptransport.NewServer(
100102
ctx,
101103
e.HealthEndpoint,
102104
decodeHealthRequest,
103105
encodeHealthResponse,
104-
options...,
106+
append(options, httptransport.ServerBefore(opentracing.FromHTTPRequest(tracer, "GET /health", logger)))...,
105107
))
106108
r.Handle("/metrics", promhttp.Handler())
107109
return r

docker-compose-zipkin.yml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
version: '2'
2+
3+
services:
4+
user:
5+
build:
6+
context: .
7+
image: weaveworksdemos/user
8+
hostname: user
9+
restart: always
10+
read_only: true
11+
environment:
12+
- MONGO_HOST=user-db:27017
13+
- ZIPKIN=http://zipkin:9411/api/v1/spans
14+
- reschedule=on-node-failure
15+
ports:
16+
- "8084:8084"
17+
user-db:
18+
build:
19+
context: ./docker/user-db/
20+
image: weaveworksdemos/user-db
21+
hostname: user-db
22+
restart: always
23+
cap_drop:
24+
- all
25+
cap_add:
26+
- CHOWN
27+
- SETGID
28+
- SETUID
29+
read_only: true
30+
tmpfs:
31+
- /tmp:rw,noexec,nosuid
32+
environment:
33+
- reschedule=on-node-failure
34+
ports:
35+
- "27017:27017"
36+
zipkin:
37+
image: openzipkin/zipkin
38+
hostname: zipkin
39+
restart: always
40+
cap_drop:
41+
- all
42+
cap_add:
43+
- CHOWN
44+
- SETGID
45+
- SETUID
46+
read_only: true
47+
tmpfs:
48+
- /tmp:rw,noexec,nosuid
49+
environment:
50+
- reschedule=on-node-failure
51+
ports:
52+
- "9411:9411"
53+
zipkinseed:
54+
image: alpine
55+
command: /bin/sh -c 'sleep 10 ; wget http://user:8084/health ; wget http://user:8084/customers ; wget http://user:8084/customers/57a98d98e4b00679b4a830af ; wget http://user:8084/cards'
56+
57+

0 commit comments

Comments
 (0)