You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

104 lines
2.5 KiB

package logger
import (
"context"
"sync"
)
const (
requestIDField string = "request-id"
userIDField string = "user-id"
serviceIDField string = "service-id"
configIDField string = "config-id"
)
//nolint:gochecknoglobals
var (
logKeys = make(map[key]struct{})
mtx sync.RWMutex
)
type key string
func SetFieldCtx(ctx context.Context, name, val string) context.Context {
nameKey := key("logger." + name)
mtx.RLock()
_, ok := logKeys[nameKey]
mtx.RUnlock()
if !ok {
mtx.Lock()
logKeys[nameKey] = struct{}{}
mtx.Unlock()
}
return context.WithValue(ctx, nameKey, val)
}
// WithFieldsContext получение контекста из полей явного типа,
// при логировании поля будут прописаны в external логгер (zap).
func WithFieldsContext(ctx context.Context, fields ...Field) context.Context {
storage, isNew := getStorageFromCtx(ctx)
for _, field := range fields {
storage.SetField(field)
}
if isNew {
// если в контексте не был записан storage возвращаем с родительским контекстом
return withStorageContext(ctx, storage)
}
// если он уже есть, достаточно вернуть текущий контекст, тк storage ссылочный
return ctx
}
func GetFieldCtx(ctx context.Context, name string) string {
if ctx == nil {
return ""
}
nameKey := "logger." + name
a := ctx.Value(nameKey)
if a == nil {
return ""
}
requestID, ok := a.(string)
if !ok {
return ""
}
return requestID
}
// SetRequestIDCtx sets request-id log field via context.
// Tip: use HTTPMiddleware instead.
func SetRequestIDCtx(ctx context.Context, val string) context.Context {
return SetFieldCtx(ctx, requestIDField, val)
}
func SetUserIDCtx(ctx context.Context, val string) context.Context {
return SetFieldCtx(ctx, userIDField, val)
}
func GetRequestIDCtx(ctx context.Context) string {
return GetFieldCtx(ctx, requestIDField)
}
func GetUserIDCtx(ctx context.Context) string {
return GetFieldCtx(ctx, userIDField)
}
func SetServiceIDCtx(ctx context.Context, val string) context.Context {
return SetFieldCtx(ctx, serviceIDField, val)
}
func GetServiceIDCtx(ctx context.Context) string {
return GetFieldCtx(ctx, serviceIDField)
}
func SetConfigIDCtx(ctx context.Context, val string) context.Context {
return SetFieldCtx(ctx, configIDField, val)
}
func GetConfigIDCtx(ctx context.Context) string {
return GetFieldCtx(ctx, configIDField)
}