github.com/MetalBlockchain/metalgo@v1.11.9/utils/logging/format.go (about)

     1  // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package logging
     5  
     6  import (
     7  	"errors"
     8  	"fmt"
     9  	"strings"
    10  
    11  	"go.uber.org/zap/zapcore"
    12  	"golang.org/x/term"
    13  )
    14  
    15  // Format modes available
    16  const (
    17  	Plain Format = iota
    18  	Colors
    19  	JSON
    20  
    21  	termTimeFormat = "[01-02|15:04:05.000]"
    22  )
    23  
    24  var (
    25  	errUnknownFormat = errors.New("unknown format")
    26  
    27  	defaultEncoderConfig = zapcore.EncoderConfig{
    28  		TimeKey:        "timestamp",
    29  		LevelKey:       "level",
    30  		NameKey:        "logger",
    31  		CallerKey:      "caller",
    32  		MessageKey:     "msg",
    33  		StacktraceKey:  "stacktrace",
    34  		EncodeDuration: zapcore.StringDurationEncoder,
    35  		EncodeCaller:   zapcore.ShortCallerEncoder,
    36  	}
    37  	jsonEncoderConfig zapcore.EncoderConfig
    38  
    39  	termTimeEncoder = zapcore.TimeEncoderOfLayout(termTimeFormat)
    40  )
    41  
    42  func init() {
    43  	jsonEncoderConfig = defaultEncoderConfig
    44  	jsonEncoderConfig.EncodeLevel = jsonLevelEncoder
    45  	jsonEncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
    46  	jsonEncoderConfig.EncodeDuration = zapcore.NanosDurationEncoder
    47  }
    48  
    49  // Highlight mode to apply to displayed logs
    50  type Format int
    51  
    52  // ToFormat chooses a highlighting mode
    53  func ToFormat(h string, fd uintptr) (Format, error) {
    54  	switch strings.ToUpper(h) {
    55  	case "PLAIN":
    56  		return Plain, nil
    57  	case "COLORS":
    58  		return Colors, nil
    59  	case "JSON":
    60  		return JSON, nil
    61  	case "AUTO":
    62  		if !term.IsTerminal(int(fd)) {
    63  			return Plain, nil
    64  		}
    65  		return Colors, nil
    66  	default:
    67  		return Plain, fmt.Errorf("unknown format mode: %s", h)
    68  	}
    69  }
    70  
    71  func (f Format) MarshalJSON() ([]byte, error) {
    72  	switch f {
    73  	case Plain:
    74  		return []byte(`"PLAIN"`), nil
    75  	case Colors:
    76  		return []byte(`"COLORS"`), nil
    77  	case JSON:
    78  		return []byte(`"JSON"`), nil
    79  	default:
    80  		return nil, errUnknownFormat
    81  	}
    82  }
    83  
    84  func (f Format) WrapPrefix(prefix string) string {
    85  	if prefix == "" || f == JSON {
    86  		return prefix
    87  	}
    88  	return fmt.Sprintf("<%s>", prefix)
    89  }
    90  
    91  func (f Format) ConsoleEncoder() zapcore.Encoder {
    92  	switch f {
    93  	case Colors:
    94  		return zapcore.NewConsoleEncoder(newTermEncoderConfig(consoleColorLevelEncoder))
    95  	case JSON:
    96  		return zapcore.NewJSONEncoder(jsonEncoderConfig)
    97  	default:
    98  		return zapcore.NewConsoleEncoder(newTermEncoderConfig(levelEncoder))
    99  	}
   100  }
   101  
   102  func (f Format) FileEncoder() zapcore.Encoder {
   103  	switch f {
   104  	case JSON:
   105  		return zapcore.NewJSONEncoder(jsonEncoderConfig)
   106  	default:
   107  		return zapcore.NewConsoleEncoder(newTermEncoderConfig(levelEncoder))
   108  	}
   109  }
   110  
   111  func newTermEncoderConfig(lvlEncoder zapcore.LevelEncoder) zapcore.EncoderConfig {
   112  	config := defaultEncoderConfig
   113  	config.EncodeLevel = lvlEncoder
   114  	config.EncodeTime = termTimeEncoder
   115  	config.ConsoleSeparator = " "
   116  	return config
   117  }
   118  
   119  func levelEncoder(l zapcore.Level, enc zapcore.PrimitiveArrayEncoder) {
   120  	enc.AppendString(Level(l).String())
   121  }
   122  
   123  func jsonLevelEncoder(l zapcore.Level, enc zapcore.PrimitiveArrayEncoder) {
   124  	enc.AppendString(Level(l).LowerString())
   125  }
   126  
   127  func consoleColorLevelEncoder(l zapcore.Level, enc zapcore.PrimitiveArrayEncoder) {
   128  	s, ok := levelToCapitalColorString[Level(l)]
   129  	if !ok {
   130  		s = unknownLevelColor.Wrap(l.String())
   131  	}
   132  	enc.AppendString(s)
   133  }