Skip to content

Commit 1e7e67c

Browse files
authored
Added request logger middleware which helps to use custom logger library for logging requests (#1980)
Added request logger middleware which helps to use custom logger library for logging requests.
1 parent 7f502b1 commit 1e7e67c

File tree

6 files changed

+823
-13
lines changed

6 files changed

+823
-13
lines changed

echo.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,11 @@ func (e *Echo) Routers() map[string]*Router {
357357

358358
// DefaultHTTPErrorHandler is the default HTTP error handler. It sends a JSON response
359359
// with status code.
360+
//
361+
// NOTE: In case errors happens in middleware call-chain that is returning from handler (which did not return an error).
362+
// When handler has already sent response (ala c.JSON()) and there is error in middleware that is returning from
363+
// handler. Then the error that global error handler received will be ignored because we have already "commited" the
364+
// response and status code header has been sent to the client.
360365
func (e *Echo) DefaultHTTPErrorHandler(err error, c Context) {
361366

362367
if c.Response().Committed {

go.mod

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@ require (
66
github.com/golang-jwt/jwt v3.2.2+incompatible
77
github.com/labstack/gommon v0.3.0
88
github.com/mattn/go-colorable v0.1.8 // indirect
9+
github.com/mattn/go-isatty v0.0.14 // indirect
910
github.com/stretchr/testify v1.4.0
1011
github.com/valyala/fasttemplate v1.2.1
11-
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
12-
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4
13-
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 // indirect
14-
golang.org/x/text v0.3.6 // indirect
12+
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
13+
golang.org/x/net v0.0.0-20210907225631-ff17edfbf26d
14+
golang.org/x/sys v0.0.0-20210908160347-a851e7ddeee0 // indirect
15+
golang.org/x/text v0.3.7 // indirect
1516
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324
1617
)

go.sum

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ
99
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
1010
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
1111
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
12-
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
1312
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
13+
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
14+
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
1415
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
1516
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
1617
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -21,23 +22,26 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC
2122
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
2223
github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
2324
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
24-
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
25-
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
25+
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ=
26+
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
2627
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
27-
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0=
28-
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
28+
golang.org/x/net v0.0.0-20210907225631-ff17edfbf26d h1:kuk8nKPQ25KCDODLCDXt99tnTVeOyOM8HGvtJ0NzAvw=
29+
golang.org/x/net v0.0.0-20210907225631-ff17edfbf26d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
2930
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
3031
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
3132
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
3233
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
3334
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
34-
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
35-
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 h1:F5Gozwx4I1xtr/sr/8CFbb57iKi3297KFs0QDbGN60A=
36-
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
35+
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
36+
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
37+
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
38+
golang.org/x/sys v0.0.0-20210908160347-a851e7ddeee0 h1:6xxeVXiyYpF8WCTnKKCbjnEdsrwjZYY8TOuk7xP0chg=
39+
golang.org/x/sys v0.0.0-20210908160347-a851e7ddeee0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
3740
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
3841
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
39-
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
4042
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
43+
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
44+
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
4145
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 h1:Hir2P/De0WpUhtrKGGjvSb2YxUgyZ7EFOSLIcSSpiwE=
4246
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
4347
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

middleware/logger_test.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,3 +171,76 @@ func TestLoggerCustomTimestamp(t *testing.T) {
171171
_, err := time.Parse(customTimeFormat, loggedTime)
172172
assert.Error(t, err)
173173
}
174+
175+
func BenchmarkLoggerWithConfig_withoutMapFields(b *testing.B) {
176+
e := echo.New()
177+
178+
buf := new(bytes.Buffer)
179+
mw := LoggerWithConfig(LoggerConfig{
180+
Format: `{"time":"${time_rfc3339_nano}","id":"${id}","remote_ip":"${remote_ip}","host":"${host}","user_agent":"${user_agent}",` +
181+
`"method":"${method}","uri":"${uri}","status":${status}, "latency":${latency},` +
182+
`"latency_human":"${latency_human}","bytes_in":${bytes_in}, "path":"${path}", "referer":"${referer}",` +
183+
`"bytes_out":${bytes_out}, "protocol":"${protocol}"}` + "\n",
184+
Output: buf,
185+
})(func(c echo.Context) error {
186+
c.Request().Header.Set(echo.HeaderXRequestID, "123")
187+
c.FormValue("to force parse form")
188+
return c.String(http.StatusTeapot, "OK")
189+
})
190+
191+
f := make(url.Values)
192+
f.Set("csrf", "token")
193+
f.Add("multiple", "1")
194+
f.Add("multiple", "2")
195+
req := httptest.NewRequest(http.MethodPost, "/test?lang=en&checked=1&checked=2", strings.NewReader(f.Encode()))
196+
req.Header.Set("Referer", "https://echo.labstack.com/")
197+
req.Header.Set("User-Agent", "curl/7.68.0")
198+
req.Header.Add(echo.HeaderContentType, echo.MIMEApplicationForm)
199+
200+
b.ReportAllocs()
201+
b.ResetTimer()
202+
203+
for i := 0; i < b.N; i++ {
204+
rec := httptest.NewRecorder()
205+
c := e.NewContext(req, rec)
206+
mw(c)
207+
buf.Reset()
208+
}
209+
}
210+
211+
func BenchmarkLoggerWithConfig_withMapFields(b *testing.B) {
212+
e := echo.New()
213+
214+
buf := new(bytes.Buffer)
215+
mw := LoggerWithConfig(LoggerConfig{
216+
Format: `{"time":"${time_rfc3339_nano}","id":"${id}","remote_ip":"${remote_ip}","host":"${host}","user_agent":"${user_agent}",` +
217+
`"method":"${method}","uri":"${uri}","status":${status}, "latency":${latency},` +
218+
`"latency_human":"${latency_human}","bytes_in":${bytes_in}, "path":"${path}", "referer":"${referer}",` +
219+
`"bytes_out":${bytes_out},"ch":"${header:X-Custom-Header}", "protocol":"${protocol}"` +
220+
`"us":"${query:username}", "cf":"${form:csrf}", "Referer2":"${header:Referer}"}` + "\n",
221+
Output: buf,
222+
})(func(c echo.Context) error {
223+
c.Request().Header.Set(echo.HeaderXRequestID, "123")
224+
c.FormValue("to force parse form")
225+
return c.String(http.StatusTeapot, "OK")
226+
})
227+
228+
f := make(url.Values)
229+
f.Set("csrf", "token")
230+
f.Add("multiple", "1")
231+
f.Add("multiple", "2")
232+
req := httptest.NewRequest(http.MethodPost, "/test?lang=en&checked=1&checked=2", strings.NewReader(f.Encode()))
233+
req.Header.Set("Referer", "https://echo.labstack.com/")
234+
req.Header.Set("User-Agent", "curl/7.68.0")
235+
req.Header.Add(echo.HeaderContentType, echo.MIMEApplicationForm)
236+
237+
b.ReportAllocs()
238+
b.ResetTimer()
239+
240+
for i := 0; i < b.N; i++ {
241+
rec := httptest.NewRecorder()
242+
c := e.NewContext(req, rec)
243+
mw(c)
244+
buf.Reset()
245+
}
246+
}

0 commit comments

Comments
 (0)