Skip to content

Commit 2c3cf53

Browse files
authored
Log response size and duration (#565)
1 parent 8da9fcc commit 2c3cf53

2 files changed

Lines changed: 23 additions & 9 deletions

File tree

server/meters/meters.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,16 @@ import (
1010

1111
// MeterEvent represents a metered event with a name, value, timestamp, dimensions, and request ID.
1212
type MeterEvent struct {
13-
EventID string
14-
Name string
15-
Value float64
16-
Timestamp time.Time
17-
Dimensions Dimensions
18-
RequestID string // Request ID associated with the event, useful for tracing
19-
StatusCode int // HTTP status code of the request that generated this event
20-
Success bool // Indicates if the event was successful (e.g., HTTP status < 400)
13+
EventID string
14+
Name string
15+
Value float64
16+
Timestamp time.Time
17+
Dimensions Dimensions
18+
RequestID string // Request ID associated with the event, useful for tracing
19+
StatusCode int // HTTP status code of the request that generated this event
20+
Success bool // Indicates if the event was successful (e.g., HTTP status < 400)
21+
Duration time.Duration // Duration of the request
22+
ResponseSize int64 // Size of the response body in bytes
2123
}
2224

2325
// NewMeterEvent creates a new MeterEvent with the current time in UTC.

server/meters/mw.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package meters
22

33
import (
44
"net/http"
5+
"time"
56

67
"github.com/interline-io/log"
78
"github.com/interline-io/transitland-lib/server/auth/authn"
@@ -46,13 +47,17 @@ func WithMeter(apiMeter MeterProvider, meterName string, meterValue float64, dim
4647
return
4748
}
4849
// Call next handler
50+
start := time.Now()
4951
next.ServeHTTP(wr, r)
52+
duration := time.Since(start)
5053

5154
// Create a new MeterEvent with the current time in UTC
5255
event := NewMeterEvent(meterName, meterValue, dims)
5356
event.RequestID = log.GetReqID(r.Context())
5457
event.StatusCode = wr.statusCode
5558
event.Success = wr.statusCode < 400
59+
event.Duration = duration
60+
event.ResponseSize = wr.responseSize
5661
// Fetch meterer again from context
5762
if err := ForContext(ctx).Meter(ctx, event); err != nil {
5863
meterLog.Error().Err(err).Msg("failed to meter event")
@@ -62,11 +67,18 @@ func WithMeter(apiMeter MeterProvider, meterName string, meterValue float64, dim
6267
}
6368

6469
type responseWriterWrapper struct {
65-
statusCode int
70+
statusCode int
71+
responseSize int64
6672
http.ResponseWriter
6773
}
6874

6975
func (w *responseWriterWrapper) WriteHeader(statusCode int) {
7076
w.statusCode = statusCode
7177
w.ResponseWriter.WriteHeader(statusCode)
7278
}
79+
80+
func (w *responseWriterWrapper) Write(b []byte) (int, error) {
81+
n, err := w.ResponseWriter.Write(b)
82+
w.responseSize += int64(n)
83+
return n, err
84+
}

0 commit comments

Comments
 (0)