Skip to content

Long-lived requests (websockets, SSE) should log request as soon as they start to block #16904

@deansheather

Description

@deansheather

Currently we log long-lived connections after they complete. This means there's no visibility into who is connecting or what endpoint they're hitting until they disconnect from the server cleanly or otherwise.

Every long-lived endpoint using WebSocket or SSE should be updated to trigger the request logging right after they've fully accepted the client and are ready to start streaming data. Usually this means right before the loopy part of the handler.

One customer is seeing a rise in pubsub subscriptions in Prometheus but there's no indication of who or why.

Relates to #16903 (same customer incident)

Implementation

I think we could add a context field with a pointer to a struct that contains a "fields" property for additional fields to log (for #16903), as well as a WriteLog(status int) method that immediately writes the logs.

type RequestLoggerContext struct {
  Fields map[string]any

  log slog.Logger
  written bool
}

func (c *RequestLoggerContext) WriteLog(status int) {
  if c.written {
    return
  }
  // write the log with the extra fields...
}

// in the middleware:
logContext := &RequestLoggerContext{ ... }
defer func() {
  logContext.WriteLog(...)
}()
ctx = ctx.WithValue(logContextKey, logContext)
next.ServeHTTP(r.WithContext(ctx), w)

Metadata

Metadata

Assignees

Labels

must-doIssues that must be completed by the end of the Sprint. Or else. Only humans may set this.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions