Logging Every Request of a Go-Kit Service

// LoggingMiddleware returns an endpoint middleware that logs the
// duration of each invocation, and the resulting error, if any.
func LoggingMiddleware(logger log.Logger) endpoint.Middleware {
return func(next endpoint.Endpoint) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
defer func(begin time.Time) {
logger.Log("transport_error", err, "took", time.Since(begin))
}(time.Now())
return next(ctx, request)
}
}
}
sumEndpoint = LoggingMiddleware(log.With(logger, "method", "Sum"))(sumEndpoint)

Problem

The problem with this logging middleware is that there is no request specific information (like the parameters contained within the request and response objects) being logged. This is due to the fact that the endpoint.Endpoint type contains both the request and response objects as type interface{}. Meaning it is impossible to access field values within the request/response without using a type assertion. This gets real messy as you start to add more request/response types (maybe 1 per each of 20 endpoints).

Solution

To solve this problem I have created a simple package called eplogger.

type AppendKeyvalser interface {
AppendKeyvals(keyvals []interface{}) []interface{}
}

Example

Here is an example of a request type with the AppendKeyvalser interface implemented:

SumRequest struct { 
A, B int
}
func (s SumRequest) AppendKeyvals(keyvals []interface{}) []interface{} {
return append(keyvals, "SumRequest.A", s.A, "SumRequest.B", s.B)
}
level=info method=Sum transport_error=null took=4.071µs SumRequest.A=2 SumRequest.B=3
type SumResponse struct {
V int `json:"v"`
Err error `json:"-"`
}
func (s SumResponse) AppendKeyvals(keyvals []interface{}) []interface{} {
return append(keyvals,
"SumResponse.R", s.V, "SumResponse.Err", s.Err)
}
level=info method=Sum transport_error=null took=4.071µs SumRequest.A=2 SumRequest.B=3 SumResponse.R=5 SumResponse.Err=null

Source

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store