Browse Source

Add client_ip to requests/response logs

DarthSim 3 years ago
parent
commit
d2061623ef
3 changed files with 31 additions and 0 deletions
  1. 3 0
      CHANGELOG.md
  2. 7 0
      router/logging.go
  3. 21 0
      router/router.go

+ 3 - 0
CHANGELOG.md

@@ -1,6 +1,9 @@
 # Changelog
 
 ## [Unreleased]
+### Added
+- Add `client_ip` to requests and responses logs.
+
 ### Change
 - Save GIFs without ImageMagick (vips 8.12+ required).
 

+ 7 - 0
router/logging.go

@@ -1,6 +1,7 @@
 package router
 
 import (
+	"net"
 	"net/http"
 
 	"github.com/imgproxy/imgproxy/v3/ierrors"
@@ -10,9 +11,12 @@ import (
 func LogRequest(reqID string, r *http.Request) {
 	path := r.RequestURI
 
+	clientIP, _, _ := net.SplitHostPort(r.RemoteAddr)
+
 	log.WithFields(log.Fields{
 		"request_id": reqID,
 		"method":     r.Method,
+		"client_ip":  clientIP,
 	}).Infof("Started %s", path)
 }
 
@@ -28,10 +32,13 @@ func LogResponse(reqID string, r *http.Request, status int, err *ierrors.Error,
 		level = log.InfoLevel
 	}
 
+	clientIP, _, _ := net.SplitHostPort(r.RemoteAddr)
+
 	fields := log.Fields{
 		"request_id": reqID,
 		"method":     r.Method,
 		"status":     status,
+		"client_ip":  clientIP,
 	}
 
 	if err != nil {

+ 21 - 0
router/router.go

@@ -1,6 +1,7 @@
 package router
 
 import (
+	"net"
 	"net/http"
 	"regexp"
 	"strings"
@@ -83,6 +84,17 @@ func (r *Router) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
 	rw.Header().Set("Server", "imgproxy")
 	rw.Header().Set(xRequestIDHeader, reqID)
 
+	if ip := req.Header.Get("CF-Connecting-IP"); len(ip) != 0 {
+		replaceRemoteAddr(req, ip)
+	} else if ip := req.Header.Get("X-Forwarded-For"); len(ip) != 0 {
+		if index := strings.Index(ip, ","); index > 0 {
+			ip = ip[:index]
+		}
+		replaceRemoteAddr(req, ip)
+	} else if ip := req.Header.Get("X-Real-IP"); len(ip) != 0 {
+		replaceRemoteAddr(req, ip)
+	}
+
 	defer func() {
 		if rerr := recover(); rerr != nil {
 			if err, ok := rerr.(error); ok && r.PanicHandler != nil {
@@ -106,3 +118,12 @@ func (r *Router) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
 
 	rw.WriteHeader(404)
 }
+
+func replaceRemoteAddr(req *http.Request, ip string) {
+	_, port, err := net.SplitHostPort(req.RemoteAddr)
+	if err != nil {
+		port = "80"
+	}
+
+	req.RemoteAddr = net.JoinHostPort(strings.TrimSpace(ip), port)
+}