github.com/helmwave/helmwave@v0.36.4-0.20240509190856-b35563eba4c6/pkg/log/log.go (about)

     1  package log
     2  
     3  import (
     4  	"github.com/helmwave/helmwave/pkg/helper"
     5  	formatter "github.com/helmwave/logrus-emoji-formatter"
     6  	"github.com/mgutz/ansi"
     7  	log "github.com/sirupsen/logrus"
     8  	"github.com/urfave/cli/v2"
     9  	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
    10  )
    11  
    12  var Default = &Settings{}
    13  
    14  // Settings stores configuration for logger.
    15  type Settings struct {
    16  	level      string
    17  	format     string
    18  	color      bool
    19  	timestamps bool
    20  }
    21  
    22  // Flags returns CLI flags for logger settings.
    23  func (l *Settings) Flags() []cli.Flag {
    24  	return []cli.Flag{
    25  		&cli.StringFlag{
    26  			Name:        "log-format",
    27  			Usage:       "You can set: [ text | json | pad | emoji ]",
    28  			Value:       "emoji",
    29  			Category:    "LOGGER",
    30  			EnvVars:     []string{"HELMWAVE_LOG_FORMAT"},
    31  			Destination: &l.format,
    32  		},
    33  		&cli.StringFlag{
    34  			Name:        "log-level",
    35  			Usage:       "You can set: [ debug | info | warn  | fatal | panic | trace ]",
    36  			Value:       "info",
    37  			Category:    "LOGGER",
    38  			EnvVars:     []string{"HELMWAVE_LOG_LEVEL", "HELMWAVE_LOG_LVL"},
    39  			Destination: &l.level,
    40  		},
    41  		&cli.BoolFlag{
    42  			Name:        "log-color",
    43  			Usage:       "on/off color",
    44  			Value:       true,
    45  			Category:    "LOGGER",
    46  			EnvVars:     []string{"HELMWAVE_LOG_COLOR"},
    47  			Destination: &l.color,
    48  		},
    49  		&cli.BoolFlag{
    50  			Name:        "log-timestamps",
    51  			Usage:       "Add timestamps to log messages",
    52  			Value:       false,
    53  			Category:    "LOGGER",
    54  			EnvVars:     []string{"HELMWAVE_LOG_TIMESTAMPS"},
    55  			Destination: &l.timestamps,
    56  		},
    57  	}
    58  }
    59  
    60  // Run initializes logger.
    61  func (l *Settings) Run(_ *cli.Context) error {
    62  	return l.Init()
    63  }
    64  
    65  // Init initializes logger and sets up hacks for other loggers (used by 3rd party libraries).
    66  func (l *Settings) Init() error {
    67  	// Skip various low-level k8s client errors
    68  	// There are a lot of context deadline errors being logged
    69  	utilruntime.ErrorHandlers = []func(error){ //nolint:reassign
    70  		logKubernetesClientError,
    71  	}
    72  
    73  	l.setFormat()
    74  
    75  	return l.setLevel()
    76  }
    77  
    78  func (l *Settings) setLevel() error {
    79  	level, err := log.ParseLevel(l.level)
    80  	if err != nil {
    81  		return NewInvalidLogLevelError(l.level, err)
    82  	}
    83  	log.SetLevel(level)
    84  	if level >= log.DebugLevel {
    85  		log.SetReportCaller(true)
    86  		helper.Helm.Debug = true
    87  	}
    88  
    89  	return nil
    90  }
    91  
    92  func (l *Settings) setFormat() {
    93  	// Helm diff also use it
    94  	ansi.DisableColors(!l.color)
    95  
    96  	switch l.format {
    97  	case "json":
    98  		log.SetFormatter(&log.JSONFormatter{
    99  			PrettyPrint: true,
   100  		})
   101  	case "pad":
   102  		log.SetFormatter(&log.TextFormatter{
   103  			PadLevelText:     true,
   104  			ForceColors:      l.color,
   105  			FullTimestamp:    l.timestamps,
   106  			DisableTimestamp: !l.timestamps,
   107  		})
   108  	case "emoji":
   109  		cfg := &formatter.Config{
   110  			Color: l.color,
   111  		}
   112  
   113  		switch {
   114  		case !l.color && l.timestamps:
   115  			cfg.LogFormat = "[%time%] [%lvl%]: %msg%"
   116  		case !l.color:
   117  			cfg.LogFormat = "[%lvl%]: %msg%"
   118  		case l.timestamps:
   119  			cfg.LogFormat = "[%time%] [%emoji% aka %lvl%]: %msg%"
   120  		}
   121  
   122  		log.SetFormatter(cfg)
   123  	case "text":
   124  		log.SetFormatter(&log.TextFormatter{
   125  			ForceColors:      l.color,
   126  			FullTimestamp:    l.timestamps,
   127  			DisableTimestamp: !l.timestamps,
   128  		})
   129  	}
   130  }
   131  
   132  func logKubernetesClientError(err error) {
   133  	log.WithError(err).Trace("kubernetes client error")
   134  }
   135  
   136  func (l *Settings) Format() string {
   137  	return l.format
   138  }