log

package
v0.17.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 2, 2024 License: MIT Imports: 19 Imported by: 0

Documentation

Index

Constants

View Source
const (
	LevelTrace = "trace"
	LevelDebug = "debug"
	LevelInfo  = "info"
	LevelWarn  = "warn"
	LevelError = "error"

	PriorityTrace = 0
	PriorityDebug = 1
	PriorityInfo  = 2
	PriorityWarn  = 3
	PriorityError = 4
)
View Source
const MessageAttributeLoggerContext = "logger:context"

Variables

This section is empty.

Functions

func AddHandlerFactory

func AddHandlerFactory(typ string, factory HandlerFactory)

func AddHandlerIoWriterFactory

func AddHandlerIoWriterFactory(typ string, factory IoWriterWriterFactory)

func AppendContextFields added in v0.13.0

func AppendContextFields(ctx context.Context, newFields map[string]any) context.Context

AppendContextFields appends the fields to the existing local context, creating a new context containing the merged fields.

Any existing fields with the same key as any new field provided will be overwritten.

This method breaks mutation links for the local context only. If you mutate global fields on the returned context and the original context was already mutable, it will see these changes as well. Example:

func mutateFields() {
	ctx := log.InitContext(context.Background())
	localCtx := log.AppendContextFields(ctx, map[string]any{
		"field": "value",
	})

	// mutations of local fields are only propagated to the local context
	localCtx = log.MutateContextFields(localCtx, map[string]any{
		"field": "new_value",
	})
	localFields := log.LocalOnlyContextFieldsResolver(localCtx)
	print(localFields["field"]) // "new_value"
	// the parent context wasn't changed
	localFields = log.LocalOnlyContextFieldsResolver(ctx)
	print(len(localFields)) // 0

	// mutations of global fields are still propagated to the original context
	localCtx = log.MutateGlobalContextFields(localCtx, map[string]any{
		"other_field": "other_value",
	})
	globalFields := log.GlobalContextFieldsResolver(ctx)
	print(globalFields["other_field"]) // "other_value"
}

func AppendGlobalContextFields added in v0.13.0

func AppendGlobalContextFields(ctx context.Context, newFields map[string]any) context.Context

AppendGlobalContextFields is similar to AppendContextFields, but appends to global fields instead.

func ContextFieldsResolver

func ContextFieldsResolver(ctx context.Context) map[string]any

ContextFieldsResolver extracts the local and global fields from a context and, if not present, it returns an empty map.

Global fields overwrite local fields of the same name.

func FormatterConsole

func FormatterConsole(timestamp string, level int, format string, args []interface{}, err error, data Data) ([]byte, error)

func FormatterJson

func FormatterJson(timestamp string, level int, format string, args []interface{}, err error, data Data) ([]byte, error)

func GetMockedStackTrace

func GetMockedStackTrace(depthSkip int) string

func GetStackTrace

func GetStackTrace(depthSkip int) string

GetStackTrace constructs the current stacktrace. depthSkip defines how many steps of the stacktrace should be skipped. This is useful to not clutter the stacktrace with logging function calls.

func GlobalContextFieldsResolver added in v0.13.0

func GlobalContextFieldsResolver(ctx context.Context) map[string]any

GlobalContextFieldsResolver extracts the global fields from a context and, if not present, it returns an empty map.

func InitContext added in v0.13.0

func InitContext(ctx context.Context) context.Context

InitContext returns a new context capable of carrying (mutable) local and global logger fields.

---------------------------------------------------------------------------------------------------------------------

A note about local and global context fields:

  • A local field is private to the current application. It will NOT be attached to stream.Messages or transferred in some other way to another service. Thus, it is somewhat cheaper to add local fields to a context as they will only not affect any downstream applications or increase message size.
  • A global field is the inverse of a local field. It will be forwarded with a message and thus "infect" other services. For some fields this might be desirable, for example, to record the identity of the user of an event. You should however be careful when adding many global fields as they will increase the size of any encoded message.

When logging messages, global fields overwrite local fields if they share the same name.

---------------------------------------------------------------------------------------------------------------------

A note about mutability: After using any of the methods returning a new context from this file (InitContext, AppendContextFields, MutateContextFields, AppendGlobalContextFields, MutateGlobalContextFields), the returned context will be mutable. This means that you can add context fields using MutateContextFields or MutateGlobalContextFields to the existing context (even though a new context is returned, it will be the same context if the context was already mutable). This allows for the following pattern:

func caller(ctx context.Context, logger log.Logger, input int) {
	ctx = log.InitContext(ctx)

	if result, err := callee(ctx, input); err == nil {
		logger.WithContext(ctx).Info("Computed result %d", result)
	} else {
		logger.WithContext(ctx).Error("Failed to compute result: %w", err)
	}
}

func callee(ctx context.Context, input int) (int, error) {
	_ = log.MutateContextFields(ctx, map[string]any{
		"input_value": input,
	})

	if input < 10 {
		return 0, fmt.Errorf("input must not be smaller than 10")
	}

	return input - 10, nil
}

