...

Source file src/github.com/Microsoft/hcsshim/internal/log/context.go

Documentation: github.com/Microsoft/hcsshim/internal/log

     1  package log
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/sirupsen/logrus"
     7  	"go.opencensus.io/trace"
     8  )
     9  
    10  type entryContextKeyType int
    11  
    12  const _entryContextKey entryContextKeyType = iota
    13  
    14  var (
    15  	// L is the default, blank logging entry. WithField and co. all return a copy
    16  	// of the original entry, so this will not leak fields between calls.
    17  	//
    18  	// Do NOT modify fields directly, as that will corrupt state for all users and
    19  	// is not thread safe.
    20  	// Instead, use `L.With*` or `L.Dup()`. Or `G(context.Background())`.
    21  	L = logrus.NewEntry(logrus.StandardLogger())
    22  
    23  	// G is an alias for GetEntry
    24  	G = GetEntry
    25  
    26  	// S is an alias for SetEntry
    27  	S = SetEntry
    28  
    29  	// U is an alias for UpdateContext
    30  	U = UpdateContext
    31  )
    32  
    33  // GetEntry returns a `logrus.Entry` stored in the context, if one exists.
    34  // Otherwise, it returns a default entry that points to the current context.
    35  //
    36  // Note: if the a new entry is returned, it will reference the passed in context.
    37  // However, existing contexts may be stored in parent contexts and additionally reference
    38  // earlier contexts.
    39  // Use `UpdateContext` to update the entry and context.
    40  func GetEntry(ctx context.Context) *logrus.Entry {
    41  	entry := fromContext(ctx)
    42  
    43  	if entry == nil {
    44  		entry = L.WithContext(ctx)
    45  	}
    46  
    47  	return entry
    48  }
    49  
    50  // SetEntry updates the log entry in the context with the provided fields, and
    51  // returns both. It is equivalent to:
    52  //
    53  //	entry := GetEntry(ctx).WithFields(fields)
    54  //	ctx = WithContext(ctx, entry)
    55  //
    56  // See WithContext for more information.
    57  func SetEntry(ctx context.Context, fields logrus.Fields) (context.Context, *logrus.Entry) {
    58  	e := GetEntry(ctx)
    59  	if len(fields) > 0 {
    60  		e = e.WithFields(fields)
    61  	}
    62  	return WithContext(ctx, e)
    63  }
    64  
    65  // UpdateContext extracts the log entry from the context, and, if the entry's
    66  // context points to a parent's of the current context, ands the entry
    67  // to the most recent context. It is equivalent to:
    68  //
    69  //	entry := GetEntry(ctx)
    70  //	ctx = WithContext(ctx, entry)
    71  //
    72  // This allows the entry to reference the most recent context and any new
    73  // values (such as span contexts) added to it.
    74  //
    75  // See WithContext for more information.
    76  func UpdateContext(ctx context.Context) context.Context {
    77  	// there is no way to check its ctx (and not one of its parents) that contains `e`
    78  	// so, at a slight cost, force add `e` to the context
    79  	ctx, _ = WithContext(ctx, GetEntry(ctx))
    80  	return ctx
    81  }
    82  
    83  // WithContext returns a context that contains the provided log entry.
    84  // The entry can be extracted with `GetEntry` (`G`)
    85  //
    86  // The entry in the context is a copy of `entry` (generated by `entry.WithContext`)
    87  func WithContext(ctx context.Context, entry *logrus.Entry) (context.Context, *logrus.Entry) {
    88  	// regardless of the order, entry.Context != GetEntry(ctx)
    89  	// here, the returned entry will reference the supplied context
    90  	entry = entry.WithContext(ctx)
    91  	ctx = context.WithValue(ctx, _entryContextKey, entry)
    92  
    93  	return ctx, entry
    94  }
    95  
    96  // Copy extracts the tracing Span and logging entry from the src Context, if they
    97  // exist, and adds them to the dst Context.
    98  //
    99  // This is useful to share tracing and logging between contexts, but not the
   100  // cancellation. For example, if the src Context has been cancelled but cleanup
   101  // operations triggered by the cancellation require a non-cancelled context to
   102  // execute.
   103  func Copy(dst context.Context, src context.Context) context.Context {
   104  	if s := trace.FromContext(src); s != nil {
   105  		dst = trace.NewContext(dst, s)
   106  	}
   107  
   108  	if e := fromContext(src); e != nil {
   109  		dst, _ = WithContext(dst, e)
   110  	}
   111  
   112  	return dst
   113  }
   114  
   115  func fromContext(ctx context.Context) *logrus.Entry {
   116  	e, _ := ctx.Value(_entryContextKey).(*logrus.Entry)
   117  	return e
   118  }
   119  

View as plain text