@@ -190,28 +190,87 @@ func (_this *proxyController) processRequest(
190
190
func (_this * proxyController ) sendRequest (reqCtx requestContext ) {
191
191
req := reqCtx .request
192
192
reqType := reqCtx .reqType
193
+ startTime := time .Now ()
193
194
194
195
// Set metric name based on request type
195
- metricName := metric .MetricProxyRequest
196
+ metricName := metric .MetricProxy
196
197
connsCounter := _this .proxyActiveConns
197
-
198
198
if reqType == mirrorRequest {
199
- metricName = metric .MetricMirrorRequest
199
+ metricName = metric .MetricMirror
200
200
connsCounter = _this .mirrorActiveConns
201
201
}
202
202
203
+ // Track connections
203
204
atomic .AddInt64 (connsCounter , 1 )
204
205
_this .recordActiveConnections (reqType )
205
-
206
- // Make the request
207
- resp , err := _this .client .Do (req )
208
-
209
- // Ensure we always decrement the counter when the function exits
210
206
defer func () {
211
207
atomic .AddInt64 (connsCounter , - 1 )
212
208
_this .recordActiveConnections (reqType )
213
209
}()
214
210
211
+ // Always record metrics and log response
212
+ var resp * http.Response
213
+ var err error
214
+ var respBody []byte
215
+ defer func () {
216
+ statusCode := http .StatusBadGateway // Default error status
217
+ statusClass := "5xx"
218
+ latency := time .Since (startTime )
219
+
220
+ if err == nil {
221
+ statusCode = resp .StatusCode
222
+ statusClass = fmt .Sprintf ("%dxx" , resp .StatusCode / 100 )
223
+ }
224
+
225
+ // Record all metrics
226
+ _ = _this .metrics .RecordRequest (
227
+ _this .ctx ,
228
+ metricName ,
229
+ req .Method ,
230
+ req .URL .Path ,
231
+ attribute .String ("method" , req .Method ),
232
+ )
233
+ _ = _this .metrics .RecordRequest (
234
+ _this .ctx ,
235
+ metricName ,
236
+ req .Method ,
237
+ req .URL .Path ,
238
+ attribute .String ("status_class" , statusClass ),
239
+ attribute .Int ("status_code" , statusCode ),
240
+ attribute .String ("method" , req .Method ),
241
+ )
242
+ _ = _this .metrics .RecordDuration (
243
+ _this .ctx ,
244
+ metricName ,
245
+ latency ,
246
+ attribute .String ("method" , req .Method ),
247
+ attribute .String ("path" , req .URL .Path ),
248
+ attribute .Int ("status_code" , statusCode ),
249
+ )
250
+
251
+ // Log response or error
252
+ if err != nil {
253
+ _this .logger .Errorw (fmt .Sprintf ("%s error" , reqType ),
254
+ "error" , err ,
255
+ "method" , req .Method ,
256
+ "url" , req .URL .String (),
257
+ "headers" , req .Header ,
258
+ "trace_id" , reqCtx .traceID ,
259
+ "latency" , latency ,
260
+ )
261
+ } else {
262
+ _this .logger .Debugw (fmt .Sprintf ("%s response" , reqType ),
263
+ "method" , req .Method ,
264
+ "url" , req .URL .String (),
265
+ "status" , statusCode ,
266
+ "content_length" , resp .ContentLength ,
267
+ "headers" , resp .Header ,
268
+ "trace_id" , reqCtx .traceID ,
269
+ "latency" , latency ,
270
+ )
271
+ }
272
+ }()
273
+
215
274
// Log outbound request
216
275
_this .logger .Debugw (fmt .Sprintf ("%s request" , reqType ),
217
276
"method" , req .Method ,
@@ -220,83 +279,43 @@ func (_this *proxyController) sendRequest(reqCtx requestContext) {
220
279
"trace_id" , reqCtx .traceID ,
221
280
)
222
281
282
+ // Make the request
283
+ resp , err = _this .client .Do (req )
223
284
if err != nil {
224
- _this .logger .Errorw (fmt .Sprintf ("%s error" , reqType ),
225
- "error" , err ,
226
- "method" , req .Method ,
227
- "url" , req .URL .String (),
228
- "headers" , req .Header ,
229
- "trace_id" , reqCtx .traceID ,
230
- "latency" , time .Since (reqCtx .startTime ),
231
- )
232
285
if reqType == proxyRequest {
233
286
reqCtx .ginContext .JSON (http .StatusBadGateway , gin.H {"error" : "proxy error" })
234
287
}
235
288
return
236
289
}
237
- // Ignore error since we are closing the body anyway
238
- defer func () { _ = resp .Body .Close () }()
290
+ defer resp .Body .Close ()
239
291
240
- // Log response
241
- _this .logger .Debugw (fmt .Sprintf ("%s response" , reqType ),
242
- "method" , req .Method ,
243
- "url" , req .URL .String (),
244
- "status" , resp .StatusCode ,
245
- "content length" , resp .ContentLength ,
246
- "headers" , resp .Header ,
247
- "trace_id" , reqCtx .traceID ,
248
- "latency" , time .Since (reqCtx .startTime ),
249
- )
250
-
251
- // Record status metrics with the appropriate prefix
252
- statusClass := fmt .Sprintf ("%dxx" , resp .StatusCode / 100 )
253
- _ = _this .metrics .RecordRequest (
254
- _this .ctx ,
255
- fmt .Sprintf ("%s_status" , metricName ),
256
- statusClass ,
257
- req .URL .Path ,
258
- attribute .String ("status_class" , statusClass ),
259
- attribute .Int ("status_code" , resp .StatusCode ),
260
- attribute .String ("method" , req .Method ),
261
- )
292
+ // For mirror requests, we're done here
293
+ if reqType == mirrorRequest {
294
+ return
295
+ }
262
296
263
- respBody , err : = io .ReadAll (resp .Body )
297
+ respBody , err = io .ReadAll (resp .Body )
264
298
if err != nil {
265
- _this .logger .Errorw (fmt .Sprintf ("failed to read %s response" , reqType ),
266
- "error" , err ,
267
- "trace_id" , reqCtx .traceID ,
268
- )
269
- if reqType == proxyRequest {
270
- reqCtx .ginContext .JSON (http .StatusInternalServerError , gin.H {"error" : "failed to read response" })
271
- }
299
+ reqCtx .ginContext .JSON (http .StatusInternalServerError , gin.H {"error" : "failed to read response" })
272
300
return
273
301
}
274
302
275
- if reqType == proxyRequest {
276
- for k , vv := range resp .Header {
277
- for _ , v := range vv {
278
- reqCtx .ginContext .Header (k , v )
279
- }
303
+ for k , vv := range resp .Header {
304
+ for _ , v := range vv {
305
+ reqCtx .ginContext .Header (k , v )
280
306
}
281
- reqCtx .ginContext .Header ("X-Proxied-By" , config .ServiceName )
282
- reqCtx .ginContext .Header ("X-Trace-ID" , reqCtx .traceID )
283
- reqCtx .ginContext .Data (resp .StatusCode , resp .Header .Get ("Content-Type" ), respBody )
284
307
}
285
-
286
- // Record duration with the same metric name prefix
287
- _ = _this .metrics .RecordDuration (_this .ctx , metricName , time .Since (reqCtx .startTime ),
288
- attribute .String ("method" , req .Method ),
289
- attribute .String ("path" , req .URL .Path ),
290
- attribute .Int ("status_code" , resp .StatusCode ),
291
- )
308
+ reqCtx .ginContext .Header ("X-Proxied-By" , config .ServiceName )
309
+ reqCtx .ginContext .Header ("X-Trace-ID" , reqCtx .traceID )
310
+ reqCtx .ginContext .Data (resp .StatusCode , resp .Header .Get ("Content-Type" ), respBody )
292
311
}
293
312
294
313
func (_this * proxyController ) recordActiveConnections (reqType requestType ) {
295
- metricName := metric .MetricProxyActiveConnections
314
+ metricName := metric .MetricProxyConnections
296
315
connsCounter := _this .proxyActiveConns
297
316
298
317
if reqType == mirrorRequest {
299
- metricName = metric .MetricMirrorActiveConnections
318
+ metricName = metric .MetricMirrorConnections
300
319
connsCounter = _this .mirrorActiveConns
301
320
}
302
321
0 commit comments