After the callee returns, we add the (now mutated) context to the logger and will see the original input value in the logged fields even though it was for example not included in the error we got back.

func LevelName

func LevelName(level int) string

func LevelPriority

func LevelPriority(level string) int

func LocalOnlyContextFieldsResolver added in v0.13.0

func LocalOnlyContextFieldsResolver(ctx context.Context) map[string]any

LocalOnlyContextFieldsResolver extracts the local fields from a context and, if not present, it returns an empty map.

Warning: Besides very specific circumstances this method is most likely not what you want. Consider using GlobalContextFieldsResolver or ContextFieldsResolver instead. Outside of tests there shouldn't normally be a need to ignore any configured global fields from a context.

func MainLoggerConfigPostProcessor

func MainLoggerConfigPostProcessor(config cfg.GosoConf) (bool, error)

func MutateContextFields added in v0.13.0

func MutateContextFields(ctx context.Context, newFields map[string]any) context.Context

MutateContextFields is similar to AppendContextFields, but it mutates the fields from the context if the context already contains fields which can be mutated. Otherwise, it initializes a new context able to carry fields in the future.

func MutateGlobalContextFields added in v0.13.0

func MutateGlobalContextFields(ctx context.Context, newFields map[string]any) context.Context

MutateGlobalContextFields is similar to MutateContextFields, but mutates to global fields instead.

func NewHandlerIoWriter

func NewHandlerIoWriter(level string, channels []string, formatter Formatter, timestampFormat string, writer io.Writer) *handlerIoWriter

func NewIoWriterFile

func NewIoWriterFile(path string) (io.Writer, error)

func NewLogger

func NewLogger() *gosoLogger

func NewLoggerWithInterfaces

func NewLoggerWithInterfaces(clock clock.Clock, handlers []Handler) *gosoLogger

func SentryContextConfigProvider

func SentryContextConfigProvider(config ConfigProvider, handler *HandlerSentry) error

func SentryContextEcsMetadataProvider

func SentryContextEcsMetadataProvider(_ ConfigProvider, handler *HandlerSentry) error

func UnmarshalHandlerSettingsFromConfig

func UnmarshalHandlerSettingsFromConfig(config cfg.Config, name string, settings interface{})

Types

type ConfigProvider

type ConfigProvider interface {
	AllSettings() map[string]interface{}
}

type ContextEnforcingLogger

type ContextEnforcingLogger struct {
	// contains filtered or unexported fields
}

func NewContextEnforcingLogger

func NewContextEnforcingLogger(logger Logger) *ContextEnforcingLogger

func NewContextEnforcingLoggerWithInterfaces

func NewContextEnforcingLoggerWithInterfaces(logger Logger, stacktraceProvider StackTraceProvider, notifier Logger) *ContextEnforcingLogger

func (*ContextEnforcingLogger) Debug

func (l *ContextEnforcingLogger) Debug(msg string, args ...interface{})

func (*ContextEnforcingLogger) Enable

func (l *ContextEnforcingLogger) Enable()

func (*ContextEnforcingLogger) Error

func (l *ContextEnforcingLogger) Error(msg string, args ...interface{})

func (*ContextEnforcingLogger) Info

func (l *ContextEnforcingLogger) Info(msg string, args ...interface{})

func (*ContextEnforcingLogger) Warn

func (l *ContextEnforcingLogger) Warn(msg string, args ...interface{})

func (*ContextEnforcingLogger) WithChannel

func (l *ContextEnforcingLogger) WithChannel(channel string) Logger

func (*ContextEnforcingLogger) WithContext

func (l *ContextEnforcingLogger) WithContext(ctx context.Context) Logger

func (*ContextEnforcingLogger) WithFields

func (l *ContextEnforcingLogger) WithFields(fields Fields) Logger

type ContextFieldsResolverFunction added in v0.13.0

type ContextFieldsResolverFunction func(ctx context.Context) map[string]any

type Data

type Data struct {
	Context       context.Context
	Channel       string
	ContextFields map[string]interface{}
	Fields        map[string]interface{}
}

type EcsMetadata

type EcsMetadata map[string]interface{}

func ReadEcsMetadata

func ReadEcsMetadata() (EcsMetadata, error)

type Fields

type Fields map[string]interface{}

type Formatter

type Formatter func(timestamp string, level int, format string, args []interface{}, err error, data Data) ([]byte, error)

type GosoLogger

type GosoLogger interface {
	Logger
	Option(opt ...Option) error
}

type Handler

type Handler interface {
	Channels() []string
	Level() int
	Log(timestamp time.Time, level int, msg string, args []interface{}, err error, data Data) error
}

func NewCliHandler

func NewCliHandler() Handler

func NewHandlersFromConfig

func NewHandlersFromConfig(config cfg.Config) ([]Handler, error)

type HandlerFactory

type HandlerFactory func(config cfg.Config, name string) (Handler, error)

