* Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
*
* Licensed 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 logger
import (
"errors"
"math"
"os"
"sync"
"time"
"go.uber.org/zap/buffer"
"go.uber.org/zap/zapcore"
"yuanrong.org/kernel/runtime/libruntime/common/constants"
)
var (
_bufferPool = buffer.NewPool()
_interfacePool = sync.Pool{New: interfaceFunc}
)
type InterfaceEncoderConfig struct {
ModuleName string
HTTPMethod string
ModuleFrom string
TenantID string
FuncName string
FuncVer string
EncodeCaller zapcore.CallerEncoder
}
type interfaceEncoder struct {
*InterfaceEncoderConfig
buf *buffer.Buffer
podName string
spaced bool
}
func interfaceFunc() interface{} {
return &interfaceEncoder{}
}
func getInterfaceEncoder() *interfaceEncoder {
return _interfacePool.Get().(*interfaceEncoder)
}
func putInterfaceEncoder(enc *interfaceEncoder) {
enc.InterfaceEncoderConfig = nil
enc.spaced = false
enc.buf = nil
_interfacePool.Put(enc)
}
func NewInterfaceEncoder(cfg InterfaceEncoderConfig, spaced bool) zapcore.Encoder {
return newInterfaceEncoder(cfg, spaced)
}
func newInterfaceEncoder(cfg InterfaceEncoderConfig, spaced bool) *interfaceEncoder {
return &interfaceEncoder{
InterfaceEncoderConfig: &cfg,
buf: _bufferPool.Get(),
spaced: spaced,
podName: os.Getenv(constants.HostNameEnvKey),
}
}
func (enc *interfaceEncoder) Clone() zapcore.Encoder {
return enc.clone()
}
func (enc *interfaceEncoder) clone() *interfaceEncoder {
clone := getInterfaceEncoder()
clone.InterfaceEncoderConfig = enc.InterfaceEncoderConfig
clone.spaced = enc.spaced
clone.buf = _bufferPool.Get()
return clone
}
func (enc *interfaceEncoder) EncodeEntry(ent zapcore.Entry, fields []zapcore.Field) (*buffer.Buffer, error) {
final := enc.clone()
final.buf.AppendByte('[')
final.AppendString(ent.Time.UTC().Format("2006-01-02 15:04:05.000"))
final.buf.AppendByte(headerSeparator)
final.AppendString("INFO")
if ent.Caller.Defined {
final.buf.AppendByte(headerSeparator)
final.EncodeCaller(ent.Caller, final)
}
final.buf.AppendByte(']')
final.buf.AppendByte(headerSeparator)
final.buf.AppendByte('[')
if enc.podName != "" {
final.buf.AppendString(enc.podName)
}
final.buf.AppendByte(']')
final.buf.AppendByte(headerSeparator)
if enc.buf.Len() > 0 {
final.buf.Write(enc.buf.Bytes())
}
final.AppendString(ent.Message)
for _, field := range fields {
field.AddTo(final)
}
final.buf.AppendString(customDefaultLineEnding)
ret := final.buf
putInterfaceEncoder(final)
return ret, nil
}
func (enc *interfaceEncoder) AddString(key, val string) {
enc.buf.AppendString(val)
}
func (enc *interfaceEncoder) AppendString(val string) {
enc.buf.AppendString(val)
}
func (enc *interfaceEncoder) AddDuration(key string, val time.Duration) {
enc.AppendDuration(val)
}
func (enc *interfaceEncoder) addElementSeparator() {
last := enc.buf.Len() - 1
if last < 0 {
return
}
switch enc.buf.Bytes()[last] {
case headerSeparator:
return
default:
enc.buf.AppendByte(headerSeparator)
if enc.spaced {
enc.buf.AppendByte(' ')
}
}
}
func (enc *interfaceEncoder) AppendTime(val time.Time) {
cur := enc.buf.Len()
interfaceTimeEncode(val, enc)
if cur == enc.buf.Len() {
enc.AppendInt64(val.UnixNano())
}
}
func (enc *interfaceEncoder) AddArray(key string, marshaler zapcore.ArrayMarshaler) error {
return errors.New("unsupported method")
}
func (enc *interfaceEncoder) AddObject(key string, marshaler zapcore.ObjectMarshaler) error {
return errors.New("unsupported method")
}
func (enc *interfaceEncoder) AddBinary(key string, value []byte) {}
func (enc *interfaceEncoder) AddByteString(key string, val []byte) {
enc.AppendByteString(val)
}
func (enc *interfaceEncoder) AddBool(key string, value bool) {}
func (enc *interfaceEncoder) AddComplex64(k string, v complex64) { enc.AddComplex128(k, complex128(v)) }
func (enc *interfaceEncoder) AddFloat32(k string, v float32) { enc.AddFloat64(k, float64(v)) }
func (enc *interfaceEncoder) AddInt(k string, v int) { enc.AddInt64(k, int64(v)) }
func (enc *interfaceEncoder) AddInt32(k string, v int32) { enc.AddInt64(k, int64(v)) }
func (enc *interfaceEncoder) AddInt16(k string, v int16) { enc.AddInt64(k, int64(v)) }
func (enc *interfaceEncoder) AddInt8(k string, v int8) { enc.AddInt64(k, int64(v)) }
func (enc *interfaceEncoder) AddUint(k string, v uint) { enc.AddUint64(k, uint64(v)) }
func (enc *interfaceEncoder) AddUint32(k string, v uint32) { enc.AddUint64(k, uint64(v)) }
func (enc *interfaceEncoder) AddUint16(k string, v uint16) { enc.AddUint64(k, uint64(v)) }
func (enc *interfaceEncoder) AddUint8(k string, v uint8) { enc.AddUint64(k, uint64(v)) }
func (enc *interfaceEncoder) AddUintptr(k string, v uintptr) { enc.AddUint64(k, uint64(v)) }
func (enc *interfaceEncoder) AddComplex128(key string, val complex128) {
enc.AppendComplex128(val)
}
func (enc *interfaceEncoder) AddFloat64(key string, val float64) {
enc.AppendFloat64(val)
}
func (enc *interfaceEncoder) AddInt64(key string, val int64) {
enc.AppendInt64(val)
}
func (enc *interfaceEncoder) AddTime(key string, value time.Time) {
enc.AppendTime(value)
}
func (enc *interfaceEncoder) AddUint64(key string, value uint64) {}
func (enc *interfaceEncoder) AddReflected(key string, value interface{}) error {
return nil
}
func (enc *interfaceEncoder) OpenNamespace(key string) {}
func (enc *interfaceEncoder) AppendComplex128(val complex128) {}
func (enc *interfaceEncoder) AppendInt64(val int64) {
enc.addElementSeparator()
enc.buf.AppendInt(val)
}
func (enc *interfaceEncoder) AppendBool(val bool) {
enc.addElementSeparator()
enc.buf.AppendBool(val)
}
func (enc *interfaceEncoder) appendFloat(val float64, bitSize int) {
enc.addElementSeparator()
switch {
case math.IsNaN(val):
enc.buf.AppendString(`"NaN"`)
case math.IsInf(val, 1):
enc.buf.AppendString(`"+Inf"`)
case math.IsInf(val, -1):
enc.buf.AppendString(`"-Inf"`)
default:
enc.buf.AppendFloat(val, bitSize)
}
}
func (enc *interfaceEncoder) AppendUint64(val uint64) {
enc.addElementSeparator()
enc.buf.AppendUint(val)
}
func (enc *interfaceEncoder) AppendByteString(val []byte) {}
func (enc *interfaceEncoder) AppendDuration(val time.Duration) {}
func (enc *interfaceEncoder) AppendComplex64(v complex64) { enc.AppendComplex128(complex128(v)) }
func (enc *interfaceEncoder) AppendFloat64(v float64) { enc.appendFloat(v, float64bitSize) }
func (enc *interfaceEncoder) AppendFloat32(v float32) { enc.appendFloat(float64(v), float32bitSize) }
func (enc *interfaceEncoder) AppendInt(v int) { enc.AppendInt64(int64(v)) }
func (enc *interfaceEncoder) AppendInt32(v int32) { enc.AppendInt64(int64(v)) }
func (enc *interfaceEncoder) AppendInt16(v int16) { enc.AppendInt64(int64(v)) }
func (enc *interfaceEncoder) AppendInt8(v int8) { enc.AppendInt64(int64(v)) }
func (enc *interfaceEncoder) AppendUint(v uint) { enc.AppendUint64(uint64(v)) }
func (enc *interfaceEncoder) AppendUint32(v uint32) { enc.AppendUint64(uint64(v)) }
func (enc *interfaceEncoder) AppendUint16(v uint16) { enc.AppendUint64(uint64(v)) }
func (enc *interfaceEncoder) AppendUint8(v uint8) { enc.AppendUint64(uint64(v)) }
func (enc *interfaceEncoder) AppendUintptr(v uintptr) { enc.AppendUint64(uint64(v)) }
func interfaceTimeEncode(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
t = t.UTC()
enc.AppendString(t.Format("2006-01-02 15:04:05.000"))
}