// commonLogHandler will log to w using the Apache common log format // http://httpd.apache.org/docs/2.2/logs.html#common // If w is nil, nothing will be logged func commonLoggerMiddleware(w io.Writer) Middleware { return func(ep *Endpoint, h Handler) Handler { // If no writer is passed to middleware just return the handler if w == nil { return h } return func(req *Request) (proto.Message, errors.Error) { var userId string if req.Auth() != nil && req.Auth().AuthUser() != nil { userId = req.Auth().AuthUser().Id } var err errors.Error var m proto.Message // In defer in case the handler panics defer func() { status := uint32(200) if err != nil { status = err.HttpCode() } size := 0 if m != nil { log.Debug(m.String()) size = len(m.String()) } fmt.Fprintf(w, "%s - %s [%s] \"%s %s %s\" %d %d\n", req.From(), userId, time.Now().Format("02/Jan/2006:15:04:05 -0700"), "GET", // Treat them all as GET's at the moment req.Endpoint(), "HTTP/1.0", // Has to be HTTP or apachetop ignores it status, size, ) }() // Execute the actual handler m, err = h(req) return m, err } } }
// publishError publishes an event when a handler returns an error func publishError(req *Request, e errors.Error) { if !PublishErrors { return } stacktrace := "" if e.MultiStack() != nil { stacktrace = e.MultiStack().String() } application := "" if req.Auth().IsAuth() && req.Auth().AuthUser() != nil { application = req.Auth().AuthUser().Application() } userId := "" if req.Auth().IsAuth() && req.Auth().AuthUser() != nil { userId = req.Auth().AuthUser().Id } msg := map[string]interface{}{ "created": time.Now(), "service": Name, "version": Version, "azName": az, "hostname": hostname, "instanceId": InstanceID, "error": e.Error(), "type": e.Type(), "code": e.Code(), "description": e.Description(), "httpCode": e.HttpCode(), "context": e.Context(), "userId": userId, "application": application, "traceId": req.TraceID(), "stacktrace": stacktrace, } payload, err := json.Marshal(msg) if err != nil { log.Errorf("[Server] Failed to JSON encode error event: %v", err) } if err = nsq.Publish(errorTopic, payload); err != nil { log.Errorf("[Server] Failed to publish error event: %v", err) } }