type HandlerIoWriterSettings

type HandlerIoWriterSettings struct {
	Level           string   `cfg:"level" default:"info"`
	Channels        []string `cfg:"channels"`
	Formatter       string   `cfg:"formatter" default:"console"`
	TimestampFormat string   `cfg:"timestamp_format" default:"15:04:05.000"`
	Writer          string   `cfg:"writer" default:"stdout"`
}

type HandlerSentry

type HandlerSentry struct {
	// contains filtered or unexported fields
}

func NewHandlerSentry

func NewHandlerSentry(config cfg.Config) (*HandlerSentry, error)

func (*HandlerSentry) Channels

func (h *HandlerSentry) Channels() []string

func (*HandlerSentry) Level

func (h *HandlerSentry) Level() int

func (*HandlerSentry) Log

func (h *HandlerSentry) Log(_ time.Time, _ int, _ string, _ []interface{}, err error, data Data) error

func (*HandlerSentry) WithContext

func (h *HandlerSentry) WithContext(name string, context map[string]interface{})

type HandlerSettings

type HandlerSettings struct {
	Type string `cfg:"type"`
}

type IoWriterWriterFactory

type IoWriterWriterFactory func(config cfg.Config, configKey string) (io.Writer, error)

type Logger

type Logger interface {
	Debug(format string, args ...interface{})
	Info(format string, args ...interface{})
	Warn(format string, args ...interface{})
	Error(format string, args ...interface{})

	WithChannel(channel string) Logger
	WithContext(ctx context.Context) Logger
	WithFields(Fields) Logger
}

func NewCliLogger

func NewCliLogger() Logger

func NewSamplingLogger

func NewSamplingLogger(logger Logger, interval time.Duration) Logger

type LoggerSettings

type LoggerSettings struct {
	Handlers map[string]HandlerSettings `cfg:"handlers"`
}

type MessageWithLoggingFieldsEncoder

type MessageWithLoggingFieldsEncoder struct {
	// contains filtered or unexported fields
}

func NewMessageWithLoggingFieldsEncoder

func NewMessageWithLoggingFieldsEncoder(_ cfg.Config, logger Logger) *MessageWithLoggingFieldsEncoder

func NewMessageWithLoggingFieldsEncoderWithInterfaces

func NewMessageWithLoggingFieldsEncoderWithInterfaces(logger Logger) *MessageWithLoggingFieldsEncoder

func (MessageWithLoggingFieldsEncoder) Decode

func (m MessageWithLoggingFieldsEncoder) Decode(ctx context.Context, _ interface{}, attributes map[string]string) (context.Context, map[string]string, error)

func (MessageWithLoggingFieldsEncoder) Encode

func (m MessageWithLoggingFieldsEncoder) Encode(ctx context.Context, _ interface{}, attributes map[string]string) (context.Context, map[string]string, error)

type Option

type Option func(logger *gosoLogger) error

func WithContextFieldsResolver

func WithContextFieldsResolver(resolvers ...ContextFieldsResolverFunction) Option

func WithFields

func WithFields(tags map[string]interface{}) Option

func WithHandlers

func WithHandlers(handler ...Handler) Option

type SamplingLogger

type SamplingLogger struct {
	Logger
	// contains filtered or unexported fields
}

func NewSamplingLoggerWithInterfaces

func NewSamplingLoggerWithInterfaces(logger Logger, clock clock.Clock, interval time.Duration) *SamplingLogger

func (*SamplingLogger) Debug

func (l *SamplingLogger) Debug(msg string, args ...interface{})

func (*SamplingLogger) Error

func (l *SamplingLogger) Error(msg string, args ...interface{})

func (*SamplingLogger) Info

func (l *SamplingLogger) Info(msg string, args ...interface{})

func (*SamplingLogger) Warn

func (l *SamplingLogger) Warn(msg string, args ...interface{})

func (*SamplingLogger) WithChannel

func (l *SamplingLogger) WithChannel(channel string) Logger

func (*SamplingLogger) WithContext

func (l *SamplingLogger) WithContext(ctx context.Context) Logger

func (*SamplingLogger) WithFields

func (l *SamplingLogger) WithFields(fields Fields) Logger

type SentryContextProvider

type SentryContextProvider func(config ConfigProvider, sentryHook *HandlerSentry) error

type SentryHub

type SentryHub interface {
	ConfigureScope(f func(scope *sentry.Scope))
	WithScope(f func(scope *sentry.Scope))
	CaptureException(exception error) *sentry.EventID
	Flush(timeout time.Duration) bool
}

func NewSentryHub

func NewSentryHub(config cfg.Config) (SentryHub, error)

func NewSentryHubWithSettings

func NewSentryHubWithSettings(settings *SentryHubSettings) (SentryHub, error)

type SentryHubSettings

type SentryHubSettings struct {
	Dsn         string
	Environment string
	AppName     string
}

type StackTraceProvider

type StackTraceProvider func(depthSkip int) string

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL