diff options
Diffstat (limited to 'vendor/gopkg.in/clog.v1/logger.go')
-rw-r--r-- | vendor/gopkg.in/clog.v1/logger.go | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/vendor/gopkg.in/clog.v1/logger.go b/vendor/gopkg.in/clog.v1/logger.go new file mode 100644 index 00000000..be8ba8f7 --- /dev/null +++ b/vendor/gopkg.in/clog.v1/logger.go @@ -0,0 +1,141 @@ +// Copyright 2017 Unknwon +// +// 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 clog + +import "fmt" + +// Logger is an interface for a logger adapter with specific mode and level. +type Logger interface { + // Level returns minimum level of given logger. + Level() LEVEL + // Init accepts a config struct specific for given logger and performs any necessary initialization. + Init(interface{}) error + // ExchangeChans accepts error channel, and returns message receive channel. + ExchangeChans(chan<- error) chan *Message + // Start starts message processing. + Start() + // Destroy releases all resources. + Destroy() +} + +// Adapter contains common fields for any logger adapter. This struct should be used as embedded struct. +type Adapter struct { + level LEVEL + msgChan chan *Message + quitChan chan struct{} + errorChan chan<- error +} + +type Factory func() Logger + +// factories keeps factory function of registered loggers. +var factories = map[MODE]Factory{} + +func Register(mode MODE, f Factory) { + if f == nil { + panic("clog: register function is nil") + } + if factories[mode] != nil { + panic("clog: register duplicated mode '" + mode + "'") + } + factories[mode] = f +} + +type receiver struct { + Logger + mode MODE + msgChan chan *Message +} + +var ( + // receivers is a list of loggers with their message channel for broadcasting. + receivers []*receiver + + errorChan = make(chan error, 5) + quitChan = make(chan struct{}) +) + +func init() { + // Start background error handling goroutine. + go func() { + for { + select { + case err := <-errorChan: + fmt.Printf("clog: unable to write message: %v\n", err) + case <-quitChan: + return + } + } + }() +} + +// New initializes and appends a new logger to the receiver list. +// Calling this function multiple times will overwrite previous logger with same mode. +func New(mode MODE, cfg interface{}) error { + factory, ok := factories[mode] + if !ok { + return fmt.Errorf("unknown mode '%s'", mode) + } + + logger := factory() + if err := logger.Init(cfg); err != nil { + return err + } + msgChan := logger.ExchangeChans(errorChan) + + // Check and replace previous logger. + hasFound := false + for i := range receivers { + if receivers[i].mode == mode { + hasFound = true + + // Release previous logger. + receivers[i].Destroy() + + // Update info to new one. + receivers[i].Logger = logger + receivers[i].msgChan = msgChan + break + } + } + if !hasFound { + receivers = append(receivers, &receiver{ + Logger: logger, + mode: mode, + msgChan: msgChan, + }) + } + + go logger.Start() + return nil +} + +// Delete removes logger from the receiver list. +func Delete(mode MODE) { + foundIdx := -1 + for i := range receivers { + if receivers[i].mode == mode { + foundIdx = i + receivers[i].Destroy() + } + } + + if foundIdx >= 0 { + newList := make([]*receiver, len(receivers)-1) + copy(newList, receivers[:foundIdx]) + copy(newList[foundIdx:], receivers[foundIdx+1:]) + receivers = newList + } +} |