func logError(ctx context.Context, err error, event string) { var lines []string lines = append(lines, fmt.Sprintf("event=%s %s", event, err)) for skip := 1; ; skip++ { pc, file, linenum, ok := runtime.Caller(skip) if !ok { break } if file[len(file)-1] == 'c' || file == thisFile { continue } f := runtime.FuncForPC(pc) line := fmt.Sprintf("%s:%d %s()", file, linenum, f.Name()) lines = append(lines, line) } if len(lines) > 1 { logMutex.Lock() defer logMutex.Unlock() } for _, line := range lines { reqlog.Print(ctx, line) } }
// Data returns a JSON response with the provided data and HTTP status // code. func Data(ctx context.Context, w http.ResponseWriter, status int, data interface{}) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(status) if err := json.NewEncoder(w).Encode(data); isBrokenPipe(err) { reqlog.Print(ctx, "unable to respond to client. event=respond_broken_pipe") metrics.Increment("respond_broken_pipe") } else if err != nil { panic(err) } }