diff --git a/cmd/planner-agent/main.go b/cmd/planner-agent/main.go index c692a8e..e0fa104 100644 --- a/cmd/planner-agent/main.go +++ b/cmd/planner-agent/main.go @@ -12,6 +12,8 @@ import ( "github.com/google/uuid" "github.com/kubev2v/migration-planner/internal/agent" "github.com/kubev2v/migration-planner/pkg/log" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" ) const ( @@ -26,14 +28,12 @@ func main() { } type agentCmd struct { - log *log.PrefixLogger config *agent.Config configFile string } func NewAgentCommand() *agentCmd { a := &agentCmd{ - log: log.NewPrefixLogger(""), config: agent.NewDefault(), } @@ -48,13 +48,22 @@ func NewAgentCommand() *agentCmd { flag.Parse() if err := a.config.ParseConfigFile(a.configFile); err != nil { - a.log.Fatalf("Error parsing config: %v", err) + zap.S().Fatalf("Error parsing config: %v", err) } if err := a.config.Validate(); err != nil { - a.log.Fatalf("Error validating config: %v", err) + zap.S().Fatalf("Error validating config: %v", err) } - a.log.SetLevel(a.config.LogLevel) + logLvl, err := zap.ParseAtomicLevel(a.config.LogLevel) + if err != nil { + logLvl = zap.NewAtomicLevelAt(zapcore.InfoLevel) + } + + logger := log.InitLog(logLvl) + defer func() { _ = logger.Sync() }() + + undo := zap.ReplaceGlobals(logger) + defer undo() return a } @@ -62,12 +71,12 @@ func NewAgentCommand() *agentCmd { func (a *agentCmd) Execute() error { agentID, err := a.getAgentID() if err != nil { - a.log.Fatalf("failed to retreive agent_id: %v", err) + zap.S().Fatalf("failed to retreive agent_id: %v", err) } - agentInstance := agent.New(uuid.MustParse(agentID), a.log, a.config) + agentInstance := agent.New(uuid.MustParse(agentID), a.config) if err := agentInstance.Run(context.Background()); err != nil { - a.log.Fatalf("running device agent: %v", err) + zap.S().Fatalf("running device agent: %v", err) } return nil } diff --git a/cmd/planner-api/migrate.go b/cmd/planner-api/migrate.go index eb3ed13..6db7915 100644 --- a/cmd/planner-api/migrate.go +++ b/cmd/planner-api/migrate.go @@ -4,17 +4,19 @@ import ( "github.com/kubev2v/migration-planner/internal/config" "github.com/kubev2v/migration-planner/internal/store" "github.com/kubev2v/migration-planner/pkg/log" - "github.com/sirupsen/logrus" "github.com/spf13/cobra" + "go.uber.org/zap" ) var migrateCmd = &cobra.Command{ Use: "migrate", Short: "Migrate the db", RunE: func(cmd *cobra.Command, args []string) error { - log := log.InitLogs() - log.Println("Starting API service") - defer log.Println("Db migrated") + logger := log.InitLog(zap.NewAtomicLevelAt(zap.InfoLevel)) + defer func() { _ = logger.Sync() }() + + undo := zap.ReplaceGlobals(logger) + defer undo() if configFile == "" { configFile = config.ConfigFile() @@ -22,27 +24,21 @@ var migrateCmd = &cobra.Command{ cfg, err := config.Load(configFile) if err != nil { - log.Fatalf("reading configuration: %v", err) - } - log.Printf("Using config: %s", cfg) - - logLvl, err := logrus.ParseLevel(cfg.Service.LogLevel) - if err != nil { - logLvl = logrus.InfoLevel + zap.S().Fatalf("reading configuration: %v", err) } - log.SetLevel(logLvl) + zap.S().Infof("Using config: %s", cfg) - log.Println("Initializing data store") - db, err := store.InitDB(cfg, log) + zap.S().Info("Initializing data store") + db, err := store.InitDB(cfg) if err != nil { - log.Fatalf("initializing data store: %v", err) + zap.S().Fatalf("initializing data store: %v", err) } - store := store.NewStore(db, log.WithField("pkg", "store")) + store := store.NewStore(db) defer store.Close() if err := store.InitialMigration(); err != nil { - log.Fatalf("running initial migration: %v", err) + zap.S().Fatalf("running initial migration: %v", err) } return nil diff --git a/cmd/planner-api/run.go b/cmd/planner-api/run.go index fa5f805..3a4fed2 100644 --- a/cmd/planner-api/run.go +++ b/cmd/planner-api/run.go @@ -12,43 +12,48 @@ import ( "github.com/kubev2v/migration-planner/internal/config" "github.com/kubev2v/migration-planner/internal/store" "github.com/kubev2v/migration-planner/pkg/log" - "github.com/sirupsen/logrus" "github.com/spf13/cobra" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" ) var runCmd = &cobra.Command{ Use: "run", Short: "Run the planner api", RunE: func(cmd *cobra.Command, args []string) error { - log := log.InitLogs() - log.Println("Starting API service") - defer log.Println("API service stopped") + zap.S().Info("Starting API service") + defer zap.S().Info("API service stopped") if configFile == "" { configFile = config.ConfigFile() } cfg, err := config.LoadOrGenerate(configFile) if err != nil { - log.Fatalf("reading configuration: %v", err) + zap.S().Fatalf("reading configuration: %v", err) } - logLvl, err := logrus.ParseLevel(cfg.Service.LogLevel) + logLvl, err := zap.ParseAtomicLevel(cfg.Service.LogLevel) if err != nil { - logLvl = logrus.InfoLevel + logLvl = zap.NewAtomicLevelAt(zapcore.InfoLevel) } - log.SetLevel(logLvl) - log.Println("Initializing data store") - db, err := store.InitDB(cfg, log) + logger := log.InitLog(logLvl) + defer func() { _ = logger.Sync() }() + + undo := zap.ReplaceGlobals(logger) + defer undo() + + zap.S().Info("Initializing data store") + db, err := store.InitDB(cfg) if err != nil { - log.Fatalf("initializing data store: %v", err) + zap.S().Fatalf("initializing data store: %v", err) } - store := store.NewStore(db, log.WithField("pkg", "store")) + store := store.NewStore(db) defer store.Close() if err := store.InitialMigration(); err != nil { - log.Fatalf("running initial migration: %v", err) + zap.S().Fatalf("running initial migration: %v", err) } ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGHUP, syscall.SIGTERM, syscall.SIGQUIT) @@ -56,12 +61,12 @@ var runCmd = &cobra.Command{ defer cancel() listener, err := newListener(cfg.Service.Address) if err != nil { - log.Fatalf("creating listener: %s", err) + zap.S().Fatalf("creating listener: %s", err) } - server := apiserver.New(log, cfg, store, listener) + server := apiserver.New(cfg, store, listener) if err := server.Run(ctx); err != nil { - log.Fatalf("Error running server: %s", err) + zap.S().Fatalf("Error running server: %s", err) } }() @@ -69,12 +74,12 @@ var runCmd = &cobra.Command{ defer cancel() listener, err := newListener(cfg.Service.AgentEndpointAddress) if err != nil { - log.Fatalf("creating listener: %s", err) + zap.S().Fatalf("creating listener: %s", err) } - agentserver := agentserver.New(log, cfg, store, listener) + agentserver := agentserver.New(cfg, store, listener) if err := agentserver.Run(ctx); err != nil { - log.Fatalf("Error running server: %s", err) + zap.S().Fatalf("Error running server: %s", err) } }() diff --git a/go.mod b/go.mod index fd2536e..f26dcb2 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/go-chi/render v1.0.3 github.com/google/uuid v1.6.0 github.com/konveyor/forklift-controller v0.0.0-20221102112227-e73b65a01cda + github.com/leosunmo/zapchi v0.2.0 github.com/libvirt/libvirt-go v7.4.0+incompatible github.com/lthibault/jitterbug v2.0.0+incompatible github.com/oapi-codegen/nethttp-middleware v1.0.2 @@ -22,13 +23,13 @@ require ( github.com/spf13/pflag v1.0.6-0.20210604193023-d5e0c0615ace github.com/thoas/go-funk v0.9.3 github.com/vmware/govmomi v0.39.0 + go.uber.org/zap v1.26.0 gorm.io/driver/postgres v1.5.9 gorm.io/driver/sqlite v1.5.6 gorm.io/gorm v1.25.11 k8s.io/api v0.29.7 k8s.io/apimachinery v0.29.7 k8s.io/client-go v0.29.7 - k8s.io/klog/v2 v2.130.1 sigs.k8s.io/yaml v1.4.0 ) @@ -110,7 +111,6 @@ require ( github.com/ulikunitz/xz v0.5.11 // indirect github.com/vincent-petithory/dataurl v1.0.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.26.0 // indirect golang.org/x/arch v0.4.0 // indirect golang.org/x/crypto v0.23.0 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect @@ -129,6 +129,7 @@ require ( gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/apiextensions-apiserver v0.28.3 // indirect + k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect k8s.io/utils v0.0.0-20240102154912-e7106e64919e // indirect kubevirt.io/api v1.1.1 // indirect diff --git a/go.sum b/go.sum index 7622f44..afd8a23 100644 --- a/go.sum +++ b/go.sum @@ -89,6 +89,7 @@ github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= github.com/go-chi/chi v1.5.5 h1:vOB/HbEMt9QqBqErz07QehcOKHaWFtuj87tTDVz2qXE= github.com/go-chi/chi v1.5.5/go.mod h1:C9JqLr3tIYjDOZpzn+BCuxY8z8vmca43EeMgyZt7irw= +github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-chi/render v1.0.3 h1:AsXqd2a1/INaIfUSKq3G5uA8weYx20FOsM7uSoCyyt4= @@ -174,6 +175,7 @@ github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20211214055906-6f57359322fd h1:1FjCyPC+syAzJ5/2S8fqdZK1R22vvA0J7JZKcuOIQ7Y= github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -237,6 +239,8 @@ github.com/kubev2v/forklift v0.0.0-20241129095927-4890e072e015/go.mod h1:fHaGLhv github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= +github.com/leosunmo/zapchi v0.2.0 h1:BSX9FIcPbgVBgMgVBAfN0CrLWv012tjFcqSTfDDUYyY= +github.com/leosunmo/zapchi v0.2.0/go.mod h1:SWyRMhaEvYcIG1Y/6rJ3nGW7Vlz71HnNtCQlRxm5ZcA= github.com/libvirt/libvirt-go v7.4.0+incompatible h1:crnSLkwPqCdXtg6jib/FxBG/hweAc/3Wxth1AehCXL4= github.com/libvirt/libvirt-go v7.4.0+incompatible/go.mod h1:34zsnB4iGeOv7Byj6qotuW8Ya4v4Tr43ttjz/F0wjLE= github.com/lthibault/jitterbug v2.0.0+incompatible h1:qouq51IKzlMx25+15jbxhC/d79YyTj0q6XFoptNqaUw= @@ -323,6 +327,7 @@ github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSz github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -371,13 +376,17 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= @@ -385,6 +394,7 @@ golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUu golang.org/x/arch v0.4.0 h1:A8WCeEWhLwPBKNbFi5Wv5UTCBx5zzubnXDlMOFAzFMc= golang.org/x/arch v0.4.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= @@ -397,6 +407,7 @@ golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTk golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -489,6 +500,9 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -540,6 +554,7 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/djherbis/times.v1 v1.3.0 h1:uxMS4iMtH6Pwsxog094W0FYldiNnfY/xba00vq6C2+o= gopkg.in/djherbis/times.v1 v1.3.0/go.mod h1:AQlg6unIsrsCEdQYhTzERy542dz6SFdQFZFv6mUY0P8= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= @@ -567,6 +582,7 @@ gorm.io/gorm v1.25.11 h1:/Wfyg1B/je1hnDx3sMkX+gAlxrlZpn6X0BXRlwXlvHg= gorm.io/gorm v1.25.11/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= k8s.io/api v0.23.3/go.mod h1:w258XdGyvCmnBj/vGzQMj6kzdufJZVUwEM1U2fRJwSQ= k8s.io/api v0.29.7 h1:Q2/thp7YYESgy0MGzxT9RvA/6doLJHBXSFH8GGLxSbc= k8s.io/api v0.29.7/go.mod h1:mPimdbyuIjwoLtBEVIGVUYb4BKOE+44XHt/n4IqKsLA= diff --git a/internal/agent/agent.go b/internal/agent/agent.go index c3bc587..27b34f2 100644 --- a/internal/agent/agent.go +++ b/internal/agent/agent.go @@ -14,8 +14,8 @@ import ( "github.com/google/uuid" api "github.com/kubev2v/migration-planner/api/v1alpha1" "github.com/kubev2v/migration-planner/internal/agent/client" - "github.com/kubev2v/migration-planner/pkg/log" "github.com/lthibault/jitterbug" + "go.uber.org/zap" utilruntime "k8s.io/apimachinery/pkg/util/runtime" ) @@ -31,10 +31,9 @@ const ( var version string // New creates a new agent. -func New(id uuid.UUID, log *log.PrefixLogger, config *Config) *Agent { +func New(id uuid.UUID, config *Config) *Agent { return &Agent{ config: config, - log: log, healtCheckStopCh: make(chan chan any), id: id, } @@ -42,22 +41,17 @@ func New(id uuid.UUID, log *log.PrefixLogger, config *Config) *Agent { type Agent struct { config *Config - log *log.PrefixLogger server *Server healtCheckStopCh chan chan any credUrl string id uuid.UUID } -func (a *Agent) GetLogPrefix() string { - return a.log.Prefix() -} - func (a *Agent) Run(ctx context.Context) error { var err error - a.log.Infof("Starting agent: %s", version) - defer a.log.Infof("Agent stopped") - a.log.Infof("Configuration: %s", a.config.String()) + zap.S().Infof("Starting agent: %s", version) + defer zap.S().Infof("Agent stopped") + zap.S().Infof("Configuration: %s", a.config.String()) defer utilruntime.HandleCrash() @@ -77,7 +71,7 @@ func (a *Agent) Run(ctx context.Context) error { case <-ctx.Done(): } - a.log.Info("stopping agent...") + zap.S().Info("stopping agent...") a.Stop() cancel() @@ -90,40 +84,39 @@ func (a *Agent) Stop() { a.server.Stop(serverCh) <-serverCh - a.log.Info("server stopped") + zap.S().Info("server stopped") c := make(chan any) a.healtCheckStopCh <- c <-c - a.log.Info("health check stopped") + zap.S().Info("health check stopped") } func (a *Agent) start(ctx context.Context, plannerClient client.Planner) { - inventoryUpdater := NewInventoryUpdater(a.log, a.id, plannerClient) - statusUpdater := NewStatusUpdater(a.log, a.id, version, a.credUrl, a.config, plannerClient) + inventoryUpdater := NewInventoryUpdater(a.id, plannerClient) + statusUpdater := NewStatusUpdater(a.id, version, a.credUrl, a.config, plannerClient) // start server a.server = NewServer(defaultAgentPort, a.config.DataDir, a.config.WwwDir) - go a.server.Start(a.log, statusUpdater) + go a.server.Start(statusUpdater) // get the credentials url credUrl := a.initializeCredentialUrl() // start the health check healthChecker, err := NewHealthChecker( - a.log, plannerClient, a.config.DataDir, time.Duration(a.config.HealthCheckInterval*int64(time.Second)), ) if err != nil { - a.log.Fatalf("failed to start health check: %w", err) + zap.S().Fatalf("failed to start health check: %w", err) } // TODO refactor health checker to call it from the main goroutine healthChecker.Start(a.healtCheckStopCh) - collector := NewCollector(a.log, a.config.DataDir) + collector := NewCollector(a.config.DataDir) collector.collect(ctx) updateTicker := jitterbug.New(time.Duration(a.config.UpdateInterval.Duration), &jitterbug.Norm{Stdev: 30 * time.Millisecond, Mean: 0}) @@ -153,12 +146,12 @@ func (a *Agent) start(ctx context.Context, plannerClient client.Planner) { if err := statusUpdater.UpdateStatus(ctx, status, statusInfo, credUrl); err != nil { if errors.Is(err, client.ErrSourceGone) { - a.log.Info("Source is gone..Stop sending requests") + zap.S().Info("Source is gone..Stop sending requests") // stop the server and the healthchecker a.Stop() break } - a.log.Errorf("unable to update agent status: %s", err) + zap.S().Errorf("unable to update agent status: %s", err) continue // skip inventory update if we cannot update agent's state. } @@ -173,7 +166,7 @@ func (a *Agent) initializeCredentialUrl() string { // Parse the service URL parsedURL, err := url.Parse(a.config.PlannerService.Service.Server) if err != nil { - a.log.Errorf("error parsing service URL: %v", err) + zap.S().Errorf("error parsing service URL: %v", err) return "N/A" } @@ -186,14 +179,14 @@ func (a *Agent) initializeCredentialUrl() string { // Connect to service conn, err := net.Dial("tcp", fmt.Sprintf("%s:%s", parsedURL.Hostname(), port)) if err != nil { - a.log.Errorf("failed connecting to migration planner: %v", err) + zap.S().Errorf("failed connecting to migration planner: %v", err) return "N/A" } defer conn.Close() localAddr := conn.LocalAddr().(*net.TCPAddr) credUrl := fmt.Sprintf("http://%s:%d", localAddr.IP.String(), defaultAgentPort) - a.log.Infof("Discovered Agent IP address: %s", credUrl) + zap.S().Infof("Discovered Agent IP address: %s", credUrl) return credUrl } diff --git a/internal/agent/agent_test.go b/internal/agent/agent_test.go index 31a08b8..fac9a48 100644 --- a/internal/agent/agent_test.go +++ b/internal/agent/agent_test.go @@ -16,7 +16,6 @@ import ( "github.com/kubev2v/migration-planner/internal/agent" "github.com/kubev2v/migration-planner/internal/agent/client" "github.com/kubev2v/migration-planner/internal/util" - "github.com/kubev2v/migration-planner/pkg/log" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" ) @@ -27,12 +26,10 @@ var _ = Describe("Agent", func() { testHttpServer *httptest.Server agentTmpFolder string agentID uuid.UUID - logger *log.PrefixLogger endpointsCalled map[string]any ) BeforeEach(func() { - logger = log.NewPrefixLogger("") agentID, _ = uuid.NewUUID() endpointsCalled = make(map[string]any) @@ -76,7 +73,7 @@ var _ = Describe("Agent", func() { } config.PlannerService.Service.Server = testHttpServer.URL - a := agent.New(agentID, logger, &config) + a := agent.New(agentID, &config) ctx, cancel := context.WithTimeout(context.TODO(), 30*time.Second) go func() { err := a.Run(ctx) diff --git a/internal/agent/collector.go b/internal/agent/collector.go index 3bdfd10..fe37f66 100644 --- a/internal/agent/collector.go +++ b/internal/agent/collector.go @@ -22,20 +22,18 @@ import ( libmodel "github.com/konveyor/forklift-controller/pkg/lib/inventory/model" apiplanner "github.com/kubev2v/migration-planner/api/v1alpha1" "github.com/kubev2v/migration-planner/internal/util" - "github.com/kubev2v/migration-planner/pkg/log" + "go.uber.org/zap" core "k8s.io/api/core/v1" meta "k8s.io/apimachinery/pkg/apis/meta/v1" ) type Collector struct { - log *log.PrefixLogger dataDir string once sync.Once } -func NewCollector(log *log.PrefixLogger, dataDir string) *Collector { +func NewCollector(dataDir string) *Collector { return &Collector{ - log: log, dataDir: dataDir, } } @@ -58,100 +56,100 @@ func (c *Collector) collect(ctx context.Context) { func (c *Collector) run() { credentialsFilePath := filepath.Join(c.dataDir, CredentialsFile) - c.log.Infof("Waiting for credentials") + zap.S().Named("collector").Infof("Waiting for credentials") waitForFile(credentialsFilePath) credsData, err := os.ReadFile(credentialsFilePath) if err != nil { - c.log.Errorf("Error reading credentials file: %v\n", err) + zap.S().Named("collector").Errorf("Error reading credentials file: %v\n", err) return } var creds Credentials if err := json.Unmarshal(credsData, &creds); err != nil { - c.log.Errorf("Error parsing credentials JSON: %v\n", err) + zap.S().Named("collector").Errorf("Error parsing credentials JSON: %v\n", err) return } opaServer := util.GetEnv("OPA_SERVER", "127.0.0.1:8181") - c.log.Infof("Create Provider") + zap.S().Named("collector").Infof("Create Provider") provider := getProvider(creds) - c.log.Infof("Create Secret") + zap.S().Named("collector").Infof("Create Secret") secret := getSecret(creds) - c.log.Infof("Check if opaServer is responding") + zap.S().Named("collector").Infof("Check if opaServer is responding") resp, err := http.Get("http://" + opaServer + "/health") if err != nil || resp.StatusCode != http.StatusOK { - c.log.Errorf("OPA server %s is not responding", opaServer) + zap.S().Named("collector").Errorf("OPA server %s is not responding", opaServer) return } defer resp.Body.Close() - c.log.Infof("Create DB") + zap.S().Named("collector").Infof("Create DB") db, err := createDB(provider) if err != nil { - c.log.Errorf("Error creating DB: %s", err) + zap.S().Named("collector").Errorf("Error creating DB: %s", err) return } - c.log.Infof("vSphere collector") + zap.S().Named("collector").Infof("vSphere collector") collector, err := createCollector(db, provider, secret) if err != nil { - c.log.Errorf("Error running collector: %s", err) + zap.S().Named("collector").Errorf("Error running collector: %s", err) return } defer collector.DB().Close(true) defer collector.Shutdown() - c.log.Infof("List VMs") + zap.S().Named("collector").Infof("List VMs") vms := &[]vspheremodel.VM{} err = collector.DB().List(vms, libmodel.FilterOptions{Detail: 1}) if err != nil { - c.log.Errorf("Error list database: %s", err) + zap.S().Named("collector").Errorf("Error list database: %s", err) return } - c.log.Infof("List Hosts") + zap.S().Named("collector").Infof("List Hosts") hosts := &[]vspheremodel.Host{} err = collector.DB().List(hosts, libmodel.FilterOptions{Detail: 1}) if err != nil { - c.log.Errorf("Error list database: %s", err) + zap.S().Named("collector").Errorf("Error list database: %s", err) return } - c.log.Infof("List Clusters") + zap.S().Named("collector").Infof("List Clusters") clusters := &[]vspheremodel.Cluster{} err = collector.DB().List(clusters, libmodel.FilterOptions{Detail: 1}) if err != nil { - c.log.Errorf("Error list database: %s", err) + zap.S().Named("collector").Errorf("Error list database: %s", err) return } - c.log.Infof("Get About") + zap.S().Named("collector").Infof("Get About") about := &vspheremodel.About{} err = collector.DB().Get(about) if err != nil { - c.log.Errorf("Error list database about table: %s", err) + zap.S().Named("collector").Errorf("Error list database about table: %s", err) return } - c.log.Infof("Create inventory") + zap.S().Named("collector").Infof("Create inventory") inv := createBasicInventoryObj(about.InstanceUuid, vms, collector, hosts, clusters) - c.log.Infof("Run the validation of VMs") + zap.S().Named("collector").Infof("Run the validation of VMs") vms, err = validation(vms, opaServer) if err != nil { - c.log.Errorf("Error running validation: %s", err) + zap.S().Named("collector").Errorf("Error running validation: %s", err) return } - c.log.Infof("Fill the inventory object with more data") + zap.S().Named("collector").Infof("Fill the inventory object with more data") fillInventoryObjectWithMoreData(vms, inv) - c.log.Infof("Write the inventory to output file") + zap.S().Named("collector").Infof("Write the inventory to output file") if err := createOuput(filepath.Join(c.dataDir, InventoryFile), inv); err != nil { - c.log.Errorf("Fill the inventory object with more data: %s", err) + zap.S().Named("collector").Errorf("Fill the inventory object with more data: %s", err) return } } diff --git a/internal/agent/fileserver.go b/internal/agent/fileserver.go index 900b014..9af2a55 100644 --- a/internal/agent/fileserver.go +++ b/internal/agent/fileserver.go @@ -7,28 +7,28 @@ import ( "github.com/go-chi/chi" "github.com/kubev2v/migration-planner/internal/agent/fileio" - "github.com/kubev2v/migration-planner/pkg/log" + "go.uber.org/zap" ) -func RegisterFileServer(router *chi.Mux, log *log.PrefixLogger, wwwDir string) { +func RegisterFileServer(router *chi.Mux, wwwDir string) { fs := http.FileServer(http.Dir(wwwDir)) - router.Get("/login", handleGetLogin(log, wwwDir)) + router.Get("/login", handleGetLogin(wwwDir)) router.Method("GET", "/*", fs) } -func handleGetLogin(log *log.PrefixLogger, wwwDir string) http.HandlerFunc { +func handleGetLogin(wwwDir string) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { pathToIndeHtml := filepath.Join(wwwDir, "index.html") file, err := fileio.NewReader().ReadFile(pathToIndeHtml) if err != nil { - log.Warnf("Failed reading %s", pathToIndeHtml) + zap.S().Named("handler_get_login").Warnf("Failed reading %s", pathToIndeHtml) } w.Header().Set("Content-Type", "text/html") w.Header().Set("Content-Length", strconv.Itoa(len(file))) if _, err := w.Write(file); err != nil { - log.Warnf("Failed writing the content of %s", pathToIndeHtml) + zap.S().Named("handler_get_login").Warnf("Failed writing the content of %s", pathToIndeHtml) } } } diff --git a/internal/agent/health.go b/internal/agent/health.go index 1e879ca..6b8a2ee 100644 --- a/internal/agent/health.go +++ b/internal/agent/health.go @@ -9,7 +9,7 @@ import ( "time" "github.com/kubev2v/migration-planner/internal/agent/client" - "github.com/kubev2v/migration-planner/pkg/log" + "go.uber.org/zap" ) type AgentHealthState int @@ -29,10 +29,9 @@ type HealthChecker struct { client client.Planner logFilepath string logFile *os.File - logger *log.PrefixLogger } -func NewHealthChecker(log *log.PrefixLogger, client client.Planner, logFolder string, checkInterval time.Duration) (*HealthChecker, error) { +func NewHealthChecker(client client.Planner, logFolder string, checkInterval time.Duration) (*HealthChecker, error) { logFile := path.Join(logFolder, logFilename) // check if we can write into the log file _, err := os.Stat(logFolder) @@ -59,7 +58,6 @@ func NewHealthChecker(log *log.PrefixLogger, client client.Planner, logFolder st client: client, logFilepath: logFile, logFile: f, - logger: log, }, nil } @@ -89,10 +87,10 @@ func (h *HealthChecker) Start(closeCh chan chan any) { select { case c := <-closeCh: if err := h.logFile.Sync(); err != nil { - h.logger.Errorf("failed to flush the log file %w", err) + zap.S().Named("health").Errorf("failed to flush the log file %w", err) } if err := h.logFile.Close(); err != nil { - h.logger.Errorf("failed to close log file %s %w", h.logFilepath, err) + zap.S().Named("health").Errorf("failed to close log file %s %w", h.logFilepath, err) } c <- struct{}{} close(c) @@ -118,7 +116,7 @@ func (h *HealthChecker) do() { err := h.client.Health(ctx) if err != nil { if _, err := h.logFile.Write([]byte(fmt.Sprintf("[%s] console.redhat.com is unreachable.\n", time.Now().Format(time.RFC3339)))); err != nil { - h.logger.Errorf("failed to write to log file %s %w", h.logFilepath, err) + zap.S().Named("health").Errorf("failed to write to log file %s %w", h.logFilepath, err) } h.lock.Lock() h.state = HealthCheckStateConsoleUnreachable @@ -128,7 +126,7 @@ func (h *HealthChecker) do() { // if state changed from unreachable to ok log the entry if h.state == HealthCheckStateConsoleUnreachable { if _, err := h.logFile.Write([]byte(fmt.Sprintf("[%s] console.redhat.com is OK.\n", time.Now().Format(time.RFC3339)))); err != nil { - h.logger.Errorf("failed to write to log file %s %w", h.logFilepath, err) + zap.S().Named("health").Errorf("failed to write to log file %s %w", h.logFilepath, err) } } h.lock.Lock() diff --git a/internal/agent/health_test.go b/internal/agent/health_test.go index fd55580..e765797 100644 --- a/internal/agent/health_test.go +++ b/internal/agent/health_test.go @@ -10,7 +10,6 @@ import ( "github.com/google/uuid" api "github.com/kubev2v/migration-planner/api/v1alpha1/agent" - "github.com/kubev2v/migration-planner/pkg/log" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" ) @@ -21,7 +20,7 @@ var _ = Describe("Health checker", func() { tmpDir, err := os.MkdirTemp("", "health") Expect(err).To(BeNil()) - healthChecker, err := NewHealthChecker(log.NewPrefixLogger(""), nil, tmpDir, 0) + healthChecker, err := NewHealthChecker(nil, tmpDir, 0) Expect(err).To(BeNil()) Expect(healthChecker.logFilepath).To(Equal(path.Join(tmpDir, "health.log"))) @@ -31,7 +30,7 @@ var _ = Describe("Health checker", func() { }) It("should fail -- log folder missing", func() { - _, err := NewHealthChecker(log.NewPrefixLogger(""), nil, "some_unknown_folder", 0) + _, err := NewHealthChecker(nil, "some_unknown_folder", 0) Expect(err).NotTo(BeNil()) }) }) @@ -49,7 +48,7 @@ var _ = Describe("Health checker", func() { testClient = &agentTestClient{} - hc, err = NewHealthChecker(log.NewPrefixLogger(""), testClient, tmpDir, 2*time.Second) + hc, err = NewHealthChecker(testClient, tmpDir, 2*time.Second) Expect(err).To(BeNil()) }) @@ -129,7 +128,7 @@ var _ = Describe("Health checker", func() { testClient = &agentTestClient{} - hc, err = NewHealthChecker(log.NewPrefixLogger(""), testClient, tmpDir, 1*time.Second) + hc, err = NewHealthChecker(testClient, tmpDir, 1*time.Second) Expect(err).To(BeNil()) }) diff --git a/internal/agent/inventory.go b/internal/agent/inventory.go index 7042394..4233336 100644 --- a/internal/agent/inventory.go +++ b/internal/agent/inventory.go @@ -9,11 +9,10 @@ import ( api "github.com/kubev2v/migration-planner/api/v1alpha1" agentapi "github.com/kubev2v/migration-planner/api/v1alpha1/agent" "github.com/kubev2v/migration-planner/internal/agent/client" - "github.com/kubev2v/migration-planner/pkg/log" + "go.uber.org/zap" ) type InventoryUpdater struct { - log *log.PrefixLogger client client.Planner agentID uuid.UUID prevStatus []byte @@ -24,9 +23,8 @@ type InventoryData struct { Error string `json:"error"` } -func NewInventoryUpdater(log *log.PrefixLogger, agentID uuid.UUID, client client.Planner) *InventoryUpdater { +func NewInventoryUpdater(agentID uuid.UUID, client client.Planner) *InventoryUpdater { updater := &InventoryUpdater{ - log: log, client: client, agentID: agentID, prevStatus: []byte{}, @@ -42,16 +40,16 @@ func (u *InventoryUpdater) UpdateServiceWithInventory(ctx context.Context, inven newContents, err := json.Marshal(update) if err != nil { - u.log.Errorf("failed marshalling new status: %v", err) + zap.S().Named("inventory").Errorf("failed marshalling new status: %v", err) } if bytes.Equal(u.prevStatus, newContents) { - u.log.Debug("Local status did not change, skipping service update") + zap.S().Named("inventory").Debug("Local status did not change, skipping service update") return } err = u.client.UpdateSourceStatus(ctx, uuid.MustParse(inventory.Vcenter.Id), update) if err != nil { - u.log.Errorf("failed updating status: %v", err) + zap.S().Named("inventory").Errorf("failed updating status: %v", err) return } diff --git a/internal/agent/inventory_test.go b/internal/agent/inventory_test.go index e772bbd..6154548 100644 --- a/internal/agent/inventory_test.go +++ b/internal/agent/inventory_test.go @@ -8,7 +8,6 @@ import ( v1alpha1 "github.com/kubev2v/migration-planner/api/v1alpha1/agent" "github.com/kubev2v/migration-planner/internal/agent" "github.com/kubev2v/migration-planner/internal/agent/client" - "github.com/kubev2v/migration-planner/pkg/log" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" ) @@ -39,7 +38,7 @@ var _ = Describe("Inventory", func() { Vms: api.VMs{Total: 2}, Vcenter: api.VCenter{Id: sourceID.String()}, } - inventoryUpdater := agent.NewInventoryUpdater(log.NewPrefixLogger(""), agentID, &client) + inventoryUpdater := agent.NewInventoryUpdater(agentID, &client) inventoryUpdater.UpdateServiceWithInventory(context.TODO(), inventory) }) }) diff --git a/internal/agent/rest.go b/internal/agent/rest.go index 6659b7f..20bf4ec 100644 --- a/internal/agent/rest.go +++ b/internal/agent/rest.go @@ -14,11 +14,11 @@ import ( "github.com/go-chi/render" liberr "github.com/konveyor/forklift-controller/pkg/lib/error" "github.com/kubev2v/migration-planner/internal/agent/fileio" - "github.com/kubev2v/migration-planner/pkg/log" "github.com/vmware/govmomi" "github.com/vmware/govmomi/session" "github.com/vmware/govmomi/vim25" "github.com/vmware/govmomi/vim25/soap" + "go.uber.org/zap" ) const ( @@ -26,7 +26,7 @@ const ( CredentialsFile = "credentials.json" ) -func RegisterApi(router *chi.Mux, log *log.PrefixLogger, statusUpdater *StatusUpdater, dataDir string) { +func RegisterApi(router *chi.Mux, statusUpdater *StatusUpdater, dataDir string) { router.Get("/api/v1/version", func(w http.ResponseWriter, r *http.Request) { _ = render.Render(w, r, VersionReply{Version: version}) }) @@ -35,7 +35,7 @@ func RegisterApi(router *chi.Mux, log *log.PrefixLogger, statusUpdater *StatusUp _ = render.Render(w, r, StatusReply{Status: string(status), StatusInfo: statusInfo}) }) router.Put("/api/v1/credentials", func(w http.ResponseWriter, r *http.Request) { - credentialHandler(log, dataDir, w, r) + credentialHandler(dataDir, w, r) }) } @@ -63,7 +63,7 @@ type Credentials struct { IsDataSharingAllowed bool `json:"isDataSharingAllowed"` } -func credentialHandler(log *log.PrefixLogger, dataDir string, w http.ResponseWriter, r *http.Request) { +func credentialHandler(dataDir string, w http.ResponseWriter, r *http.Request) { credentials := &Credentials{} err := json.NewDecoder(r.Body).Decode(credentials) @@ -77,8 +77,8 @@ func credentialHandler(log *log.PrefixLogger, dataDir string, w http.ResponseWri return } - log.Info("received credentials") - status, err := testVmwareConnection(r.Context(), log, credentials) + zap.S().Named("rest").Info("received credentials") + status, err := testVmwareConnection(r.Context(), credentials) if err != nil { http.Error(w, err.Error(), status) return @@ -94,7 +94,7 @@ func credentialHandler(log *log.PrefixLogger, dataDir string, w http.ResponseWri return } - log.Info("successfully wrote credentials to file") + zap.S().Named("rest").Info("successfully wrote credentials to file") w.WriteHeader(http.StatusNoContent) } @@ -111,7 +111,7 @@ func parseUrl(credentials *Credentials) (*url.URL, error) { return u, nil } -func testVmwareConnection(requestCtx context.Context, log *log.PrefixLogger, credentials *Credentials) (status int, err error) { +func testVmwareConnection(requestCtx context.Context, credentials *Credentials) (status int, err error) { u, err := parseUrl(credentials) if err != nil { return http.StatusUnprocessableEntity, liberr.Wrap(err) @@ -127,7 +127,7 @@ func testVmwareConnection(requestCtx context.Context, log *log.PrefixLogger, cre SessionManager: session.NewManager(vimClient), Client: vimClient, } - log.Info("logging into vmware using received credentials") + zap.S().Named("rest").Info("logging into vmware using received credentials") err = client.Login(ctx, u.User) if err != nil { err = liberr.Wrap(err) diff --git a/internal/agent/server.go b/internal/agent/server.go index e9fd52c..4f4a7f3 100644 --- a/internal/agent/server.go +++ b/internal/agent/server.go @@ -8,7 +8,7 @@ import ( "github.com/go-chi/chi" "github.com/go-chi/chi/middleware" - "github.com/kubev2v/migration-planner/pkg/log" + "go.uber.org/zap" ) /* @@ -22,7 +22,6 @@ type Server struct { dataFolder string wwwFolder string restServer *http.Server - log *log.PrefixLogger } func NewServer(port int, dataFolder, wwwFolder string) *Server { @@ -33,21 +32,20 @@ func NewServer(port int, dataFolder, wwwFolder string) *Server { } } -func (s *Server) Start(log *log.PrefixLogger, statusUpdater *StatusUpdater) { +func (s *Server) Start(statusUpdater *StatusUpdater) { router := chi.NewRouter() router.Use(middleware.RequestID) router.Use(middleware.Logger) - RegisterFileServer(router, log, s.wwwFolder) - RegisterApi(router, log, statusUpdater, s.dataFolder) + RegisterFileServer(router, s.wwwFolder) + RegisterApi(router, statusUpdater, s.dataFolder) s.restServer = &http.Server{Addr: fmt.Sprintf("0.0.0.0:%d", s.port), Handler: router} // Run the server - s.log = log err := s.restServer.ListenAndServe() if err != nil && err != http.ErrServerClosed { - s.log.Fatalf("failed to start server: %w", err) + zap.S().Named("server").Fatalf("failed to start server: %w", err) } } @@ -58,7 +56,7 @@ func (s *Server) Stop(stopCh chan any) { go func() { err := s.restServer.Shutdown(shutdownCtx) if err != nil { - s.log.Errorf("failed to graceful shutdown the server: %s", err) + zap.S().Named("server").Errorf("failed to graceful shutdown the server: %s", err) } close(doneCh) }() diff --git a/internal/agent/status.go b/internal/agent/status.go index b0d1b90..a038499 100644 --- a/internal/agent/status.go +++ b/internal/agent/status.go @@ -12,7 +12,6 @@ import ( agentapi "github.com/kubev2v/migration-planner/api/v1alpha1/agent" "github.com/kubev2v/migration-planner/internal/agent/client" "github.com/kubev2v/migration-planner/internal/agent/fileio" - "github.com/kubev2v/migration-planner/pkg/log" ) const ( @@ -21,16 +20,14 @@ const ( type StatusUpdater struct { agentID uuid.UUID - log *log.PrefixLogger version string config *Config client client.Planner credUrl string } -func NewStatusUpdater(log *log.PrefixLogger, agentID uuid.UUID, version, credUrl string, config *Config, client client.Planner) *StatusUpdater { +func NewStatusUpdater(agentID uuid.UUID, version, credUrl string, config *Config, client client.Planner) *StatusUpdater { return &StatusUpdater{ - log: log, client: client, config: config, agentID: agentID, diff --git a/internal/agent/status_test.go b/internal/agent/status_test.go index 98f125e..2e9f18c 100644 --- a/internal/agent/status_test.go +++ b/internal/agent/status_test.go @@ -10,7 +10,6 @@ import ( v1alpha1 "github.com/kubev2v/migration-planner/api/v1alpha1/agent" "github.com/kubev2v/migration-planner/internal/agent" "github.com/kubev2v/migration-planner/internal/agent/client" - "github.com/kubev2v/migration-planner/pkg/log" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" ) @@ -40,7 +39,7 @@ var _ = Describe("Status", func() { }, } - statusUpdater := agent.NewStatusUpdater(log.NewPrefixLogger(""), agentID, "best_version", "www-cred-url", &agent.Config{}, &client) + statusUpdater := agent.NewStatusUpdater(agentID, "best_version", "www-cred-url", &agent.Config{}, &client) Expect(statusUpdater.UpdateStatus(context.TODO(), api.AgentStatusUpToDate, "status_info", "www-cred-url")) }) }) @@ -61,7 +60,7 @@ var _ = Describe("Status", func() { }) It("compute status returns Waiting for credentials", func() { - statusUpdater := agent.NewStatusUpdater(log.NewPrefixLogger(""), + statusUpdater := agent.NewStatusUpdater( agentID, "best_version", "www-cred-url", @@ -83,7 +82,7 @@ var _ = Describe("Status", func() { Expect(err).To(BeNil()) creds.Close() - statusUpdater := agent.NewStatusUpdater(log.NewPrefixLogger(""), + statusUpdater := agent.NewStatusUpdater( agentID, "best_version", "www-cred-url", @@ -111,7 +110,7 @@ var _ = Describe("Status", func() { _, err = inventoryFile.Write([]byte("{\"inventory\": {}, \"error\": \"\"}")) Expect(err).To(BeNil()) - statusUpdater := agent.NewStatusUpdater(log.NewPrefixLogger(""), + statusUpdater := agent.NewStatusUpdater( agentID, "best_version", "www-cred-url", diff --git a/internal/api_server/agentserver/server.go b/internal/api_server/agentserver/server.go index 92a3858..7b5ca47 100644 --- a/internal/api_server/agentserver/server.go +++ b/internal/api_server/agentserver/server.go @@ -15,8 +15,9 @@ import ( "github.com/kubev2v/migration-planner/internal/config" service "github.com/kubev2v/migration-planner/internal/service/agent" "github.com/kubev2v/migration-planner/internal/store" + "github.com/leosunmo/zapchi" oapimiddleware "github.com/oapi-codegen/nethttp-middleware" - "github.com/sirupsen/logrus" + "go.uber.org/zap" ) const ( @@ -24,7 +25,6 @@ const ( ) type AgentServer struct { - log logrus.FieldLogger cfg *config.Config store store.Store listener net.Listener @@ -32,13 +32,11 @@ type AgentServer struct { // New returns a new instance of a migration-planner server. func New( - log logrus.FieldLogger, cfg *config.Config, store store.Store, listener net.Listener, ) *AgentServer { return &AgentServer{ - log: log, cfg: cfg, store: store, listener: listener, @@ -50,7 +48,7 @@ func oapiErrorHandler(w http.ResponseWriter, message string, statusCode int) { } func (s *AgentServer) Run(ctx context.Context) error { - s.log.Println("Initializing Agent-side API server") + zap.S().Named("agent_server").Info("Initializing Agent-side API server") swagger, err := api.GetSwagger() if err != nil { return fmt.Errorf("failed loading swagger spec: %w", err) @@ -65,18 +63,18 @@ func (s *AgentServer) Run(ctx context.Context) error { router := chi.NewRouter() router.Use( middleware.RequestID, - middleware.Logger, + zapchi.Logger(zap.S(), "router_agent"), middleware.Recoverer, oapimiddleware.OapiRequestValidatorWithOptions(swagger, &oapiOpts), ) - h := service.NewAgentServiceHandler(s.store, s.log) + h := service.NewAgentServiceHandler(s.store) server.HandlerFromMux(server.NewStrictHandler(h, nil), router) srv := http.Server{Addr: s.cfg.Service.Address, Handler: router} go func() { <-ctx.Done() - s.log.Println("Shutdown signal received:", ctx.Err()) + zap.S().Named("agent_server").Infof("Shutdown signal received: %s", ctx.Err()) ctxTimeout, cancel := context.WithTimeout(context.Background(), gracefulShutdownTimeout) defer cancel() @@ -84,7 +82,7 @@ func (s *AgentServer) Run(ctx context.Context) error { _ = srv.Shutdown(ctxTimeout) }() - s.log.Printf("Listening on %s...", s.listener.Addr().String()) + zap.S().Named("agent_server").Infof("Listening on %s...", s.listener.Addr().String()) if err := srv.Serve(s.listener); err != nil && !errors.Is(err, net.ErrClosed) { return err } diff --git a/internal/api_server/server.go b/internal/api_server/server.go index 49d2958..58e5488 100644 --- a/internal/api_server/server.go +++ b/internal/api_server/server.go @@ -16,8 +16,9 @@ import ( "github.com/kubev2v/migration-planner/internal/image" "github.com/kubev2v/migration-planner/internal/service" "github.com/kubev2v/migration-planner/internal/store" + "github.com/leosunmo/zapchi" oapimiddleware "github.com/oapi-codegen/nethttp-middleware" - "github.com/sirupsen/logrus" + "go.uber.org/zap" ) const ( @@ -25,7 +26,6 @@ const ( ) type Server struct { - log logrus.FieldLogger cfg *config.Config store store.Store listener net.Listener @@ -33,13 +33,11 @@ type Server struct { // New returns a new instance of a migration-planner server. func New( - log logrus.FieldLogger, cfg *config.Config, store store.Store, listener net.Listener, ) *Server { return &Server{ - log: log, cfg: cfg, store: store, listener: listener, @@ -61,7 +59,7 @@ func withResponseWriter(next http.Handler) http.Handler { } func (s *Server) Run(ctx context.Context) error { - s.log.Println("Initializing API server") + zap.S().Named("api_server").Info("Initializing API server") swagger, err := api.GetSwagger() if err != nil { return fmt.Errorf("failed loading swagger spec: %w", err) @@ -76,19 +74,19 @@ func (s *Server) Run(ctx context.Context) error { router := chi.NewRouter() router.Use( middleware.RequestID, - middleware.Logger, + zapchi.Logger(zap.S(), "router_api"), middleware.Recoverer, oapimiddleware.OapiRequestValidatorWithOptions(swagger, &oapiOpts), withResponseWriter, ) - h := service.NewServiceHandler(s.store, s.log) + h := service.NewServiceHandler(s.store) server.HandlerFromMux(server.NewStrictHandler(h, nil), router) srv := http.Server{Addr: s.cfg.Service.Address, Handler: router} go func() { <-ctx.Done() - s.log.Println("Shutdown signal received:", ctx.Err()) + zap.S().Named("api_server").Infof("Shutdown signal received: %s", ctx.Err()) ctxTimeout, cancel := context.WithTimeout(context.Background(), gracefulShutdownTimeout) defer cancel() @@ -96,7 +94,7 @@ func (s *Server) Run(ctx context.Context) error { _ = srv.Shutdown(ctxTimeout) }() - s.log.Printf("Listening on %s...", s.listener.Addr().String()) + zap.S().Named("api_server").Infof("Listening on %s...", s.listener.Addr().String()) if err := srv.Serve(s.listener); err != nil && !errors.Is(err, net.ErrClosed) { return err } diff --git a/internal/service/agent/handler.go b/internal/service/agent/handler.go index 1c29289..2db5aac 100644 --- a/internal/service/agent/handler.go +++ b/internal/service/agent/handler.go @@ -6,21 +6,19 @@ import ( agentServer "github.com/kubev2v/migration-planner/internal/api/server/agent" "github.com/kubev2v/migration-planner/internal/store" - "github.com/sirupsen/logrus" + "go.uber.org/zap" ) type AgentServiceHandler struct { store store.Store - log logrus.FieldLogger } // Make sure we conform to servers Service interface var _ agentServer.Service = (*AgentServiceHandler)(nil) -func NewAgentServiceHandler(store store.Store, log logrus.FieldLogger) *AgentServiceHandler { +func NewAgentServiceHandler(store store.Store) *AgentServiceHandler { return &AgentServiceHandler{ store: store, - log: log, } } @@ -66,7 +64,7 @@ func (h *AgentServiceHandler) ReplaceSourceStatus(ctx context.Context, request a // We are not allowing updates from agents not associated with the source ("first come first serve"). if !agent.Associated { - h.log.Errorf("Failed to update status of source %s from agent %s. Agent is not the associated with the source", source.Id, agent.Id) + zap.S().Errorf("Failed to update status of source %s from agent %s. Agent is not the associated with the source", source.Id, agent.Id) if _, err := store.Commit(ctx); err != nil { return agentServer.ReplaceSourceStatus500JSONResponse{}, nil } diff --git a/internal/service/agent/handler_test.go b/internal/service/agent/handler_test.go index f0d7c03..f4b9b09 100644 --- a/internal/service/agent/handler_test.go +++ b/internal/service/agent/handler_test.go @@ -15,7 +15,6 @@ import ( "github.com/kubev2v/migration-planner/internal/store" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/sirupsen/logrus" "gorm.io/gorm" ) @@ -33,11 +32,10 @@ var _ = Describe("agent store", Ordered, func() { ) BeforeAll(func() { - log := logrus.New() - db, err := store.InitDB(config.NewDefault(), log) + db, err := store.InitDB(config.NewDefault()) Expect(err).To(BeNil()) - s = store.NewStore(db, log) + s = store.NewStore(db) gormdb = db _ = s.InitialMigration() }) @@ -50,7 +48,7 @@ var _ = Describe("agent store", Ordered, func() { It("successfully creates the agent", func() { agentID := uuid.New() - srv := service.NewAgentServiceHandler(s, logrus.New()) + srv := service.NewAgentServiceHandler(s) resp, err := srv.UpdateAgentStatus(context.TODO(), server.UpdateAgentStatusRequestObject{ Id: agentID, Body: &apiAgent.UpdateAgentStatusJSONRequestBody{ @@ -80,7 +78,7 @@ var _ = Describe("agent store", Ordered, func() { tx := gormdb.Exec(fmt.Sprintf(insertAgentStm, agentID, "not-connected", "status-info-1", "cred_url-1")) Expect(tx.Error).To(BeNil()) - srv := service.NewAgentServiceHandler(s, logrus.New()) + srv := service.NewAgentServiceHandler(s) resp, err := srv.UpdateAgentStatus(context.TODO(), server.UpdateAgentStatusRequestObject{ Id: agentID, Body: &apiAgent.UpdateAgentStatusJSONRequestBody{ @@ -110,7 +108,7 @@ var _ = Describe("agent store", Ordered, func() { tx := gormdb.Exec(fmt.Sprintf(insertAgentWithDeletedAtStm, agentID, "not-connected", "status-info-1", "cred_url-1", time.Now().Format(time.RFC3339), time.Now().Format(time.RFC3339), time.Now().Format(time.RFC3339))) Expect(tx.Error).To(BeNil()) - srv := service.NewAgentServiceHandler(s, logrus.New()) + srv := service.NewAgentServiceHandler(s) resp, err := srv.UpdateAgentStatus(context.TODO(), server.UpdateAgentStatusRequestObject{ Id: agentID, Body: &apiAgent.UpdateAgentStatusJSONRequestBody{ @@ -137,7 +135,7 @@ var _ = Describe("agent store", Ordered, func() { Expect(tx.Error).To(BeNil()) sourceID := uuid.New() - srv := service.NewAgentServiceHandler(s, logrus.New()) + srv := service.NewAgentServiceHandler(s) resp, err := srv.ReplaceSourceStatus(context.TODO(), server.ReplaceSourceStatusRequestObject{ Id: sourceID, Body: &apiAgent.SourceStatusUpdate{ @@ -167,7 +165,7 @@ var _ = Describe("agent store", Ordered, func() { Expect(tx.Error).To(BeNil()) sourceID := uuid.New() - srv := service.NewAgentServiceHandler(s, logrus.New()) + srv := service.NewAgentServiceHandler(s) resp, err := srv.ReplaceSourceStatus(context.TODO(), server.ReplaceSourceStatusRequestObject{ Id: sourceID, Body: &apiAgent.SourceStatusUpdate{ @@ -190,7 +188,7 @@ var _ = Describe("agent store", Ordered, func() { Expect(*source.Agents).To(HaveLen(1)) Expect((*source.Agents)[0].Id).To(Equal(agentID)) - // make another request from another agent + // make another request from another agent secondAgentID := uuid.New() tx = gormdb.Exec(fmt.Sprintf(insertAgentStm, secondAgentID, "not-connected", "status-info-1", "cred_url-1")) Expect(tx.Error).To(BeNil()) diff --git a/internal/service/agent_test.go b/internal/service/agent_test.go index bb86564..42d20cd 100644 --- a/internal/service/agent_test.go +++ b/internal/service/agent_test.go @@ -12,7 +12,6 @@ import ( "github.com/kubev2v/migration-planner/internal/store" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/sirupsen/logrus" "gorm.io/gorm" ) @@ -28,11 +27,10 @@ var _ = Describe("agent handler", Ordered, func() { ) BeforeAll(func() { - log := logrus.New() - db, err := store.InitDB(config.NewDefault(), log) + db, err := store.InitDB(config.NewDefault()) Expect(err).To(BeNil()) - s = store.NewStore(db, log) + s = store.NewStore(db) gormdb = db _ = s.InitialMigration() }) @@ -48,7 +46,7 @@ var _ = Describe("agent handler", Ordered, func() { tx = gormdb.Exec(fmt.Sprintf(insertAgentStm, "agent-2", "not-connected", "status-info-2", "cred_url-2")) Expect(tx.Error).To(BeNil()) - srv := service.NewServiceHandler(s, logrus.New()) + srv := service.NewServiceHandler(s) resp, err := srv.ListAgents(context.TODO(), server.ListAgentsRequestObject{}) Expect(err).To(BeNil()) Expect(reflect.TypeOf(resp)).To(Equal(reflect.TypeOf(server.ListAgents200JSONResponse{}))) @@ -66,7 +64,7 @@ var _ = Describe("agent handler", Ordered, func() { tx := gormdb.Exec(fmt.Sprintf(insertAgentStm, agentID, "not-connected", "status-info-1", "cred_url-1")) Expect(tx.Error).To(BeNil()) - srv := service.NewServiceHandler(s, logrus.New()) + srv := service.NewServiceHandler(s) resp, err := srv.DeleteAgent(context.TODO(), server.DeleteAgentRequestObject{Id: agentID}) Expect(err).To(BeNil()) Expect(reflect.TypeOf(resp)).To(Equal(reflect.TypeOf(server.DeleteAgent200JSONResponse{}))) @@ -81,7 +79,7 @@ var _ = Describe("agent handler", Ordered, func() { tx := gormdb.Exec(fmt.Sprintf(insertAgentStm, agentID, "not-connected", "status-info-1", "cred_url-1")) Expect(tx.Error).To(BeNil()) - srv := service.NewServiceHandler(s, logrus.New()) + srv := service.NewServiceHandler(s) resp, err := srv.DeleteAgent(context.TODO(), server.DeleteAgentRequestObject{Id: uuid.New()}) Expect(err).To(BeNil()) Expect(reflect.TypeOf(resp)).To(Equal(reflect.TypeOf(server.DeleteAgent404JSONResponse{}))) @@ -92,7 +90,7 @@ var _ = Describe("agent handler", Ordered, func() { tx := gormdb.Exec(fmt.Sprintf(insertAssociatedAgentStm, agentID)) Expect(tx.Error).To(BeNil()) - srv := service.NewServiceHandler(s, logrus.New()) + srv := service.NewServiceHandler(s) resp, err := srv.DeleteAgent(context.TODO(), server.DeleteAgentRequestObject{Id: agentID}) Expect(err).To(BeNil()) Expect(reflect.TypeOf(resp)).To(Equal(reflect.TypeOf(server.DeleteAgent400JSONResponse{}))) diff --git a/internal/service/handler.go b/internal/service/handler.go index 1f7f3cc..b2b9a4b 100644 --- a/internal/service/handler.go +++ b/internal/service/handler.go @@ -3,20 +3,17 @@ package service import ( "github.com/kubev2v/migration-planner/internal/api/server" "github.com/kubev2v/migration-planner/internal/store" - "github.com/sirupsen/logrus" ) type ServiceHandler struct { store store.Store - log logrus.FieldLogger } // Make sure we conform to servers Service interface var _ server.Service = (*ServiceHandler)(nil) -func NewServiceHandler(store store.Store, log logrus.FieldLogger) *ServiceHandler { +func NewServiceHandler(store store.Store) *ServiceHandler { return &ServiceHandler{ store: store, - log: log, } } diff --git a/internal/service/source_test.go b/internal/service/source_test.go index 3b9a1bd..3f71b76 100644 --- a/internal/service/source_test.go +++ b/internal/service/source_test.go @@ -12,7 +12,6 @@ import ( "github.com/kubev2v/migration-planner/internal/store" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/sirupsen/logrus" "gorm.io/gorm" ) @@ -28,11 +27,10 @@ var _ = Describe("source handler", Ordered, func() { ) BeforeAll(func() { - log := logrus.New() - db, err := store.InitDB(config.NewDefault(), log) + db, err := store.InitDB(config.NewDefault()) Expect(err).To(BeNil()) - s = store.NewStore(db, log) + s = store.NewStore(db) gormdb = db _ = s.InitialMigration() }) @@ -48,7 +46,7 @@ var _ = Describe("source handler", Ordered, func() { tx = gormdb.Exec(fmt.Sprintf(insertSourceStm, uuid.NewString())) Expect(tx.Error).To(BeNil()) - srv := service.NewServiceHandler(s, logrus.New()) + srv := service.NewServiceHandler(s) resp, err := srv.ListSources(context.TODO(), server.ListSourcesRequestObject{}) Expect(err).To(BeNil()) Expect(reflect.TypeOf(resp)).To(Equal(reflect.TypeOf(server.ListSources200JSONResponse{}))) @@ -69,7 +67,7 @@ var _ = Describe("source handler", Ordered, func() { tx = gormdb.Exec(fmt.Sprintf(insertSourceStm, uuid.NewString())) Expect(tx.Error).To(BeNil()) - srv := service.NewServiceHandler(s, logrus.New()) + srv := service.NewServiceHandler(s) resp, err := srv.ReadSource(context.TODO(), server.ReadSourceRequestObject{Id: firstSource}) Expect(err).To(BeNil()) Expect(reflect.TypeOf(resp)).To(Equal(reflect.TypeOf(server.ReadSource200JSONResponse{}))) @@ -81,7 +79,7 @@ var _ = Describe("source handler", Ordered, func() { tx = gormdb.Exec(fmt.Sprintf(insertSourceStm, uuid.NewString())) Expect(tx.Error).To(BeNil()) - srv := service.NewServiceHandler(s, logrus.New()) + srv := service.NewServiceHandler(s) resp, err := srv.ReadSource(context.TODO(), server.ReadSourceRequestObject{Id: uuid.New()}) Expect(err).To(BeNil()) Expect(reflect.TypeOf(resp)).To(Equal(reflect.TypeOf(server.ReadSource404JSONResponse{}))) @@ -100,7 +98,7 @@ var _ = Describe("source handler", Ordered, func() { tx = gormdb.Exec(fmt.Sprintf(insertSourceStm, uuid.NewString())) Expect(tx.Error).To(BeNil()) - srv := service.NewServiceHandler(s, logrus.New()) + srv := service.NewServiceHandler(s) _, err := srv.DeleteSources(context.TODO(), server.DeleteSourcesRequestObject{}) Expect(err).To(BeNil()) @@ -119,7 +117,7 @@ var _ = Describe("source handler", Ordered, func() { tx = gormdb.Exec(fmt.Sprintf(insertAgentWithSourceStm, agent.String(), source.String())) Expect(tx.Error).To(BeNil()) - srv := service.NewServiceHandler(s, logrus.New()) + srv := service.NewServiceHandler(s) _, err := srv.DeleteSource(context.TODO(), server.DeleteSourceRequestObject{Id: source}) Expect(err).To(BeNil()) diff --git a/internal/store/agent.go b/internal/store/agent.go index b9f6e93..6c5a67f 100644 --- a/internal/store/agent.go +++ b/internal/store/agent.go @@ -7,7 +7,7 @@ import ( api "github.com/kubev2v/migration-planner/api/v1alpha1" apiAgent "github.com/kubev2v/migration-planner/api/v1alpha1/agent" "github.com/kubev2v/migration-planner/internal/store/model" - "github.com/sirupsen/logrus" + "go.uber.org/zap" "gorm.io/gorm" "gorm.io/gorm/clause" ) @@ -32,12 +32,11 @@ type Agent interface { } type AgentStore struct { - db *gorm.DB - log logrus.FieldLogger + db *gorm.DB } -func NewAgentSource(db *gorm.DB, log logrus.FieldLogger) Agent { - return &AgentStore{db: db, log: log} +func NewAgentSource(db *gorm.DB) Agent { + return &AgentStore{db: db} } func (a *AgentStore) InitialMigration(ctx context.Context) error { @@ -143,7 +142,7 @@ func (a *AgentStore) Delete(ctx context.Context, id string, softDeletion bool) e } result := tx.Delete(&agent) if result.Error != nil && !errors.Is(result.Error, gorm.ErrRecordNotFound) { - a.log.Infof("ERROR: %v", result.Error) + zap.S().Named("agent_store").Infof("ERROR: %v", result.Error) return result.Error } return nil diff --git a/internal/store/agent_test.go b/internal/store/agent_test.go index e1c36d5..5994913 100644 --- a/internal/store/agent_test.go +++ b/internal/store/agent_test.go @@ -10,7 +10,6 @@ import ( "github.com/kubev2v/migration-planner/internal/store" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/sirupsen/logrus" "gorm.io/gorm" ) @@ -28,11 +27,10 @@ var _ = Describe("agent store", Ordered, func() { ) BeforeAll(func() { - log := logrus.New() - db, err := store.InitDB(config.NewDefault(), log) + db, err := store.InitDB(config.NewDefault()) Expect(err).To(BeNil()) - s = store.NewStore(db, log) + s = store.NewStore(db) gormdb = db }) diff --git a/internal/store/gorm.go b/internal/store/gorm.go index 36a135d..a91ccf9 100644 --- a/internal/store/gorm.go +++ b/internal/store/gorm.go @@ -6,14 +6,14 @@ import ( "github.com/kubev2v/migration-planner/internal/config" "github.com/sirupsen/logrus" + "go.uber.org/zap" "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/gorm" "gorm.io/gorm/logger" - "k8s.io/klog/v2" ) -func InitDB(cfg *config.Config, log *logrus.Logger) (*gorm.DB, error) { +func InitDB(cfg *config.Config) (*gorm.DB, error) { var dia gorm.Dialector if cfg.Database.Type == "pgsql" { @@ -32,7 +32,7 @@ func InitDB(cfg *config.Config, log *logrus.Logger) (*gorm.DB, error) { } newLogger := logger.New( - log, + logrus.New(), logger.Config{ SlowThreshold: time.Second, // Slow SQL threshold LogLevel: logger.Warn, // Log level @@ -44,13 +44,13 @@ func InitDB(cfg *config.Config, log *logrus.Logger) (*gorm.DB, error) { newDB, err := gorm.Open(dia, &gorm.Config{Logger: newLogger, TranslateError: true}) if err != nil { - klog.Fatalf("failed to connect database: %v", err) + zap.S().Named("gorm").Fatalf("failed to connect database: %v", err) return nil, err } sqlDB, err := newDB.DB() if err != nil { - klog.Fatalf("failed to configure connections: %v", err) + zap.S().Named("gorm").Fatalf("failed to configure connections: %v", err) return nil, err } sqlDB.SetMaxIdleConns(10) @@ -59,11 +59,11 @@ func InitDB(cfg *config.Config, log *logrus.Logger) (*gorm.DB, error) { if cfg.Database.Type == "pgsql" { var minorVersion string if result := newDB.Raw("SELECT version()").Scan(&minorVersion); result.Error != nil { - klog.Infoln(result.Error.Error()) + zap.S().Named("gorm").Infoln(result.Error.Error()) return nil, result.Error } - klog.Infof("PostgreSQL information: '%s'", minorVersion) + zap.S().Named("gorm").Infof("PostgreSQL information: '%s'", minorVersion) } return newDB, nil diff --git a/internal/store/source.go b/internal/store/source.go index 11ee6ab..09ba02d 100644 --- a/internal/store/source.go +++ b/internal/store/source.go @@ -7,7 +7,7 @@ import ( "github.com/google/uuid" api "github.com/kubev2v/migration-planner/api/v1alpha1" "github.com/kubev2v/migration-planner/internal/store/model" - "github.com/sirupsen/logrus" + "go.uber.org/zap" "gorm.io/gorm" "gorm.io/gorm/clause" ) @@ -27,15 +27,14 @@ type Source interface { } type SourceStore struct { - db *gorm.DB - log logrus.FieldLogger + db *gorm.DB } // Make sure we conform to Source interface var _ Source = (*SourceStore)(nil) -func NewSource(db *gorm.DB, log logrus.FieldLogger) Source { - return &SourceStore{db: db, log: log} +func NewSource(db *gorm.DB) Source { + return &SourceStore{db: db} } func (s *SourceStore) InitialMigration(ctx context.Context) error { @@ -83,7 +82,7 @@ func (s *SourceStore) Delete(ctx context.Context, id uuid.UUID) error { source := model.NewSourceFromId(id) result := s.getDB(ctx).Unscoped().Delete(&source) if result.Error != nil && !errors.Is(result.Error, gorm.ErrRecordNotFound) { - s.log.Infof("ERROR: %v", result.Error) + zap.S().Named("source_store").Infof("ERROR: %v", result.Error) return result.Error } return nil diff --git a/internal/store/source_test.go b/internal/store/source_test.go index e18de28..4f32457 100644 --- a/internal/store/source_test.go +++ b/internal/store/source_test.go @@ -9,7 +9,6 @@ import ( "github.com/kubev2v/migration-planner/internal/store" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/sirupsen/logrus" "gorm.io/gorm" ) @@ -24,11 +23,10 @@ var _ = Describe("source store", Ordered, func() { ) BeforeAll(func() { - log := logrus.New() - db, err := store.InitDB(config.NewDefault(), log) + db, err := store.InitDB(config.NewDefault()) Expect(err).To(BeNil()) - s = store.NewStore(db, log) + s = store.NewStore(db) gormdb = db }) diff --git a/internal/store/store.go b/internal/store/store.go index cfdc3f8..547dca0 100644 --- a/internal/store/store.go +++ b/internal/store/store.go @@ -3,7 +3,6 @@ package store import ( "context" - "github.com/sirupsen/logrus" "gorm.io/gorm" ) @@ -19,20 +18,18 @@ type DataStore struct { agent Agent db *gorm.DB source Source - log logrus.FieldLogger } -func NewStore(db *gorm.DB, log logrus.FieldLogger) Store { +func NewStore(db *gorm.DB) Store { return &DataStore{ - agent: NewAgentSource(db, log), - source: NewSource(db, log), + agent: NewAgentSource(db), + source: NewSource(db), db: db, - log: log, } } func (s *DataStore) NewTransactionContext(ctx context.Context) (context.Context, error) { - return newTransactionContext(ctx, s.db, s.log) + return newTransactionContext(ctx, s.db) } func (s *DataStore) Source() Source { diff --git a/internal/store/store_test.go b/internal/store/store_test.go index 0b9f8fb..04743d3 100644 --- a/internal/store/store_test.go +++ b/internal/store/store_test.go @@ -6,7 +6,6 @@ import ( "github.com/google/uuid" "github.com/kubev2v/migration-planner/internal/config" st "github.com/kubev2v/migration-planner/internal/store" - "github.com/kubev2v/migration-planner/pkg/log" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "gorm.io/gorm" @@ -19,13 +18,12 @@ var _ = Describe("Store", Ordered, func() { ) BeforeAll(func() { - log := log.InitLogs() cfg := config.NewDefault() - db, err := st.InitDB(cfg, log) + db, err := st.InitDB(cfg) Expect(err).To(BeNil()) gormDB = db - store = st.NewStore(db, log.WithField("test", "store")) + store = st.NewStore(db) Expect(store).ToNot(BeNil()) }) diff --git a/internal/store/transaction.go b/internal/store/transaction.go index 859fdc3..3f31182 100644 --- a/internal/store/transaction.go +++ b/internal/store/transaction.go @@ -4,7 +4,7 @@ import ( "context" "errors" - "github.com/sirupsen/logrus" + "go.uber.org/zap" "gorm.io/gorm" ) @@ -17,7 +17,6 @@ const ( type Tx struct { txId int64 tx *gorm.DB - log logrus.FieldLogger } func Commit(ctx context.Context) (context.Context, error) { @@ -49,7 +48,7 @@ func FromContext(ctx context.Context) *gorm.DB { return nil } -func newTransactionContext(ctx context.Context, db *gorm.DB, log logrus.FieldLogger) (context.Context, error) { +func newTransactionContext(ctx context.Context, db *gorm.DB) (context.Context, error) { //look into the context to see if we have another tx _, found := ctx.Value(transactionKey).(*Tx) if found { @@ -61,7 +60,7 @@ func newTransactionContext(ctx context.Context, db *gorm.DB, log logrus.FieldLog Context: ctx, }) - tx, err := newTransaction(conn, log) + tx, err := newTransaction(conn) if err != nil { return ctx, err } @@ -70,7 +69,7 @@ func newTransactionContext(ctx context.Context, db *gorm.DB, log logrus.FieldLog return ctx, nil } -func newTransaction(db *gorm.DB, log logrus.FieldLogger) (*Tx, error) { +func newTransaction(db *gorm.DB) (*Tx, error) { // must call begin on 'db', which is Gorm. tx := db.Begin() if tx.Error != nil { @@ -85,7 +84,6 @@ func newTransaction(db *gorm.DB, log logrus.FieldLogger) (*Tx, error) { return &Tx{ txId: txid.ID, tx: tx, - log: log, }, nil } @@ -102,10 +100,10 @@ func (t *Tx) Commit() error { } if err := t.tx.Commit().Error; err != nil { - t.log.Errorf("failed to commit transaction %d: %w", t.txId, err) + zap.S().Named("transaction").Errorf("failed to commit transaction %d: %w", t.txId, err) return err } - t.log.Debugf("transaction %d commited", t.txId) + zap.S().Named("transaction").Debugf("transaction %d commited", t.txId) t.tx = nil // in case we call commit twice return nil } @@ -116,11 +114,11 @@ func (t *Tx) Rollback() error { } if err := t.tx.Rollback().Error; err != nil { - t.log.Errorf("failed to rollback transaction %d: %w", t.txId, err) + zap.S().Named("transaction").Errorf("failed to rollback transaction %d: %w", t.txId, err) return err } t.tx = nil // in case we call commit twice - t.log.Debugf("transaction %d rollback", t.txId) + zap.S().Named("transaction").Debugf("transaction %d rollback", t.txId) return nil } diff --git a/pkg/log/log.go b/pkg/log/log.go index 7354ea5..f8c7e9b 100644 --- a/pkg/log/log.go +++ b/pkg/log/log.go @@ -1,102 +1,33 @@ package log import ( - "context" - - "github.com/go-chi/chi/v5/middleware" - "github.com/sirupsen/logrus" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" ) -func InitLogs() *logrus.Logger { - log := logrus.New() - - log.SetReportCaller(true) - - return log -} - -// WithReqIDFromCtx create logger with request id from the context, request id is set by middleware.RequestID -func WithReqIDFromCtx(ctx context.Context, inner logrus.FieldLogger) logrus.FieldLogger { - return inner.WithField("request_id", middleware.GetReqID(ctx)) -} - -func WithReqID(reqID string, inner logrus.FieldLogger) logrus.FieldLogger { - return inner.WithField("request_id", reqID) -} - -// PrefixLogger is wrapper around a logrus with an optional prefix -type PrefixLogger struct { - logger *logrus.Logger - prefix string -} - -// NewPrefixLogger creates a new PrefixLogger -func NewPrefixLogger(prefix string) *PrefixLogger { - logger := logrus.New() - logger.SetReportCaller(true) - - return &PrefixLogger{ - logger: logger, - prefix: prefix, +func InitLog(lvl zap.AtomicLevel) *zap.Logger { + loggerCfg := &zap.Config{ + Level: lvl, + Encoding: "console", + EncoderConfig: zapcore.EncoderConfig{ + TimeKey: "time", + LevelKey: "severity", + NameKey: "logger", + CallerKey: "caller", + MessageKey: "message", + StacktraceKey: "stacktrace", + LineEnding: zapcore.DefaultLineEnding, + EncodeTime: zapcore.RFC3339TimeEncoder, + EncodeLevel: zapcore.LowercaseLevelEncoder, + EncodeDuration: zapcore.MillisDurationEncoder, EncodeCaller: zapcore.ShortCallerEncoder}, + OutputPaths: []string{"stdout"}, + ErrorOutputPaths: []string{"stderr"}, } -} - -func (p *PrefixLogger) Info(args ...interface{}) { - p.logger.Info(p.prependPrefix(args[0].(string))) -} - -func (p *PrefixLogger) Infof(format string, args ...interface{}) { - p.logger.Infof(p.prependPrefix(format), args...) -} - -func (p *PrefixLogger) Error(args ...interface{}) { - p.logger.Error(p.prependPrefix(args[0].(string))) -} -func (p *PrefixLogger) Errorf(format string, args ...interface{}) { - p.logger.Errorf(p.prependPrefix(format), args...) -} - -func (p *PrefixLogger) Debug(args ...interface{}) { - p.logger.Debug(p.prependPrefix(args[0].(string))) -} - -func (p *PrefixLogger) Debugf(format string, args ...interface{}) { - p.logger.Debugf(p.prependPrefix(format), args...) -} - -func (p *PrefixLogger) Warn(args ...interface{}) { - p.logger.Warn(p.prependPrefix(args[0].(string))) -} - -func (p *PrefixLogger) Warnf(format string, args ...interface{}) { - p.logger.Warnf(p.prependPrefix(format), args...) -} - -func (p *PrefixLogger) Fatal(args ...interface{}) { - p.logger.Fatal(p.prependPrefix(args[0].(string))) -} - -func (p *PrefixLogger) Fatalf(format string, args ...interface{}) { - p.logger.Fatalf(p.prependPrefix(format), args...) -} - -func (p *PrefixLogger) SetLevel(level string) { - parsedLevel, err := logrus.ParseLevel(level) + plain, err := loggerCfg.Build(zap.AddStacktrace(zap.DPanicLevel)) if err != nil { - parsedLevel = logrus.InfoLevel + panic(err) } - p.logger.SetLevel(parsedLevel) -} - -func (p *PrefixLogger) Prefix() string { - return p.prefix -} -// prependPrefix checks if a prefix is set and prepends it to the message -func (p *PrefixLogger) prependPrefix(msg string) string { - if p.prefix != "" { - return p.prefix + ": " + msg - } - return msg + return plain }