Skip to content

Commit

Permalink
save cli log output to file and store a copy in the support bundle up…
Browse files Browse the repository at this point in the history
…on error (aws#4289)
  • Loading branch information
cxbrowne1207 authored Dec 8, 2022
1 parent 3c83f07 commit edb31bc
Show file tree
Hide file tree
Showing 16 changed files with 329 additions and 39 deletions.
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"))
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.
// 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

0 comments on commit edb31bc

Please sign in to comment.