From 02afa55442376ecf07477563f42c47af5e65abd7 Mon Sep 17 00:00:00 2001 From: Phil Winder Date: Thu, 22 Sep 2016 23:00:37 +0100 Subject: [PATCH 1/5] Added prometheus monitoring. --- api/middlewares.go | 97 ++++++++++++++++++++++++++++++++++++++++++++++ api/transport.go | 2 + glide.lock | 43 ++++++++++++++++---- glide.yaml | 7 +++- main.go | 20 ++++++++++ 5 files changed, 161 insertions(+), 8 deletions(-) diff --git a/api/middlewares.go b/api/middlewares.go index 3abbec16..aaa57554 100644 --- a/api/middlewares.go +++ b/api/middlewares.go @@ -4,6 +4,7 @@ import ( "time" "github.com/go-kit/kit/log" + "github.com/go-kit/kit/metrics" "github.com/microservices-demo/user/users" ) @@ -146,3 +147,99 @@ func (mw loggingMiddleware) Delete(entity, id string) (err error) { }(time.Now()) return mw.next.Delete(entity, id) } + +type instrumentingService struct { + requestCount metrics.Counter + requestLatency metrics.Histogram + Service +} + +// NewInstrumentingService returns an instance of an instrumenting Service. +func NewInstrumentingService(requestCount metrics.Counter, requestLatency metrics.Histogram, s Service) Service { + return &instrumentingService{ + requestCount: requestCount, + requestLatency: requestLatency, + Service: s, + } +} + +func (s *instrumentingService) Login(username, password string) (users.User, error) { + defer func(begin time.Time) { + s.requestCount.With("method", "login").Add(1) + s.requestLatency.With("method", "login").Observe(time.Since(begin).Seconds()) + }(time.Now()) + + return s.Service.Login(username, password) +} + +func (s *instrumentingService) Register(username, password, email string) (string, error) { + defer func(begin time.Time) { + s.requestCount.With("method", "register").Add(1) + s.requestLatency.With("method", "register").Observe(time.Since(begin).Seconds()) + }(time.Now()) + + return s.Service.Register(username, password, email) +} + +func (s *instrumentingService) PostUser(user users.User) (string, error) { + defer func(begin time.Time) { + s.requestCount.With("method", "postUser").Add(1) + s.requestLatency.With("method", "postUser").Observe(time.Since(begin).Seconds()) + }(time.Now()) + + return s.Service.PostUser(user) +} + +func (s *instrumentingService) GetUsers(id string) (u []users.User, err error) { + defer func(begin time.Time) { + s.requestCount.With("method", "getUsers").Add(1) + s.requestLatency.With("method", "getUsers").Observe(time.Since(begin).Seconds()) + }(time.Now()) + + return s.Service.GetUsers(id) +} + +func (s *instrumentingService) PostAddress(add users.Address, id string) (string, error) { + defer func(begin time.Time) { + s.requestCount.With("method", "postAddress").Add(1) + s.requestLatency.With("method", "postAddress").Observe(time.Since(begin).Seconds()) + }(time.Now()) + + return s.Service.PostAddress(add, id) +} + +func (s *instrumentingService) GetAddresses(id string) ([]users.Address, error) { + defer func(begin time.Time) { + s.requestCount.With("method", "getAddresses").Add(1) + s.requestLatency.With("method", "getAddresses").Observe(time.Since(begin).Seconds()) + }(time.Now()) + + return s.Service.GetAddresses(id) +} + +func (s *instrumentingService) PostCard(card users.Card, id string) (string, error) { + defer func(begin time.Time) { + s.requestCount.With("method", "postCard").Add(1) + s.requestLatency.With("method", "postCard").Observe(time.Since(begin).Seconds()) + }(time.Now()) + + return s.Service.PostCard(card, id) +} + +func (s *instrumentingService) GetCards(id string) ([]users.Card, error) { + defer func(begin time.Time) { + s.requestCount.With("method", "getCards").Add(1) + s.requestLatency.With("method", "getCards").Observe(time.Since(begin).Seconds()) + }(time.Now()) + + return s.Service.GetCards(id) +} + +func (s *instrumentingService) Delete(entity, id string) error { + defer func(begin time.Time) { + s.requestCount.With("method", "delete").Add(1) + s.requestLatency.With("method", "delete").Observe(time.Since(begin).Seconds()) + }(time.Now()) + + return s.Service.Delete(entity, id) +} diff --git a/api/transport.go b/api/transport.go index 03758480..2f522d8e 100644 --- a/api/transport.go +++ b/api/transport.go @@ -13,6 +13,7 @@ import ( httptransport "github.com/go-kit/kit/transport/http" "github.com/gorilla/mux" "github.com/microservices-demo/user/users" + "github.com/prometheus/client_golang/prometheus/promhttp" "golang.org/x/net/context" ) @@ -102,6 +103,7 @@ func MakeHTTPHandler(ctx context.Context, e Endpoints, logger log.Logger) http.H encodeHealthResponse, options..., )) + r.Handle("/metrics", promhttp.Handler()) return r } diff --git a/glide.lock b/glide.lock index bf13561e..481afe04 100644 --- a/glide.lock +++ b/glide.lock @@ -1,22 +1,53 @@ -hash: 207174d144994ec9ad587fb6da88600ef359b20dafd1c6d09a0fff8a390580be -updated: 2016-08-24T09:19:22.154633293+02:00 +hash: c5965c301f7206beca5d0b4a1a9954295a6151e365e3d3323ec081d7a591cd8e +updated: 2016-09-22T22:39:17.110450335+01:00 imports: +- name: github.com/beorn7/perks + version: 4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9 + subpackages: + - quantile - name: github.com/go-kit/kit - version: 633c2a06b2a7ee99b211d3a382bce1e53f50f6e6 + version: 988c05d06d8ee3a9c13782f0e49b2c6e4726388d subpackages: - endpoint - log + - metrics + - metrics/prometheus - transport/http - name: github.com/go-logfmt/logfmt version: d4327190ff838312623b09bfeb50d7c93c8d9c1d - name: github.com/go-stack/stack version: 100eb0c0a9c5b306ca2fb4f165df21d80ada4b82 +- name: github.com/golang/protobuf + version: 1f49d83d9aa00e6ce4fc8258c71cc7786aec968a + subpackages: + - proto - name: github.com/gorilla/context version: 08b5f424b9271eedf6f9f0ce86cb9396ed337a42 - name: github.com/gorilla/mux version: cf79e51a62d8219d52060dfc1b4e810414ba2d15 - name: github.com/kr/logfmt version: b84e30acd515aadc4b783ad4ff83aff3299bdfe0 +- name: github.com/matttproud/golang_protobuf_extensions + version: c12348ce28de40eed0136aa2b644d0ee0650e56c + subpackages: + - pbutil +- name: github.com/prometheus/client_golang + version: 5636dc67ae776adf5590da7349e70fbb9559972d + subpackages: + - prometheus + - prometheus/promhttp +- name: github.com/prometheus/client_model + version: fa8ad6fec33561be4280a8f0514318c79d7f6cb6 + subpackages: + - go +- name: github.com/prometheus/common + version: 9a94032291f2192936512bab367bc45e77990d6a + subpackages: + - expfmt + - model + - internal/bitbucket.org/ww/goautoneg +- name: github.com/prometheus/procfs + version: abf152e5f3e97f2fafac028d2cc06c1feb87ffa5 - name: golang.org/x/net version: 7394c112eae4dba7e96bfcfe738e6373d61772b4 subpackages: @@ -26,9 +57,7 @@ imports: version: 3f83fa5005286a7fe593b055f0d7771a7dce4655 subpackages: - bson - - dbtest - - internal/json - internal/sasl - internal/scram -- name: gopkg.in/tomb.v2 - version: 14b3d72120e8d10ea6e6b7f87f7175734b1faab8 + - internal/json +devImports: [] diff --git a/glide.yaml b/glide.yaml index 096b92a2..1f720c65 100644 --- a/glide.yaml +++ b/glide.yaml @@ -4,12 +4,17 @@ import: subpackages: - endpoint - log + - metrics + - metrics/prometheus - transport/http - package: github.com/gorilla/mux +- package: github.com/prometheus/client_golang + subpackages: + - prometheus + - prometheus/promhttp - package: golang.org/x/net subpackages: - context - package: gopkg.in/mgo.v2 subpackages: - bson -- package: gopkg.in/tomb.v2 diff --git a/main.go b/main.go index 29deddb4..701f82a5 100644 --- a/main.go +++ b/main.go @@ -11,9 +11,11 @@ import ( corelog "log" "github.com/go-kit/kit/log" + kitprometheus "github.com/go-kit/kit/metrics/prometheus" "github.com/microservices-demo/user/api" "github.com/microservices-demo/user/db" "github.com/microservices-demo/user/db/mongodb" + stdprometheus "github.com/prometheus/client_golang/prometheus" "golang.org/x/net/context" ) @@ -53,11 +55,29 @@ func main() { } } + fieldKeys := []string{"method"} // Service domain. var service api.Service { service = api.NewFixedService() service = api.LoggingMiddleware(logger)(service) + service = api.NewInstrumentingService( + kitprometheus.NewCounterFrom( + stdprometheus.CounterOpts{ + Namespace: "microservices_demo", + Subsystem: "user", + Name: "request_count", + Help: "Number of requests received.", + }, + fieldKeys), + kitprometheus.NewSummaryFrom(stdprometheus.SummaryOpts{ + Namespace: "microservices_demo", + Subsystem: "user", + Name: "request_latency_microseconds", + Help: "Total duration of requests in microseconds.", + }, fieldKeys), + service, + ) } // Endpoint domain. From 1d417970f00c50629cc240e3f12f1bbfab14d3b9 Mon Sep 17 00:00:00 2001 From: Jason Smith Date: Fri, 23 Sep 2016 10:31:53 +0200 Subject: [PATCH 2/5] added tomb --- glide.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/glide.yaml b/glide.yaml index 1f720c65..e5fea30e 100644 --- a/glide.yaml +++ b/glide.yaml @@ -18,3 +18,5 @@ import: - package: gopkg.in/mgo.v2 subpackages: - bson +- package: gopkg.in/tomb.v2 + From 3335e309ca4ca730bfb623667b34cecf25834dbb Mon Sep 17 00:00:00 2001 From: Jason Smith Date: Fri, 23 Sep 2016 11:22:13 +0200 Subject: [PATCH 3/5] updated glide.lock --- glide.lock | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/glide.lock b/glide.lock index 481afe04..cbaf36ab 100644 --- a/glide.lock +++ b/glide.lock @@ -1,12 +1,12 @@ -hash: c5965c301f7206beca5d0b4a1a9954295a6151e365e3d3323ec081d7a591cd8e -updated: 2016-09-22T22:39:17.110450335+01:00 +hash: 7cf20a5dbbcdf643b0f1dcef14164a797643ebcfb17ec36ecc6f0fbe9d56cf59 +updated: 2016-09-23T11:21:28.08760085+02:00 imports: - name: github.com/beorn7/perks version: 4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9 subpackages: - quantile - name: github.com/go-kit/kit - version: 988c05d06d8ee3a9c13782f0e49b2c6e4726388d + version: 633c2a06b2a7ee99b211d3a382bce1e53f50f6e6 subpackages: - endpoint - log @@ -44,8 +44,8 @@ imports: version: 9a94032291f2192936512bab367bc45e77990d6a subpackages: - expfmt - - model - internal/bitbucket.org/ww/goautoneg + - model - name: github.com/prometheus/procfs version: abf152e5f3e97f2fafac028d2cc06c1feb87ffa5 - name: golang.org/x/net @@ -57,7 +57,10 @@ imports: version: 3f83fa5005286a7fe593b055f0d7771a7dce4655 subpackages: - bson + - dbtest + - internal/json - internal/sasl - internal/scram - - internal/json -devImports: [] +- name: gopkg.in/tomb.v2 + version: 14b3d72120e8d10ea6e6b7f87f7175734b1faab8 +testImports: [] From 3ae2015ae792c23f5f0eb67b746f0ee1ee990da7 Mon Sep 17 00:00:00 2001 From: Jason Smith Date: Fri, 23 Sep 2016 11:40:07 +0200 Subject: [PATCH 4/5] fixed glide.lock --- glide.lock | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/glide.lock b/glide.lock index cbaf36ab..85e932e8 100644 --- a/glide.lock +++ b/glide.lock @@ -1,12 +1,12 @@ -hash: 7cf20a5dbbcdf643b0f1dcef14164a797643ebcfb17ec36ecc6f0fbe9d56cf59 -updated: 2016-09-23T11:21:28.08760085+02:00 +hash: c5965c301f7206beca5d0b4a1a9954295a6151e365e3d3323ec081d7a591cd8e +updated: 2016-09-22T22:39:17.110450335+01:00 imports: - name: github.com/beorn7/perks version: 4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9 subpackages: - quantile - name: github.com/go-kit/kit - version: 633c2a06b2a7ee99b211d3a382bce1e53f50f6e6 + version: 988c05d06d8ee3a9c13782f0e49b2c6e4726388d subpackages: - endpoint - log @@ -44,8 +44,8 @@ imports: version: 9a94032291f2192936512bab367bc45e77990d6a subpackages: - expfmt - - internal/bitbucket.org/ww/goautoneg - model + - internal/bitbucket.org/ww/goautoneg - name: github.com/prometheus/procfs version: abf152e5f3e97f2fafac028d2cc06c1feb87ffa5 - name: golang.org/x/net @@ -57,10 +57,9 @@ imports: version: 3f83fa5005286a7fe593b055f0d7771a7dce4655 subpackages: - bson - - dbtest - - internal/json - internal/sasl - internal/scram + - internal/json - name: gopkg.in/tomb.v2 version: 14b3d72120e8d10ea6e6b7f87f7175734b1faab8 -testImports: [] +devImports: [] From 5f85dc757cd1fae70219fb4254e032ecab071b0d Mon Sep 17 00:00:00 2001 From: Phil Winder Date: Fri, 23 Sep 2016 13:30:37 +0100 Subject: [PATCH 5/5] Fixed Service API when merging into master. --- api/middlewares.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/middlewares.go b/api/middlewares.go index 20cda665..fb1e8353 100644 --- a/api/middlewares.go +++ b/api/middlewares.go @@ -172,13 +172,13 @@ func (s *instrumentingService) Login(username, password string) (users.User, err return s.Service.Login(username, password) } -func (s *instrumentingService) Register(username, password, email string) (string, error) { +func (s *instrumentingService) Register(username, password, email, first, last string) (string, error) { defer func(begin time.Time) { s.requestCount.With("method", "register").Add(1) s.requestLatency.With("method", "register").Observe(time.Since(begin).Seconds()) }(time.Now()) - return s.Service.Register(username, password, email) + return s.Service.Register(username, password, email, first, last) } func (s *instrumentingService) PostUser(user users.User) (string, error) {