log/logger_factory.go (105 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 log import ( "errors" "fmt" "sync" "github.com/apache/incubator-eventmesh/eventmesh-server-go/plugin" "go.uber.org/zap" "go.uber.org/zap/zapcore" ) func init() { RegisterWriter(OutputConsole, DefaultConsoleWriterFactory) RegisterWriter(OutputFile, DefaultFileWriterFactory) Register(defaultLoggerName, NewZapLog(defaultConfig)) plugin.Register(defaultLoggerName, DefaultLogFactory) } const ( pluginType = "log" defaultLoggerName = "default" ) var ( // DefaultLogger the default Logger. The initial output is console. When frame start, it is // over write by configuration. DefaultLogger Logger // DefaultLogFactory is the default log loader. Users may replace it with their own // implementation. DefaultLogFactory = &Factory{} mu sync.RWMutex loggers = make(map[string]Logger) ) // Register registers Logger. It supports multiple Logger implementation. func Register(name string, logger Logger) { mu.Lock() defer mu.Unlock() if logger == nil { panic("log: Register logger is nil") } if _, dup := loggers[name]; dup && name != defaultLoggerName { panic("log: Register called twice for logger name " + name) } loggers[name] = logger if name == defaultLoggerName { DefaultLogger = logger } } // GetDefaultLogger gets the default Logger. // To configure it, set key in configuration file to default. // The console output is the default value. func GetDefaultLogger() Logger { mu.RLock() l := DefaultLogger mu.RUnlock() return l } // SetLogger sets the default Logger. func SetLogger(logger Logger) { mu.Lock() DefaultLogger = logger mu.Unlock() } // Get returns the Logger implementation by log name. // log.Debug use DefaultLogger to print logs. You may also use log.Get("name").Debug. func Get(name string) Logger { mu.RLock() l := loggers[name] mu.RUnlock() return l } // Decoder decodes the log. type Decoder struct { OutputConfig *OutputConfig Core zapcore.Core ZapLevel zap.AtomicLevel } // Decode decodes writer configuration, copy one. func (d *Decoder) Decode(cfg interface{}) error { output, ok := cfg.(**OutputConfig) if !ok { return fmt.Errorf("decoder config type:%T invalid, not **OutputConfig", cfg) } *output = d.OutputConfig return nil } // Factory is the log plugin factory. // When server start, the configuration is feed to Factory to generate a log instance. type Factory struct { } // Type returns the log plugin type. func (f *Factory) Type() string { return pluginType } // Setup starts, load and register logs. func (f *Factory) Setup(name string, dec plugin.Decoder) error { if dec == nil { return errors.New("log config decoder empty") } cfg, callerSkip, err := f.setupConfig(dec) if err != nil { return err } logger := NewZapLogWithCallerSkip(cfg, callerSkip) if logger == nil { return errors.New("new zap logger fail") } Register(name, logger) return nil } func (f *Factory) setupConfig(configDec plugin.Decoder) (Config, int, error) { cfg := Config{} if err := configDec.Decode(&cfg); err != nil { return nil, 0, err } if len(cfg) == 0 { return nil, 0, errors.New("log config output empty") } // If caller skip is not configured, use 2 as default. callerSkip := 2 for i := 0; i < len(cfg); i++ { if cfg[i].CallerSkip != 0 { callerSkip = cfg[i].CallerSkip } } return cfg, callerSkip, nil }