Last active
August 14, 2019 12:25
-
-
Save turgayozgur/057eee4fca80b61373f6b8abf84c6622 to your computer and use it in GitHub Desktop.
Golang custom logger that provides the request headers to log result.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"context" | |
"fmt" | |
"log" | |
"net/http" | |
"os" | |
"runtime" | |
"time" | |
) | |
func main() { | |
http.Handle("/", errorHandler(index)) | |
http.ListenAndServe(":8000", nil) | |
} | |
func index(w http.ResponseWriter, r *http.Request) { | |
panic("Something went wrong :/") | |
} | |
// Error Handler | |
type errorHandler func(http.ResponseWriter, *http.Request) | |
func (fn errorHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { | |
ctx := addHeadersForLogging(r) // Required to read headers from request context. | |
defer func() { | |
if rec := recover(); rec != nil { | |
logError(ctx, "Panic: %+v", rec) | |
w.WriteHeader(http.StatusInternalServerError) | |
} | |
}() | |
fn(w, r.WithContext(ctx)) | |
} | |
// Error log | |
func logError(ctx context.Context, format string, v ...interface{}) { | |
// message | |
message := fmt.Sprintf(format, v...) | |
// headers | |
h := ctx.Value("logkey").(*Headers) | |
// stack trace | |
buf := make([]byte, 1024) | |
stackTrace := runtime.Stack(buf, true) | |
// log (use sync.Once for getting instance of new logger). | |
log.New(os.Stdout, "", 0).Printf("error: %s %s \"%s\"\n%s", time.Now().UTC().Format(time.RFC3339Nano), h.RequestID, message, buf[0:stackTrace]) | |
} | |
// Headers contains header values to logging. | |
type Headers struct { | |
RequestID string | |
} | |
// AddHeaders will add any common HTTP headers | |
func addHeadersForLogging(r *http.Request) context.Context { | |
headers := &Headers{ | |
RequestID: r.Header.Get("x-request-id"), | |
} | |
return context.WithValue(r.Context(), "logkey", headers) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment