github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/pkg/util/spanlogger/spanlogger.go (about)

     1  package spanlogger
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/go-kit/log"
     7  	"github.com/grafana/dskit/spanlogger"
     8  	"github.com/opentracing/opentracing-go"
     9  
    10  	"github.com/grafana/dskit/tenant"
    11  
    12  	util_log "github.com/grafana/loki/pkg/util/log"
    13  )
    14  
    15  type loggerCtxMarker struct{}
    16  
    17  const (
    18  	// TenantIDsTagName is the tenant IDs tag name.
    19  	TenantIDsTagName = spanlogger.TenantIDsTagName
    20  )
    21  
    22  type resolverProxy struct{}
    23  
    24  func (r *resolverProxy) TenantID(ctx context.Context) (string, error) {
    25  	return tenant.TenantID(ctx)
    26  }
    27  
    28  func (r *resolverProxy) TenantIDs(ctx context.Context) ([]string, error) {
    29  	return tenant.TenantIDs(ctx)
    30  }
    31  
    32  var (
    33  	loggerCtxKey = &loggerCtxMarker{}
    34  	resolver     = &resolverProxy{}
    35  )
    36  
    37  // SpanLogger unifies tracing and logging, to reduce repetition.
    38  type SpanLogger = spanlogger.SpanLogger
    39  
    40  // New makes a new SpanLogger with a log.Logger to send logs to. The provided context will have the logger attached
    41  // to it and can be retrieved with FromContext.
    42  func New(ctx context.Context, method string, kvps ...interface{}) (*SpanLogger, context.Context) {
    43  	return spanlogger.New(ctx, util_log.Logger, method, resolver, kvps...)
    44  }
    45  
    46  // NewWithLogger is like New but allows to pass a logger.
    47  func NewWithLogger(ctx context.Context, logger log.Logger, method string, kvps ...interface{}) (*SpanLogger, context.Context) {
    48  	return spanlogger.New(ctx, logger, method, resolver, kvps...)
    49  }
    50  
    51  // FromContext returns a SpanLogger using the current parent span.
    52  // If there is no parent span, the SpanLogger will only log to the logger
    53  // within the context. If the context doesn't have a logger, the fallback
    54  // logger is used.
    55  func FromContext(ctx context.Context) *SpanLogger {
    56  	return spanlogger.FromContext(ctx, util_log.Logger, resolver)
    57  }
    58  
    59  // FromContextWithFallback returns a span logger using the current parent span.
    60  // IF there is no parent span, the SpanLogger will only log to the logger
    61  // within the context. If the context doesn't have a logger, the fallback
    62  // logger is used.
    63  func FromContextWithFallback(ctx context.Context, fallback log.Logger) *SpanLogger {
    64  	logger, ok := ctx.Value(loggerCtxKey).(log.Logger)
    65  	if !ok {
    66  		logger = fallback
    67  	}
    68  	sp := opentracing.SpanFromContext(ctx)
    69  	if sp == nil {
    70  		sp = defaultNoopSpan
    71  	}
    72  	return &SpanLogger{
    73  		Logger: util_log.WithContext(ctx, logger),
    74  		Span:   sp,
    75  	}
    76  }