github.com/kubewharf/katalyst-core@v0.5.3/pkg/util/general/log.go (about)

     1  /*
     2  Copyright 2022 The Katalyst Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package general
    18  
    19  import (
    20  	"fmt"
    21  	"runtime"
    22  	"strconv"
    23  	"strings"
    24  	"sync"
    25  
    26  	"k8s.io/klog/v2"
    27  )
    28  
    29  type LoggingPKG int
    30  
    31  func (l *LoggingPKG) Type() string {
    32  	return "LoggingPKG"
    33  }
    34  
    35  func (l *LoggingPKG) String() string {
    36  	return fmt.Sprintf("logging-level: %v", *l)
    37  }
    38  
    39  func (l *LoggingPKG) Set(value string) error {
    40  	level, err := strconv.Atoi(value)
    41  	if err != nil {
    42  		return err
    43  	}
    44  	*l = LoggingPKG(level)
    45  	return nil
    46  }
    47  
    48  const (
    49  	LoggingPKGNone LoggingPKG = iota
    50  	LoggingPKGShort
    51  	LoggingPKGFull
    52  )
    53  
    54  var (
    55  	defaultLoggingPackage = LoggingPKGFull
    56  	defaultLoggingMtx     sync.RWMutex
    57  )
    58  
    59  // SetDefaultLoggingPackage should only be called by flags,
    60  // and should not be alerted dynamically.
    61  func SetDefaultLoggingPackage(l LoggingPKG) {
    62  	defaultLoggingMtx.Lock()
    63  	defer defaultLoggingMtx.Unlock()
    64  	defaultLoggingPackage = l
    65  }
    66  
    67  func getDefaultLoggingPackage() LoggingPKG {
    68  	defaultLoggingMtx.RLock()
    69  	defer defaultLoggingMtx.RUnlock()
    70  	return defaultLoggingPackage
    71  }
    72  
    73  const callDepth = 3
    74  
    75  const skippedPackagePrefix = "github.com/kubewharf/"
    76  
    77  // loggingWithDepth returns the logging-prefix for caller.
    78  // it will help to avoid hardcode function names in logging
    79  // message especially for cases that function names are changed.
    80  func loggingWithDepth(pkg LoggingPKG) string {
    81  	pc, _, _, ok := runtime.Caller(callDepth)
    82  	if !ok {
    83  		return ""
    84  	}
    85  
    86  	callPath := runtime.FuncForPC(pc).Name()
    87  	callerNames := strings.Split(callPath, "/")
    88  	if len(callerNames) == 0 {
    89  		return ""
    90  	}
    91  
    92  	switch pkg {
    93  	case LoggingPKGNone:
    94  		funcNames := strings.Split(callerNames[len(callerNames)-1], ".")
    95  		if len(funcNames) == 0 {
    96  			return ""
    97  		}
    98  		return funcNames[len(funcNames)-1]
    99  	case LoggingPKGShort:
   100  		return callerNames[len(callerNames)-1]
   101  	case LoggingPKGFull:
   102  		return strings.TrimPrefix(callPath, skippedPackagePrefix)
   103  	}
   104  	return ""
   105  }
   106  
   107  func logging(message string, params ...interface{}) string {
   108  	return "[" + loggingWithDepth(getDefaultLoggingPackage()) + "] " + fmt.Sprintf(message, params...)
   109  }
   110  
   111  func loggingPath(pkg LoggingPKG, message string, params ...interface{}) string {
   112  	return "[" + loggingWithDepth(pkg) + "] " + fmt.Sprintf(message, params...)
   113  }
   114  
   115  func InfoS(message string, params ...interface{}) {
   116  	klog.InfoSDepth(1, logging(message), params...)
   117  }
   118  
   119  func InfoSPath(pkg LoggingPKG, message string, params ...interface{}) {
   120  	klog.InfoSDepth(1, loggingPath(pkg, message), params...)
   121  }
   122  
   123  func Infof(message string, params ...interface{}) {
   124  	klog.InfofDepth(1, logging(message, params...))
   125  }
   126  
   127  func InfofPath(pkg LoggingPKG, message string, params ...interface{}) {
   128  	klog.InfofDepth(1, loggingPath(pkg, message, params...))
   129  }
   130  
   131  func InfofV(level int, message string, params ...interface{}) {
   132  	klog.V(klog.Level(level)).InfofDepth(1, logging(message, params...))
   133  }
   134  
   135  func InfofVPath(pkg LoggingPKG, level int, message string, params ...interface{}) {
   136  	klog.V(klog.Level(level)).InfofDepth(1, loggingPath(pkg, message, params...))
   137  }
   138  
   139  func Warningf(message string, params ...interface{}) {
   140  	klog.WarningfDepth(1, logging(message, params...))
   141  }
   142  
   143  func WarningfPath(pkg LoggingPKG, message string, params ...interface{}) {
   144  	klog.WarningfDepth(1, loggingPath(pkg, message, params...))
   145  }
   146  
   147  func Errorf(message string, params ...interface{}) {
   148  	klog.ErrorfDepth(1, logging(message, params...))
   149  }
   150  
   151  func ErrorfPath(pkg LoggingPKG, message string, params ...interface{}) {
   152  	klog.ErrorfDepth(1, loggingPath(pkg, message, params...))
   153  }
   154  
   155  func ErrorS(err error, message string, params ...interface{}) {
   156  	klog.ErrorSDepth(1, err, logging(message), params...)
   157  }
   158  
   159  func ErrorSPath(pkg LoggingPKG, err error, message string, params ...interface{}) {
   160  	klog.ErrorSDepth(1, err, loggingPath(pkg, message), params...)
   161  }
   162  
   163  func Fatalf(message string, params ...interface{}) {
   164  	klog.FatalfDepth(1, logging(message, params...))
   165  }
   166  
   167  func FatalfPath(pkg LoggingPKG, message string, params ...interface{}) {
   168  	klog.FatalfDepth(1, loggingPath(pkg, message, params...))
   169  }
   170  
   171  type Logger struct {
   172  	pkg    LoggingPKG
   173  	prefix string
   174  }
   175  
   176  func LoggerWithPrefix(prefix string, pkg LoggingPKG) Logger {
   177  	if len(prefix) > 0 {
   178  		prefix = fmt.Sprintf("%v: ", prefix)
   179  	}
   180  	return Logger{pkg: pkg, prefix: prefix}
   181  }
   182  
   183  func (l Logger) logging(message string, params ...interface{}) string {
   184  	return "[" + l.prefix + loggingWithDepth(l.pkg) + "] " + fmt.Sprintf(message, params...)
   185  }
   186  
   187  func (l Logger) InfoS(message string, params ...interface{}) {
   188  	klog.InfoSDepth(1, l.logging(message), params...)
   189  }
   190  
   191  func (l Logger) Infof(message string, params ...interface{}) {
   192  	klog.InfofDepth(1, l.logging(message, params...))
   193  }
   194  
   195  func (l Logger) InfofV(level int, message string, params ...interface{}) {
   196  	klog.V(klog.Level(level)).InfofDepth(1, l.logging(message, params...))
   197  }
   198  
   199  func (l Logger) Warningf(message string, params ...interface{}) {
   200  	klog.WarningfDepth(1, l.logging(message, params...))
   201  }
   202  
   203  func (l Logger) Errorf(message string, params ...interface{}) {
   204  	klog.ErrorfDepth(1, l.logging(message, params...))
   205  }
   206  
   207  func (l Logger) ErrorS(err error, message string, params ...interface{}) {
   208  	klog.ErrorSDepth(1, err, l.logging(message), params...)
   209  }
   210  
   211  func (l Logger) Fatalf(message string, params ...interface{}) {
   212  	klog.FatalfDepth(1, l.logging(message, params...))
   213  }