From f9fd734760b1233f80de4240932fb8a31d31b4b4 Mon Sep 17 00:00:00 2001 From: hainenber Date: Sun, 16 Aug 2026 17:54:01 +0700 Subject: [PATCH] refactor: replace external `sirupsen/logrus` with built-in `log/slog` for logging Signed-off-by: hainenber --- .../license/LICENSE-WITH-3RD-PARTY-LICENSES | 24 ----- actor/sharedaction/logging.go | 4 +- actor/sharedaction/resource.go | 88 +++++++------------ actor/sharedaction/sharedaction_suite_test.go | 7 +- actor/v7action/build.go | 7 +- actor/v7action/package.go | 7 +- actor/v7action/process_summary.go | 7 +- actor/v7action/resource_match.go | 12 +-- actor/v7action/task.go | 7 +- actor/v7action/v7action_suite_test.go | 7 +- actor/v7pushaction/actualize.go | 8 +- .../create_bits_package_for_application.go | 8 +- actor/v7pushaction/restart_application.go | 6 +- .../set_default_bits_path_for_push_plan.go | 5 +- actor/v7pushaction/stop_application.go | 5 +- actor/v7pushaction/v7pushaction_suite_test.go | 9 +- cf/commands/commands_suite_test.go | 9 +- command/command_suite_test.go | 10 ++- command/common/common_suite_test.go | 9 +- command/common/install_plugin_command.go | 30 +++---- command/minimum_version_check.go | 11 +-- .../convert_to_translatable_error.go | 4 +- command/v7/env_command.go | 6 +- command/v7/push_command.go | 26 +++--- command/v7/shared/app_summary_displayer.go | 6 +- command/v7/v7_suite_test.go | 8 +- go.mod | 1 - go.sum | 2 - util/clissh/ssh.go | 12 +-- util/clissh/ssh_suite_test.go | 10 +-- util/command_parser/command_parser.go | 7 +- util/command_parser/parser_suite_test.go | 9 +- util/progressbar/progress_bar.go | 6 +- util/ui/i18n.go | 4 +- 34 files changed, 166 insertions(+), 215 deletions(-) diff --git a/.github/license/LICENSE-WITH-3RD-PARTY-LICENSES b/.github/license/LICENSE-WITH-3RD-PARTY-LICENSES index d8ce5236b07..30f695f1430 100644 --- a/.github/license/LICENSE-WITH-3RD-PARTY-LICENSES +++ b/.github/license/LICENSE-WITH-3RD-PARTY-LICENSES @@ -791,30 +791,6 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -For vendor/github.com/sirupsen/logrus: - -The MIT License (MIT) - -Copyright (c) 2014 Simon Eskildsen - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - For vendor/github.com/lunixbochs/vtclean: diff --git a/actor/sharedaction/logging.go b/actor/sharedaction/logging.go index bb1cb095bdf..53b9cd0c90a 100644 --- a/actor/sharedaction/logging.go +++ b/actor/sharedaction/logging.go @@ -5,13 +5,13 @@ import ( "errors" "fmt" "log" + "log/slog" "strings" "time" logcache "code.cloudfoundry.org/go-log-cache/v2" "code.cloudfoundry.org/go-log-cache/v2/rpc/logcache_v1" "code.cloudfoundry.org/go-loggregator/v9/rpc/loggregator_v2" - "github.com/sirupsen/logrus" ) const ( @@ -123,7 +123,7 @@ func (b *cliRetryBackoff) Reset() { func GetStreamingLogs(appGUID string, client LogCacheClient) (<-chan LogMessage, <-chan error, context.CancelFunc) { - logrus.Info("Start Tailing Logs") + slog.Info("Start Tailing Logs") outgoingLogStream := make(chan LogMessage, 1000) outgoingErrStream := make(chan error, 1000) diff --git a/actor/sharedaction/resource.go b/actor/sharedaction/resource.go index de0d5f16f59..0fd0a4b289d 100644 --- a/actor/sharedaction/resource.go +++ b/actor/sharedaction/resource.go @@ -5,6 +5,7 @@ import ( "crypto/sha1" "fmt" "io" + "log/slog" "os" "path/filepath" "strings" @@ -14,7 +15,6 @@ import ( "code.cloudfoundry.org/cli/v9/actor/actionerror" "code.cloudfoundry.org/ykk" ignore "github.com/sabhiram/go-gitignore" - log "github.com/sirupsen/logrus" ) const ( @@ -81,7 +81,7 @@ func (actor Actor) GatherArchiveResources(archivePath string) ([]Resource, error gitIgnore, err := actor.generateArchiveCFIgnoreMatcher(reader.File) if err != nil { - log.Errorln("reading .cfignore file:", err) + slog.Error("reading .cfignore file", "err", err) return nil, err } @@ -135,13 +135,13 @@ func (actor Actor) GatherDirectoryResources(sourceDir string) ([]Resource, error gitIgnore, err := actor.generateDirectoryCFIgnoreMatcher(sourceDir) if err != nil { - log.Errorln("reading .cfignore file:", err) + slog.Error("reading .cfignore file", "err", err) return nil, err } evalDir, err := filepath.EvalSymlinks(sourceDir) if err != nil { - log.Errorln("evaluating symlink:", err) + slog.Error("evaluating symlink", "err", err) return nil, err } @@ -212,7 +212,7 @@ func (actor Actor) GatherDirectoryResources(sourceDir string) ([]Resource, error // path/filename) list of resources and returns the location. On Windows, the // filemode for user is forced to be readable and executable. func (actor Actor) ZipArchiveResources(sourceArchivePath string, filesToInclude []Resource) (string, error) { - log.WithField("sourceArchive", sourceArchivePath).Info("zipping source files from archive") + slog.Info("zipping source files from archive", "sourceArchive", sourceArchivePath) zipFile, err := os.CreateTemp("", "cf-cli-") if err != nil { return "", err @@ -237,15 +237,15 @@ func (actor Actor) ZipArchiveResources(sourceArchivePath string, filesToInclude for _, archiveFile := range reader.File { resource, ok := actor.findInResources(archiveFile.Name, filesToInclude) if !ok { - log.WithField("archiveFileName", archiveFile.Name).Debug("skipping file") + slog.Debug("skipping file", "archiveFileName", archiveFile.Name) continue } - log.WithField("archiveFileName", archiveFile.Name).Debug("zipping file") + slog.Debug("zipping file", "archiveFileName", archiveFile.Name) // archiveFile.Open opens the symlink file, not the file it points too reader, openErr := archiveFile.Open() if openErr != nil { - log.WithField("archiveFile", archiveFile.Name).Errorln("opening path in dir:", openErr) + slog.Error("opening path in dir", "archiveFile", archiveFile.Name, "err", openErr) return zipPath, openErr } defer reader.Close() @@ -255,16 +255,13 @@ func (actor Actor) ZipArchiveResources(sourceArchivePath string, filesToInclude resource, writer, ) if err != nil { - log.WithField("archiveFileName", archiveFile.Name).Errorln("zipping file:", err) + slog.Error("zipping file", "archiveFileName", archiveFile.Name, "err", err) return zipPath, err } reader.Close() } - log.WithFields(log.Fields{ - "zip_file_location": zipFile.Name(), - "zipped_file_count": len(filesToInclude), - }).Info("zip file created") + slog.Info("zip file created", "zip_file_location", zipFile.Name(), "zipped_file_count", len(filesToInclude)) return zipPath, nil } @@ -272,7 +269,7 @@ func (actor Actor) ZipArchiveResources(sourceArchivePath string, filesToInclude // path/filename) list of resources and returns the location. On Windows, the // filemode for user is forced to be readable and executable. func (actor Actor) ZipDirectoryResources(sourceDir string, filesToInclude []Resource) (string, error) { - log.WithField("sourceDir", sourceDir).Info("zipping source files from directory") + slog.Info("zipping source files from directory", "sourceDir", sourceDir) zipFile, err := os.CreateTemp("", "cf-cli-") if err != nil { return "", err @@ -285,26 +282,26 @@ func (actor Actor) ZipDirectoryResources(sourceDir string, filesToInclude []Reso for _, resource := range filesToInclude { fullPath := filepath.Join(sourceDir, resource.Filename) - log.WithField("fullPath", fullPath).Debug("zipping file") + slog.Debug("zipping file", "fullPath", fullPath) fileInfo, err := os.Lstat(fullPath) if err != nil { - log.WithField("fullPath", fullPath).Errorln("stat error in dir:", err) + slog.Error("stat error in dir", "fullPath", fullPath, "err", err) return zipPath, err } - log.WithField("file-mode", fileInfo.Mode().String()).Debug("resource file info") + slog.Debug("resource file info", "file-mode", fileInfo.Mode().String()) if fileInfo.Mode()&os.ModeSymlink == os.ModeSymlink { // we need to user os.Readlink to read a symlink file from a directory err = actor.addLinkToZipFromFileSystem(fullPath, fileInfo, resource, writer) if err != nil { - log.WithField("fullPath", fullPath).Errorln("zipping file:", err) + slog.Error("zipping file", "fullPath", fullPath, "err", err) return zipPath, err } } else { srcFile, err := os.Open(fullPath) if err != nil { - log.WithField("fullPath", fullPath).Errorln("opening path in dir:", err) + slog.Error("opening path in dir", "fullPath", fullPath, "err", err) return zipPath, err } defer srcFile.Close() @@ -315,16 +312,13 @@ func (actor Actor) ZipDirectoryResources(sourceDir string, filesToInclude []Reso ) srcFile.Close() if err != nil { - log.WithField("fullPath", fullPath).Errorln("zipping file:", err) + slog.Error("zipping file", "fullPath", fullPath, "err", err) return zipPath, err } } } - log.WithFields(log.Fields{ - "zip_file_location": zipFile.Name(), - "zipped_file_count": len(filesToInclude), - }).Info("zip file created") + slog.Info("zip file created", "zip_file_location", zipFile.Name(), "zipped_file_count", len(filesToInclude)) return zipPath, nil } @@ -334,22 +328,18 @@ func (Actor) addLinkToZipFromFileSystem(srcPath string, ) error { header, err := zip.FileInfoHeader(fileInfo) if err != nil { - log.WithField("srcPath", srcPath).Errorln("getting file info in dir:", err) + slog.Error("getting file info in dir", "srcPath", srcPath, "err", err) return err } header.Name = resource.Filename header.Method = zip.Deflate - log.WithFields(log.Fields{ - "srcPath": srcPath, - "destPath": header.Name, - "mode": header.Mode().String(), - }).Debug("setting mode for file") + slog.Debug("setting mode for file", "srcPath", srcPath, "destPath", header.Name, "mode", header.Mode().String()) destFileWriter, err := zipFile.CreateHeader(header) if err != nil { - log.Errorln("creating header:", err) + slog.Error("creating header", "err", err) return err } @@ -357,10 +347,10 @@ func (Actor) addLinkToZipFromFileSystem(srcPath string, if err != nil { return err } - log.WithField("path", pathInSymlink).Debug("resolving symlink") + slog.Debug("resolving symlink", "path", pathInSymlink) symLinkContents := strings.NewReader(pathInSymlink) if _, err := io.Copy(destFileWriter, symLinkContents); err != nil { - log.WithField("srcPath", srcPath).Errorln("copying data in dir:", err) + slog.Error("copying data in dir", "srcPath", srcPath, "err", err) return err } @@ -373,7 +363,7 @@ func (Actor) addFileToZipFromFileSystem(srcPath string, ) error { header, err := zip.FileInfoHeader(fileInfo) if err != nil { - log.WithField("srcPath", srcPath).Errorln("getting file info in dir:", err) + slog.Error("getting file info in dir", "srcPath", srcPath, "err", err) return err } @@ -386,15 +376,11 @@ func (Actor) addFileToZipFromFileSystem(srcPath string, header.Method = zip.Deflate header.SetMode(resource.Mode) - log.WithFields(log.Fields{ - "srcPath": srcPath, - "destPath": header.Name, - "mode": header.Mode().String(), - }).Debug("setting mode for file") + slog.Debug("setting mode for file", "srcPath", srcPath, "destPath", header.Name, "mode", header.Mode().String()) destFileWriter, err := zipFile.CreateHeader(header) if err != nil { - log.Errorln("creating header:", err) + slog.Error("creating header", "err", err) return err } @@ -403,15 +389,12 @@ func (Actor) addFileToZipFromFileSystem(srcPath string, multi := io.MultiWriter(sum, destFileWriter) if _, err := io.Copy(multi, srcFile); err != nil { - log.WithField("srcPath", srcPath).Errorln("copying data in dir:", err) + slog.Error("copying data in dir", "srcPath", srcPath, "err", err) return err } if currentSum := fmt.Sprintf("%x", sum.Sum(nil)); resource.SHA1 != currentSum { - log.WithFields(log.Fields{ - "expected": resource.SHA1, - "currentSum": currentSum, - }).Error("setting mode for file") + slog.Error("setting mode for file", "expected", resource.SHA1, "currentSum", currentSum) return actionerror.FileChangedError{Filename: srcPath} } } else if fileInfo.Mode()&os.ModeSymlink == os.ModeSymlink { @@ -446,10 +429,7 @@ func (Actor) generateArchiveCFIgnoreMatcher(files []*zip.File) (*ignore.GitIgnor func (actor Actor) generateDirectoryCFIgnoreMatcher(sourceDir string) (*ignore.GitIgnore, error) { pathToCFIgnore := filepath.Join(sourceDir, ".cfignore") - log.WithFields(log.Fields{ - "pathToCFIgnore": pathToCFIgnore, - "sourceDir": sourceDir, - }).Debug("using ignore file") + slog.Debug("using ignore file", "pathToCFIgnore", pathToCFIgnore, "sourceDir", sourceDir) additionalIgnoreLines := DefaultIgnoreLines @@ -461,7 +441,7 @@ func (actor Actor) generateDirectoryCFIgnoreMatcher(sourceDir string) (*ignore.G } } - log.Debugf("ignore rules: %v", additionalIgnoreLines) + slog.Debug("ignore rules", "rules", additionalIgnoreLines) if _, err := os.Stat(pathToCFIgnore); !os.IsNotExist(err) { return ignore.CompileIgnoreFileAndLines(pathToCFIgnore, additionalIgnoreLines...) @@ -472,12 +452,12 @@ func (actor Actor) generateDirectoryCFIgnoreMatcher(sourceDir string) (*ignore.G func (Actor) findInResources(path string, filesToInclude []Resource) (Resource, bool) { for _, resource := range filesToInclude { if resource.Filename == filepath.ToSlash(path) { - log.WithField("resource", resource.Filename).Debug("found resource in files to include") + slog.Debug("found resource in files to include", "resource", resource.Filename) return resource, true } } - log.WithField("path", path).Debug("did not find resource in files to include") + slog.Debug("did not find resource in files to include", "path", path) return Resource{}, false } @@ -500,14 +480,14 @@ func (actor Actor) CreateArchive(bitsPath string, resources []Resource) (io.Read func (Actor) ReadArchive(archivePath string) (io.ReadCloser, int64, error) { archive, err := os.Open(archivePath) if err != nil { - log.WithField("archivePath", archivePath).Errorln("opening temp archive:", err) + slog.Error("opening temp archive", "archivePath", archivePath, "err", err) return nil, -1, err } archiveInfo, err := archive.Stat() if err != nil { archive.Close() - log.WithField("archivePath", archivePath).Errorln("stat temp archive:", err) + slog.Error("stat temp archive", "archivePath", archivePath, "err", err) return nil, -1, err } diff --git a/actor/sharedaction/sharedaction_suite_test.go b/actor/sharedaction/sharedaction_suite_test.go index 022001ef6e1..b3bb83e900f 100644 --- a/actor/sharedaction/sharedaction_suite_test.go +++ b/actor/sharedaction/sharedaction_suite_test.go @@ -3,6 +3,7 @@ package sharedaction_test import ( "archive/zip" "io" + "log/slog" "os" "path/filepath" "strings" @@ -10,7 +11,6 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - log "github.com/sirupsen/logrus" ) func TestSharedAction(t *testing.T) { @@ -18,8 +18,9 @@ func TestSharedAction(t *testing.T) { RunSpecs(t, "Shared Actions Suite") } -var _ = BeforeEach(func() { - log.SetLevel(log.PanicLevel) +var _ = BeforeSuite(func() { + // Suppress log output during tests. This equates with setting to panic-level severity in older logging libraries + slog.SetDefault(slog.New(slog.NewTextHandler(io.Discard, nil))) }) // Thanks to Svett Ralchev diff --git a/actor/v7action/build.go b/actor/v7action/build.go index 6a7f36c9a4c..c465ca19d85 100644 --- a/actor/v7action/build.go +++ b/actor/v7action/build.go @@ -2,6 +2,7 @@ package v7action import ( "errors" + "log/slog" "strings" "time" @@ -9,8 +10,6 @@ import ( "code.cloudfoundry.org/cli/v9/api/cloudcontroller/ccv3" "code.cloudfoundry.org/cli/v9/api/cloudcontroller/ccv3/constant" "code.cloudfoundry.org/cli/v9/resources" - - log "github.com/sirupsen/logrus" ) func (actor Actor) StagePackage(packageGUID, appName, spaceGUID string) (<-chan resources.Droplet, <-chan Warnings, <-chan error) { @@ -119,13 +118,13 @@ func (actor Actor) StageApplicationPackage(packageGUID string) (resources.Build, build := resources.Build{PackageGUID: packageGUID} build, warnings, err := actor.CloudControllerClient.CreateBuild(build) - log.Debug("created build") + slog.Debug("created build") allWarnings = append(allWarnings, warnings...) if err != nil { return resources.Build{}, allWarnings, err } - log.Debug("no errors creating build") + slog.Debug("no errors creating build") return resources.Build{GUID: build.GUID}, allWarnings, nil } diff --git a/actor/v7action/package.go b/actor/v7action/package.go index 86d728a492b..2a2d138bc00 100644 --- a/actor/v7action/package.go +++ b/actor/v7action/package.go @@ -2,6 +2,7 @@ package v7action import ( "io" + "log/slog" "os" "time" @@ -10,7 +11,6 @@ import ( "code.cloudfoundry.org/cli/v9/api/cloudcontroller/ccv3" "code.cloudfoundry.org/cli/v9/api/cloudcontroller/ccv3/constant" "code.cloudfoundry.org/cli/v9/resources" - log "github.com/sirupsen/logrus" ) const ( @@ -207,10 +207,7 @@ func (actor Actor) PollPackage(pkg resources.Package) (resources.Package, Warnin for pkg.State != constant.PackageReady && pkg.State != constant.PackageFailed && pkg.State != constant.PackageExpired { time.Sleep(actor.Config.PollingInterval()) ccPkg, warnings, err := actor.CloudControllerClient.GetPackage(pkg.GUID) - log.WithFields(log.Fields{ - "package_guid": pkg.GUID, - "state": pkg.State, - }).Debug("polling package state") + slog.Debug("polling package state", "package_guid", pkg.GUID, "state", pkg.State) allWarnings = append(allWarnings, warnings...) if err != nil { diff --git a/actor/v7action/process_summary.go b/actor/v7action/process_summary.go index 0b381d13d97..53eba1484fb 100644 --- a/actor/v7action/process_summary.go +++ b/actor/v7action/process_summary.go @@ -2,12 +2,12 @@ package v7action import ( "fmt" + "log/slog" "sort" "strings" "code.cloudfoundry.org/cli/v9/api/cloudcontroller/ccv3/constant" "code.cloudfoundry.org/cli/v9/resources" - log "github.com/sirupsen/logrus" ) // ProcessSummary represents a process with instance details. @@ -73,10 +73,7 @@ func (ps ProcessSummaries) String() string { } func (actor Actor) getProcessSummariesForApp(appGUID string, withObfuscatedValues bool) (ProcessSummaries, Warnings, error) { - log.WithFields(log.Fields{ - "appGUID": appGUID, - "withObfuscatedValues": withObfuscatedValues, - }).Info("retrieving process information") + slog.Info("retrieving process information", "appGUID", appGUID, "withObfuscatedValues", withObfuscatedValues) ccv3Processes, warnings, err := actor.CloudControllerClient.GetApplicationProcesses(appGUID) allWarnings := Warnings(warnings) diff --git a/actor/v7action/resource_match.go b/actor/v7action/resource_match.go index 6f8cc944456..76deb37e629 100644 --- a/actor/v7action/resource_match.go +++ b/actor/v7action/resource_match.go @@ -1,19 +1,17 @@ package v7action import ( + "log/slog" + "code.cloudfoundry.org/cli/v9/actor/sharedaction" "code.cloudfoundry.org/cli/v9/api/cloudcontroller/ccv3" "code.cloudfoundry.org/cli/v9/api/cloudcontroller/ccv3/constant" - log "github.com/sirupsen/logrus" ) func (actor Actor) ResourceMatch(resources []sharedaction.V3Resource) ([]sharedaction.V3Resource, Warnings, error) { resourceChunks := actor.chunkResources(resources) - log.WithFields(log.Fields{ - "total_resources": len(resources), - "chunks": len(resourceChunks), - }).Debug("sending resource match stats") + slog.Debug("sending resource match stats", "total_resources", len(resources), "chunks", len(resourceChunks)) var ( allWarnings Warnings @@ -36,9 +34,7 @@ func (actor Actor) ResourceMatch(resources []sharedaction.V3Resource) ([]shareda matchedResources = append(matchedResources, sharedaction.V3Resource(resource)) } - log.WithFields(log.Fields{ - "matchedResources": len(matchedResources), - }).Debug("number of resources matched by CC") + slog.Debug("number of resources matched by CC", "matchedResources", len(matchedResources)) return matchedResources, allWarnings, nil } diff --git a/actor/v7action/task.go b/actor/v7action/task.go index 981543f7a90..e70da38713c 100644 --- a/actor/v7action/task.go +++ b/actor/v7action/task.go @@ -1,6 +1,7 @@ package v7action import ( + "log/slog" "sort" "strconv" "time" @@ -10,7 +11,6 @@ import ( "code.cloudfoundry.org/cli/v9/api/cloudcontroller/ccv3" "code.cloudfoundry.org/cli/v9/api/cloudcontroller/ccv3/constant" "code.cloudfoundry.org/cli/v9/resources" - log "github.com/sirupsen/logrus" ) // Run resources.Task runs the provided command in the application environment associated @@ -80,10 +80,7 @@ func (actor Actor) PollTask(task resources.Task) (resources.Task, Warnings, erro time.Sleep(actor.Config.PollingInterval()) ccTask, warnings, err := actor.CloudControllerClient.GetTask(task.GUID) - log.WithFields(log.Fields{ - "task_guid": task.GUID, - "state": task.State, - }).Debug("polling task state") + slog.Debug("polling task state", "task_guid", task.GUID, "state", task.State) allWarnings = append(allWarnings, warnings...) diff --git a/actor/v7action/v7action_suite_test.go b/actor/v7action/v7action_suite_test.go index 2bd6dcc6b8c..afe00680ff2 100644 --- a/actor/v7action/v7action_suite_test.go +++ b/actor/v7action/v7action_suite_test.go @@ -3,6 +3,7 @@ package v7action_test import ( "archive/zip" "io" + "log/slog" "os" "path/filepath" "strings" @@ -14,7 +15,6 @@ import ( "code.cloudfoundry.org/clock/fakeclock" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - log "github.com/sirupsen/logrus" ) func TestV3Action(t *testing.T) { @@ -22,8 +22,9 @@ func TestV3Action(t *testing.T) { RunSpecs(t, "V7 Actions Suite") } -var _ = BeforeEach(func() { - log.SetLevel(log.PanicLevel) +var _ = BeforeSuite(func() { + // Suppress log output during tests. This equates with setting to panic-level severity in older logging libraries + slog.SetDefault(slog.New(slog.NewTextHandler(io.Discard, nil))) }) func NewTestActor() (*Actor, *v7actionfakes.FakeCloudControllerClient, *v7actionfakes.FakeConfig, *v7actionfakes.FakeSharedActor, *v7actionfakes.FakeUAAClient, *v7actionfakes.FakeRoutingClient, *fakeclock.FakeClock) { diff --git a/actor/v7pushaction/actualize.go b/actor/v7pushaction/actualize.go index 601775064c9..35d7e5a7a88 100644 --- a/actor/v7pushaction/actualize.go +++ b/actor/v7pushaction/actualize.go @@ -1,15 +1,15 @@ package v7pushaction import ( - log "github.com/sirupsen/logrus" + "log/slog" ) func (actor Actor) Actualize(plan PushPlan, progressBar ProgressBar) <-chan *PushEvent { - log.Debugln("Starting to Actualize Push plan:", plan) + slog.Debug("Starting to Actualize Push plan", "plan", plan) eventStream := make(chan *PushEvent) go func() { - log.Debug("starting actualize go routine") + slog.Debug("starting actualize go routine") defer close(eventStream) var err error @@ -22,7 +22,7 @@ func (actor Actor) Actualize(plan PushPlan, progressBar ProgressBar) <-chan *Pus } } - log.Debug("completed apply") + slog.Debug("completed apply") }() return eventStream diff --git a/actor/v7pushaction/create_bits_package_for_application.go b/actor/v7pushaction/create_bits_package_for_application.go index b04a0ab919e..33e1ca01ed7 100644 --- a/actor/v7pushaction/create_bits_package_for_application.go +++ b/actor/v7pushaction/create_bits_package_for_application.go @@ -1,6 +1,7 @@ package v7pushaction import ( + "log/slog" "os" "code.cloudfoundry.org/cli/v9/actor/actionerror" @@ -8,7 +9,6 @@ import ( "code.cloudfoundry.org/cli/v9/actor/v7action" "code.cloudfoundry.org/cli/v9/api/cloudcontroller/ccerror" "code.cloudfoundry.org/cli/v9/resources" - log "github.com/sirupsen/logrus" ) const PushRetries = 3 @@ -27,7 +27,7 @@ func (actor Actor) CreateBitsPackageForApplication(pushPlan PushPlan, eventStrea } func (actor Actor) CreateAndUploadApplicationBits(pushPlan PushPlan, eventStream chan<- *PushEvent, progressBar ProgressBar) (resources.Package, Warnings, error) { - log.WithField("Path", pushPlan.BitsPath).Info("creating archive") + slog.Info("creating archive", "Path", pushPlan.BitsPath) var ( allWarnings Warnings @@ -59,7 +59,7 @@ func (actor Actor) CreateAndUploadApplicationBits(pushPlan PushPlan, eventStream } eventStream <- &PushEvent{Plan: pushPlan, Event: CreatingPackage} - log.WithField("GUID", pushPlan.Application.GUID).Info("creating package") + slog.Info("creating package", "GUID", pushPlan.Application.GUID) pkg, createPackageWarnings, err := actor.V7Actor.CreateBitsPackageByApplication(pushPlan.Application.GUID) allWarnings = append(allWarnings, createPackageWarnings...) if err != nil { @@ -77,7 +77,7 @@ func (actor Actor) CreateAndUploadApplicationBits(pushPlan PushPlan, eventStream // Uploading package/app bits for count := 0; count < PushRetries; count++ { eventStream <- &PushEvent{Plan: pushPlan, Event: ReadingArchive} - log.WithField("GUID", pushPlan.Application.GUID).Info("reading archive") + slog.Info("reading archive", "GUID", pushPlan.Application.GUID) file, size, readErr := actor.SharedActor.ReadArchive(archivePath) if readErr != nil { return resources.Package{}, allWarnings, readErr diff --git a/actor/v7pushaction/restart_application.go b/actor/v7pushaction/restart_application.go index 077b2e58a08..10a2a4646d8 100644 --- a/actor/v7pushaction/restart_application.go +++ b/actor/v7pushaction/restart_application.go @@ -1,11 +1,9 @@ package v7pushaction -import ( - log "github.com/sirupsen/logrus" -) +import "log/slog" func (actor Actor) RestartApplication(pushPlan PushPlan, eventStream chan<- *PushEvent, progressBar ProgressBar) (PushPlan, Warnings, error) { - log.Info("Restarting Application") + slog.Info("Restarting Application") var allWarnings Warnings diff --git a/actor/v7pushaction/set_default_bits_path_for_push_plan.go b/actor/v7pushaction/set_default_bits_path_for_push_plan.go index 4a1e1cd1ddd..2748fd9065a 100644 --- a/actor/v7pushaction/set_default_bits_path_for_push_plan.go +++ b/actor/v7pushaction/set_default_bits_path_for_push_plan.go @@ -1,16 +1,15 @@ package v7pushaction import ( + "log/slog" "os" - - log "github.com/sirupsen/logrus" ) func SetDefaultBitsPathForPushPlan(pushPlan PushPlan, overrides FlagOverrides) (PushPlan, error) { if pushPlan.BitsPath == "" && pushPlan.DropletPath == "" && pushPlan.DockerImageCredentials.Path == "" { var err error pushPlan.BitsPath, err = os.Getwd() - log.WithField("path", pushPlan.BitsPath).Debug("using current directory for bits path") + slog.Debug("using current directory for bits path", "path", pushPlan.BitsPath) if err != nil { return pushPlan, err } diff --git a/actor/v7pushaction/stop_application.go b/actor/v7pushaction/stop_application.go index e4c6eabfc92..7fcb34e389e 100644 --- a/actor/v7pushaction/stop_application.go +++ b/actor/v7pushaction/stop_application.go @@ -1,15 +1,16 @@ package v7pushaction import ( + "log/slog" + "code.cloudfoundry.org/cli/v9/actor/v7action" - log "github.com/sirupsen/logrus" ) func (actor Actor) StopApplication(pushPlan PushPlan, eventStream chan<- *PushEvent, progressBar ProgressBar) (PushPlan, Warnings, error) { var warnings v7action.Warnings var err error - log.Info("Stopping Application") + slog.Info("Stopping Application") eventStream <- &PushEvent{Plan: pushPlan, Event: StoppingApplication} warnings, err = actor.V7Actor.StopApplication(pushPlan.Application.GUID) if err != nil { diff --git a/actor/v7pushaction/v7pushaction_suite_test.go b/actor/v7pushaction/v7pushaction_suite_test.go index 9147fd72092..2a9ec1928ee 100644 --- a/actor/v7pushaction/v7pushaction_suite_test.go +++ b/actor/v7pushaction/v7pushaction_suite_test.go @@ -1,6 +1,8 @@ package v7pushaction_test import ( + "io" + "log/slog" "os" "testing" "time" @@ -9,8 +11,6 @@ import ( "code.cloudfoundry.org/cli/v9/actor/v7pushaction/v7pushactionfakes" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - - log "github.com/sirupsen/logrus" ) func TestPushAction(t *testing.T) { @@ -18,9 +18,10 @@ func TestPushAction(t *testing.T) { RunSpecs(t, "V7 Push Actions Suite") } -var _ = BeforeEach(func() { +var _ = BeforeSuite(func() { + // Suppress log output during tests. This equates with setting to panic-level severity in older logging libraries + slog.SetDefault(slog.New(slog.NewTextHandler(io.Discard, nil))) SetDefaultEventuallyTimeout(3 * time.Second) - log.SetLevel(log.PanicLevel) }) func getCurrentDir() string { diff --git a/cf/commands/commands_suite_test.go b/cf/commands/commands_suite_test.go index a31de4866cc..b4413a1ad83 100644 --- a/cf/commands/commands_suite_test.go +++ b/cf/commands/commands_suite_test.go @@ -1,12 +1,14 @@ package commands_test import ( + "io" + "log/slog" + "code.cloudfoundry.org/cli/v9/cf/commands" "code.cloudfoundry.org/cli/v9/cf/i18n" "code.cloudfoundry.org/cli/v9/cf/util/testhelpers/configuration" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - log "github.com/sirupsen/logrus" "testing" ) @@ -21,8 +23,9 @@ func TestCommands(t *testing.T) { RunSpecs(t, "Commands Suite") } -var _ = BeforeEach(func() { - log.SetLevel(log.PanicLevel) +var _ = BeforeSuite(func() { + // Suppress log output during tests. This equates with setting to panic-level severity in older logging libraries + slog.SetDefault(slog.New(slog.NewTextHandler(io.Discard, nil))) }) type passingRequirement struct { diff --git a/command/command_suite_test.go b/command/command_suite_test.go index af257e39a12..9db6153755a 100644 --- a/command/command_suite_test.go +++ b/command/command_suite_test.go @@ -1,12 +1,13 @@ package command_test import ( + "io" + "log/slog" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "testing" - - log "github.com/sirupsen/logrus" ) func TestCommand(t *testing.T) { @@ -14,6 +15,7 @@ func TestCommand(t *testing.T) { RunSpecs(t, "Command Suite") } -var _ = BeforeEach(func() { - log.SetLevel(log.PanicLevel) +var _ = BeforeSuite(func() { + // Suppress log output during tests. This equates with setting to panic-level severity in older logging libraries + slog.SetDefault(slog.New(slog.NewTextHandler(io.Discard, nil))) }) diff --git a/command/common/common_suite_test.go b/command/common/common_suite_test.go index 4f17bfab8ae..dafd0d0d01f 100644 --- a/command/common/common_suite_test.go +++ b/command/common/common_suite_test.go @@ -1,9 +1,11 @@ package common_test import ( + "io" + "log/slog" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - log "github.com/sirupsen/logrus" "testing" ) @@ -13,6 +15,7 @@ func TestCommon(t *testing.T) { RunSpecs(t, "Common Commands Suite") } -var _ = BeforeEach(func() { - log.SetLevel(log.PanicLevel) +var _ = BeforeSuite(func() { + // Suppress log output during tests. This equates with setting to panic-level severity in older logging libraries + slog.SetDefault(slog.New(slog.NewTextHandler(io.Discard, nil))) }) diff --git a/command/common/install_plugin_command.go b/command/common/install_plugin_command.go index 7ebb070d95b..7b704333d7c 100644 --- a/command/common/install_plugin_command.go +++ b/command/common/install_plugin_command.go @@ -1,6 +1,7 @@ package common import ( + "log/slog" "os" "runtime" "strings" @@ -16,7 +17,6 @@ import ( "code.cloudfoundry.org/cli/v9/command/translatableerror" "code.cloudfoundry.org/cli/v9/util" "code.cloudfoundry.org/cli/v9/util/configv3" - log "github.com/sirupsen/logrus" ) //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . InstallPluginActor @@ -75,11 +75,11 @@ func (cmd *InstallPluginCommand) Setup(config command.Config, ui command.UI) err } func (cmd InstallPluginCommand) Execute([]string) (err error) { - log.WithField("PluginHome", cmd.Config.PluginHome()).Info("making plugin dir") + slog.Info("making plugin dir", "PluginHome", cmd.Config.PluginHome()) var tempPluginDir string tempPluginDir, err = os.MkdirTemp(cmd.Config.PluginHome(), "temp") - log.WithField("tempPluginDir", tempPluginDir).Debug("making tempPluginDir dir") + slog.Info("making plugin dir", "tempPluginDir", tempPluginDir) defer func() { removed := false @@ -119,7 +119,7 @@ func (cmd InstallPluginCommand) Execute([]string) (err error) { } else if err != nil { return err } - log.WithFields(log.Fields{"tempPluginPath": tempPluginPath, "pluginSource": pluginSource}).Debug("getPluginBinaryAndSource") + slog.Debug("getPluginBinaryAndSource", "tempPluginPath", tempPluginPath, "pluginSource", pluginSource) // copy twice when downloading from a URL to keep Windows specific code // isolated to CreateExecutableCopy @@ -127,22 +127,22 @@ func (cmd InstallPluginCommand) Execute([]string) (err error) { if err != nil { return err } - log.WithField("executablePath", executablePath).Debug("created executable copy") + slog.Debug("created executable copy", "executablePath", executablePath) rpcService, err := shared.NewRPCService(cmd.Config, cmd.UI) if err != nil { return err } - log.Info("started RPC server") + slog.Info("started RPC server") plugin, err := cmd.Actor.GetAndValidatePlugin(rpcService, Commands, executablePath) if err != nil { return err } - log.Info("validated plugin") + slog.Info("validated plugin") if installedPlugin, installed := cmd.Config.GetPluginCaseInsensitive(plugin.Name); installed { - log.WithField("version", installedPlugin.Version).Debug("uninstall plugin") + slog.Debug("uninstall plugin", "version", installedPlugin.Version) if !cmd.Force && pluginSource != PluginFromRepository { return translatableerror.PluginAlreadyInstalledError{ @@ -158,7 +158,7 @@ func (cmd InstallPluginCommand) Execute([]string) (err error) { } } - log.Info("install plugin") + slog.Info("install plugin") return cmd.installPlugin(plugin, executablePath) } @@ -206,7 +206,7 @@ func (cmd InstallPluginCommand) getPluginBinaryAndSource(tempPluginDir string) ( switch { case cmd.RegisteredRepository != "": - log.WithField("RegisteredRepository", cmd.RegisteredRepository).Info("installing from specified repository") + slog.Info("installing from specified repository", "RegisteredRepository", cmd.RegisteredRepository) pluginRepository, err := cmd.Actor.GetPluginRepository(cmd.RegisteredRepository) if err != nil { return "", 0, err @@ -235,19 +235,19 @@ func (cmd InstallPluginCommand) getPluginBinaryAndSource(tempPluginDir string) ( return path, pluginSource, nil case cmd.Actor.FileExists(pluginNameOrLocation): - log.WithField("pluginNameOrLocation", pluginNameOrLocation).Info("installing from specified file") + slog.Info("installing from specified file", "pluginNameOrLocation", pluginNameOrLocation) return cmd.getPluginFromLocalFile(pluginNameOrLocation) case util.IsHTTPScheme(pluginNameOrLocation): - log.WithField("pluginNameOrLocation", pluginNameOrLocation).Info("installing from specified URL") + slog.Info("installing from specified URL", "pluginNameOrLocation", pluginNameOrLocation) return cmd.getPluginFromURL(pluginNameOrLocation, tempPluginDir) case util.IsUnsupportedURLScheme(pluginNameOrLocation): - log.WithField("pluginNameOrLocation", pluginNameOrLocation).Error("Unsupported URL") + slog.Error("Unsupported URL", "pluginNameOrLocation", pluginNameOrLocation) return "", 0, translatableerror.UnsupportedURLSchemeError{UnsupportedURL: pluginNameOrLocation} default: - log.Info("installing from first repository with plugin") + slog.Info("installing from first repository with plugin") repos := cmd.Config.PluginRepositories() if len(repos) == 0 { return "", 0, translatableerror.PluginNotFoundOnDiskOrInAnyRepositoryError{PluginName: pluginNameOrLocation, BinaryName: cmd.Config.BinaryName()} @@ -406,7 +406,7 @@ func (cmd InstallPluginCommand) installPluginPrompt(template string, templateVal } if !really { - log.Debug("plugin confirmation - 'no' inputted") + slog.Debug("plugin confirmation - 'no' inputted") return cancelInstall{} } diff --git a/command/minimum_version_check.go b/command/minimum_version_check.go index 78ec18ee1d7..6b6085e099e 100644 --- a/command/minimum_version_check.go +++ b/command/minimum_version_check.go @@ -1,12 +1,13 @@ package command import ( + "log/slog" + "code.cloudfoundry.org/cli/v9/command/translatableerror" - log "github.com/sirupsen/logrus" ) func MinimumCCAPIVersionCheck(current string, minimum string, customCommand ...string) error { - log.WithFields(log.Fields{"current": current, "minimum": minimum}).Debug("minimum api version") + slog.Error("minimum api version", "current", current, "minimum", minimum) var command string if len(customCommand) > 0 { command = customCommand[0] @@ -18,7 +19,7 @@ func MinimumCCAPIVersionCheck(current string, minimum string, customCommand ...s } if isOutdated { - log.WithFields(log.Fields{"current": current, "minimum": minimum}).Error("minimum not met") + slog.Error("minimum not met", "current", current, "minimum", minimum) return translatableerror.MinimumCFAPIVersionNotMetError{ Command: command, CurrentVersion: current, @@ -30,7 +31,7 @@ func MinimumCCAPIVersionCheck(current string, minimum string, customCommand ...s } func MinimumUAAAPIVersionCheck(current string, minimum string, customCommand ...string) error { - log.WithFields(log.Fields{"current": current, "minimum": minimum}).Debug("minimum api version") + slog.Error("minimum not met", "current", current, "minimum", minimum) var command string if len(customCommand) > 0 { command = customCommand[0] @@ -42,7 +43,7 @@ func MinimumUAAAPIVersionCheck(current string, minimum string, customCommand ... } if isOutdated { - log.WithFields(log.Fields{"current": current, "minimum": minimum}).Error("minimum not met") + slog.Error("minimum not met", "current", current, "minimum", minimum) return translatableerror.MinimumUAAAPIVersionNotMetError{ Command: command, MinimumVersion: minimum, diff --git a/command/translatableerror/convert_to_translatable_error.go b/command/translatableerror/convert_to_translatable_error.go index 13e9734a806..b5227981cd0 100644 --- a/command/translatableerror/convert_to_translatable_error.go +++ b/command/translatableerror/convert_to_translatable_error.go @@ -3,6 +3,7 @@ package translatableerror import ( "encoding/json" "fmt" + "log/slog" "strings" "code.cloudfoundry.org/cli/v9/actor/actionerror" @@ -12,11 +13,10 @@ import ( "code.cloudfoundry.org/cli/v9/util/clissh/ssherror" "code.cloudfoundry.org/cli/v9/util/download" "code.cloudfoundry.org/cli/v9/util/manifest" - log "github.com/sirupsen/logrus" ) func ConvertToTranslatableError(err error) error { - log.WithField("err", fmt.Sprintf("%#v", err)).Debugf("convert to translatable error") + slog.Debug("convert to translatable error", "err", fmt.Sprintf("%#v", err)) switch e := err.(type) { // Action Errors diff --git a/command/v7/env_command.go b/command/v7/env_command.go index 735d89261a4..e6c606cab61 100644 --- a/command/v7/env_command.go +++ b/command/v7/env_command.go @@ -2,10 +2,10 @@ package v7 import ( "fmt" + "log/slog" "sort" "code.cloudfoundry.org/cli/v9/command/flag" - log "github.com/sirupsen/logrus" ) type EnvCommand struct { @@ -48,13 +48,13 @@ func (cmd EnvCommand) Execute(_ []string) error { cmd.UI.DisplayHeader("System-Provided:") err = cmd.displaySystem(envGroups.System) if err != nil { - log.Errorln("error formatting system provided:", err) + slog.Error("error formatting system provided", "err", err) } if len(envGroups.Application) > 0 { cmd.UI.DisplayNewline() err = cmd.displaySystem(envGroups.Application) if err != nil { - log.Errorln("error formatting application:", err) + slog.Error("error formatting application", "err", err) } } } else { diff --git a/command/v7/push_command.go b/command/v7/push_command.go index d83fa2e4c7d..d394aff04eb 100644 --- a/command/v7/push_command.go +++ b/command/v7/push_command.go @@ -3,13 +3,13 @@ package v7 import ( "context" "fmt" + "log/slog" "os" "strconv" "strings" "code.cloudfoundry.org/cli/v9/api/cloudcontroller/ccversion" "github.com/cloudfoundry/bosh-cli/director/template" - log "github.com/sirupsen/logrus" "gopkg.in/yaml.v2" "code.cloudfoundry.org/cli/v9/actor/actionerror" @@ -253,7 +253,7 @@ func (cmd PushCommand) Execute(args []string) error { return err } - log.WithField("number of plans", len(pushPlans)).Debug("completed generating plan") + slog.Debug("completed generating plan", "number of plans", len(pushPlans)) defer func() { if cmd.stopStreamingFunc != nil { cmd.stopStreamingFunc() @@ -261,7 +261,7 @@ func (cmd PushCommand) Execute(args []string) error { }() for _, plan := range pushPlans { - log.WithField("app_name", plan.Application.Name).Info("actualizing") + slog.Info("actualizing", "app_name", plan.Application.Name) eventStream := cmd.PushActor.Actualize(plan, cmd.ProgressBar) err := cmd.eventStreamHandler(eventStream) @@ -286,14 +286,14 @@ func (cmd PushCommand) GetBaseManifest(flagOverrides v7pushaction.FlagOverrides) }, } if cmd.NoManifest { - log.Debugf("No manifest given, generating manifest") + slog.Debug("No manifest given, generating manifest") return defaultManifest, nil } - log.Info("reading manifest if exists") + slog.Info("reading manifest if exists") readPath := cmd.CWD if flagOverrides.ManifestPath != "" { - log.WithField("manifestPath", flagOverrides.ManifestPath).Debug("reading '-f' provided manifest") + slog.Debug("reading '-f' provided manifest", "manifestPath", flagOverrides.ManifestPath) readPath = flagOverrides.ManifestPath } @@ -303,14 +303,14 @@ func (cmd PushCommand) GetBaseManifest(flagOverrides v7pushaction.FlagOverrides) } if !exists { - log.Debugf("No manifest given, generating manifest") + slog.Debug("No manifest given, generating manifest") return defaultManifest, nil } - log.WithField("manifestPath", pathToManifest).Debug("path to manifest") + slog.Debug("path to manifest", "manifestPath", pathToManifest) rawManifest, err := cmd.ManifestParser.InterpolateManifest(pathToManifest, flagOverrides.PathsToVarsFiles, flagOverrides.Vars) if err != nil { - log.Errorln("reading manifest:", err) + slog.Error("reading manifest", "err", err) if _, ok := err.(*yaml.TypeError); ok { return manifestparser.Manifest{}, errors.New(fmt.Sprintf("Unable to push app because manifest %s is not valid yaml.", pathToManifest)) } @@ -319,7 +319,7 @@ func (cmd PushCommand) GetBaseManifest(flagOverrides v7pushaction.FlagOverrides) manifest, err := cmd.ManifestParser.ParseManifest(pathToManifest, rawManifest) if err != nil { - log.Errorln("parsing manifest:", err) + slog.Error("parsing manifest", "err", err) return manifestparser.Manifest{}, err } @@ -647,7 +647,7 @@ func (cmd PushCommand) announcePushing(appNames []string, user configv3.User) { } func (cmd PushCommand) displayAppSummary(plan v7pushaction.PushPlan) error { - log.Info("getting application summary info") + slog.Info("getting application summary info") summary, warnings, err := cmd.VersionActor.GetDetailedAppSummary( plan.Application.Name, cmd.Config.TargetedSpace().GUID, @@ -683,7 +683,7 @@ func (cmd *PushCommand) processEvent(event v7pushaction.Event, appName string) e cmd.UI.DisplayText("Packaging files to upload...") case v7pushaction.UploadingApplicationWithArchive: cmd.UI.DisplayText("Uploading files...") - log.Debug("starting progress bar") + slog.Debug("starting progress bar") cmd.ProgressBar.Ready() case v7pushaction.UploadingApplication: cmd.UI.DisplayText("All files found in remote cache; nothing to upload.") @@ -748,7 +748,7 @@ func (cmd *PushCommand) processEvent(event v7pushaction.Event, appName string) e cmd.UI.DisplayText("Waiting for app to deploy...") cmd.UI.DisplayNewline() default: - log.WithField("event", event).Debug("ignoring event") + slog.Debug("ignoring event", "event", event) } return nil diff --git a/command/v7/shared/app_summary_displayer.go b/command/v7/shared/app_summary_displayer.go index 5de2b18fa32..5cfd50369c0 100644 --- a/command/v7/shared/app_summary_displayer.go +++ b/command/v7/shared/app_summary_displayer.go @@ -2,6 +2,7 @@ package shared import ( "fmt" + "log/slog" "strconv" "strings" "time" @@ -12,7 +13,6 @@ import ( "code.cloudfoundry.org/cli/v9/command" "code.cloudfoundry.org/cli/v9/resources" "code.cloudfoundry.org/cli/v9/util/ui" - log "github.com/sirupsen/logrus" ) type AppSummaryDisplayer struct { @@ -206,7 +206,7 @@ func (display AppSummaryDisplayer) getCreatedTime(summary v7action.DetailedAppli if summary.CurrentDroplet.CreatedAt != "" { timestamp, err := time.Parse(time.RFC3339, summary.CurrentDroplet.CreatedAt) if err != nil { - log.WithField("createdAt", summary.CurrentDroplet.CreatedAt).Errorln("error parsing created at:", err) + slog.Error("error parsing created at", "err", err, "createdAt", summary.CurrentDroplet.CreatedAt) } return display.UI.UserFriendlyDate(timestamp) @@ -219,7 +219,7 @@ func (display AppSummaryDisplayer) getLastStatusChangeTime(summary v7action.Deta if summary.Deployment.LastStatusChange != "" { timestamp, err := time.Parse(time.RFC3339, summary.Deployment.LastStatusChange) if err != nil { - log.WithField("last_status_change", summary.Deployment.LastStatusChange).Errorln("error parsing last status change:", err) + slog.Error("error parsing last status change", "err", err, "last_status_change", summary.Deployment.LastStatusChange) } return display.UI.UserFriendlyDate(timestamp) diff --git a/command/v7/v7_suite_test.go b/command/v7/v7_suite_test.go index 8a1af2c03a2..a741c0209b7 100644 --- a/command/v7/v7_suite_test.go +++ b/command/v7/v7_suite_test.go @@ -2,6 +2,8 @@ package v7_test import ( "fmt" + "io" + "log/slog" "reflect" "strings" "testing" @@ -9,7 +11,6 @@ import ( uuid "github.com/nu7hatch/gouuid" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - log "github.com/sirupsen/logrus" ) func TestV3(t *testing.T) { @@ -17,8 +18,9 @@ func TestV3(t *testing.T) { RunSpecs(t, "V7 Command Suite") } -var _ = BeforeEach(func() { - log.SetLevel(log.PanicLevel) +var _ = BeforeSuite(func() { + // Suppress log output during tests. This equates with setting to panic-level severity in older logging libraries + slog.SetDefault(slog.New(slog.NewTextHandler(io.Discard, nil))) }) // RandomString provides a random string diff --git a/go.mod b/go.mod index 4a632a1e93a..0a22f3f0368 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,6 @@ require ( github.com/pkg/errors v0.9.1 github.com/sabhiram/go-gitignore v0.0.0-20171017070213-362f9845770f github.com/sajari/fuzzy v1.0.0 - github.com/sirupsen/logrus v1.9.4 github.com/tedsuo/rata v1.0.1-0.20170830210128-07d200713958 github.com/vito/go-interact v0.0.0-20171111012221-fa338ed9e9ec golang.org/x/crypto v0.54.0 diff --git a/go.sum b/go.sum index 1542799fdab..a6ab96aa73e 100644 --- a/go.sum +++ b/go.sum @@ -242,8 +242,6 @@ github.com/sajari/fuzzy v1.0.0/go.mod h1:OjYR6KxoWOe9+dOlXeiCJd4dIbED4Oo8wpS89o0 github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= github.com/sclevine/spec v1.4.0 h1:z/Q9idDcay5m5irkZ28M7PtQM4aOISzOpj4bUPkDee8= github.com/sclevine/spec v1.4.0/go.mod h1:LvpgJaFyvQzRvc1kaDs0bulYwzC70PbiYjC4QnFHkOM= -github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w= -github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g= github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/square/certstrap v1.3.0 h1:N9P0ZRA+DjT8pq5fGDj0z3FjafRKnBDypP0QHpMlaAk= diff --git a/util/clissh/ssh.go b/util/clissh/ssh.go index a836004d240..08cf3d64e80 100644 --- a/util/clissh/ssh.go +++ b/util/clissh/ssh.go @@ -9,6 +9,7 @@ import ( "errors" "fmt" "io" + "log/slog" "net" "os" "os/signal" @@ -21,7 +22,6 @@ import ( "code.cloudfoundry.org/cli/v9/cf/ssh/sigwinch" "code.cloudfoundry.org/cli/v9/util/clissh/ssherror" "github.com/moby/term" - log "github.com/sirupsen/logrus" "golang.org/x/crypto/ssh" ) @@ -151,7 +151,7 @@ func (c *SecureShell) InteractiveSession(commands []string, terminalRequest TTYR if err == nil { defer func() { err := c.terminalHelper.RestoreTerminal(stdinFd, state) - log.Errorln("restore terminal", err) + slog.Error("restore terminal", "error", err) }() } } @@ -302,7 +302,7 @@ func (c *SecureShell) resize(resized <-chan os.Signal, session SecureSession, te _, err := session.SendRequest("window-change", false, ssh.Marshal(message)) if err != nil { - log.Errorln("window-change:", err) + slog.Error("window-change", "err", err) } previousWidth = width @@ -344,7 +344,7 @@ func sha256Fingerprint(key ssh.PublicKey, encode bool) string { func copyAndClose(wg *sync.WaitGroup, dest io.WriteCloser, src io.Reader) { _, err := io.Copy(dest, src) if err != nil { - log.Errorln("copy and close:", err) + slog.Error("copy and close", "err", err) } _ = dest.Close() if wg != nil { @@ -355,7 +355,7 @@ func copyAndClose(wg *sync.WaitGroup, dest io.WriteCloser, src io.Reader) { func copyAndDone(wg *sync.WaitGroup, dest io.Writer, src io.Reader) { _, err := io.Copy(dest, src) if err != nil { - log.Errorln("copy and done:", err) + slog.Error("copy and done", "err", err) } wg.Done() } @@ -402,7 +402,7 @@ func keepalive(conn ssh.Conn, ticker *time.Ticker, stopCh chan struct{}) { case <-ticker.C: _, _, err := conn.SendRequest("keepalive@cloudfoundry.org", true, nil) if err != nil { - log.Errorln("err sending keep alive:", err) + slog.Error("err sending keep alive", "err", err) } case <-stopCh: ticker.Stop() diff --git a/util/clissh/ssh_suite_test.go b/util/clissh/ssh_suite_test.go index 1276d6b36af..a5f97172cfb 100644 --- a/util/clissh/ssh_suite_test.go +++ b/util/clissh/ssh_suite_test.go @@ -1,6 +1,8 @@ package clissh_test import ( + "io" + "log/slog" "os" "path/filepath" "testing" @@ -8,7 +10,6 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - log "github.com/sirupsen/logrus" "golang.org/x/crypto/ssh" ) @@ -23,6 +24,9 @@ func TestCmd(t *testing.T) { } var _ = BeforeSuite(func() { + // Suppress log output during tests. This equates with setting to panic-level severity in older logging libraries + slog.SetDefault(slog.New(slog.NewTextHandler(io.Discard, nil))) + SetDefaultEventuallyTimeout(3 * time.Second) hostKeyBytes, err := os.ReadFile(filepath.Join("..", "..", "fixtures", "host-key")) @@ -38,7 +42,3 @@ var _ = BeforeSuite(func() { TestHostKey = hostKey TestPrivateKey = privateKey }) - -var _ = BeforeEach(func() { - log.SetLevel(log.PanicLevel) -}) diff --git a/util/command_parser/command_parser.go b/util/command_parser/command_parser.go index 5124e625655..f1aa2f5b833 100644 --- a/util/command_parser/command_parser.go +++ b/util/command_parser/command_parser.go @@ -3,6 +3,7 @@ package command_parser import ( "errors" "fmt" + "log/slog" "os" "reflect" "strings" @@ -15,7 +16,6 @@ import ( "code.cloudfoundry.org/cli/v9/util/configv3" "code.cloudfoundry.org/cli/v9/util/ui" "github.com/jessevdk/go-flags" - log "github.com/sirupsen/logrus" "golang.org/x/crypto/ssh" ) @@ -77,9 +77,6 @@ func (p *CommandParser) executionWrapper(cmd flags.Commander, args []string) err }() if extendedCmd, ok := cmd.(command.ExtendedCommander); ok { - log.SetOutput(os.Stderr) - log.SetLevel(log.Level(cfConfig.LogLevel())) - err = extendedCmd.Setup(cfConfig, p.UI) if err != nil { return p.handleError(err) @@ -101,7 +98,7 @@ func (p *CommandParser) handleError(passedErr error) error { switch typedErr := translatedErr.(type) { case translatableerror.V3V2SwitchError: - log.Info("Received a V3V2SwitchError - switch to the V2 version of the command") + slog.Info("Received a V3V2SwitchError - switch to the V2 version of the command") return passedErr case TriggerLegacyMain: if typedErr.Error() != "" { diff --git a/util/command_parser/parser_suite_test.go b/util/command_parser/parser_suite_test.go index 1e796cb6cfb..6a0ec73006e 100644 --- a/util/command_parser/parser_suite_test.go +++ b/util/command_parser/parser_suite_test.go @@ -1,9 +1,11 @@ package command_parser_test import ( + "io" + "log/slog" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - log "github.com/sirupsen/logrus" "testing" ) @@ -13,6 +15,7 @@ func TestCommon(t *testing.T) { RunSpecs(t, "Command Parser Suite") } -var _ = BeforeEach(func() { - log.SetLevel(log.PanicLevel) +var _ = BeforeSuite(func() { + // Suppress log output during tests. This equates with setting to panic-level severity in older logging libraries + slog.SetDefault(slog.New(slog.NewTextHandler(io.Discard, nil))) }) diff --git a/util/progressbar/progress_bar.go b/util/progressbar/progress_bar.go index c97efeb48d8..b4d87b8873a 100644 --- a/util/progressbar/progress_bar.go +++ b/util/progressbar/progress_bar.go @@ -2,9 +2,9 @@ package progressbar import ( "io" + "log/slog" "time" - log "github.com/sirupsen/logrus" pb "gopkg.in/cheggaaa/pb.v1" ) @@ -26,14 +26,14 @@ func (p *ProgressBar) Complete() { } func (p *ProgressBar) NewProgressBarWrapper(reader io.Reader, sizeOfFile int64) io.Reader { - log.WithField("file_size", sizeOfFile).Debug("new progress bar") + slog.Debug("new progress bar", "file_size", sizeOfFile) ready, ok := <-p.ready if !ready || !ok { return nil } - log.Debug("progress bar ready") + slog.Debug("progress bar ready") p.bar = pb.New(int(sizeOfFile)).SetUnits(pb.U_BYTES) p.bar.ShowTimeLeft = false p.bar.Start() diff --git a/util/ui/i18n.go b/util/ui/i18n.go index 763db6ed8d7..316dc76f4ad 100644 --- a/util/ui/i18n.go +++ b/util/ui/i18n.go @@ -4,11 +4,11 @@ import ( "bytes" "encoding/json" "fmt" + "log/slog" "strings" "text/template" "code.cloudfoundry.org/cli/v9/i18n/resources" - log "github.com/sirupsen/logrus" "golang.org/x/text/language" ) @@ -119,7 +119,7 @@ func generateTranslationFunc(rawTranslation []byte) (TranslateFunc, error) { formattedTemplate := template.Must(template.New("Display Text").Parse(translated)) err := formattedTemplate.Execute(&buffer, keys) if err != nil { - log.WithField("translationID", translationID).Errorln("executing template:", err) + slog.Error("executing template", "translationID", translationID, "err", err) } return buffer.String()