Skip to content

chore: add prometheus timing to latency endpoint #7742

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions coderd/coderd.go
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@ func New(options *Options) *API {
derpHandler := derphttp.Handler(api.DERPServer)
derpHandler, api.derpCloseFunc = tailnet.WithWebsocketSupport(api.DERPServer, derpHandler)
cors := httpmw.Cors(options.DeploymentValues.Dangerous.AllowAllCors.Value())
prometheusMW := httpmw.Prometheus(options.PrometheusRegistry)

r.Use(
cors,
Expand All @@ -414,7 +415,7 @@ func New(options *Options) *API {
httpmw.AttachRequestID,
httpmw.ExtractRealIP(api.RealIPConfig),
httpmw.Logger(api.Logger),
httpmw.Prometheus(options.PrometheusRegistry),
prometheusMW,
// SubdomainAppMW checks if the first subdomain is a valid app URL. If
// it is, it will serve that application.
//
Expand Down Expand Up @@ -832,7 +833,7 @@ func New(options *Options) *API {
// This is the only route we add before all the middleware.
// We want to time the latency of the request, so any middleware will
// interfere with that timing.
rootRouter.Get("/latency-check", cors(LatencyCheck(options.DeploymentValues.Dangerous.AllowAllCors.Value(), api.AccessURL)).ServeHTTP)
rootRouter.Get("/latency-check", tracing.StatusWriterMiddleware(prometheusMW(LatencyCheck())).ServeHTTP)
rootRouter.Mount("/", r)
api.RootHandler = rootRouter

Expand Down
23 changes: 8 additions & 15 deletions coderd/latencycheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,24 @@ package coderd

import (
"net/http"
"net/url"
"strings"
)

// LatencyCheck is an endpoint for the web ui to measure latency with.
// allowAll allows any Origin to get timing information. The allowAll should
// only be set in dev modes.
//
//nolint:revive
func LatencyCheck(allowAll bool, allowedOrigins ...*url.URL) http.HandlerFunc {
allowed := make([]string, 0, len(allowedOrigins))
for _, origin := range allowedOrigins {
// Allow the origin without a path
tmp := *origin
tmp.Path = ""
allowed = append(allowed, strings.TrimSuffix(origin.String(), "/"))
}
if allowAll {
allowed = append(allowed, "*")
}
origins := strings.Join(allowed, ",")
func LatencyCheck() http.HandlerFunc {
return func(rw http.ResponseWriter, r *http.Request) {
// Allowing timing information to be shared. This allows the browser
// to exclude TLS handshake timing.
rw.Header().Set("Timing-Allow-Origin", origins)
rw.Header().Set("Timing-Allow-Origin", "*")
// Always allow all CORs on this route.
rw.Header().Set("Access-Control-Allow-Origin", "*")
rw.Header().Set("Access-Control-Allow-Headers", "*")
rw.Header().Set("Access-Control-Allow-Credentials", "false")
rw.Header().Set("Access-Control-Allow-Methods", "*")
rw.WriteHeader(http.StatusOK)
_, _ = rw.Write([]byte("OK"))
}
}
5 changes: 3 additions & 2 deletions enterprise/wsproxy/wsproxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ func New(ctx context.Context, opts *Options) (*Server, error) {
// The primary coderd dashboard needs to make some GET requests to
// the workspace proxies to check latency.
corsMW := httpmw.Cors(opts.AllowAllCors, opts.DashboardURL.String())
prometheusMW := httpmw.Prometheus(s.PrometheusRegistry)

// Routes
apiRateLimiter := httpmw.RateLimit(opts.APIRateLimit, time.Minute)
Expand All @@ -205,7 +206,7 @@ func New(ctx context.Context, opts *Options) (*Server, error) {
httpmw.AttachRequestID,
httpmw.ExtractRealIP(s.Options.RealIPConfig),
httpmw.Logger(s.Logger),
httpmw.Prometheus(s.PrometheusRegistry),
prometheusMW,
corsMW,

// HandleSubdomain is a middleware that handles all requests to the
Expand Down Expand Up @@ -258,7 +259,7 @@ func New(ctx context.Context, opts *Options) (*Server, error) {
// See coderd/coderd.go for why we need this.
rootRouter := chi.NewRouter()
// Make sure to add the cors middleware to the latency check route.
rootRouter.Get("/latency-check", corsMW(coderd.LatencyCheck(opts.AllowAllCors, s.DashboardURL, s.AppServer.AccessURL)).ServeHTTP)
rootRouter.Get("/latency-check", tracing.StatusWriterMiddleware(prometheusMW(coderd.LatencyCheck())).ServeHTTP)
rootRouter.Mount("/", r)
s.Handler = rootRouter

Expand Down
3 changes: 0 additions & 3 deletions site/src/contexts/useProxyLatency.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,6 @@ export const useProxyLatency = (
const proxyRequests = Object.keys(proxyChecks).map((latencyURL) => {
return axios.get(latencyURL, {
withCredentials: false,
// Must add a custom header to make the request not a "simple request"
// https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests
headers: { "X-LATENCY-CHECK": "true" },
})
})

Expand Down