zapecs

package module
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: May 28, 2021 License: MIT Imports: 5 Imported by: 0

README

zap-ecs

build

This package provides a zap logging layer that groups and serializes ECS compliant field keys into its appropriate JSON representations upon encoding. This is done via field aggregation and proxying on encoding time. Also, it providers helpers that create zap.Field instances of supported ECS fields

ECS Compatibility status

Please note that this currently only encompasses a small subset of the complete ECS standard (https://www.elastic.co/guide/en/ecs/current), so you may consider it a WIP. You can check the currently supported keys/fields at ecs/ecs_keys.go

Usage

Creating a zap.Logger instance

The logger implements and exposes the following interface, which can be composed for decoration if needed by the consumer:

// Derived interface from zap.Logger
type Logger interface {
SetLevel(level Level)
	Debug(msg string, fields ...zap.Field)
	Info(msg string, fields ...zap.Field)
	Warn(msg string, fields ...zap.Field)
	Error(msg string, fields ...zap.Field)
	Panic(msg string, fields ...zap.Field)
	Fatal(msg string, fields ...zap.Field)

	Flush() error
}

The ecs logger requires the following parameter struct:

type Options struct {
    BaseLoggerField zap.Field
    BaseTags        []string
    BaseLabels      []zap.Field
    Logger          *zap.Logger
}

In this context, BaseLoggerField is the zap.Field instance that identifies the logger and uses the "log.logger" field key, BaseTags is the zap.Field instance that identifies the log entry tags ("tags" field) and BaseLabels is an arbitrary set of fields that belong to the root level of any log entry and will be autoinjected on all messages

An example of a general purpose code based on environment variables could be the following

// Definition of base tags and fields to be inyected by default on log entries
var (
    baseLoggerField = zap.String(zapEcsKeys.FieldLogger, "my-app_(uber-go/zap)")
        baseTags        = func() []string { return []string{os.Getenv("ENVIRONMENT")} }
            baseFields      = func() []zap.Field {
                return []zap.Field{
                    zap.String(ecs.FieldLabelApplication, os.Getenv("APPLICATION_NAME")),
                    zap.String(ecs.FieldLabelService, os.Getenv("LOGGING_SERVICE_NAME")),
                    zap.String(ecs.FieldLabelEnvironment, os.Getenv("ENVIRONMENT")),
                    zap.String(ecs.FieldLabelLibVersion, "v0.0.1"),
                    zap.String(ecs.FieldLabelLibLanguage, os.Getenv("GO_VERSION")),
                    zap.String(ecs.FieldLabelPodName, os.Getenv("MY_POD_NAME")),
                    zap.String(ecs.FieldLabelNodeName, os.Getenv("MY_NODE_NAME")),
        }
    }
)

Then, the logger instance can be built from the application:

	cfg := zap.NewProductionConfig()

    // Adapt field names to ECS base:
    // https://www.elastic.co/guide/en/ecs/current/ecs-base.html
    cfg.EncoderConfig.MessageKey = zapEcsKeys.FieldMessage
    cfg.EncoderConfig.TimeKey = zapEcsKeys.FieldTimestamp
    cfg.EncoderConfig.LevelKey = "" // Omit it, we will generate it on our own (it conflicts with the ECS ObjectEncoder)
    cfg.DisableStacktrace = true    // Omit automatic stacktraces, these should be emitted by the recovery middleware


	l, err := cfg.Build()
	if err != nil {
		return nil, err
	}

	ecsLogger := zapEcs.NewECSLogger(zapEcs.Options{
		BaseLoggerField: baseLoggerField,
		BaseTags:        baseTags,
		BaseLabels:      baseFields,
		Logger:          l,
		Level:           cfg.Level.Level(),
	})

	if ecsLogger == nil {
	    return nil, errors.New("log: failed to create ECS log")
	}
	
	// use ecsLogger as needed
Helpers

For convenience, the encapsulated logger exposes the following methods from the native zap instance (use only if needed):

AsCoreLogger() zapcore.Core

AsSugaredLogger() *zap.SugaredLogger

Documentation

Index

Constants

View Source
const (
	// DebugLevel logs are typically voluminous, and are usually disabled in
	// production.
	DebugLevel Level = iota - 1
	// InfoLevel is the default logging priority.
	InfoLevel = zapcore.InfoLevel
	// WarnLevel logs are more important than Info, but don't need individual
	// human review.
	WarnLevel = zapcore.WarnLevel
	// ErrorLevel logs are high-priority. If an application is running smoothly,
	// it shouldn't generate any error-level logs.
	ErrorLevel = zapcore.ErrorLevel
	// DPanicLevel logs are particularly important errors. In development the
	// logger panics after writing the message.
	DPanicLevel = zapcore.DPanicLevel
	// PanicLevel logs a message, then panics.
	PanicLevel = zapcore.PanicLevel
	// FatalLevel logs a message, then calls os.Exit(1).
	FatalLevel = zapcore.FatalLevel
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Level

type Level = zapcore.Level

Level is a proxy type to zapcore.Level

type Logger

type Logger interface {
	SetLevel(level Level)

	Debug(msg string, fields ...zap.Field)
	Info(msg string, fields ...zap.Field)
	Warn(msg string, fields ...zap.Field)
	Error(msg string, fields ...zap.Field)
	Panic(msg string, fields ...zap.Field)
	Fatal(msg string, fields ...zap.Field)

	Flush() error
}

Derived interface from zap.Logger

func NewECSLogger

func NewECSLogger(o Options) Logger

type Options

type Options struct {
	BaseLoggerField zap.Field
	BaseTags        []string
	BaseLabels      []zap.Field
	Logger          *zap.Logger
}

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

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