mirror of https://github.com/minio/minio.git
				
				
				
			
		
			
				
	
	
		
			236 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			236 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			Go
		
	
	
	
| /*
 | |
|  * Minio Cloud Storage, (C) 2015, 2016, 2017 Minio, Inc.
 | |
|  *
 | |
|  * 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 cmd
 | |
| 
 | |
| import (
 | |
| 	"errors"
 | |
| 	"fmt"
 | |
| 	"io/ioutil"
 | |
| 	"path"
 | |
| 	"runtime"
 | |
| 	"strings"
 | |
| 	"sync"
 | |
| 
 | |
| 	"github.com/Sirupsen/logrus"
 | |
| 	"github.com/minio/mc/pkg/console"
 | |
| )
 | |
| 
 | |
| var log = NewLogger()
 | |
| 
 | |
| type loggers struct {
 | |
| 	sync.RWMutex
 | |
| 	Console ConsoleLogger `json:"console"`
 | |
| 	File    FileLogger    `json:"file"`
 | |
| }
 | |
| 
 | |
| // Validate - Check whether loggers are valid or not.
 | |
| func (l *loggers) Validate() (err error) {
 | |
| 	if l != nil {
 | |
| 		fileLogger := l.GetFile()
 | |
| 		if fileLogger.Enable && fileLogger.Filename == "" {
 | |
| 			err = errors.New("Missing filename for enabled file logger")
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return err
 | |
| }
 | |
| 
 | |
| // SetFile set new file logger.
 | |
| func (l *loggers) SetFile(flogger FileLogger) {
 | |
| 	l.Lock()
 | |
| 	defer l.Unlock()
 | |
| 	l.File = flogger
 | |
| }
 | |
| 
 | |
| // GetFileLogger get current file logger.
 | |
| func (l *loggers) GetFile() FileLogger {
 | |
| 	l.RLock()
 | |
| 	defer l.RUnlock()
 | |
| 	return l.File
 | |
| }
 | |
| 
 | |
| // SetConsole set new console logger.
 | |
| func (l *loggers) SetConsole(clogger ConsoleLogger) {
 | |
| 	l.Lock()
 | |
| 	defer l.Unlock()
 | |
| 	l.Console = clogger
 | |
| }
 | |
| 
 | |
| // GetConsole get current console logger.
 | |
| func (l *loggers) GetConsole() ConsoleLogger {
 | |
| 	l.RLock()
 | |
| 	defer l.RUnlock()
 | |
| 	return l.Console
 | |
| }
 | |
| 
 | |
| // LogTarget - interface for log target.
 | |
| type LogTarget interface {
 | |
| 	Fire(entry *logrus.Entry) error
 | |
| 	String() string
 | |
| }
 | |
| 
 | |
| // BaseLogTarget - base log target.
 | |
| type BaseLogTarget struct {
 | |
| 	Enable    bool `json:"enable"`
 | |
| 	formatter logrus.Formatter
 | |
| }
 | |
| 
 | |
| // Logger - higher level logger.
 | |
| type Logger struct {
 | |
| 	logger        *logrus.Logger
 | |
| 	consoleTarget ConsoleLogger
 | |
| 	targets       []LogTarget
 | |
| 	quiet         bool
 | |
| }
 | |
| 
 | |
| // AddTarget - add logger to this hook.
 | |
| func (log *Logger) AddTarget(logTarget LogTarget) {
 | |
| 	log.targets = append(log.targets, logTarget)
 | |
| }
 | |
| 
 | |
| // SetConsoleTarget - sets console target to this hook.
 | |
| func (log *Logger) SetConsoleTarget(consoleTarget ConsoleLogger) {
 | |
| 	log.consoleTarget = consoleTarget
 | |
| }
 | |
| 
 | |
| // Fire - log entry handler to save logs.
 | |
| func (log *Logger) Fire(entry *logrus.Entry) (err error) {
 | |
| 	if err = log.consoleTarget.Fire(entry); err != nil {
 | |
| 		log.Printf("Unable to log to console target. %s\n", err)
 | |
| 	}
 | |
| 
 | |
| 	for _, logTarget := range log.targets {
 | |
| 		if err = logTarget.Fire(entry); err != nil {
 | |
| 			log.Printf("Unable to log to target %s. %s\n", logTarget, err)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return err
 | |
| }
 | |
| 
 | |
| // Levels - returns list of log levels support.
 | |
| func (log *Logger) Levels() []logrus.Level {
 | |
| 	return []logrus.Level{
 | |
| 		logrus.PanicLevel,
 | |
| 		logrus.FatalLevel,
 | |
| 		logrus.ErrorLevel,
 | |
| 		logrus.WarnLevel,
 | |
| 		logrus.InfoLevel,
 | |
| 		logrus.DebugLevel,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // EnableQuiet - sets quiet option.
 | |
| func (log *Logger) EnableQuiet() {
 | |
| 	log.quiet = true
 | |
| }
 | |
| 
 | |
| // Println - wrapper to console.Println() with quiet flag.
 | |
| func (log *Logger) Println(args ...interface{}) {
 | |
| 	if !log.quiet {
 | |
| 		console.Println(args...)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Printf - wrapper to console.Printf() with quiet flag.
 | |
| func (log *Logger) Printf(format string, args ...interface{}) {
 | |
| 	if !log.quiet {
 | |
| 		console.Printf(format, args...)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // NewLogger - returns a new initialized logger.
 | |
| func NewLogger() *Logger {
 | |
| 	logger := logrus.New()
 | |
| 	logger.Out = ioutil.Discard
 | |
| 	logger.Level = logrus.DebugLevel
 | |
| 
 | |
| 	l := &Logger{
 | |
| 		logger:        logger,
 | |
| 		consoleTarget: NewConsoleLogger(),
 | |
| 	}
 | |
| 
 | |
| 	// Adds a console logger.
 | |
| 	logger.Hooks.Add(l)
 | |
| 
 | |
| 	return l
 | |
| }
 | |
| 
 | |
| func getSource() string {
 | |
| 	var funcName string
 | |
| 	pc, filename, lineNum, ok := runtime.Caller(2)
 | |
| 	if ok {
 | |
| 		filename = path.Base(filename)
 | |
| 		funcName = strings.TrimPrefix(runtime.FuncForPC(pc).Name(), "github.com/minio/minio/cmd.")
 | |
| 	} else {
 | |
| 		filename = "<unknown>"
 | |
| 		lineNum = 0
 | |
| 	}
 | |
| 
 | |
| 	return fmt.Sprintf("[%s:%d:%s()]", filename, lineNum, funcName)
 | |
| }
 | |
| 
 | |
| func logIf(level logrus.Level, source string, err error, msg string, data ...interface{}) {
 | |
| 	isErrIgnored := func(err error) (ok bool) {
 | |
| 		err = errorCause(err)
 | |
| 		switch err.(type) {
 | |
| 		case BucketNotFound, BucketNotEmpty, BucketExists:
 | |
| 			ok = true
 | |
| 		case ObjectNotFound, ObjectExistsAsDirectory, BucketPolicyNotFound, InvalidUploadID, BadDigest:
 | |
| 			ok = true
 | |
| 		}
 | |
| 
 | |
| 		return ok
 | |
| 	}
 | |
| 
 | |
| 	if err == nil || isErrIgnored(err) {
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	fields := logrus.Fields{
 | |
| 		"source": source,
 | |
| 		"cause":  err.Error(),
 | |
| 	}
 | |
| 
 | |
| 	if terr, ok := err.(*Error); ok {
 | |
| 		fields["stack"] = strings.Join(terr.Trace(), " ")
 | |
| 	}
 | |
| 
 | |
| 	switch level {
 | |
| 	case logrus.PanicLevel:
 | |
| 		log.logger.WithFields(fields).Panicf(msg, data...)
 | |
| 	case logrus.FatalLevel:
 | |
| 		log.logger.WithFields(fields).Fatalf(msg, data...)
 | |
| 	case logrus.ErrorLevel:
 | |
| 		log.logger.WithFields(fields).Errorf(msg, data...)
 | |
| 	case logrus.WarnLevel:
 | |
| 		log.logger.WithFields(fields).Warnf(msg, data...)
 | |
| 	case logrus.InfoLevel:
 | |
| 		log.logger.WithFields(fields).Infof(msg, data...)
 | |
| 	default:
 | |
| 		log.logger.WithFields(fields).Debugf(msg, data...)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func errorIf(err error, msg string, data ...interface{}) {
 | |
| 	logIf(logrus.ErrorLevel, getSource(), err, msg, data...)
 | |
| }
 | |
| 
 | |
| func fatalIf(err error, msg string, data ...interface{}) {
 | |
| 	logIf(logrus.FatalLevel, getSource(), err, msg, data...)
 | |
| }
 |