From b165efdfcb8af9803abd84f4870c78f8bc2344c0 Mon Sep 17 00:00:00 2001 From: "Frederick F. Kautz IV" Date: Sat, 28 Mar 2015 15:58:48 -0700 Subject: [PATCH] Refactoring pkg/utils/log, copying from golang's log and modifying --- main.go | 2 +- pkg/api/api_bucket_handlers.go | 8 +- pkg/api/api_object_handlers.go | 12 +- pkg/api/api_policy_handlers.go | 8 +- pkg/drivers/donut/donut.go | 2 +- pkg/server/server.go | 4 +- pkg/utils/log/definitions.go | 335 ++++++++++++++++++++++++++++++--- pkg/utils/log/log-debug.go | 26 --- pkg/utils/log/log-normal.go | 26 --- pkg/utils/log/log.go | 44 ----- pkg/utils/log/log_test.go | 19 -- 11 files changed, 331 insertions(+), 155 deletions(-) delete mode 100644 pkg/utils/log/log-debug.go delete mode 100644 pkg/utils/log/log-normal.go delete mode 100644 pkg/utils/log/log.go delete mode 100644 pkg/utils/log/log_test.go diff --git a/main.go b/main.go index c95630e9c..c03eb8d3a 100644 --- a/main.go +++ b/main.go @@ -133,7 +133,7 @@ func main() { app.Action = runCmd err := app.Run(os.Args) if err != nil { - log.Errorln(err) + log.Error.Println(err) } } diff --git a/pkg/api/api_bucket_handlers.go b/pkg/api/api_bucket_handlers.go index d99b4e854..7ffed9c09 100644 --- a/pkg/api/api_bucket_handlers.go +++ b/pkg/api/api_bucket_handlers.go @@ -62,7 +62,7 @@ func (server *minioAPI) listObjectsHandler(w http.ResponseWriter, req *http.Requ case drivers.ImplementationError: { // Embed error log on server side - log.Errorln(err) + log.Error.Println(err) error := errorCodeError(InternalError) errorResponse := getErrorResponse(error, bucket) w.WriteHeader(error.HTTPStatusCode) @@ -100,7 +100,7 @@ func (server *minioAPI) listBucketsHandler(w http.ResponseWriter, req *http.Requ } case drivers.ImplementationError: { - log.Errorln(err) + log.Error.Println(err) error := errorCodeError(InternalError) errorResponse := getErrorResponse(error, "") w.WriteHeader(error.HTTPStatusCode) @@ -108,7 +108,7 @@ func (server *minioAPI) listBucketsHandler(w http.ResponseWriter, req *http.Requ } case drivers.BackendCorrupted: { - log.Errorln(err) + log.Error.Println(err) error := errorCodeError(InternalError) errorResponse := getErrorResponse(error, "") w.WriteHeader(error.HTTPStatusCode) @@ -155,7 +155,7 @@ func (server *minioAPI) putBucketHandler(w http.ResponseWriter, req *http.Reques case drivers.ImplementationError: { // Embed errors log on server side - log.Errorln(err) + log.Error.Println(err) error := errorCodeError(InternalError) errorResponse := getErrorResponse(error, bucket) w.WriteHeader(error.HTTPStatusCode) diff --git a/pkg/api/api_object_handlers.go b/pkg/api/api_object_handlers.go index 05156ee66..7d38e7bd0 100644 --- a/pkg/api/api_object_handlers.go +++ b/pkg/api/api_object_handlers.go @@ -42,7 +42,7 @@ func (server *minioAPI) getObjectHandler(w http.ResponseWriter, req *http.Reques log.Println("Found: " + bucket + "#" + object) httpRange, err := newRange(req, metadata.Size) if err != nil { - log.Errorln(err) + log.Error.Println(err) error := errorCodeError(InvalidRange) errorResponse := getErrorResponse(error, "/"+bucket+"/"+object) w.WriteHeader(error.HTTPStatusCode) @@ -53,7 +53,7 @@ func (server *minioAPI) getObjectHandler(w http.ResponseWriter, req *http.Reques case true: writeObjectHeaders(w, metadata) if _, err := server.driver.GetObject(w, bucket, object); err != nil { - log.Errorln(err) + log.Error.Println(err) error := errorCodeError(InternalError) errorResponse := getErrorResponse(error, "/"+bucket+"/"+object) w.WriteHeader(error.HTTPStatusCode) @@ -66,7 +66,7 @@ func (server *minioAPI) getObjectHandler(w http.ResponseWriter, req *http.Reques w.WriteHeader(http.StatusPartialContent) _, err := server.driver.GetPartialObject(w, bucket, object, httpRange.start, httpRange.length) if err != nil { - log.Errorln(err) + log.Error.Println(err) error := errorCodeError(InternalError) errorResponse := getErrorResponse(error, "/"+bucket+"/"+object) w.WriteHeader(error.HTTPStatusCode) @@ -107,7 +107,7 @@ func (server *minioAPI) getObjectHandler(w http.ResponseWriter, req *http.Reques default: { // Embed errors log on serve side - log.Errorln(err) + log.Error.Println(err) error := errorCodeError(InternalError) errorResponse := getErrorResponse(error, "/"+bucket+"/"+object) w.WriteHeader(error.HTTPStatusCode) @@ -147,7 +147,7 @@ func (server *minioAPI) headObjectHandler(w http.ResponseWriter, req *http.Reque case drivers.ImplementationError: { // Embed error log on server side - log.Errorln(err) + log.Error.Println(err) error := errorCodeError(InternalError) errorResponse := getErrorResponse(error, "/"+bucket+"/"+object) w.WriteHeader(error.HTTPStatusCode) @@ -182,7 +182,7 @@ func (server *minioAPI) putObjectHandler(w http.ResponseWriter, req *http.Reques case drivers.ImplementationError: { // Embed error log on server side - log.Errorln(err) + log.Error.Println(err) error := errorCodeError(InternalError) errorResponse := getErrorResponse(error, "/"+bucket+"/"+object) w.WriteHeader(error.HTTPStatusCode) diff --git a/pkg/api/api_policy_handlers.go b/pkg/api/api_policy_handlers.go index 18338ccd5..ba95d726f 100644 --- a/pkg/api/api_policy_handlers.go +++ b/pkg/api/api_policy_handlers.go @@ -67,7 +67,7 @@ func (server *minioAPI) putBucketPolicyHandler(w http.ResponseWriter, req *http. } case drivers.BackendCorrupted: { - log.Errorln(err) + log.Error.Println(err) error := errorCodeError(InternalError) errorResponse := getErrorResponse(error, bucket) w.WriteHeader(error.HTTPStatusCode) @@ -75,7 +75,7 @@ func (server *minioAPI) putBucketPolicyHandler(w http.ResponseWriter, req *http. } case drivers.ImplementationError: { - log.Errorln(err) + log.Error.Println(err) error := errorCodeError(InternalError) errorResponse := getErrorResponse(error, bucket) w.WriteHeader(error.HTTPStatusCode) @@ -131,7 +131,7 @@ func (server *minioAPI) getBucketPolicyHandler(w http.ResponseWriter, req *http. } case drivers.BackendCorrupted: { - log.Errorln(err) + log.Error.Println(err) error := errorCodeError(InternalError) errorResponse := getErrorResponse(error, bucket) w.WriteHeader(error.HTTPStatusCode) @@ -139,7 +139,7 @@ func (server *minioAPI) getBucketPolicyHandler(w http.ResponseWriter, req *http. } case drivers.ImplementationError: { - log.Errorln(err) + log.Error.Println(err) error := errorCodeError(InternalError) errorResponse := getErrorResponse(error, bucket) w.WriteHeader(error.HTTPStatusCode) diff --git a/pkg/drivers/donut/donut.go b/pkg/drivers/donut/donut.go index 2a144a6b0..248b95296 100644 --- a/pkg/drivers/donut/donut.go +++ b/pkg/drivers/donut/donut.go @@ -50,7 +50,7 @@ func Start(path string) (chan<- string, <-chan error, drivers.Driver) { s.donut, err = donut.NewDonut(path) err = iodine.New(err, map[string]string{"path": path}) if err != nil { - log.Errorln(err) + log.Error.Println(err) } go start(ctrlChannel, errorChannel, s) diff --git a/pkg/server/server.go b/pkg/server/server.go index 0e5927b29..d2a90bd84 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -142,7 +142,7 @@ func getDriverChannels(driverType DriverType) (ctrlChans []chan<- string, status { u, err := user.Current() if err != nil { - log.Errorln(iodine.New(err, nil)) + log.Error.Println(iodine.New(err, nil)) return nil, nil, nil } root := path.Join(u.HomeDir, "minio-storage", "file") @@ -154,7 +154,7 @@ func getDriverChannels(driverType DriverType) (ctrlChans []chan<- string, status { u, err := user.Current() if err != nil { - log.Errorln(iodine.New(err, nil)) + log.Error.Println(iodine.New(err, nil)) return nil, nil, nil } root := path.Join(u.HomeDir, "minio-storage", "donut") diff --git a/pkg/utils/log/definitions.go b/pkg/utils/log/definitions.go index f68ec38cb..a2ec93882 100644 --- a/pkg/utils/log/definitions.go +++ b/pkg/utils/log/definitions.go @@ -1,34 +1,325 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package log implements a simple logging package. It defines a type, Logger, +// with methods for formatting output. It also has a predefined 'standard' +// Logger accessible through helper functions Print[f|ln], Fatal[f|ln], and +// Panic[f|ln], which are easier to use than creating a Logger manually. +// That logger writes to standard error and prints the date and time +// of each logged message. +// The Fatal functions call os.Exit(1) after writing the log message. +// The Panic functions call panic after writing the log message. package log import ( - internalLog "log" + "fmt" + "io" + "os" + "runtime" + "sync" + "time" ) -// Fatal - prints string and terminates -var Fatal = internalLog.Fatal +// These flags define which text to prefix to each log entry generated by the Logger. +// Bits or'ed together to control what's printed. There is no control over the +// order they appear (the order listed here) or the format they present (as +// described in the comments). A colon appears after these items: +// 2009/01/23 01:23:23.123123 /a/b/c/d.go:23: message +const ( + Ldate = 1 << iota // the date: 2009/01/23 + Ltime + Lmicroseconds // microsecond resolution: 01:23:23.123123. assumes Ltime. + Llongfile // full file name and line number: /a/b/c/d.go:23 + Lshortfile // final file name element and line number: d.go:23. overrides Llongfile + LstdFlags = Ldate | Ltime // initial values for the standard logger +) -// Fatalf - prints formatted string and terminates -var Fatalf = internalLog.Fatalf +// A Logger represents an active logging object that generates lines of +// output to an io.Writer. Each logging operation makes a single call to +// the Writer's Write method. A Logger can be used simultaneously from +// multiple goroutines; it guarantees to serialize access to the Writer. +type Logger struct { + mu sync.Mutex // ensures atomic writes; protects the following fields + prefix string // prefix to write at beginning of each line + flag int // properties + out io.Writer // destination for output + buf []byte // for accumulating text to write +} -// Fatalln - prints with newline and terminates -var Fatalln = internalLog.Fatalln +// New creates a new Logger. The out variable sets the +// destination to which log data will be written. +// The prefix appears at the beginning of each generated log line. +// The flag argument defines the logging properties. +func New(out io.Writer, prefix string, flag int) *Logger { + return &Logger{out: out, prefix: prefix, flag: flag} +} -// Error - prints string but does not terminate -func Error(args ...interface{}) { internalLog.Print(args...) } +var std = New(os.Stderr, "", LstdFlags) -// Errorf - prints formatted string but does not terminate -func Errorf(s string, args ...interface{}) { internalLog.Printf(s, args...) } +// Error is an error logger +var Error = New(os.Stderr, "", 0) -// Errorln - prints string with newline but does not terminate -func Errorln(args ...interface{}) { internalLog.Println(args...) } +// Cheap integer to fixed-width decimal ASCII. Give a negative width to avoid zero-padding. +// Knows the buffer has capacity. +func itoa(buf *[]byte, i int, wid int) { + var u = uint(i) + if u == 0 && wid <= 1 { + *buf = append(*buf, '0') + return + } -// Level - logging level -type Level int + // Assemble decimal in reverse order. + var b [32]byte + bp := len(b) + for ; u > 0 || wid > 0; u /= 10 { + bp-- + wid-- + b[bp] = byte(u%10) + '0' + } + *buf = append(*buf, b[bp:]...) +} -// Different log levels -const ( - QuietLOG Level = iota - NormalLOG - DebugLOG - TraceLOG -) +func (l *Logger) formatHeader(buf *[]byte, t time.Time, file string, line int) { + *buf = append(*buf, l.prefix...) + if l.flag&(Ldate|Ltime|Lmicroseconds) != 0 { + if l.flag&Ldate != 0 { + year, month, day := t.Date() + itoa(buf, year, 4) + *buf = append(*buf, '/') + itoa(buf, int(month), 2) + *buf = append(*buf, '/') + itoa(buf, day, 2) + *buf = append(*buf, ' ') + } + if l.flag&(Ltime|Lmicroseconds) != 0 { + hour, min, sec := t.Clock() + itoa(buf, hour, 2) + *buf = append(*buf, ':') + itoa(buf, min, 2) + *buf = append(*buf, ':') + itoa(buf, sec, 2) + if l.flag&Lmicroseconds != 0 { + *buf = append(*buf, '.') + itoa(buf, t.Nanosecond()/1e3, 6) + } + *buf = append(*buf, ' ') + } + } + if l.flag&(Lshortfile|Llongfile) != 0 { + if l.flag&Lshortfile != 0 { + short := file + for i := len(file) - 1; i > 0; i-- { + if file[i] == '/' { + short = file[i+1:] + break + } + } + file = short + } + *buf = append(*buf, file...) + *buf = append(*buf, ':') + itoa(buf, line, -1) + *buf = append(*buf, ": "...) + } +} + +// Output writes the output for a logging event. The string s contains +// the text to print after the prefix specified by the flags of the +// Logger. A newline is appended if the last character of s is not +// already a newline. Calldepth is used to recover the PC and is +// provided for generality, although at the moment on all pre-defined +// paths it will be 2. +func (l *Logger) Output(calldepth int, s string) error { + now := time.Now() // get this early. + var file string + var line int + l.mu.Lock() + defer l.mu.Unlock() + if l.flag&(Lshortfile|Llongfile) != 0 { + // release lock while getting caller info - it's expensive. + l.mu.Unlock() + var ok bool + _, file, line, ok = runtime.Caller(calldepth) + if !ok { + file = "???" + line = 0 + } + l.mu.Lock() + } + l.buf = l.buf[:0] + l.formatHeader(&l.buf, now, file, line) + l.buf = append(l.buf, s...) + if len(s) > 0 && s[len(s)-1] != '\n' { + l.buf = append(l.buf, '\n') + } + _, err := l.out.Write(l.buf) + return err +} + +// Printf calls l.Output to print to the logger. +// Arguments are handled in the manner of fmt.Printf. +func (l *Logger) Printf(format string, v ...interface{}) { + l.Output(2, fmt.Sprintf(format, v...)) +} + +// Print calls l.Output to print to the logger. +// Arguments are handled in the manner of fmt.Print. +func (l *Logger) Print(v ...interface{}) { l.Output(2, fmt.Sprint(v...)) } + +// Println calls l.Output to print to the logger. +// Arguments are handled in the manner of fmt.Println. +func (l *Logger) Println(v ...interface{}) { l.Output(2, fmt.Sprintln(v...)) } + +// Fatal is equivalent to l.Print() followed by a call to os.Exit(1). +func (l *Logger) Fatal(v ...interface{}) { + l.Output(2, fmt.Sprint(v...)) + os.Exit(1) +} + +// Fatalf is equivalent to l.Printf() followed by a call to os.Exit(1). +func (l *Logger) Fatalf(format string, v ...interface{}) { + l.Output(2, fmt.Sprintf(format, v...)) + os.Exit(1) +} + +// Fatalln is equivalent to l.Println() followed by a call to os.Exit(1). +func (l *Logger) Fatalln(v ...interface{}) { + l.Output(2, fmt.Sprintln(v...)) + os.Exit(1) +} + +// Panic is equivalent to l.Print() followed by a call to panic(). +func (l *Logger) Panic(v ...interface{}) { + s := fmt.Sprint(v...) + l.Output(2, s) + panic(s) +} + +// Panicf is equivalent to l.Printf() followed by a call to panic(). +func (l *Logger) Panicf(format string, v ...interface{}) { + s := fmt.Sprintf(format, v...) + l.Output(2, s) + panic(s) +} + +// Panicln is equivalent to l.Println() followed by a call to panic(). +func (l *Logger) Panicln(v ...interface{}) { + s := fmt.Sprintln(v...) + l.Output(2, s) + panic(s) +} + +// Flags returns the output flags for the logger. +func (l *Logger) Flags() int { + l.mu.Lock() + defer l.mu.Unlock() + return l.flag +} + +// SetFlags sets the output flags for the logger. +func (l *Logger) SetFlags(flag int) { + l.mu.Lock() + defer l.mu.Unlock() + l.flag = flag +} + +// Prefix returns the output prefix for the logger. +func (l *Logger) Prefix() string { + l.mu.Lock() + defer l.mu.Unlock() + return l.prefix +} + +// SetPrefix sets the output prefix for the logger. +func (l *Logger) SetPrefix(prefix string) { + l.mu.Lock() + defer l.mu.Unlock() + l.prefix = prefix +} + +// SetOutput sets the output destination for the standard logger. +func SetOutput(w io.Writer) { + std.mu.Lock() + defer std.mu.Unlock() + std.out = w +} + +// Flags returns the output flags for the standard logger. +func Flags() int { + return std.Flags() +} + +// SetFlags sets the output flags for the standard logger. +func SetFlags(flag int) { + std.SetFlags(flag) +} + +// Prefix returns the output prefix for the standard logger. +func Prefix() string { + return std.Prefix() +} + +// SetPrefix sets the output prefix for the standard logger. +func SetPrefix(prefix string) { + std.SetPrefix(prefix) +} + +// These functions write to the standard logger. + +// Print calls Output to print to the standard logger. +// Arguments are handled in the manner of fmt.Print. +func Print(v ...interface{}) { + std.Output(2, fmt.Sprint(v...)) +} + +// Printf calls Output to print to the standard logger. +// Arguments are handled in the manner of fmt.Printf. +func Printf(format string, v ...interface{}) { + std.Output(2, fmt.Sprintf(format, v...)) +} + +// Println calls Output to print to the standard logger. +// Arguments are handled in the manner of fmt.Println. +func Println(v ...interface{}) { + std.Output(2, fmt.Sprintln(v...)) +} + +// Fatal is equivalent to Print() followed by a call to os.Exit(1). +func Fatal(v ...interface{}) { + std.Output(2, fmt.Sprint(v...)) + os.Exit(1) +} + +// Fatalf is equivalent to Printf() followed by a call to os.Exit(1). +func Fatalf(format string, v ...interface{}) { + std.Output(2, fmt.Sprintf(format, v...)) + os.Exit(1) +} + +// Fatalln is equivalent to Println() followed by a call to os.Exit(1). +func Fatalln(v ...interface{}) { + std.Output(2, fmt.Sprintln(v...)) + os.Exit(1) +} + +// Panic is equivalent to Print() followed by a call to panic(). +func Panic(v ...interface{}) { + s := fmt.Sprint(v...) + std.Output(2, s) + panic(s) +} + +// Panicf is equivalent to Printf() followed by a call to panic(). +func Panicf(format string, v ...interface{}) { + s := fmt.Sprintf(format, v...) + std.Output(2, s) + panic(s) +} + +// Panicln is equivalent to Println() followed by a call to panic(). +func Panicln(v ...interface{}) { + s := fmt.Sprintln(v...) + std.Output(2, s) + panic(s) +} diff --git a/pkg/utils/log/log-debug.go b/pkg/utils/log/log-debug.go deleted file mode 100644 index 1d8c329ea..000000000 --- a/pkg/utils/log/log-debug.go +++ /dev/null @@ -1,26 +0,0 @@ -package log - -import ( - internalLog "log" -) - -// Debug logging -func Debug(args ...interface{}) { - if verify(DebugLOG) { - internalLog.Print(args...) - } -} - -// Debugf formatted debug logging -func Debugf(s string, args ...interface{}) { - if verify(DebugLOG) { - internalLog.Printf(s, args...) - } -} - -// Debugln logging with newline -func Debugln(args ...interface{}) { - if verify(DebugLOG) { - internalLog.Println(args...) - } -} diff --git a/pkg/utils/log/log-normal.go b/pkg/utils/log/log-normal.go deleted file mode 100644 index f90a704cc..000000000 --- a/pkg/utils/log/log-normal.go +++ /dev/null @@ -1,26 +0,0 @@ -package log - -import ( - internalLog "log" -) - -// Print - Normal logging -func Print(args ...interface{}) { - if verify(NormalLOG) { - internalLog.Print(args...) - } -} - -// Printf - Normal formatted logging -func Printf(s string, args ...interface{}) { - if verify(NormalLOG) { - internalLog.Printf(s, args...) - } -} - -// Println - Normal logging with newline -func Println(args ...interface{}) { - if verify(NormalLOG) { - internalLog.Println(args...) - } -} diff --git a/pkg/utils/log/log.go b/pkg/utils/log/log.go deleted file mode 100644 index 8dfcd060f..000000000 --- a/pkg/utils/log/log.go +++ /dev/null @@ -1,44 +0,0 @@ -package log - -import ( - internalLog "log" - "sync" -) - -// Global variable to be set -var verbosity = NormalLOG -var mutex sync.RWMutex - -func verify(level Level) bool { - mutex.RLock() - defer mutex.RUnlock() - return Level(verbosity) >= level -} - -// SetVerbosity - set log level value globally -func SetVerbosity(level Level) { - mutex.Lock() - defer mutex.Unlock() - verbosity = level -} - -// Log - variable logging against global verbosity -func Log(level Level, args ...interface{}) { - if verify(level) { - internalLog.Print(args...) - } -} - -// Logf - variable formatted logging against global verbosity -func Logf(level Level, s string, args ...interface{}) { - if verify(level) { - internalLog.Printf(s, args...) - } -} - -// Logln - variable logging with newline against global verbosity -func Logln(level Level, args ...interface{}) { - if verify(level) { - internalLog.Println(args...) - } -} diff --git a/pkg/utils/log/log_test.go b/pkg/utils/log/log_test.go deleted file mode 100644 index c244927c6..000000000 --- a/pkg/utils/log/log_test.go +++ /dev/null @@ -1,19 +0,0 @@ -package log - -import ( - "testing" - - . "gopkg.in/check.v1" -) - -type MySuite struct{} - -var _ = Suite(&MySuite{}) - -func Test(t *testing.T) { TestingT(t) } - -func (s *MySuite) TestLogLevel(c *C) { - c.Assert(verbosity, Equals, NormalLOG) - SetVerbosity(QuietLOG) - c.Assert(verbosity, Equals, QuietLOG) -}