@@ -88,6 +88,7 @@ type Logger struct {
8888 stdEnabled bool
8989 authEnabled bool
9090 reqEnabled bool
91+ reverseProxy bool
9192 excludePaths map[string]struct{}
9293 stdLogTemplate *template.Template
9394 authTemplate *template.Template
@@ -102,6 +103,7 @@ func New(flag int) *Logger {
102103 stdEnabled: true,
103104 authEnabled: true,
104105 reqEnabled: true,
106+ reverseProxy: false,
105107 excludePaths: nil,
106108 stdLogTemplate: template.Must(template.New("std-log").Parse(DefaultStandardLoggingFormat)),
107109 authTemplate: template.Must(template.New("auth-log").Parse(DefaultAuthLoggingFormat)),
@@ -151,7 +153,7 @@ func (l *Logger) PrintAuth(username string, req *http.Request, status AuthStatus
151153 username = "-"
152154 }
153155
154− client := GetClient(req)
156+ client := GetClient(req, l.reverseProxy)
155157
156158 l.mu.Lock()
157159 defer l.mu.Unlock()
@@ -199,7 +201,7 @@ func (l *Logger) PrintReq(username, upstream string, req *http.Request, url url.
199201 }
200202 }
201203
202− client := GetClient(req)
204+ client := GetClient(req, l.reverseProxy)
203205
204206 l.mu.Lock()
205207 defer l.mu.Unlock()
@@ -251,10 +253,12 @@ func (l *Logger) GetFileLineString(calldepth int) string {
251253}
252254
253255// GetClient parses an HTTP request for the client/remote IP address.
254−func GetClient(req *http.Request) string {
255− client := req.Header.Get("X-Real-IP")
256− if client == "" {
257− client = req.RemoteAddr
256+func GetClient(req *http.Request, reverseProxy bool) string {
257+ client := req.RemoteAddr
258+ if reverseProxy {
259+ if ip := req.Header.Get("X-Real-IP"); ip != "" {
260+ client = ip
261+ }
258262 }
259263
260264 if c, _, err := net.SplitHostPort(client); err == nil {
@@ -308,6 +312,13 @@ func (l *Logger) SetReqEnabled(e bool) {
308312 l.reqEnabled = e
309313}
310314
315+// SetReverseProxy controls whether logging will trust headers that can be set by a reverse proxy.
316+func (l *Logger) SetReverseProxy(e bool) {
317+ l.mu.Lock()
318+ defer l.mu.Unlock()
319+ l.reverseProxy = e
320+}
321+
311322// SetExcludePaths sets the paths to exclude from logging.
312323func (l *Logger) SetExcludePaths(s []string) {
313324 l.mu.Lock()
@@ -381,6 +392,12 @@ func SetReqEnabled(e bool) {
381392 std.SetReqEnabled(e)
382393}
383394
395+// SetReverseProxy controls whether logging will trust headers that can be set
396+// by a reverse proxy for the standard logger.
397+func SetReverseProxy(e bool) {
398+ std.SetReverseProxy(e)
399+}
400+
384401// SetExcludePaths sets the path to exclude from logging, eg: health checks
385402func SetExcludePaths(s []string) {
386403 std.SetExcludePaths(s)