func GetLoggableValue(ctx Valuer, key string) interface{} {
	fields := GetLoggableValues(ctx)
	if v, ok := fields[key]; ok {
		return v
	}
	return nil
}
GetLoggableValue returns the value of the metadata currently attached to the Context.
package logger
import (
	"context"
	"github.com/sirupsen/logrus"
)
type contextKey int
const (
	logFieldsKey contextKey = iota
)
type Loggable interface {
	LogFields() logrus.Fields
}
type Valuer interface {
	Value(key interface{}) interface{}
}
type keyValueContext struct {
	context.Context
	key   string
	value interface{}
}
func (c *keyValueContext) Value(key interface{}) interface{} {
	if key == logFieldsKey {
		prev := GetLoggableValues(c.Context)
		prev[c.key] = c.value
		return prev
	}
	return c.Context.Value(key)
}
type loggableContext struct {
	context.Context
	loggable Loggable
}
func (c *loggableContext) Value(key interface{}) interface{} {
	if key == logFieldsKey {
		prev := GetLoggableValues(c.Context)
		for k, v := range c.loggable.LogFields() {
			prev[k] = v
		}
		return prev
	}
	return c.Context.Value(key)
}
func WithField(ctx context.Context, k string, v interface{}) context.Context {
	return &keyValueContext{Context: ctx, key: k, value: v}
}
func WithFields(ctx context.Context, m logrus.Fields) context.Context {
	for k, v := range m {
		ctx = WithField(ctx, k, v)
	}
	return ctx
}
func WithLoggable(ctx context.Context, l Loggable) context.Context {
	return WithFields(ctx, l.LogFields())
}
func WatchingLoggable(ctx context.Context, l Loggable) context.Context {
	return &loggableContext{Context: ctx, loggable: l}
}