123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- package log
- import (
- "context"
- "github.com/sirupsen/logrus"
- "go.opencensus.io/trace"
- )
- type entryContextKeyType int
- const _entryContextKey entryContextKeyType = iota
- var (
- // L is the default, blank logging entry. WithField and co. all return a copy
- // of the original entry, so this will not leak fields between calls.
- //
- // Do NOT modify fields directly, as that will corrupt state for all users and
- // is not thread safe.
- // Instead, use `L.With*` or `L.Dup()`. Or `G(context.Background())`.
- L = logrus.NewEntry(logrus.StandardLogger())
- // G is an alias for GetEntry
- G = GetEntry
- // S is an alias for SetEntry
- S = SetEntry
- // U is an alias for UpdateContext
- U = UpdateContext
- )
- // GetEntry returns a `logrus.Entry` stored in the context, if one exists.
- // Otherwise, it returns a default entry that points to the current context.
- //
- // Note: if the a new entry is returned, it will reference the passed in context.
- // However, existing contexts may be stored in parent contexts and additionally reference
- // earlier contexts.
- // Use `UpdateContext` to update the entry and context.
- func GetEntry(ctx context.Context) *logrus.Entry {
- entry := fromContext(ctx)
- if entry == nil {
- entry = L.WithContext(ctx)
- }
- return entry
- }
- // SetEntry updates the log entry in the context with the provided fields, and
- // returns both. It is equivalent to:
- //
- // entry := GetEntry(ctx).WithFields(fields)
- // ctx = WithContext(ctx, entry)
- //
- // See WithContext for more information.
- func SetEntry(ctx context.Context, fields logrus.Fields) (context.Context, *logrus.Entry) {
- e := GetEntry(ctx)
- if len(fields) > 0 {
- e = e.WithFields(fields)
- }
- return WithContext(ctx, e)
- }
- // UpdateContext extracts the log entry from the context, and, if the entry's
- // context points to a parent's of the current context, ands the entry
- // to the most recent context. It is equivalent to:
- //
- // entry := GetEntry(ctx)
- // ctx = WithContext(ctx, entry)
- //
- // This allows the entry to reference the most recent context and any new
- // values (such as span contexts) added to it.
- //
- // See WithContext for more information.
- func UpdateContext(ctx context.Context) context.Context {
- // there is no way to check its ctx (and not one of its parents) that contains `e`
- // so, at a slight cost, force add `e` to the context
- ctx, _ = WithContext(ctx, GetEntry(ctx))
- return ctx
- }
- // WithContext returns a context that contains the provided log entry.
- // The entry can be extracted with `GetEntry` (`G`)
- //
- // The entry in the context is a copy of `entry` (generated by `entry.WithContext`)
- func WithContext(ctx context.Context, entry *logrus.Entry) (context.Context, *logrus.Entry) {
- // regardless of the order, entry.Context != GetEntry(ctx)
- // here, the returned entry will reference the supplied context
- entry = entry.WithContext(ctx)
- ctx = context.WithValue(ctx, _entryContextKey, entry)
- return ctx, entry
- }
- // Copy extracts the tracing Span and logging entry from the src Context, if they
- // exist, and adds them to the dst Context.
- //
- // This is useful to share tracing and logging between contexts, but not the
- // cancellation. For example, if the src Context has been cancelled but cleanup
- // operations triggered by the cancellation require a non-cancelled context to
- // execute.
- func Copy(dst context.Context, src context.Context) context.Context {
- if s := trace.FromContext(src); s != nil {
- dst = trace.NewContext(dst, s)
- }
- if e := fromContext(src); e != nil {
- dst, _ = WithContext(dst, e)
- }
- return dst
- }
- func fromContext(ctx context.Context) *logrus.Entry {
- e, _ := ctx.Value(_entryContextKey).(*logrus.Entry)
- return e
- }
|