Path: blob/main/component/otelcol/receiver/prometheus/internal/logger.go
5414 views
// Copyright The OpenTelemetry Authors1//2// Licensed under the Apache License, Version 2.0 (the "License");3// you may not use this file except in compliance with the License.4// You may obtain a copy of the License at5//6// http://www.apache.org/licenses/LICENSE-2.07//8// Unless required by applicable law or agreed to in writing, software9// distributed under the License is distributed on an "AS IS" BASIS,10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.11// See the License for the specific language governing permissions and12// limitations under the License.1314package internal // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/prometheusreceiver/internal"1516import (17gokitLog "github.com/go-kit/log"18"github.com/go-kit/log/level"19"go.uber.org/zap"20)2122const (23levelKey = "level"24msgKey = "msg"25errKey = "err"26)2728// NewZapToGokitLogAdapter create an adapter for zap.Logger to gokitLog.Logger29func NewZapToGokitLogAdapter(logger *zap.Logger) gokitLog.Logger {30// need to skip two levels in order to get the correct caller31// one for this method, the other for gokitLog32logger = logger.WithOptions(zap.AddCallerSkip(2))33return &zapToGokitLogAdapter{l: logger.Sugar()}34}3536type zapToGokitLogAdapter struct {37l *zap.SugaredLogger38}3940type logData struct {41level level.Value42msg string43otherFields []interface{}44}4546func (w *zapToGokitLogAdapter) Log(keyvals ...interface{}) error {47// expecting key value pairs, the number of items need to be even48if len(keyvals)%2 == 0 {49// Extract log level and message and log them using corresponding zap function50ld := extractLogData(keyvals)51logFunc := levelToFunc(w.l, ld.level)52logFunc(ld.msg, ld.otherFields...)53} else {54// in case something goes wrong55w.l.Info(keyvals...)56}57return nil58}5960func extractLogData(keyvals []interface{}) logData {61ld := logData{62level: level.InfoValue(), // default63}6465for i := 0; i < len(keyvals); i += 2 {66key := keyvals[i]67val := keyvals[i+1]6869if l, ok := matchLogLevel(key, val); ok {70ld.level = l71continue72}7374if m, ok := matchLogMessage(key, val); ok {75ld.msg = m76continue77}7879if err, ok := matchError(key, val); ok {80ld.otherFields = append(ld.otherFields, zap.Error(err))81continue82}8384ld.otherFields = append(ld.otherFields, key, val)85}8687return ld88}8990// check if a given key-value pair represents go-kit log message and return it91func matchLogMessage(key interface{}, val interface{}) (string, bool) {92if strKey, ok := key.(string); !ok || strKey != msgKey {93return "", false94}9596msg, ok := val.(string)97if !ok {98return "", false99}100return msg, true101}102103// check if a given key-value pair represents go-kit log level and return it104func matchLogLevel(key interface{}, val interface{}) (level.Value, bool) {105strKey, ok := key.(string)106if !ok || strKey != levelKey {107return nil, false108}109110levelVal, ok := val.(level.Value)111if !ok {112return nil, false113}114return levelVal, true115}116117//revive:disable:error-return118119// check if a given key-value pair represents an error and return it120func matchError(key interface{}, val interface{}) (error, bool) {121strKey, ok := key.(string)122if !ok || strKey != errKey {123return nil, false124}125126err, ok := val.(error)127if !ok {128return nil, false129}130return err, true131}132133//revive:enable:error-return134135// find a matching zap logging function to be used for a given level136func levelToFunc(logger *zap.SugaredLogger, lvl level.Value) func(string, ...interface{}) {137switch lvl {138case level.DebugValue():139return logger.Debugw140case level.InfoValue():141return logger.Infow142case level.WarnValue():143return logger.Warnw144case level.ErrorValue():145return logger.Errorw146}147148// default149return logger.Infow150}151152var _ gokitLog.Logger = (*zapToGokitLogAdapter)(nil)153154155