Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Save CLI log output to file included in support bundle #4289

Merged
merged 1 commit into from
Dec 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion cmd/eks-a-tool/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ func rootPersistentPreRun(cmd *cobra.Command, args []string) {
}

func initLogger() error {
if err := logger.InitZap(viper.GetInt("verbosity")); err != nil {
if err := logger.InitZap(logger.ZapOpts{
Level: viper.GetInt("verbosity"),
}); err != nil {
return fmt.Errorf("failed init zap logger in root command: %v", err)
}

Expand Down
18 changes: 17 additions & 1 deletion cmd/eksctl-anywhere/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"context"
"fmt"
"log"
"os"
"time"

"github.com/spf13/cobra"
"github.com/spf13/viper"
Expand All @@ -16,6 +18,16 @@ var rootCmd = &cobra.Command{
Short: "Amazon EKS Anywhere",
Long: `Use eksctl anywhere to build your own self-managing cluster on your hardware with the best of Amazon EKS`,
PersistentPreRun: rootPersistentPreRun,
PersistentPostRun: func(cmd *cobra.Command, args []string) {
outputFilePath := logger.GetOutputFilePath()
if outputFilePath == "" {
return
}

if err := os.Remove(outputFilePath); err != nil {
fmt.Printf("Failed to cleanup log file %s: %s", outputFilePath, err)
}
},
}

func init() {
Expand All @@ -32,7 +44,11 @@ func rootPersistentPreRun(cmd *cobra.Command, args []string) {
}

func initLogger() error {
if err := logger.InitZap(viper.GetInt("verbosity")); err != nil {
outputFilePath := fmt.Sprintf("./eksa-cli-%s.log", time.Now().Format("2006-01-02T15_04_05"))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we look into deleting this file after a successful cli operation?

if err := logger.InitZap(logger.ZapOpts{
Level: viper.GetInt("verbosity"),
OutputFilePath: outputFilePath,
}); err != nil {
return fmt.Errorf("failed init zap logger in root command: %v", err)
}

Expand Down
4 changes: 3 additions & 1 deletion cmd/integration_test/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ func rootPersistentPreRun(cmd *cobra.Command, args []string) {
}

func initLogger() error {
if err := logger.InitZap(viper.GetInt("verbosity")); err != nil {
if err := logger.InitZap(logger.ZapOpts{
Level: viper.GetInt("verbosity"),
}); err != nil {
return fmt.Errorf("failed init zap logger in root command: %v", err)
}

Expand Down
6 changes: 6 additions & 0 deletions pkg/diagnostics/collector_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ type Collect struct {
ClusterResources *clusterResources `json:"clusterResources,omitempty"`
Secret *secret `json:"secret,omitempty"`
Logs *logs `json:"logs,omitempty"`
Data *data `json:"data,omitempty"`
CopyFromHost *copyFromHost `json:"copyFromHost,omitempty"`
Exec *exec `json:"exec,omitempty"`
RunPod *runPod `json:"runPod,omitempty"`
Expand Down Expand Up @@ -46,6 +47,11 @@ type logs struct {
Limits *logLimits `json:"limits,omitempty"`
}

type data struct {
Name string `json:"name,omitempty"`
Data string `json:"data,omitempty"`
}

type copyFromHost struct {
collectorMeta `json:",inline"`
Name string `json:"name,omitempty"`
Expand Down
23 changes: 23 additions & 0 deletions pkg/diagnostics/collectors.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ package diagnostics

import (
"fmt"
"path/filepath"
"time"

v1 "k8s.io/api/core/v1"

"github.com/aws/eks-anywhere/pkg/api/v1alpha1"
"github.com/aws/eks-anywhere/pkg/cluster"
"github.com/aws/eks-anywhere/pkg/constants"
"github.com/aws/eks-anywhere/pkg/files"
"github.com/aws/eks-anywhere/pkg/providers"
)

Expand Down Expand Up @@ -171,6 +173,27 @@ func (c *collectorFactory) PackagesCollectors() []*Collect {
return collectors
}

func (c *collectorFactory) FileCollectors(paths []string) []*Collect {
collectors := []*Collect{}

for _, path := range paths {
r := files.NewReader()
content, err := r.ReadFile(path)
if err != nil {
content = []byte(fmt.Sprintf("Failed to retrieve file %s for collection: %s", path, err))
}

collectors = append(collectors, &Collect{
Data: &data{
Data: string(content),
Name: filepath.Base(path),
},
})
}

return collectors
}

func (c *collectorFactory) getCollectorsMap() map[v1alpha1.OSFamily][]*Collect {
return map[v1alpha1.OSFamily][]*Collect{
v1alpha1.Ubuntu: c.ubuntuHostCollectors(),
Expand Down
23 changes: 23 additions & 0 deletions pkg/diagnostics/collectors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package diagnostics_test

import (
"fmt"
"path/filepath"
"testing"

. "github.com/onsi/gomega"
Expand All @@ -13,8 +14,30 @@ import (
"github.com/aws/eks-anywhere/pkg/cluster"
"github.com/aws/eks-anywhere/pkg/constants"
"github.com/aws/eks-anywhere/pkg/diagnostics"
"github.com/aws/eks-anywhere/pkg/filewriter"
)

func TestFileCollectors(t *testing.T) {
g := NewGomegaWithT(t)
factory := diagnostics.NewDefaultCollectorFactory()

w, err := filewriter.NewWriter(t.TempDir())
g.Expect(err).To(BeNil())

logOut, err := w.Write("test.log", []byte("test content"))
g.Expect(err).To(BeNil())
g.Expect(logOut).To(BeAnExistingFile())

collectors := factory.FileCollectors([]string{logOut})
g.Expect(collectors).To(HaveLen(1), "DefaultCollectors() mismatch between number of desired collectors and actual")
g.Expect(collectors[0].Data.Data).To(Equal("test content"))
g.Expect(collectors[0].Data.Name).To(Equal(filepath.Base(logOut)))

collectors = factory.FileCollectors([]string{"does-not-exist.log"})
g.Expect(collectors).To(HaveLen(1), "DefaultCollectors() mismatch between number of desired collectors and actual")
g.Expect(collectors[0].Data.Data).To(ContainSubstring("Failed to retrieve file does-not-exist.log for collection"))
}

func TestVsphereDataCenterConfigCollectors(t *testing.T) {
g := NewGomegaWithT(t)
spec := test.NewClusterSpec(func(s *cluster.Spec) {
Expand Down
12 changes: 11 additions & 1 deletion pkg/diagnostics/diagnostic_bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ func newDiagnosticBundleManagementCluster(af AnalyzerFactory, cf CollectorFactor
}

b.WithDefaultCollectors().
WithFileCollectors([]string{logger.GetOutputFilePath()}).
WithDefaultAnalyzers().
WithManagementCluster(true).
WithDatacenterConfig(spec.Cluster.Spec.DatacenterRef, spec).
Expand Down Expand Up @@ -116,6 +117,7 @@ func newDiagnosticBundleFromSpec(af AnalyzerFactory, cf CollectorFactory, spec *
WithManagementCluster(spec.Cluster.IsSelfManaged()).
WithDefaultAnalyzers().
WithDefaultCollectors().
WithFileCollectors([]string{logger.GetOutputFilePath()}).
WithPackagesCollectors().
WithLogTextAnalyzers()

Expand All @@ -142,7 +144,9 @@ func newDiagnosticBundleDefault(af AnalyzerFactory, cf CollectorFactory) *EksaDi
analyzerFactory: af,
collectorFactory: cf,
}
return b.WithDefaultAnalyzers().WithDefaultCollectors().WithManagementCluster(true)
return b.WithDefaultAnalyzers().
WithDefaultCollectors().
WithManagementCluster(true)
}

func newDiagnosticBundleCustom(af AnalyzerFactory, cf CollectorFactory, client BundleClient, kubectl *executables.Kubectl, bundlePath string, kubeconfig string, writer filewriter.FileWriter) *EksaDiagnosticBundle {
Expand Down Expand Up @@ -260,6 +264,12 @@ func (e *EksaDiagnosticBundle) WithManagementCluster(isSelfManaged bool) *EksaDi
return e
}

// WithFileCollectors appends collectors that collect static data from the specified paths to the bundle.
func (e *EksaDiagnosticBundle) WithFileCollectors(paths []string) *EksaDiagnosticBundle {
e.bundle.Spec.Collectors = append(e.bundle.Spec.Collectors, e.collectorFactory.FileCollectors(paths)...)
return e
}

func (e *EksaDiagnosticBundle) WithPackagesCollectors() *EksaDiagnosticBundle {
e.bundle.Spec.Analyzers = append(e.bundle.Spec.Analyzers, e.analyzerFactory.PackageAnalyzers()...)
e.bundle.Spec.Collectors = append(e.bundle.Spec.Collectors, e.collectorFactory.PackagesCollectors()...)
Expand Down
6 changes: 6 additions & 0 deletions pkg/diagnostics/diagnostic_bundle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ func TestGenerateBundleConfigWithExternalEtcd(t *testing.T) {
c.EXPECT().ManagementClusterCollectors().Return(nil)
c.EXPECT().DataCenterConfigCollectors(spec.Cluster.Spec.DatacenterRef, spec).Return(nil)
c.EXPECT().PackagesCollectors().Return(nil)
c.EXPECT().FileCollectors(gomock.Any()).Return(nil)

w := givenWriter(t)
w.EXPECT().Write(gomock.Any(), gomock.Any())
Expand Down Expand Up @@ -191,6 +192,7 @@ func TestGenerateBundleConfigWithOidc(t *testing.T) {
c.EXPECT().ManagementClusterCollectors().Return(nil)
c.EXPECT().DataCenterConfigCollectors(spec.Cluster.Spec.DatacenterRef, spec).Return(nil)
c.EXPECT().PackagesCollectors().Return(nil)
c.EXPECT().FileCollectors(gomock.Any()).Return(nil)

opts := diagnostics.EksaDiagnosticBundleFactoryOpts{
AnalyzerFactory: a,
Expand Down Expand Up @@ -250,6 +252,7 @@ func TestGenerateBundleConfigWithGitOps(t *testing.T) {
c.EXPECT().ManagementClusterCollectors().Return(nil)
c.EXPECT().DataCenterConfigCollectors(spec.Cluster.Spec.DatacenterRef, spec).Return(nil)
c.EXPECT().PackagesCollectors().Return(nil)
c.EXPECT().FileCollectors(gomock.Any()).Return(nil)

opts := diagnostics.EksaDiagnosticBundleFactoryOpts{
AnalyzerFactory: a,
Expand Down Expand Up @@ -333,6 +336,7 @@ func TestBundleFromSpecComplete(t *testing.T) {
c.EXPECT().ManagementClusterCollectors().Return(nil)
c.EXPECT().DataCenterConfigCollectors(spec.Cluster.Spec.DatacenterRef, spec).Return(nil)
c.EXPECT().PackagesCollectors().Return(nil)
c.EXPECT().FileCollectors(gomock.Any()).Return(nil)

w := givenWriter(t)
w.EXPECT().Write(gomock.Any(), gomock.Any()).Times(2)
Expand Down Expand Up @@ -475,6 +479,7 @@ func TestGenerateManagementClusterBundleVsphereProvider(t *testing.T) {
c.EXPECT().DefaultCollectors().Return(nil)
c.EXPECT().ManagementClusterCollectors().Return(nil)
c.EXPECT().DataCenterConfigCollectors(spec.Cluster.Spec.DatacenterRef, spec).Return(nil)
c.EXPECT().FileCollectors(gomock.Any()).Return(nil)

w := givenWriter(t)
w.EXPECT().Write(gomock.Any(), gomock.Any()).Times(2)
Expand Down Expand Up @@ -522,6 +527,7 @@ func TestGenerateManagementClusterBundleDockerProvider(t *testing.T) {
c.EXPECT().DefaultCollectors().Return(nil)
c.EXPECT().ManagementClusterCollectors().Return(nil)
c.EXPECT().DataCenterConfigCollectors(spec.Cluster.Spec.DatacenterRef, spec).Return(nil)
c.EXPECT().FileCollectors(gomock.Any()).Return(nil)

w := givenWriter(t)
w.EXPECT().Write(gomock.Any(), gomock.Any()).Times(2)
Expand Down
2 changes: 2 additions & 0 deletions pkg/diagnostics/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ type DiagnosticBundle interface {
CollectAndAnalyze(ctx context.Context, sinceTimeValue *time.Time) error
WithDefaultAnalyzers() *EksaDiagnosticBundle
WithDefaultCollectors() *EksaDiagnosticBundle
WithFileCollectors(paths []string) *EksaDiagnosticBundle
WithDatacenterConfig(config v1alpha1.Ref, spec *cluster.Spec) *EksaDiagnosticBundle
WithOidcConfig(config *v1alpha1.OIDCConfig) *EksaDiagnosticBundle
WithExternalEtcd(config *v1alpha1.ExternalEtcdConfiguration) *EksaDiagnosticBundle
Expand All @@ -53,6 +54,7 @@ type AnalyzerFactory interface {
type CollectorFactory interface {
PackagesCollectors() []*Collect
DefaultCollectors() []*Collect
FileCollectors(paths []string) []*Collect
ManagementClusterCollectors() []*Collect
EksaHostCollectors(configs []providers.MachineConfig) []*Collect
DataCenterConfigCollectors(datacenter v1alpha1.Ref, spec *cluster.Spec) []*Collect
Expand Down
28 changes: 28 additions & 0 deletions pkg/diagnostics/interfaces/mocks/diagnostics.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 11 additions & 11 deletions pkg/logger/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,24 @@ const (
)

var (
l logr.Logger = logr.Discard()
once sync.Once
l logr.Logger = logr.Discard()
once sync.Once
outputFilePath string
)

func set(logger logr.Logger) {
func set(logger logr.Logger, out string) {
once.Do(func() {
l = logger
outputFilePath = out
})
}

// GetOutputFilePath returns the path to the file where high verbosity logs are written to.
g-gaston marked this conversation as resolved.
Show resolved Hide resolved
// If the logger hasn't been configured to output to a file, it returns an empty string.
func GetOutputFilePath() string {
return outputFilePath
}

// Get returns the logger instance that has been previously set.
// If no logger has been set, it returns a null logger.
func Get() logr.Logger {
Expand Down Expand Up @@ -83,11 +91,3 @@ func MarkFail(msg string, keysAndValues ...interface{}) {
func MarkWarning(msg string, keysAndValues ...interface{}) {
l.V(0).Info(markWarning+msg, keysAndValues...)
}

type LoggerOpt func(logr *logr.Logger)

func WithName(name string) LoggerOpt {
return func(logr *logr.Logger) {
*logr = (*logr).WithName(name)
}
}
3 changes: 3 additions & 0 deletions pkg/logger/logger_wb_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package logger

var NewZap = newZap
Loading