[MM-64244] Add websocket disconnect reason metric (#31032)

We've recently spent some effort improving websocket reconnection logic. With this commit, I've augmented the websocket reconnect metric to include a disconnect reason. This will help us measure the impact of these changes in production.
Этот коммит содержится в:
David Krauser
2025-05-30 08:15:20 -04:00
коммит произвёл GitHub
родитель 611b2a8e79
Коммит 761584c040
9 изменённых файлов: 215 добавлений и 41 удалений

Просмотреть файл

@@ -5,6 +5,7 @@ package api4
import (
"net/http"
"strconv"
"github.com/gorilla/websocket"
@@ -15,11 +16,39 @@ import (
)
const (
connectionIDParam = "connection_id"
sequenceNumberParam = "sequence_number"
postedAckParam = "posted_ack"
connectionIDParam = "connection_id"
sequenceNumberParam = "sequence_number"
postedAckParam = "posted_ack"
disconnectErrCodeParam = "disconnect_err_code"
clientPingTimeoutErrCode = 4000
clientSequenceMismatchErrCode = 4001
)
// validateDisconnectErrCode ensures the specified disconnect error code
// is a valid websocket close code
func validateDisconnectErrCode(errCode string) bool {
if errCode == "" {
return false
}
// Ensure the disconnect code is a standard close code
code, err := strconv.Atoi(errCode)
if err != nil {
return false
}
// We only support the standard close codes between
// 1000 and 1016, and a few custom application codes
if (code < 1000 || code > 1016) &&
code != clientPingTimeoutErrCode &&
code != clientSequenceMismatchErrCode {
return false
}
return true
}
func (api *API) InitWebSocket() {
// Optionally supports a trailing slash
api.BaseRoutes.APIRoot.Handle("/{websocket:websocket(?:\\/)?}", api.APIHandlerTrustRequester(connectWebSocket)).Methods(http.MethodGet)
@@ -53,6 +82,12 @@ func connectWebSocket(c *Context, w http.ResponseWriter, r *http.Request) {
RemoteAddress: c.AppContext.IPAddress(),
XForwardedFor: c.AppContext.XForwardedFor(),
}
disconnectErrCode := r.URL.Query().Get(disconnectErrCodeParam)
if codeValid := validateDisconnectErrCode(disconnectErrCode); codeValid {
cfg.DisconnectErrCode = disconnectErrCode
}
// The WebSocket upgrade request coming from mobile is missing the
// user agent so we need to fallback on the session's metadata.
if c.AppContext.Session().IsMobileApp() {