diff --git a/api/middlewares.go b/api/middlewares.go index aedc27f3..fb1e8353 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, 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, first, last) +} + +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..85e932e8 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,9 @@ imports: version: 3f83fa5005286a7fe593b055f0d7771a7dce4655 subpackages: - bson - - dbtest - - internal/json - internal/sasl - internal/scram + - internal/json - name: gopkg.in/tomb.v2 version: 14b3d72120e8d10ea6e6b7f87f7175734b1faab8 +devImports: [] diff --git a/glide.yaml b/glide.yaml index 096b92a2..e5fea30e 100644 --- a/glide.yaml +++ b/glide.yaml @@ -4,8 +4,14 @@ 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 @@ -13,3 +19,4 @@ import: 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.