diff --git a/api-spec/payment.json b/api-spec/payment.json index 05447e0..0cb8d23 100644 --- a/api-spec/payment.json +++ b/api-spec/payment.json @@ -64,16 +64,26 @@ "title": "Health", "type": "object", "properties": { - "status": { - "type": "string" - }, - "time": { - "type": "string" + "health": { + "type": "array", + "items": { + "type": "object", + "properties": { + "service": { + "type": "string" + }, + "status": { + "type": "string" + }, + "time": { + "type": "string" + } + } + } } }, "required": [ - "status", - "time" + "health" ] }, "paymentAuth": { diff --git a/endpoints.go b/endpoints.go index 3a23306..72948ff 100644 --- a/endpoints.go +++ b/endpoints.go @@ -1,8 +1,6 @@ package payment import ( - "time" - "github.com/go-kit/kit/endpoint" "golang.org/x/net/context" ) @@ -34,7 +32,8 @@ func MakeAuthoriseEndpoint(s Service) endpoint.Endpoint { // MakeHealthEndpoint returns current health of the given service. func MakeHealthEndpoint(s Service) endpoint.Endpoint { return func(ctx context.Context, request interface{}) (response interface{}, err error) { - return healthResponse{Status: "OK", Time: time.Now().String()}, nil + health := s.Health() + return healthResponse{Health: health}, nil } } @@ -55,6 +54,5 @@ type healthRequest struct { } type healthResponse struct { - Status string `json:"status"` - Time string `json:"time"` + Health []Health `json:"health"` } diff --git a/middlewares.go b/middlewares.go index 5978f9d..1132f5c 100644 --- a/middlewares.go +++ b/middlewares.go @@ -35,6 +35,17 @@ func (mw loggingMiddleware) Authorise(amount float32) (auth Authorisation, err e return mw.next.Authorise(amount) } +func (mw loggingMiddleware) Health() (health []Health) { + defer func(begin time.Time) { + mw.logger.Log( + "method", "Health", + "result", len(health), + "took", time.Since(begin), + ) + }(time.Now()) + return mw.next.Health() +} + type instrumentingService struct { requestCount metrics.Counter requestLatency metrics.Histogram @@ -58,3 +69,12 @@ func (s *instrumentingService) Authorise(amount float32) (auth Authorisation, er return s.Service.Authorise(amount) } + +func (s *instrumentingService) Health() []Health { + defer func(begin time.Time) { + s.requestCount.With("method", "health").Add(1) + s.requestLatency.With("method", "health").Observe(time.Since(begin).Seconds()) + }(time.Now()) + + return s.Service.Health() +} diff --git a/service.go b/service.go index 7cfcd76..d585875 100644 --- a/service.go +++ b/service.go @@ -1,15 +1,25 @@ package payment -import "errors" +import ( + "errors" + "time" +) type Service interface { Authorise(total float32) (Authorisation, error) // GET /paymentAuth + Health() []Health // GET /health } type Authorisation struct { Authorised bool `json:"authorised"` } +type Health struct { + Service string `json:"service"` + Status string `json:"status"` + Time string `json:"time"` +} + // NewFixedService returns a simple implementation of the Service interface, // fixed over a predefined set of socks and tags. In a real service you'd // probably construct this with a database handle to your socks DB, etc. @@ -39,4 +49,11 @@ func (s *service) Authorise(amount float32) (Authorisation, error) { }, nil } +func (s *service) Health() []Health { + var health []Health + app := Health{"payment", "OK", time.Now().String()} + health = append(health, app) + return health +} + var ErrInvalidPaymentAmount = errors.New("Invalid payment amount")