@@ -87,6 +87,36 @@ type Server struct {
87
87
// discarded.
88
88
Logf func (string , ... any )
89
89
90
+ // LogRequests, if true, enables detailed (but noisy) debug logging of all
91
+ // requests handled by the reverse proxy. Logs are written to Logf.
92
+ //
93
+ // Each request is presented in the format:
94
+ //
95
+ // B U:"<url>" H:<digest> C:<bool>
96
+ // E H:<digest> <disposition> B:<bytes> (<time> elapsed)
97
+ // - H:<digest> miss
98
+ //
99
+ // The "B" line is when the request began, and "E" when it was finished.
100
+ // The abbreviated fields are:
101
+ //
102
+ // U: -- request URL
103
+ // H: -- request URL digest (cache key)
104
+ // C: -- whether the request is cacheable (true/false)
105
+ // B: -- body size in bytes (for hits)
106
+ //
107
+ // The dispositions of a request are:
108
+ //
109
+ // hit mem -- cache hit in memory (volatile)
110
+ // hit disk -- cache hit in local disk
111
+ // hit S3 -- cache hit in S3 (faulted to disk)
112
+ // fetch -- fetched from the origin server
113
+ //
114
+ // On fetches, the "RC" tag indicates whether the response is cacheable,
115
+ // with "no" meaning it was not cached at all, "mem" meaning it was cached
116
+ // as a short-lived volatile response in memory, and "yes" meaning it was
117
+ // cached on disk (and S3).
118
+ LogRequests bool
119
+
90
120
initOnce sync.Once
91
121
tasks * taskgroup.Group
92
122
start func (taskgroup.Task ) * taskgroup.Group
@@ -157,12 +187,15 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
157
187
158
188
hash := hashRequestURL (r .URL )
159
189
canCache := s .canCacheRequest (r )
190
+ s .vlogf ("B U:%q H:%s C:%v" , r .URL , hash , canCache )
191
+ start := time .Now ()
160
192
if canCache {
161
193
// Check for a hit on this object in the memory cache.
162
194
if data , hdr , err := s .cacheLoadMemory (hash ); err == nil {
163
195
s .reqMemoryHit .Add (1 )
164
196
setXCacheInfo (hdr , "hit, memory" , hash )
165
197
writeCachedResponse (w , hdr , data )
198
+ s .vlogf ("E H:%s hit mem B:%d (%v elapsed)" , hash , len (data ), time .Since (start ))
166
199
return
167
200
}
168
201
@@ -171,6 +204,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
171
204
s .reqLocalHit .Add (1 )
172
205
setXCacheInfo (hdr , "hit, local" , hash )
173
206
writeCachedResponse (w , hdr , data )
207
+ s .vlogf ("E H:%s hit disk B:%d (%v elapsed)" , hash , len (data ), time .Since (start ))
174
208
return
175
209
}
176
210
s .reqLocalMiss .Add (1 )
@@ -183,9 +217,11 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
183
217
}
184
218
setXCacheInfo (hdr , "hit, remote" , hash )
185
219
writeCachedResponse (w , hdr , data )
220
+ s .vlogf ("E H:%s hit S3 B:%d (%v elapsed)" , hash , len (data ), time .Since (start ))
186
221
return
187
222
}
188
223
s .reqFaultMiss .Add (1 )
224
+ s .vlogf ("- H:%s miss" , hash )
189
225
}
190
226
191
227
// Reaching here, the object is not already cached locally so we have to
@@ -202,6 +238,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
202
238
// A response we cannot cache at all.
203
239
setXCacheInfo (rsp .Header , "fetch, uncached" , "" )
204
240
s .rspNotCached .Add (1 )
241
+ s .vlogf ("E H:%s fetch RC:no (%v elapsed)" , hash , time .Since (start ))
205
242
return nil
206
243
}
207
244
@@ -220,6 +257,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
220
257
s .rspSaveMem .Add (1 )
221
258
222
259
// N.B. Don't persist on disk or in S3.
260
+ s .vlogf ("E H:%s fetch RC:mem B:%d (%v elapsed)" , hash , len (body ), time .Since (start ))
223
261
}
224
262
} else {
225
263
setXCacheInfo (rsp .Header , "fetch, cached" , hash )
@@ -235,6 +273,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
235
273
s .rspSaveBytes .Add (int64 (len (body )))
236
274
s .start (s .cacheStoreS3 (hash , rsp .Header , body ))
237
275
}
276
+ s .vlogf ("E H:%s fetch RC:yes B:%d (%v elapsed)" , hash , len (body ), time .Since (start ))
238
277
}
239
278
}
240
279
return nil
@@ -272,6 +311,12 @@ func (s *Server) logf(msg string, args ...any) {
272
311
}
273
312
}
274
313
314
+ func (s * Server ) vlogf (msg string , args ... any ) {
315
+ if s .LogRequests {
316
+ s .logf (msg , args ... )
317
+ }
318
+ }
319
+
275
320
func hostMatchesTarget (host string , targets []string ) bool {
276
321
return slices .Contains (targets , host )
277
322
}
0 commit comments