From 93aa8a8cff90a02c978de6103b8ab837317cf75d Mon Sep 17 00:00:00 2001 From: Sonia Appasamy Date: Wed, 11 Oct 2023 14:35:22 -0400 Subject: [PATCH] client/web: allow providing logger implementation Also report metrics in separate go routine with a 5 second timeout. Updates tailscale/corp#14335 Signed-off-by: Sonia Appasamy --- client/web/web.go | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/client/web/web.go b/client/web/web.go index 2b010ecc6..43707821a 100644 --- a/client/web/web.go +++ b/client/web/web.go @@ -32,12 +32,14 @@ import ( "tailscale.com/licenses" "tailscale.com/net/netutil" "tailscale.com/tailcfg" + "tailscale.com/types/logger" "tailscale.com/util/httpm" "tailscale.com/version/distro" ) // Server is the backend server for a Tailscale web client. type Server struct { + logf logger.Logf lc *tailscale.LocalClient timeNow func() time.Time @@ -136,6 +138,8 @@ type ServerOpts struct { // TimeNow optionally provides a time function. // time.Now is used as default. TimeNow func() time.Time + + Logf logger.Logf } // NewServer constructs a new Tailscale web client server. @@ -144,6 +148,7 @@ func NewServer(opts ServerOpts) (s *Server, cleanup func()) { opts.LocalClient = &tailscale.LocalClient{} } s = &Server{ + logf: opts.Logf, devMode: opts.DevMode, lc: opts.LocalClient, cgiMode: opts.CGIMode, @@ -153,9 +158,14 @@ func NewServer(opts ServerOpts) (s *Server, cleanup func()) { if s.timeNow == nil { s.timeNow = time.Now } + if s.logf == nil { + s.logf = log.Printf + } s.tsDebugMode = s.debugMode() s.assetsHandler, cleanup = assetsHandler(opts.DevMode) + var metric string // clientmetric to report on startup + // Create handler for "/api" requests with CSRF protection. // We don't require secure cookies, since the web client is regularly used // on network appliances that are served on local non-https URLs. @@ -166,12 +176,19 @@ func NewServer(opts ServerOpts) (s *Server, cleanup func()) { // For the login client, we don't serve the full web client API, // only the login endpoints. s.apiHandler = csrfProtect(http.HandlerFunc(s.serveLoginAPI)) - s.lc.IncrementCounter(context.Background(), "web_login_client_initialization", 1) + metric = "web_login_client_initialization" } else { s.apiHandler = csrfProtect(http.HandlerFunc(s.serveAPI)) - s.lc.IncrementCounter(context.Background(), "web_client_initialization", 1) + metric = "web_client_initialization" } + // Report metric in separate go routine with 5 second timeout. + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + go func() { + defer cancel() + s.lc.IncrementCounter(ctx, metric, 1) + }() + return s, cleanup } @@ -645,7 +662,7 @@ func (s *Server) servePostNodeUpdate(w http.ResponseWriter, r *http.Request) { } mp.Prefs.WantRunning = true mp.Prefs.AdvertiseRoutes = routes - log.Printf("Doing edit: %v", mp.Pretty()) + s.logf("Doing edit: %v", mp.Pretty()) if _, err := s.lc.EditPrefs(r.Context(), mp); err != nil { w.WriteHeader(http.StatusInternalServerError) @@ -661,9 +678,9 @@ func (s *Server) servePostNodeUpdate(w http.ResponseWriter, r *http.Request) { if postData.ForceLogout { logout = true } - log.Printf("tailscaleUp(reauth=%v, logout=%v) ...", reauth, logout) + s.logf("tailscaleUp(reauth=%v, logout=%v) ...", reauth, logout) url, err := s.tailscaleUp(r.Context(), st, postData) - log.Printf("tailscaleUp = (URL %v, %v)", url != "", err) + s.logf("tailscaleUp = (URL %v, %v)", url != "", err) if err != nil { w.WriteHeader(http.StatusInternalServerError) json.NewEncoder(w).Encode(mi{"error": err.Error()})