github.com/dominant-strategies/go-quai@v0.28.2/log/logger.go (about)

     1  package log
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  	"runtime"
     8  	"strings"
     9  
    10  	"github.com/natefinch/lumberjack"
    11  	"github.com/sirupsen/logrus"
    12  	"gopkg.in/urfave/cli.v1"
    13  )
    14  
    15  type Logger struct {
    16  	*logrus.Logger
    17  }
    18  
    19  var Log Logger = Logger{logrus.New()}
    20  
    21  func init() {
    22  
    23  }
    24  
    25  func ConfigureLogger(ctx *cli.Context) {
    26  	logLevel := logrus.Level(ctx.GlobalInt("verbosity"))
    27  	Log.SetLevel(logLevel)
    28  
    29  	logToStdOut := ctx.GlobalBool("logtostdout")
    30  
    31  	log_filename := "nodelogs"
    32  	regionNum := ctx.GlobalString("region")
    33  
    34  	if ctx.GlobalIsSet("zone") {
    35  		zoneNum := ctx.GlobalString("zone")
    36  		log_filename = filepath.Join(log_filename, "zone-"+regionNum+"-"+zoneNum)
    37  	} else if ctx.GlobalIsSet("region") {
    38  		log_filename = filepath.Join(log_filename, "region-"+regionNum)
    39  	} else {
    40  		log_filename = filepath.Join(log_filename, "prime")
    41  	}
    42  	log_filename += ".log"
    43  
    44  	Log.Formatter = &logrus.TextFormatter{
    45  		ForceColors:     ctx.GlobalBool("showcolors"),
    46  		PadLevelText:    true,
    47  		FullTimestamp:   true,
    48  		TimestampFormat: "01-02|15:04:05.000",
    49  	}
    50  
    51  	if logToStdOut {
    52  		Log.SetOutput(os.Stdout)
    53  	} else {
    54  		Log.SetOutput(&lumberjack.Logger{
    55  			Filename:   log_filename,
    56  			MaxSize:    500, // megabytes
    57  			MaxBackups: 5,
    58  			MaxAge:     28, //days
    59  		})
    60  	}
    61  }
    62  
    63  func SetLevelInt(level int) {
    64  	Log.SetLevel(logrus.Level(level))
    65  }
    66  
    67  func SetLevelString(level string) {
    68  	logLevel, err := logrus.ParseLevel(level)
    69  	if err != nil {
    70  		Log.Error("Invalid log level: ", level)
    71  		return
    72  	}
    73  	Log.SetLevel(logLevel)
    74  }
    75  
    76  func New(out_path string) Logger {
    77  	logger := logrus.New()
    78  	logger.SetOutput(&lumberjack.Logger{
    79  		Filename:   out_path,
    80  		MaxSize:    500, // megabytes
    81  		MaxBackups: 3,
    82  		MaxAge:     28, //days
    83  	})
    84  	return Logger{logger}
    85  }
    86  
    87  // Uses of the global logger will use the following static method.
    88  func Trace(msg string, args ...interface{}) {
    89  	Log.Trace(constructLogMessage(msg, args...))
    90  }
    91  
    92  // Individual logging instances will use the following method.
    93  func (l Logger) Trace(msg string, args ...interface{}) {
    94  	l.Logger.Trace(constructLogMessage(msg, args...))
    95  }
    96  
    97  func Debug(msg string, args ...interface{}) {
    98  	Log.Debug(constructLogMessage(msg, args...))
    99  }
   100  func (l Logger) Debug(msg string, args ...interface{}) {
   101  	l.Logger.Debug(constructLogMessage(msg, args...))
   102  }
   103  
   104  func Info(msg string, args ...interface{}) {
   105  	Log.Info(constructLogMessage(msg, args...))
   106  }
   107  func (l Logger) Info(msg string, args ...interface{}) {
   108  	l.Logger.Info(constructLogMessage(msg, args...))
   109  }
   110  
   111  func Warn(msg string, args ...interface{}) {
   112  	Log.Warn(constructLogMessage(msg, args...))
   113  }
   114  func (l Logger) Warn(msg string, args ...interface{}) {
   115  	l.Logger.Warn(constructLogMessage(msg, args...))
   116  }
   117  
   118  func Error(msg string, args ...interface{}) {
   119  	Log.Error(constructLogMessage(msg, args...))
   120  }
   121  func (l Logger) Error(msg string, args ...interface{}) {
   122  	l.Logger.Error(constructLogMessage(msg, args...))
   123  }
   124  
   125  func Fatal(msg string, args ...interface{}) {
   126  	Log.Fatal(constructLogMessage(msg, args...))
   127  }
   128  func (l Logger) Fatal(msg string, args ...interface{}) {
   129  	l.Logger.Fatal(constructLogMessage(msg, args...))
   130  }
   131  
   132  func Panic(msg string, args ...interface{}) {
   133  	Log.Panic(constructLogMessage(msg, args...))
   134  }
   135  func (l Logger) Panic(msg string, args ...interface{}) {
   136  	l.Logger.Panic(constructLogMessage(msg, args...))
   137  }
   138  
   139  func Lazy(fn func() string, logLevel string) {
   140  	level, err := logrus.ParseLevel(logLevel)
   141  	if err == nil && Log.IsLevelEnabled(level) {
   142  		callCorrectLevel(level, fn())
   143  	}
   144  }
   145  
   146  func reportLineNumber(skiplevel int) string {
   147  	if Logger.GetLevel(Log) < logrus.DebugLevel {
   148  		return ""
   149  	}
   150  	_, file, line, ok := runtime.Caller(skiplevel + 1)
   151  	fileAndDir := filepath.Join(filepath.Base(filepath.Dir(file)), filepath.Base(file))
   152  	if !ok || fileAndDir == "log/logger.go" {
   153  		return ""
   154  	}
   155  	return fmt.Sprintf("%s:%d", fileAndDir, line)
   156  }
   157  
   158  func callCorrectLevel(level logrus.Level, msg string, args ...interface{}) {
   159  	switch level {
   160  	case logrus.TraceLevel:
   161  		Trace(msg, args...)
   162  	case logrus.DebugLevel:
   163  		Debug(msg, args...)
   164  	case logrus.InfoLevel:
   165  		Info(msg, args...)
   166  	case logrus.WarnLevel:
   167  		Warn(msg, args...)
   168  	case logrus.ErrorLevel:
   169  		Error(msg, args...)
   170  	case logrus.FatalLevel:
   171  		Fatal(msg, args...)
   172  	case logrus.PanicLevel:
   173  		Panic(msg, args...)
   174  	default:
   175  		Error("Unknown log level: %v", level)
   176  	}
   177  }
   178  
   179  func constructLogMessage(msg string, fields ...interface{}) string {
   180  	var pairs []string
   181  
   182  	lineInfo := reportLineNumber(2)
   183  
   184  	if len(fields) != 1 {
   185  		// Sometimes we want to log a single string,
   186  		if len(fields)%2 != 0 {
   187  			fields = append(fields, "MISSING VALUE")
   188  		}
   189  
   190  		for i := 0; i < len(fields); i += 2 {
   191  			key := fields[i]
   192  			value := fields[i+1]
   193  			pairs = append(pairs, fmt.Sprintf("%v=%v", key, value))
   194  		}
   195  	}
   196  
   197  	if lineInfo != "" {
   198  		return fmt.Sprintf("%-40s %-40s %s", lineInfo, msg, strings.Join(pairs, " "))
   199  	} else {
   200  		return fmt.Sprintf("%-40s %s", msg, strings.Join(pairs, " "))
   201  	}
   202  }