github.com/facebookincubator/go-belt@v0.0.0-20230703220935-39cd348f1a38/tool/logger/types/level.go (about)

     1  // Copyright 2022 Meta Platforms, Inc. and affiliates.
     2  //
     3  // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
     4  //
     5  // 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
     6  //
     7  // 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
     8  //
     9  // 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
    10  //
    11  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 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.
    12  
    13  // Copyright (c) Facebook, Inc. and its affiliates.
    14  //
    15  // This source code is licensed under the MIT license found in the
    16  // LICENSE file in the root directory of this source tree.
    17  
    18  // Package types of logger unifies different types of loggers into
    19  // interfaces Logger. For example it allows to upgrade simple fmt.Printf
    20  // to be a fully functional Logger. Therefore multiple wrappers are implemented
    21  // here to provide different functions which could be missing in some loggers.
    22  package types
    23  
    24  import (
    25  	"fmt"
    26  	"strings"
    27  )
    28  
    29  // Level is a severity of a message/Entry.
    30  //
    31  // There are two ways to use Level:
    32  // 1. To define a severity of a specific message/Entry (when logging).
    33  // 2. To define a severity of messages/Entries be actually logged (when configuring a Logger).
    34  type Level int
    35  
    36  const (
    37  	// LevelUndefined is an erroneous value of log-level which just corresponds
    38  	// to the zero-value.
    39  	LevelUndefined = Level(iota)
    40  
    41  	// LevelNone means to do not log anything.
    42  	//
    43  	// But even if a Logger is setup with this level, messages with levels Panic
    44  	// and Fatal will still cause panics and os.Exit, just we except this to avoid
    45  	// sending log messages (some Logger implementations may ignore this rule).
    46  	LevelNone
    47  
    48  	// LevelFatal means non-recoverable error case.
    49  	//
    50  	// If a message sent with this level then os.Exit is invoked in the end of processing the message.
    51  	//
    52  	// If a Logger is setup with this level, it will just ignore messages with level higher than Panic,
    53  	// will silently panic on a Panic message and will loudly exit on a Fatal message.
    54  	//
    55  	// Some Logger implementations may ignore the rule about panicking "silently".
    56  	LevelFatal
    57  
    58  	// LevelPanic means a panic case (basically a recoverable, but critical problem).
    59  	//
    60  	// If a message sent with this level then panic() is invoked in the end of processing the message.
    61  	//
    62  	// If a Logger is setup with this level, it will ignore messages with level higher than Panic.
    63  	LevelPanic
    64  
    65  	// LevelError means an error case (not a critical problem, but yet an error).
    66  	//
    67  	// A message with this level is just logged if the Logger is setup with level no less that this.
    68  	LevelError
    69  
    70  	// LevelWarning means an odd/unexpected/wrong/undesired/etc case. Basically this is something
    71  	// to keep an eye on. For example which could explain odd/erroneous behavior of the application
    72  	// in future.
    73  	//
    74  	// A message with this level is just logged if the Logger is setup with level no less that this.
    75  	LevelWarning
    76  
    77  	// LevelInfo means an information message, essential enough to notify the end user (who is
    78  	// not a developer of the application), but about something benign and that does not
    79  	// says to any wrong behavior of the application.
    80  	//
    81  	// A message with this level is just logged if the Logger is setup with level no less that this.
    82  	//
    83  	// Recommended as the default level.
    84  	LevelInfo
    85  
    86  	// LevelDebug means a message non-essential for the end user, but useful for debugging
    87  	// the application by its developer.
    88  	//
    89  	// A message with this level is just logged if the Logger is setup with level no less that this.
    90  	LevelDebug
    91  
    92  	// LevelTrace is for all other messages.
    93  	//
    94  	// For example, sometimes in complex processes/application it sometimes useful
    95  	// to have an extra layer to put an insane amount put all useless messages, which
    96  	// may suddenly become very useful for some very difficult debug process.
    97  	//
    98  	// A message with this level is just logged if the Logger is setup with level no less that this.
    99  	LevelTrace
   100  
   101  	// EndOfLevel just defines a maximum level + 1.
   102  	EndOfLevel
   103  )
   104  
   105  // Byte is similar to String, but returns a single byte, which
   106  // describes in a human-readable way the logging level.
   107  func (logLevel Level) Byte() byte {
   108  	switch logLevel {
   109  	case LevelUndefined:
   110  		return '?'
   111  	case LevelNone:
   112  		return '-'
   113  	case LevelDebug:
   114  		return 'D'
   115  	case LevelInfo:
   116  		return 'I'
   117  	case LevelWarning:
   118  		return 'W'
   119  	case LevelError:
   120  		return 'E'
   121  	case LevelPanic:
   122  		return 'P'
   123  	case LevelFatal:
   124  		return 'F'
   125  	}
   126  	return 'U'
   127  }
   128  
   129  // String just implements fmt.Stringer, flag.Value and pflag.Value.
   130  func (logLevel Level) String() string {
   131  	switch logLevel {
   132  	case LevelUndefined:
   133  		return "undefined"
   134  	case LevelNone:
   135  		return "none"
   136  	case LevelTrace:
   137  		return "trace"
   138  	case LevelDebug:
   139  		return "debug"
   140  	case LevelInfo:
   141  		return "info"
   142  	case LevelWarning:
   143  		return "warning"
   144  	case LevelError:
   145  		return "error"
   146  	case LevelPanic:
   147  		return "panic"
   148  	case LevelFatal:
   149  		return "fatal"
   150  	}
   151  	return fmt.Sprintf("unknown_%d", logLevel)
   152  }
   153  
   154  // Set updates the logging level values based on the passed string value.
   155  // This method just implements flag.Value and pflag.Value.
   156  func (logLevel *Level) Set(value string) error {
   157  	newLogLevel, err := ParseLogLevel(value)
   158  	if err != nil {
   159  		return err
   160  	}
   161  	*logLevel = newLogLevel
   162  	return nil
   163  }
   164  
   165  // Type just implements pflag.Value.
   166  func (logLevel *Level) Type() string {
   167  	return "Level"
   168  }
   169  
   170  // ParseLogLevel parses incoming string into a Level and returns
   171  // LevelUndefined with an error if an unknown logging level was passed.
   172  func ParseLogLevel(in string) (Level, error) {
   173  	switch strings.ToLower(in) {
   174  	case "t", "trace":
   175  		return LevelTrace, nil
   176  	case "d", "debug":
   177  		return LevelDebug, nil
   178  	case "i", "info":
   179  		return LevelInfo, nil
   180  	case "w", "warn", "warning":
   181  		return LevelWarning, nil
   182  	case "e", "err", "error":
   183  		return LevelError, nil
   184  	case "p", "panic":
   185  		return LevelPanic, nil
   186  	case "f", "fatal":
   187  		return LevelFatal, nil
   188  	case "n", "none":
   189  		return LevelNone, nil
   190  	}
   191  	var allowedValues []string
   192  	for logLevel := LevelFatal; logLevel <= LevelDebug; logLevel++ {
   193  		allowedValues = append(allowedValues, logLevel.String())
   194  	}
   195  	return LevelUndefined, fmt.Errorf("unknown logging level '%s', known values are: %s",
   196  		in, strings.Join(allowedValues, ", "))
   197  }