Skip to content

Commit a42dec7

Browse files
committed
Add a new method that returns the fields
This is helpful for those who wish to use their own output or logging.
1 parent 3b27027 commit a42dec7

File tree

2 files changed

+79
-0
lines changed

2 files changed

+79
-0
lines changed

logrequest.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,16 @@ type statusWriter struct {
2323
statusCode int
2424
}
2525

26+
type RequestFields struct {
27+
Method string
28+
Url string
29+
RemoteAddress string
30+
Protocol string
31+
Time time.Time
32+
Duration time.Duration
33+
StatusCode int
34+
}
35+
2636
// ToLogger will print the Started and Completed request info to the passed logger
2737
func (lr LogRequest) ToLogger(logger *log.Logger) {
2838
if lr.Timestamp {
@@ -67,6 +77,23 @@ func (lr LogRequest) ToString() map[string]string {
6777
return ts
6878
}
6979

80+
// ToFields returns a RequestFields struct which contains each field that is
81+
// used in the request.
82+
func (lr LogRequest) ToFields() RequestFields {
83+
sw, completedDuration := lr.parseRequest()
84+
85+
rf := RequestFields{}
86+
rf.Method = lr.Request.Method
87+
rf.Url = lr.Request.URL.RequestURI()
88+
rf.RemoteAddress = lr.Request.RemoteAddr
89+
rf.Protocol = lr.Request.Proto
90+
rf.Time = time.Now()
91+
rf.Duration = completedDuration
92+
rf.StatusCode = sw.statusCode
93+
94+
return rf
95+
}
96+
7097
// parseRequest will time the request and retrieve the status from the
7198
// ResponseWriter. Returns the statusWriter struct and the duration
7299
// of the request.

logrequest_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,10 +172,55 @@ func TestToStringWithOptionals(t *testing.T) {
172172
}
173173
}
174174

175+
func TestToFields(t *testing.T) {
176+
tables := []struct {
177+
statusCode int
178+
method string
179+
path string
180+
expectedFields RequestFields
181+
}{
182+
{http.StatusOK, http.MethodGet, "/foo", RequestFields{Method: http.MethodGet, Url: "/foo", StatusCode: http.StatusOK}},
183+
{http.StatusUnauthorized, http.MethodPost, "/bar/create", RequestFields{Method: http.MethodPost, Url: "/bar/create", StatusCode: http.StatusUnauthorized}},
184+
{http.StatusNotFound, http.MethodGet, "/hello/world", RequestFields{Method: http.MethodGet, Url: "/hello/world", StatusCode: http.StatusNotFound}},
185+
{http.StatusInternalServerError, http.MethodGet, "/", RequestFields{Method: http.MethodGet, Url: "/", StatusCode: http.StatusInternalServerError}},
186+
{http.StatusServiceUnavailable, http.MethodPut, "/foo/update", RequestFields{Method: http.MethodPut, Url: "/foo/update", StatusCode: http.StatusServiceUnavailable}},
187+
}
188+
189+
for _, table := range tables {
190+
app := &application{}
191+
192+
req, err := http.NewRequest(table.method, table.path, nil)
193+
if err != nil {
194+
t.Fatal(err)
195+
}
196+
197+
testHandler := http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
198+
rw.WriteHeader(table.statusCode)
199+
})
200+
201+
rr := httptest.NewRecorder()
202+
handler := app.logRequestToFields(testHandler)
203+
handler.ServeHTTP(rr, req)
204+
205+
if app.RequestFields.StatusCode != table.expectedFields.StatusCode {
206+
t.Errorf("Expected field was incorrect, %d should be %d", app.RequestFields.StatusCode, table.expectedFields.StatusCode)
207+
}
208+
209+
if app.RequestFields.Method != table.expectedFields.Method {
210+
t.Errorf("Expected field was incorrect, %s should be %s", app.RequestFields.Method, table.expectedFields.Method)
211+
}
212+
213+
if app.RequestFields.Url != table.expectedFields.Url {
214+
t.Errorf("Expected field was incorrect, %s should be %s", app.RequestFields.Url, table.expectedFields.Url)
215+
}
216+
}
217+
}
218+
175219
// Helpers
176220

177221
type application struct {
178222
infoLog *log.Logger
223+
RequestFields
179224
}
180225

181226
func (app *application) logRequestToLogger(next http.Handler) http.Handler {
@@ -207,3 +252,10 @@ func (app *application) logRequestToStringWithOptionals(next http.Handler) http.
207252
app.infoLog.Println(lr.ToString()["completed"])
208253
})
209254
}
255+
256+
func (app *application) logRequestToFields(next http.Handler) http.Handler {
257+
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
258+
lr := LogRequest{Request: r, Writer: w, Handler: next}
259+
app.RequestFields = lr.ToFields()
260+
})
261+
}

0 commit comments

Comments
 (0)