Logging: errorIf fatalIf print in the format [file.go:82:funcName()] (#3127)

master
Krishna Srinivas 8 years ago committed by Harshavardhana
parent 79b98b5c25
commit 0b3282ac9f
  1. 1
      cmd/globals.go
  2. 46
      cmd/logger.go
  3. 27
      cmd/logger_test.go
  4. 3
      cmd/main.go
  5. 29
      cmd/namespace-lock.go

@ -42,7 +42,6 @@ const (
var ( var (
globalQuiet = false // Quiet flag set via command line globalQuiet = false // Quiet flag set via command line
globalTrace = false // Trace flag set via environment setting.
// Add new global flags here. // Add new global flags here.

@ -17,13 +17,9 @@
package cmd package cmd
import ( import (
"bufio"
"bytes"
"fmt" "fmt"
"path" "path"
"path/filepath"
"runtime" "runtime"
"runtime/debug"
"strings" "strings"
"github.com/Sirupsen/logrus" "github.com/Sirupsen/logrus"
@ -46,37 +42,6 @@ type logger struct {
// Add new loggers here. // Add new loggers here.
} }
// Function takes input with the results from runtime.Caller(1). Depending on the boolean.
// This function can either returned a shotFile form or a longFile form.
func funcFromPC(pc uintptr, file string, line int, shortFile bool) string {
var fn, name string
if shortFile {
fn = strings.Replace(file, path.Join(filepath.ToSlash(GOPATH)+"/src/github.com/minio/minio/cmd/")+"/", "", -1)
name = strings.Replace(runtime.FuncForPC(pc).Name(), "github.com/minio/minio/cmd.", "", -1)
} else {
fn = strings.Replace(file, path.Join(filepath.ToSlash(GOPATH)+"/src/")+"/", "", -1)
name = strings.Replace(runtime.FuncForPC(pc).Name(), "github.com/minio/minio/cmd.", "", -1)
}
return fmt.Sprintf("%s [%s:%d]", name, fn, line)
}
// stackInfo returns printable stack trace.
func stackInfo() string {
// Convert stack-trace bytes to io.Reader.
rawStack := bufio.NewReader(bytes.NewBuffer(debug.Stack()))
// Skip stack trace lines until our real caller.
for i := 0; i <= 4; i++ {
rawStack.ReadLine()
}
// Read the rest of useful stack trace.
stackBuf := new(bytes.Buffer)
stackBuf.ReadFrom(rawStack)
// Strip GOPATH of the build system and return.
return strings.Replace(stackBuf.String(), filepath.ToSlash(GOPATH)+"/src/", "", -1)
}
// Get file, line, function name of the caller. // Get file, line, function name of the caller.
func callerLocation() string { func callerLocation() string {
pc, file, line, success := runtime.Caller(2) pc, file, line, success := runtime.Caller(2)
@ -84,9 +49,10 @@ func callerLocation() string {
file = "<unknown>" file = "<unknown>"
line = 0 line = 0
} }
shortFile := true // We are only interested in short file form. file = path.Base(file)
callerLoc := funcFromPC(pc, file, line, shortFile) name := runtime.FuncForPC(pc).Name()
return callerLoc name = strings.TrimPrefix(name, "github.com/minio/minio/cmd.")
return fmt.Sprintf("[%s:%d:%s()]", file, line, name)
} }
// errorIf synonymous with fatalIf but doesn't exit on error != nil // errorIf synonymous with fatalIf but doesn't exit on error != nil
@ -116,8 +82,8 @@ func fatalIf(err error, msg string, data ...interface{}) {
"location": location, "location": location,
"cause": err.Error(), "cause": err.Error(),
} }
if globalTrace { if e, ok := err.(*Error); ok {
fields["stack"] = "\n" + stackInfo() fields["stack"] = strings.Join(e.Trace(), " ")
} }
log.WithFields(fields).Fatalf(msg, data...) log.WithFields(fields).Fatalf(msg, data...)
} }

@ -20,31 +20,18 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"errors" "errors"
"os"
"path/filepath"
"runtime"
"testing" "testing"
"github.com/Sirupsen/logrus" "github.com/Sirupsen/logrus"
) )
// Tests func obtained from process stack counter. // Tests callerLocation.
func TestFuncToPC(t *testing.T) { func TestCallerLocation(t *testing.T) {
GOPATH = filepath.ToSlash(os.Getenv("GOPATH")) currentLocation := func() string { return callerLocation() }
pc, file, line, success := runtime.Caller(0) gotLocation := currentLocation()
if !success { expectedLocation := "[logger_test.go:31:TestCallerLocation()]"
file = "???" if gotLocation != expectedLocation {
line = 0 t.Errorf("expected : %s, got : %s", expectedLocation, gotLocation)
}
shortFile := true // We are only interested in short file form.
cLocation := funcFromPC(pc, file, line, shortFile)
if cLocation != "TestFuncToPC [logger_test.go:34]" {
t.Fatal("Unexpected caller location found", cLocation)
}
shortFile = false // We are not interested in short file form.
cLocation = funcFromPC(pc, file, line, shortFile)
if cLocation != "TestFuncToPC [github.com/minio/minio/cmd/logger_test.go:34]" {
t.Fatal("Unexpected caller location found", cLocation)
} }
} }

@ -71,9 +71,6 @@ VERSION:
func init() { func init() {
// Check if minio was compiled using a supported version of Golang. // Check if minio was compiled using a supported version of Golang.
checkGoVersion() checkGoVersion()
// Set global trace flag.
globalTrace = os.Getenv("MINIO_TRACE") == "1"
} }
func migrate() { func migrate() {

@ -20,7 +20,6 @@ import (
"errors" "errors"
"net/url" "net/url"
pathutil "path" pathutil "path"
"runtime"
"sync" "sync"
"github.com/minio/dsync" "github.com/minio/dsync"
@ -197,19 +196,7 @@ func (n *nsLockMap) unlock(volume, path, opsID string, readLock bool) {
func (n *nsLockMap) Lock(volume, path, opsID string) { func (n *nsLockMap) Lock(volume, path, opsID string) {
readLock := false // This is a write lock. readLock := false // This is a write lock.
// The caller information of the lock held has been obtained lockLocation := callerLocation() // Useful for debugging
// here before calling any other function.
// Fetching the package, function name and the line number of
// the caller from the runtime.
pc, file, line, success := runtime.Caller(1)
if !success {
file = "???"
line = 0
}
shortFile := true // We are only interested in short file form.
lockLocation := funcFromPC(pc, file, line, shortFile)
n.lock(volume, path, lockLocation, opsID, readLock) n.lock(volume, path, lockLocation, opsID, readLock)
} }
@ -223,19 +210,7 @@ func (n *nsLockMap) Unlock(volume, path, opsID string) {
func (n *nsLockMap) RLock(volume, path, opsID string) { func (n *nsLockMap) RLock(volume, path, opsID string) {
readLock := true readLock := true
// The caller information of the lock held has been obtained lockLocation := callerLocation() // Useful for debugging
// here before calling any other function.
// Fetching the package, function name and the line number of
// the caller from the runtime.
pc, file, line, success := runtime.Caller(1)
if !success {
file = "???"
line = 0
}
shortFile := true // We are only interested in short file form.
lockLocation := funcFromPC(pc, file, line, shortFile)
n.lock(volume, path, lockLocation, opsID, readLock) n.lock(volume, path, lockLocation, opsID, readLock)
} }

Loading…
Cancel
Save