From 07ff292c59ed6aac9c1ab981a40d45fc9d188b4b Mon Sep 17 00:00:00 2001 From: Marco Dinis Date: Fri, 25 Oct 2024 16:51:24 +0100 Subject: [PATCH] [v16] Replace logrus with slog in most of `lib/srv/app` (#47885) * Replace logrus with slog in most of `lib/srv/app` * move things * avoid slog.Logger().With * Update lib/srv/app/aws/handler.go Co-authored-by: rosstimothy <39066650+rosstimothy@users.noreply.github.com> * fix: use legacy logger for reconciler --------- Co-authored-by: rosstimothy <39066650+rosstimothy@users.noreply.github.com> --- lib/srv/app/aws/handler.go | 18 ++++++++++----- lib/srv/app/azure/credential.go | 2 +- lib/srv/app/azure/handler.go | 35 +++++++++++++++++------------- lib/srv/app/cloud.go | 4 ---- lib/srv/app/common/audit.go | 8 +++---- lib/srv/app/connections_handler.go | 2 +- lib/srv/app/gcp/handler.go | 27 ++++++++++++++++------- lib/srv/app/server.go | 31 ++++++++++++++------------ lib/srv/app/session.go | 28 ++++++++++++++++-------- lib/srv/app/session_test.go | 4 +++- lib/srv/app/transport.go | 13 ++++++----- lib/srv/app/watcher.go | 19 +++++++++------- 12 files changed, 116 insertions(+), 75 deletions(-) diff --git a/lib/srv/app/aws/handler.go b/lib/srv/app/aws/handler.go index f98b3222891a7..8e2d0933bb441 100644 --- a/lib/srv/app/aws/handler.go +++ b/lib/srv/app/aws/handler.go @@ -22,6 +22,7 @@ import ( "bytes" "context" "io" + "log/slog" "net/http" "net/url" "strings" @@ -53,8 +54,12 @@ type signerHandler struct { // SignerHandlerConfig is the awsSignerHandler configuration. type SignerHandlerConfig struct { + // LegacyLogger is the old logger. + // Should be removed gradually. + // Deprecated: use Log instead. + LegacyLogger logrus.FieldLogger // Log is a logger for the handler. - Log logrus.FieldLogger + Log *slog.Logger // RoundTripper is an http.RoundTripper instance used for requests. RoundTripper http.RoundTripper // SigningService is used to sign requests before forwarding them. @@ -77,8 +82,11 @@ func (cfg *SignerHandlerConfig) CheckAndSetDefaults() error { } cfg.RoundTripper = tr } + if cfg.LegacyLogger == nil { + cfg.LegacyLogger = logrus.WithField(teleport.ComponentKey, "aws:signer") + } if cfg.Log == nil { - cfg.Log = logrus.WithField(teleport.ComponentKey, "aws:signer") + cfg.Log = slog.With(teleport.ComponentKey, "aws:signer") } if cfg.Clock == nil { cfg.Clock = clockwork.NewRealClock() @@ -106,7 +114,7 @@ func NewAWSSignerHandler(ctx context.Context, config SignerHandlerConfig) (http. var err error handler.fwd, err = reverseproxy.New( reverseproxy.WithRoundTripper(config.RoundTripper), - reverseproxy.WithLogger(config.Log), + reverseproxy.WithLogger(config.LegacyLogger), reverseproxy.WithErrorHandler(handler.formatForwardResponseError), ) @@ -115,7 +123,7 @@ func NewAWSSignerHandler(ctx context.Context, config SignerHandlerConfig) (http. // formatForwardResponseError converts an error to a status code and writes the code to a response. func (s *signerHandler) formatForwardResponseError(rw http.ResponseWriter, r *http.Request, err error) { - s.Log.WithError(err).Debugf("Failed to process request.") + s.Log.DebugContext(r.Context(), "Failed to process request", "error", err) common.SetTeleportAPIErrorHeader(rw, err) // Convert trace error type to HTTP and write response. @@ -217,7 +225,7 @@ func (s *signerHandler) emitAudit(sessCtx *common.SessionContext, req *http.Requ } if auditErr != nil { // log but don't return the error, because we already handed off request/response handling to the oxy forwarder. - s.Log.WithError(auditErr).Warn("Failed to emit audit event.") + s.Log.WarnContext(req.Context(), "Failed to emit audit event.", "error", auditErr) } } diff --git a/lib/srv/app/azure/credential.go b/lib/srv/app/azure/credential.go index fede72eb6f37b..e653bb2a2917f 100644 --- a/lib/srv/app/azure/credential.go +++ b/lib/srv/app/azure/credential.go @@ -89,7 +89,7 @@ func findDefaultCredentialProvider(ctx context.Context, logger *slog.Logger) (cr defaultWorkloadIdentity, err := azidentity.NewWorkloadIdentityCredential(nil) if err != nil { // If no workload identity is found, fall back to regular managed identity. - logger.With("error", err).DebugContext(ctx, "Failed to load azure workload identity.") + logger.DebugContext(ctx, "Failed to load azure workload identity.", "error", err) logger.InfoContext(ctx, "Using azure managed identity.") return managedIdentityCredentialProvider{}, nil } diff --git a/lib/srv/app/azure/handler.go b/lib/srv/app/azure/handler.go index d405a59a9422e..0affaef32e6e8 100644 --- a/lib/srv/app/azure/handler.go +++ b/lib/srv/app/azure/handler.go @@ -51,11 +51,12 @@ const ComponentKey = "azure:fwd" type HandlerConfig struct { // RoundTripper is the underlying transport given to an oxy Forwarder. RoundTripper http.RoundTripper - // Log is the Logger. - // TODO(greedy52) replace with slog. - Log logrus.FieldLogger - // Logger is the slog.Logger. - Logger *slog.Logger + // LegacyLogger is the old logger. + // Should be removed gradually. + // Deprecated: use Log instead. + LegacyLogger logrus.FieldLogger + // Log is a logger for the handler. + Log *slog.Logger // Clock is used to override time in tests. Clock clockwork.Clock @@ -75,14 +76,14 @@ func (s *HandlerConfig) CheckAndSetDefaults(ctx context.Context) error { if s.Clock == nil { s.Clock = clockwork.NewRealClock() } - if s.Log == nil { - s.Log = logrus.WithField(teleport.ComponentKey, ComponentKey) + if s.LegacyLogger == nil { + s.LegacyLogger = logrus.WithField(teleport.ComponentKey, ComponentKey) } - if s.Logger == nil { - s.Logger = slog.Default().With(teleport.ComponentKey, ComponentKey) + if s.Log == nil { + s.Log = slog.With(teleport.ComponentKey, ComponentKey) } if s.getAccessToken == nil { - s.getAccessToken = lazyGetAccessTokenFromDefaultCredentialProvider(s.Logger) + s.getAccessToken = lazyGetAccessTokenFromDefaultCredentialProvider(s.Log) } return nil } @@ -127,7 +128,7 @@ func newAzureHandler(ctx context.Context, config HandlerConfig) (*handler, error svc.fwd, err = reverseproxy.New( reverseproxy.WithRoundTripper(config.RoundTripper), - reverseproxy.WithLogger(config.Log), + reverseproxy.WithLogger(config.LegacyLogger), reverseproxy.WithErrorHandler(svc.formatForwardResponseError), ) @@ -161,13 +162,13 @@ func (s *handler) serveHTTP(w http.ResponseWriter, req *http.Request) error { if err := sessionCtx.Audit.OnRequest(req.Context(), sessionCtx, fwdRequest, status, nil); err != nil { // log but don't return the error, because we already handed off request/response handling to the oxy forwarder. - s.Log.WithError(err).Warn("Failed to emit audit event.") + s.Log.WarnContext(req.Context(), "Failed to emit audit event.", "error", err) } return nil } func (s *handler) formatForwardResponseError(rw http.ResponseWriter, r *http.Request, err error) { - s.Log.WithError(err).Debugf("Failed to process request.") + s.Log.DebugContext(r.Context(), "Failed to process request.", "error", err) common.SetTeleportAPIErrorHeader(rw, err) // Convert trace error type to HTTP and write response. @@ -224,7 +225,7 @@ func getPeerKey(certs []*x509.Certificate) (crypto.PublicKey, error) { func (s *handler) replaceAuthHeaders(r *http.Request, sessionCtx *common.SessionContext, reqCopy *http.Request) error { auth := reqCopy.Header.Get("Authorization") if auth == "" { - s.Log.Debugf("No Authorization header present, skipping replacement.") + s.Log.DebugContext(r.Context(), "No Authorization header present, skipping replacement.") return nil } @@ -238,7 +239,11 @@ func (s *handler) replaceAuthHeaders(r *http.Request, sessionCtx *common.Session return trace.Wrap(err, "failed to parse Authorization header") } - s.Log.Debugf("Processing request, sessionId = %q, azureIdentity = %q, claims = %v", sessionCtx.Identity.RouteToApp.SessionID, sessionCtx.Identity.RouteToApp.AzureIdentity, claims) + s.Log.DebugContext(r.Context(), "Processing request.", + "session_id", sessionCtx.Identity.RouteToApp.SessionID, + "azure_identity", sessionCtx.Identity.RouteToApp.AzureIdentity, + "claims", claims, + ) token, err := s.getToken(r.Context(), sessionCtx.Identity.RouteToApp.AzureIdentity, claims.Resource) if err != nil { return trace.Wrap(err) diff --git a/lib/srv/app/cloud.go b/lib/srv/app/cloud.go index 3675bc14910ed..0196cdff2faa0 100644 --- a/lib/srv/app/cloud.go +++ b/lib/srv/app/cloud.go @@ -35,9 +35,7 @@ import ( awssession "github.com/aws/aws-sdk-go/aws/session" "github.com/gravitational/trace" "github.com/jonboulle/clockwork" - "github.com/sirupsen/logrus" - "github.com/gravitational/teleport" "github.com/gravitational/teleport/api/constants" "github.com/gravitational/teleport/lib/tlsca" awsutils "github.com/gravitational/teleport/lib/utils/aws" @@ -110,7 +108,6 @@ func (c *CloudConfig) CheckAndSetDefaults() error { type cloud struct { cfg CloudConfig - log logrus.FieldLogger } // NewCloud creates a new cloud service. @@ -120,7 +117,6 @@ func NewCloud(cfg CloudConfig) (Cloud, error) { } return &cloud{ cfg: cfg, - log: logrus.WithField(teleport.ComponentKey, "cloud"), }, nil } diff --git a/lib/srv/app/common/audit.go b/lib/srv/app/common/audit.go index 4b6a465b2b52b..2c745be2b3495 100644 --- a/lib/srv/app/common/audit.go +++ b/lib/srv/app/common/audit.go @@ -20,11 +20,11 @@ package common import ( "context" + "log/slog" "net/http" "github.com/aws/aws-sdk-go/aws/endpoints" "github.com/gravitational/trace" - "github.com/sirupsen/logrus" "github.com/gravitational/teleport" apidefaults "github.com/gravitational/teleport/api/defaults" @@ -75,7 +75,7 @@ type audit struct { // cfg is the audit events emitter configuration. cfg AuditConfig // log is used for logging - log logrus.FieldLogger + log *slog.Logger } // NewAudit returns a new instance of the audit events emitter. @@ -85,7 +85,7 @@ func NewAudit(config AuditConfig) (Audit, error) { } return &audit{ cfg: config, - log: logrus.WithField(teleport.ComponentKey, "app:audit"), + log: slog.With(teleport.ComponentKey, "app:audit"), }, nil } @@ -199,7 +199,7 @@ func (a *audit) OnDynamoDBRequest(ctx context.Context, sessionCtx *SessionContex // If this fails, we still want to emit the rest of the event info; the request event Body is nullable, so it's ok if body is left nil here. body, err := awsutils.UnmarshalRequestBody(req) if err != nil { - a.log.WithError(err).Warn("Failed to read request body as JSON, omitting the body from the audit event.") + a.log.WarnContext(ctx, "Failed to read request body as JSON, omitting the body from the audit event.", "error", err) } // get the API target from the request header, according to the API request format documentation: // https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.LowLevelAPI.html#Programming.LowLevelAPI.RequestFormat diff --git a/lib/srv/app/connections_handler.go b/lib/srv/app/connections_handler.go index 179f6e4bec284..5cc34fb4f0ab5 100644 --- a/lib/srv/app/connections_handler.go +++ b/lib/srv/app/connections_handler.go @@ -225,7 +225,7 @@ func NewConnectionsHandler(closeContext context.Context, cfg *ConnectionsHandler } azureHandler, err := appazure.NewAzureHandler(closeContext, appazure.HandlerConfig{ - Logger: cfg.Logger.With(teleport.ComponentKey, appazure.ComponentKey), + Log: cfg.Logger.With(teleport.ComponentKey, appazure.ComponentKey), }) if err != nil { return nil, trace.Wrap(err) diff --git a/lib/srv/app/gcp/handler.go b/lib/srv/app/gcp/handler.go index c0e7b8ff64611..ebafa0faf07cc 100644 --- a/lib/srv/app/gcp/handler.go +++ b/lib/srv/app/gcp/handler.go @@ -22,6 +22,7 @@ import ( "bytes" "context" "fmt" + "log/slog" "net/http" "time" @@ -68,8 +69,12 @@ var _ cloudClientGCP = (*cloudClientGCPImpl[iamCredentialsClient])(nil) type HandlerConfig struct { // RoundTripper is the underlying transport given to an oxy Forwarder. RoundTripper http.RoundTripper - // Log is the Logger. - Log logrus.FieldLogger + // LegacyLogger is the old logger. + // Should be removed gradually. + // Deprecated: use Log instead. + LegacyLogger logrus.FieldLogger + // Log is a logger for the handler. + Log *slog.Logger // Clock is used to override time in tests. Clock clockwork.Clock // cloudClientGCP holds a reference to GCP IAM client. Normally set in CheckAndSetDefaults, it is overridden in tests. @@ -89,7 +94,10 @@ func (s *HandlerConfig) CheckAndSetDefaults() error { s.Clock = clockwork.NewRealClock() } if s.Log == nil { - s.Log = logrus.WithField(teleport.ComponentKey, "gcp:fwd") + s.Log = slog.With(teleport.ComponentKey, "gcp:fwd") + } + if s.LegacyLogger == nil { + s.LegacyLogger = logrus.WithField(teleport.ComponentKey, "gcp:fwd") } if s.cloudClientGCP == nil { clients, err := cloud.NewClients() @@ -141,7 +149,7 @@ func newGCPHandler(ctx context.Context, config HandlerConfig) (*handler, error) svc.fwd, err = reverseproxy.New( reverseproxy.WithRoundTripper(config.RoundTripper), - reverseproxy.WithLogger(config.Log), + reverseproxy.WithLogger(config.LegacyLogger), reverseproxy.WithErrorHandler(svc.formatForwardResponseError), ) return svc, trace.Wrap(err) @@ -164,7 +172,10 @@ func (s *handler) serveHTTP(w http.ResponseWriter, req *http.Request) error { if err != nil { return trace.Wrap(err) } - s.Log.Debugf("Processing request, sessionId = %q, gcpServiceAccount = %q", sessionCtx.Identity.RouteToApp.SessionID, sessionCtx.Identity.RouteToApp.GCPServiceAccount) + s.Log.DebugContext(req.Context(), "Processing request", + "session_id", sessionCtx.Identity.RouteToApp.SessionID, + "gcp_service_account", sessionCtx.Identity.RouteToApp.GCPServiceAccount, + ) fwdRequest, err := s.prepareForwardRequest(req, sessionCtx) if err != nil { @@ -176,13 +187,13 @@ func (s *handler) serveHTTP(w http.ResponseWriter, req *http.Request) error { if err := sessionCtx.Audit.OnRequest(req.Context(), sessionCtx, fwdRequest, status, nil); err != nil { // log but don't return the error, because we already handed off request/response handling to the oxy forwarder. - s.Log.WithError(err).Warn("Failed to emit audit event.") + s.Log.WarnContext(req.Context(), "Failed to emit audit event.", "error", err) } return nil } func (s *handler) formatForwardResponseError(rw http.ResponseWriter, r *http.Request, err error) { - s.Log.WithError(err).Debugf("Failed to process request.") + s.Log.DebugContext(r.Context(), "Failed to process request.", "error", err) common.SetTeleportAPIErrorHeader(rw, err) // Convert trace error type to HTTP and write response. @@ -224,7 +235,7 @@ func (s *handler) prepareForwardRequest(r *http.Request, sessionCtx *common.Sess func (s *handler) replaceAuthHeaders(r *http.Request, sessionCtx *common.SessionContext, reqCopy *http.Request) error { auth := reqCopy.Header.Get("Authorization") if auth == "" { - s.Log.Debugf("No Authorization header present, skipping replacement.") + s.Log.DebugContext(r.Context(), "No Authorization header present, skipping replacement.") return nil } diff --git a/lib/srv/app/server.go b/lib/srv/app/server.go index 0a248bc941018..83684289cdb3b 100644 --- a/lib/srv/app/server.go +++ b/lib/srv/app/server.go @@ -23,6 +23,7 @@ package app import ( "context" + "log/slog" "net" "sync" @@ -131,8 +132,9 @@ func (c *Config) CheckAndSetDefaults() error { // Server is an application server. It authenticates requests from the web // proxy and forwards th to internal applications. type Server struct { - c *Config - log *logrus.Entry + c *Config + legacyLog *logrus.Entry + log *slog.Logger closeContext context.Context closeFunc context.CancelFunc @@ -199,9 +201,10 @@ func New(ctx context.Context, c *Config) (*Server, error) { s := &Server{ c: c, // TODO(greedy52) replace with slog from Config.Logger. - log: logrus.WithFields(logrus.Fields{ + legacyLog: logrus.WithFields(logrus.Fields{ teleport.ComponentKey: teleport.ComponentApp, }), + log: slog.With(teleport.ComponentKey, teleport.ComponentApp), heartbeats: make(map[string]srv.HeartbeatI), dynamicLabels: make(map[string]*labels.Dynamic), apps: make(map[string]types.Application), @@ -231,7 +234,7 @@ func (s *Server) startApp(ctx context.Context, app types.Application) error { if err := s.startHeartbeat(ctx, app); err != nil { return trace.Wrap(err) } - s.log.Debugf("Started %v.", app) + s.log.DebugContext(ctx, "App started.", "app", app) return nil } @@ -241,7 +244,7 @@ func (s *Server) stopApp(ctx context.Context, name string) error { if err := s.stopHeartbeat(name); err != nil { return trace.Wrap(err) } - s.log.Debugf("Stopped app %q.", name) + s.log.DebugContext(ctx, "App stopped.", "app", name) return nil } @@ -365,7 +368,7 @@ func (s *Server) getServerInfo(app types.Application) (*types.AppServerV3, error func (s *Server) getRotationState() types.Rotation { rotation, err := s.c.GetRotation(types.RoleApp) if err != nil && !trace.IsNotFound(err) && !trace.IsConnectionProblem(err) { - s.log.WithError(err).Warn("Failed to get rotation state.") + s.log.WarnContext(s.closeContext, "Failed to get rotation state.", "error", err) } if rotation != nil { return *rotation @@ -488,21 +491,21 @@ func (s *Server) close(ctx context.Context) error { } if heartbeat != nil { - log := s.log.WithField("app", name) - log.Debug("Stopping app") + log := s.log.With("app", name) + log.DebugContext(ctx, "Stopping app") if err := heartbeat.Close(); err != nil { - log.WithError(err).Warn("Failed to stop app.") + log.WarnContext(ctx, "Failed to stop app.", "error", err) } else { - log.Debug("Stopped app") + log.DebugContext(ctx, "Stopped app") } if shouldDeleteApps { g.Go(func() error { - log.Debug("Deleting app") + log.DebugContext(ctx, "Deleting app") if err := s.removeAppServer(gctx, name); err != nil { - log.WithError(err).Warn("Failed to delete app.") + log.WarnContext(ctx, "Failed to delete app.", "error", err) } else { - log.Debug("Deleted app") + log.DebugContext(ctx, "Deleted app") } return nil }) @@ -512,7 +515,7 @@ func (s *Server) close(ctx context.Context) error { s.mu.RUnlock() if err := g.Wait(); err != nil { - s.log.WithError(err).Warn("Deleting all apps failed") + s.log.WarnContext(ctx, "Deleting all apps failed", "error", err) } s.mu.Lock() diff --git a/lib/srv/app/session.go b/lib/srv/app/session.go index 8574501041d79..f1b53f3994f8f 100644 --- a/lib/srv/app/session.go +++ b/lib/srv/app/session.go @@ -21,6 +21,7 @@ package app import ( "context" "errors" + "log/slog" "net/http" "sync" "time" @@ -83,7 +84,9 @@ type sessionChunk struct { // for ~7 minutes at most. closeTimeout time.Duration - log *logrus.Entry + log *slog.Logger + + legacyLogger *logrus.Entry } // sessionOpt defines an option function for creating sessionChunk. @@ -99,10 +102,11 @@ func (c *ConnectionsHandler) newSessionChunk(ctx context.Context, identity *tlsc closeC: make(chan struct{}), inflightCond: sync.NewCond(&sync.Mutex{}), closeTimeout: sessionChunkCloseTimeout, - log: c.legacyLogger, + log: c.log, + legacyLogger: c.legacyLogger, } - sess.log.Debugf("Creating app session chunk %s", sess.id) + sess.log.DebugContext(ctx, "Creating app session chunk", "session_id", sess.id) // Create a session tracker so that other services, such as the // session upload completer, can track the session chunk's lifetime. @@ -139,7 +143,7 @@ func (c *ConnectionsHandler) newSessionChunk(ctx context.Context, identity *tlsc return nil, trace.Wrap(err) } - sess.log.Debugf("Created app session chunk %s", sess.id) + sess.log.DebugContext(ctx, "Created app session chunk", "session_id", sess.id) return sess, nil } @@ -188,7 +192,7 @@ func (c *ConnectionsHandler) withJWTTokenForwarder(ctx context.Context, sess *se cipherSuites: c.cfg.CipherSuites, jwt: jwt, traits: traits, - log: c.legacyLogger, + log: c.log, }) if err != nil { return trace.Wrap(err) @@ -198,7 +202,7 @@ func (c *ConnectionsHandler) withJWTTokenForwarder(ctx context.Context, sess *se sess.handler, err = reverseproxy.New( reverseproxy.WithFlushInterval(100*time.Millisecond), reverseproxy.WithRoundTripper(transport), - reverseproxy.WithLogger(sess.log), + reverseproxy.WithLogger(sess.legacyLogger), reverseproxy.WithRewriter(common.NewHeaderRewriter(delegate)), ) if err != nil { @@ -262,16 +266,22 @@ func (s *sessionChunk) close(ctx context.Context) error { if s.inflight == 0 { break } else if time.Now().After(deadline) { - s.log.Debugf("Timeout expired, forcibly closing session chunk %s, inflight requests: %d", s.id, s.inflight) + s.log.DebugContext(ctx, "Timeout expired, forcibly closing session chunk", + "session_id", s.id, + "inflight_requests", s.inflight, + ) break } - s.log.Debugf("Inflight requests: %d, waiting to close session chunk %s", s.inflight, s.id) + s.log.DebugContext(ctx, "Waiting to close session chunk", + "session_id", s.id, + "inflight_requests", s.inflight, + ) s.inflightCond.Wait() } s.inflight = -1 s.inflightCond.L.Unlock() close(s.closeC) - s.log.Debugf("Closed session chunk %s", s.id) + s.log.DebugContext(ctx, "Closed session chunk", "session_id", s.id) return trace.Wrap(s.streamCloser.Close(ctx)) } diff --git a/lib/srv/app/session_test.go b/lib/srv/app/session_test.go index f6b94552c8fb2..d76fdcb6a9a22 100644 --- a/lib/srv/app/session_test.go +++ b/lib/srv/app/session_test.go @@ -29,6 +29,7 @@ import ( "github.com/stretchr/testify/require" "github.com/gravitational/teleport/lib/events" + "github.com/gravitational/teleport/lib/utils" ) func newSessionChunk(timeout time.Duration) *sessionChunk { @@ -37,7 +38,8 @@ func newSessionChunk(timeout time.Duration) *sessionChunk { closeC: make(chan struct{}), inflightCond: sync.NewCond(&sync.Mutex{}), closeTimeout: timeout, - log: logrus.NewEntry(logrus.StandardLogger()), + legacyLogger: logrus.NewEntry(logrus.StandardLogger()), + log: utils.NewSlogLoggerForTests(), streamCloser: events.NewDiscardRecorder(), } } diff --git a/lib/srv/app/transport.go b/lib/srv/app/transport.go index cb545acb0846d..d019af70dbe9f 100644 --- a/lib/srv/app/transport.go +++ b/lib/srv/app/transport.go @@ -21,6 +21,7 @@ package app import ( "context" "crypto/tls" + "log/slog" "net" "net/http" "net/url" @@ -28,7 +29,6 @@ import ( "slices" "github.com/gravitational/trace" - "github.com/sirupsen/logrus" "github.com/gravitational/teleport" "github.com/gravitational/teleport/api/types" @@ -47,7 +47,7 @@ type transportConfig struct { cipherSuites []uint16 jwt string traits wrappers.Traits - log logrus.FieldLogger + log *slog.Logger } // Check validates configuration. @@ -62,7 +62,7 @@ func (c *transportConfig) Check() error { return trace.BadParameter("jwt missing") } if c.log == nil { - c.log = logrus.WithField(teleport.ComponentKey, "transport") + c.log = slog.With(teleport.ComponentKey, "transport") } return nil @@ -185,12 +185,15 @@ func rewriteHeaders(r *http.Request, c *transportConfig) { } for _, header := range c.app.GetRewrite().Headers { if common.IsReservedHeader(header.Name) { - c.log.Debugf("Not rewriting Teleport header %q.", header.Name) + c.log.DebugContext(r.Context(), "Not rewriting Teleport reserved header", "header_name", header.Name) continue } values, err := services.ApplyValueTraits(header.Value, c.traits) if err != nil { - c.log.Debugf("Failed to apply traits to %q: %v.", header.Value, err) + c.log.DebugContext(r.Context(), "Failed to apply traits", + "header_value", header.Value, + "error", err, + ) continue } r.Header.Del(header.Name) diff --git a/lib/srv/app/watcher.go b/lib/srv/app/watcher.go index 280a37882ab9d..ff6541436478a 100644 --- a/lib/srv/app/watcher.go +++ b/lib/srv/app/watcher.go @@ -40,7 +40,7 @@ func (s *Server) startReconciler(ctx context.Context) error { OnCreate: s.onCreate, OnUpdate: s.onUpdate, OnDelete: s.onDelete, - Log: s.log, + Log: s.legacyLog, }) if err != nil { return trace.Wrap(err) @@ -50,12 +50,12 @@ func (s *Server) startReconciler(ctx context.Context) error { select { case <-s.reconcileCh: if err := reconciler.Reconcile(ctx); err != nil { - s.log.WithError(err).Error("Failed to reconcile.") + s.log.ErrorContext(ctx, "Failed to reconcile.", "error", err) } else if s.c.OnReconcile != nil { s.c.OnReconcile(s.getApps()) } case <-ctx.Done(): - s.log.Debug("Reconciler done.") + s.log.DebugContext(ctx, "Reconciler done.") return } } @@ -67,14 +67,14 @@ func (s *Server) startReconciler(ctx context.Context) error { // registers/unregisters the proxied applications accordingly. func (s *Server) startResourceWatcher(ctx context.Context) (*services.AppWatcher, error) { if len(s.c.ResourceMatchers) == 0 { - s.log.Debug("Not initializing application resource watcher.") + s.log.DebugContext(ctx, "Not initializing application resource watcher.") return nil, nil } - s.log.Debug("Initializing application resource watcher.") + s.log.DebugContext(ctx, "Initializing application resource watcher.") watcher, err := services.NewAppWatcher(ctx, services.AppWatcherConfig{ ResourceWatcherConfig: services.ResourceWatcherConfig{ Component: teleport.ComponentApp, - Log: s.log, + Log: s.legacyLog, Client: s.c.AccessPoint, }, }) @@ -97,7 +97,7 @@ func (s *Server) startResourceWatcher(ctx context.Context) (*services.AppWatcher return } case <-ctx.Done(): - s.log.Debug("Application resource watcher done.") + s.log.DebugContext(ctx, "Application resource watcher done.") return } } @@ -115,7 +115,10 @@ func (s *Server) guessPublicAddr(app types.Application) types.Application { if err == nil { appCopy.Spec.PublicAddr = pubAddr } else { - s.log.WithError(err).Errorf("Unable to find public address for app %q, leaving empty.", app.GetName()) + s.log.ErrorContext(s.closeContext, "Unable to find public address for app, leaving empty", + "app_name", app.GetName(), + "error", err, + ) } return appCopy }