164 lines
5.7 KiB
Go
164 lines
5.7 KiB
Go
|
// Licensed to Elasticsearch B.V. under one or more contributor
|
||
|
// license agreements. See the NOTICE file distributed with
|
||
|
// this work for additional information regarding copyright
|
||
|
// ownership. Elasticsearch B.V. licenses this file to you under
|
||
|
// the Apache License, Version 2.0 (the "License"); you may
|
||
|
// not use this file except in compliance with the License.
|
||
|
// You may obtain a copy of the License at
|
||
|
//
|
||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||
|
//
|
||
|
// Unless required by applicable law or agreed to in writing,
|
||
|
// software distributed under the License is distributed on an
|
||
|
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||
|
// KIND, either express or implied. See the License for the
|
||
|
// specific language governing permissions and limitations
|
||
|
// under the License.
|
||
|
|
||
|
package ecszap
|
||
|
|
||
|
import (
|
||
|
"go.uber.org/zap/zapcore"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
defaultLineEnding = zapcore.DefaultLineEnding
|
||
|
defaultEncodeName = zapcore.FullNameEncoder
|
||
|
defaultEncodeDuration = zapcore.NanosDurationEncoder
|
||
|
defaultEncodeLevel = zapcore.LowercaseLevelEncoder
|
||
|
defaultEncodeCaller = ShortCallerEncoder
|
||
|
|
||
|
callerKey = "log.origin"
|
||
|
logLevelKey = "log.level"
|
||
|
logNameKey = "log.logger"
|
||
|
messageKey = "message"
|
||
|
stackTraceKey = "log.origin.stack_trace"
|
||
|
timeKey = "@timestamp"
|
||
|
encodeTime = zapcore.ISO8601TimeEncoder
|
||
|
)
|
||
|
|
||
|
// EncoderConfig exports all non ECS related configurable settings.
|
||
|
// The configuration can be used to create an ECS compatible zapcore.Core
|
||
|
type EncoderConfig struct {
|
||
|
// EnableName controls if a logger's name should be serialized
|
||
|
// when available. If enabled, the EncodeName configuration is
|
||
|
// used for serialization.
|
||
|
EnableName bool `json:"enableName" yaml:"enableName"`
|
||
|
|
||
|
// EnableStackTrace controls if a stack trace should be serialized when available.
|
||
|
EnableStackTrace bool `json:"enableStackTrace" yaml:"enableStackTrace"`
|
||
|
|
||
|
// EnableCaller controls if the entry caller should be serialized.
|
||
|
// If enabled, the EncodeCaller configuration is used for serialization.
|
||
|
EnableCaller bool `json:"enableCaller" yaml:"enableCaller"`
|
||
|
|
||
|
// LineEnding defines the string used for line endings.
|
||
|
LineEnding string `json:"lineEnding" yaml:"lineEnding"`
|
||
|
|
||
|
// EncodeName defines how to encode a loggers name.
|
||
|
// It will only be applied if EnableName is set to true.
|
||
|
EncodeName zapcore.NameEncoder `json:"nameEncoder" yaml:"nameEncoder"`
|
||
|
|
||
|
// EncodeLevel sets the log level for which any context should be logged.
|
||
|
EncodeLevel zapcore.LevelEncoder `json:"levelEncoder" yaml:"levelEncoder"`
|
||
|
|
||
|
// EncodeDuration sets the format for encoding time.Duration values.
|
||
|
EncodeDuration zapcore.DurationEncoder `json:"durationEncoder" yaml:"durationEncoder"`
|
||
|
|
||
|
// EncodeCaller defines how an entry caller should be serialized.
|
||
|
// It will only be applied if EnableCaller is set to true.
|
||
|
EncodeCaller CallerEncoder `json:"callerEncoder" yaml:"callerEncoder"`
|
||
|
}
|
||
|
|
||
|
// NewDefaultEncoderConfig returns an EncoderConfig with default settings.
|
||
|
func NewDefaultEncoderConfig() EncoderConfig {
|
||
|
return EncoderConfig{
|
||
|
EnableName: true,
|
||
|
EnableCaller: true,
|
||
|
EnableStackTrace: true,
|
||
|
LineEnding: defaultLineEnding,
|
||
|
EncodeName: defaultEncodeName,
|
||
|
EncodeLevel: defaultEncodeLevel,
|
||
|
EncodeDuration: defaultEncodeDuration,
|
||
|
EncodeCaller: defaultEncodeCaller,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ToZapCoreEncoderConfig transforms the ecszap.EncoderConfig into
|
||
|
// a zapcore.EncoderConfig
|
||
|
func (cfg EncoderConfig) ToZapCoreEncoderConfig() zapcore.EncoderConfig {
|
||
|
encCfg := zapcore.EncoderConfig{
|
||
|
MessageKey: messageKey,
|
||
|
LevelKey: logLevelKey,
|
||
|
TimeKey: timeKey,
|
||
|
EncodeTime: encodeTime,
|
||
|
LineEnding: cfg.LineEnding,
|
||
|
EncodeDuration: cfg.EncodeDuration,
|
||
|
EncodeName: cfg.EncodeName,
|
||
|
EncodeLevel: cfg.EncodeLevel,
|
||
|
}
|
||
|
if encCfg.EncodeDuration == nil {
|
||
|
encCfg.EncodeDuration = defaultEncodeDuration
|
||
|
}
|
||
|
if cfg.EnableName {
|
||
|
encCfg.NameKey = logNameKey
|
||
|
if encCfg.EncodeName == nil {
|
||
|
encCfg.EncodeName = defaultEncodeName
|
||
|
}
|
||
|
}
|
||
|
if cfg.EnableStackTrace {
|
||
|
encCfg.StacktraceKey = stackTraceKey
|
||
|
}
|
||
|
if cfg.EnableCaller {
|
||
|
encCfg.CallerKey = callerKey
|
||
|
if cfg.EncodeCaller == nil {
|
||
|
encCfg.EncodeCaller = defaultEncodeCaller
|
||
|
} else {
|
||
|
encCfg.EncodeCaller = zapcore.CallerEncoder(cfg.EncodeCaller)
|
||
|
}
|
||
|
}
|
||
|
if encCfg.EncodeLevel == nil {
|
||
|
encCfg.EncodeLevel = defaultEncodeLevel
|
||
|
}
|
||
|
return encCfg
|
||
|
}
|
||
|
|
||
|
// ECSCompatibleEncoderConfig takes an existing zapcore.EncoderConfig
|
||
|
// and sets ECS relevant configuration options to ECS conformant values.
|
||
|
// The returned zapcore.EncoderConfig can be used to create
|
||
|
// an ECS conformant encoder.
|
||
|
// Be aware that this will always replace any set EncodeCaller function
|
||
|
// with the ecszap.ShortCallerEncoder.
|
||
|
// This is a pure convenience function for making a transition from
|
||
|
// existing an zap logger to an ECS conformant zap loggers easier.
|
||
|
// It is recommended to make use of the ecszap.EncoderConfig whenever possible.
|
||
|
func ECSCompatibleEncoderConfig(cfg zapcore.EncoderConfig) zapcore.EncoderConfig {
|
||
|
// set the required MVP ECS keys
|
||
|
cfg.MessageKey = messageKey
|
||
|
cfg.LevelKey = logLevelKey
|
||
|
cfg.TimeKey = timeKey
|
||
|
if cfg.NameKey != "" {
|
||
|
cfg.NameKey = logNameKey
|
||
|
}
|
||
|
// set further ECS defined keys only if keys were defined,
|
||
|
// as zap omits these log attributes when keys are not defined
|
||
|
// and ecszap does not intend to change this logic
|
||
|
if cfg.StacktraceKey != "" {
|
||
|
cfg.StacktraceKey = stackTraceKey
|
||
|
}
|
||
|
if cfg.CallerKey != "" {
|
||
|
cfg.CallerKey = callerKey
|
||
|
cfg.EncodeCaller = defaultEncodeCaller
|
||
|
}
|
||
|
// always set the time encoding to the ISO8601 time format
|
||
|
cfg.EncodeTime = encodeTime
|
||
|
// ensure all required encoders are set
|
||
|
if cfg.EncodeDuration == nil {
|
||
|
cfg.EncodeDuration = defaultEncodeDuration
|
||
|
}
|
||
|
if cfg.EncodeLevel == nil {
|
||
|
cfg.EncodeLevel = defaultEncodeLevel
|
||
|
}
|
||
|
return cfg
|
||
|
}
|