github.com/kaisenlinux/docker@v0.0.0-20230510090727-ea55db55fac7/swarmkit/log/context.go (about)

     1  package log
     2  
     3  import (
     4  	"context"
     5  	"path"
     6  
     7  	"github.com/sirupsen/logrus"
     8  )
     9  
    10  var (
    11  	// G is an alias for GetLogger.
    12  	//
    13  	// We may want to define this locally to a package to get package tagged log
    14  	// messages.
    15  	G = GetLogger
    16  
    17  	// L is an alias for the the standard logger.
    18  	L = logrus.NewEntry(logrus.StandardLogger())
    19  )
    20  
    21  type (
    22  	loggerKey struct{}
    23  	moduleKey struct{}
    24  )
    25  
    26  // WithLogger returns a new context with the provided logger. Use in
    27  // combination with logger.WithField(s) for great effect.
    28  func WithLogger(ctx context.Context, logger *logrus.Entry) context.Context {
    29  	return context.WithValue(ctx, loggerKey{}, logger)
    30  }
    31  
    32  // WithFields returns a new context with added fields to logger.
    33  func WithFields(ctx context.Context, fields logrus.Fields) context.Context {
    34  	logger := ctx.Value(loggerKey{})
    35  
    36  	if logger == nil {
    37  		logger = L
    38  	}
    39  	return WithLogger(ctx, logger.(*logrus.Entry).WithFields(fields))
    40  }
    41  
    42  // WithField is convenience wrapper around WithFields.
    43  func WithField(ctx context.Context, key, value string) context.Context {
    44  	return WithFields(ctx, logrus.Fields{key: value})
    45  }
    46  
    47  // GetLogger retrieves the current logger from the context. If no logger is
    48  // available, the default logger is returned.
    49  func GetLogger(ctx context.Context) *logrus.Entry {
    50  	logger := ctx.Value(loggerKey{})
    51  
    52  	if logger == nil {
    53  		return L
    54  	}
    55  
    56  	return logger.(*logrus.Entry)
    57  }
    58  
    59  // WithModule adds the module to the context, appending it with a slash if a
    60  // module already exists. A module is just a roughly correlated defined by the
    61  // call tree for a given context.
    62  //
    63  // As an example, we might have a "node" module already part of a context. If
    64  // this function is called with "tls", the new value of module will be
    65  // "node/tls".
    66  //
    67  // Modules represent the call path. If the new module and last module are the
    68  // same, a new module entry will not be created. If the new module and old
    69  // older module are the same but separated by other modules, the cycle will be
    70  // represented by the module path.
    71  func WithModule(ctx context.Context, module string) context.Context {
    72  	parent := GetModulePath(ctx)
    73  
    74  	if parent != "" {
    75  		// don't re-append module when module is the same.
    76  		if path.Base(parent) == module {
    77  			return ctx
    78  		}
    79  
    80  		module = path.Join(parent, module)
    81  	}
    82  
    83  	ctx = WithLogger(ctx, GetLogger(ctx).WithField("module", module))
    84  	return context.WithValue(ctx, moduleKey{}, module)
    85  }
    86  
    87  // GetModulePath returns the module path for the provided context. If no module
    88  // is set, an empty string is returned.
    89  func GetModulePath(ctx context.Context) string {
    90  	module := ctx.Value(moduleKey{})
    91  	if module == nil {
    92  		return ""
    93  	}
    94  
    95  	return module.(string)
    96  }