| /* |
| * 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 |
| } |
| } |