pkg/model/log.go (150 lines of code) (raw):
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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 model
import (
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
import (
"github.com/apache/dubbo-go-pixiu/pkg/logger"
)
type Log struct {
Level string `json:"level" yaml:"level"`
Development bool `json:"development" yaml:"development"`
DisableCaller bool `json:"disableCaller" yaml:"disableCaller"`
DisableStacktrace bool `json:"disableStacktrace" yaml:"disableStacktrace"`
Sampling SamplingConfig `json:"sampling" yaml:"sampling"`
Encoding string `json:"encoding" yaml:"encoding"`
EncoderConfig EncoderConfig `json:"encoderConfig" yaml:"encoderConfig"`
OutputPaths []string `json:"outputPaths" yaml:"outputPaths"`
ErrorOutputPaths []string `json:"errorOutputPaths" yaml:"errorOutputPaths"`
InitialFields map[string]any `json:"initialFields" yaml:"initialFields"`
}
func (l *Log) Build() *zap.Config {
if l.Level == "" {
l.Level = "info"
}
lvl, err := zap.ParseAtomicLevel(l.Level)
if err != nil {
logger.Errorf("failed parse %s to zap.AtomicLevel", l.Level)
}
return &zap.Config{
Level: lvl,
Development: l.Development,
DisableCaller: l.DisableCaller,
DisableStacktrace: l.DisableStacktrace,
Sampling: l.Sampling.build(),
Encoding: l.Encoding,
EncoderConfig: l.EncoderConfig.build(),
OutputPaths: l.OutputPaths,
ErrorOutputPaths: l.ErrorOutputPaths,
InitialFields: l.InitialFields,
}
}
type SamplingConfig struct {
Initial int `json:"initial" yaml:"initial"`
Thereafter int `json:"thereafter" yaml:"thereafter"`
Hook func(zapcore.Entry, zapcore.SamplingDecision) `json:"-" yaml:"-"`
}
func (s *SamplingConfig) build() *zap.SamplingConfig {
if s == nil {
return &zap.SamplingConfig{}
}
return &zap.SamplingConfig{
Initial: s.Initial,
Thereafter: s.Thereafter,
}
}
type EncoderConfig struct {
MessageKey string `json:"messageKey" yaml:"messageKey"`
LevelKey string `json:"levelKey" yaml:"levelKey"`
TimeKey string `json:"timeKey" yaml:"timeKey"`
NameKey string `json:"nameKey" yaml:"nameKey"`
CallerKey string `json:"callerKey" yaml:"callerKey"`
FunctionKey string `json:"functionKey" yaml:"functionKey"`
StacktraceKey string `json:"stacktraceKey" yaml:"stacktraceKey"`
SkipLineEnding bool `json:"skipLineEnding" yaml:"skipLineEnding"`
LineEnding string `json:"lineEnding" yaml:"lineEnding"`
EncodeLevel string `json:"levelEncoder" yaml:"levelEncoder"`
EncodeTime string `json:"timeEncoder" yaml:"timeEncoder"`
EncodeDuration string `json:"durationEncoder" yaml:"durationEncoder"`
EncodeCaller string `json:"callerEncoder" yaml:"callerEncoder"`
EncodeName string `json:"nameEncoder" yaml:"nameEncoder"`
ConsoleSeparator string `json:"consoleSeparator" yaml:"consoleSeparator"`
}
func (e *EncoderConfig) build() zapcore.EncoderConfig {
if e == nil {
return zapcore.EncoderConfig{}
}
return zapcore.EncoderConfig{
MessageKey: e.MessageKey,
LevelKey: e.LevelKey,
TimeKey: e.TimeKey,
NameKey: e.NameKey,
CallerKey: e.CallerKey,
FunctionKey: e.FunctionKey,
StacktraceKey: e.StacktraceKey,
SkipLineEnding: e.SkipLineEnding,
LineEnding: e.LineEnding,
EncodeLevel: e.unmarshalLevelEncoder(),
EncodeTime: e.unmarshalTimeEncoder(),
EncodeDuration: e.unmarshalDurationEncoder(),
EncodeCaller: e.unmarshalCallerEncoder(),
EncodeName: e.unmarshalNameEncoder(),
ConsoleSeparator: e.ConsoleSeparator,
}
}
func (e *EncoderConfig) unmarshalLevelEncoder() zapcore.LevelEncoder {
switch e.EncodeLevel {
case "capital":
return zapcore.CapitalLevelEncoder
case "capitalColor":
return zapcore.CapitalColorLevelEncoder
case "color":
return zapcore.LowercaseColorLevelEncoder
default:
return zapcore.LowercaseLevelEncoder
}
}
func (e *EncoderConfig) unmarshalTimeEncoder() zapcore.TimeEncoder {
switch e.EncodeTime {
case "rfc3339nano", "RFC3339Nano":
return zapcore.RFC3339NanoTimeEncoder
case "rfc3339", "RFC3339":
return zapcore.RFC3339TimeEncoder
case "iso8601", "ISO8601":
return zapcore.ISO8601TimeEncoder
case "millis":
return zapcore.EpochMillisTimeEncoder
case "nanos":
return zapcore.EpochNanosTimeEncoder
default:
return zapcore.EpochTimeEncoder
}
}
func (e *EncoderConfig) unmarshalDurationEncoder() zapcore.DurationEncoder {
switch e.EncodeDuration {
case "string":
return zapcore.StringDurationEncoder
case "nanos":
return zapcore.NanosDurationEncoder
case "ms":
return zapcore.MillisDurationEncoder
default:
return zapcore.SecondsDurationEncoder
}
}
func (e *EncoderConfig) unmarshalCallerEncoder() zapcore.CallerEncoder {
switch e.EncodeCaller {
case "full":
return zapcore.FullCallerEncoder
default:
return zapcore.ShortCallerEncoder
}
}
func (e *EncoderConfig) unmarshalNameEncoder() zapcore.NameEncoder {
switch e.EncodeName {
case "full":
return zapcore.FullNameEncoder
default:
return zapcore.FullNameEncoder
}
}