-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve logging #179
Improve logging #179
Changes from all commits
98d9df5
ebdaac7
515505d
e0df889
c98b0e8
3455846
e4da27a
db1ac74
ea76b66
0557b10
afa5b7f
0631a39
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package main | ||
|
||
import ( | ||
flag "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag" | ||
commander "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander" | ||
"github.com/jbenet/go-ipfs/core/commands" | ||
) | ||
|
||
var cmdIpfsLog = &commander.Command{ | ||
UsageLine: "log <name> <level> ", | ||
Short: "switch logging levels of a running daemon", | ||
Long: `ipfs log <name> <level> - switch logging levels of a running daemon | ||
|
||
<name> is a the subsystem logging identifier. Use * for all subsystems. | ||
<level> is one of: debug, info, notice, warning, error, critical | ||
|
||
ipfs log is a utility command used to change the logging output of a running daemon. | ||
`, | ||
Run: logCmd, | ||
Flag: *flag.NewFlagSet("ipfs-log", flag.ExitOnError), | ||
} | ||
|
||
var logCmd = makeCommand(command{ | ||
name: "log", | ||
args: 2, | ||
flags: nil, | ||
online: true, | ||
cmdFn: commands.Log, | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package commands | ||
|
||
import ( | ||
"io" | ||
|
||
"github.com/jbenet/go-ipfs/core" | ||
u "github.com/jbenet/go-ipfs/util" | ||
) | ||
|
||
// Log changes the log level of a subsystem | ||
func Log(n *core.IpfsNode, args []string, opts map[string]interface{}, out io.Writer) error { | ||
if err := u.SetLogLevel(args[0], args[1]); err != nil { | ||
return err | ||
} | ||
|
||
log.Info("Changed LogLevel of %q to %q", args[0], args[1]) | ||
return nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,17 +11,14 @@ func init() { | |
SetupLogging() | ||
} | ||
|
||
var log = Logger("util") | ||
|
||
// LogFormat is the format used for our logger. | ||
var LogFormat = "%{color}%{time:2006-01-02 15:04:05.999999} %{shortfile} %{level}: %{color:reset}%{message}" | ||
|
||
// loggers is the set of loggers in the system | ||
var loggers = map[string]*logging.Logger{} | ||
|
||
// PErr is a shorthand printing function to output to Stderr. | ||
func PErr(format string, a ...interface{}) { | ||
fmt.Fprintf(os.Stderr, format, a...) | ||
} | ||
|
||
// POut is a shorthand printing function to output to Stdout. | ||
func POut(format string, a ...interface{}) { | ||
fmt.Fprintf(os.Stdout, format, a...) | ||
|
@@ -35,31 +32,61 @@ func SetupLogging() { | |
|
||
lvl := logging.ERROR | ||
|
||
var err error | ||
if logenv := os.Getenv("IPFS_LOGGING"); logenv != "" { | ||
var err error | ||
lvl, err = logging.LogLevel(logenv) | ||
if err != nil { | ||
PErr("invalid logging level: %s\n", logenv) | ||
PErr("using logging.DEBUG\n") | ||
lvl = logging.DEBUG | ||
log.Error("logging.LogLevel() Error: %q", err) | ||
lvl = logging.ERROR // reset to ERROR, could be undefined now(?) | ||
} | ||
} | ||
|
||
if Debug { | ||
lvl = logging.DEBUG | ||
} | ||
|
||
SetAllLoggers(lvl) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Was there a bug with how the logic was before (setting |
||
|
||
} | ||
|
||
// SetAllLoggers changes the logging.Level of all loggers to lvl | ||
func SetAllLoggers(lvl logging.Level) { | ||
logging.SetLevel(lvl, "") | ||
for n, log := range loggers { | ||
logging.SetLevel(lvl, n) | ||
log.Error("setting logger: %s to %v", n, lvl) | ||
log.Notice("setting logger: %q to %v", n, lvl) | ||
} | ||
} | ||
|
||
// Logger retrieves a particular logger + initializes it at a particular level | ||
// Logger retrieves a particular logger | ||
func Logger(name string) *logging.Logger { | ||
log := logging.MustGetLogger(name) | ||
// logging.SetLevel(lvl, name) // can't set level here. | ||
loggers[name] = log | ||
return log | ||
} | ||
|
||
// SetLogLevel changes the log level of a specific subsystem | ||
// name=="*" changes all subsystems | ||
func SetLogLevel(name, level string) error { | ||
lvl, err := logging.LogLevel(level) | ||
if err != nil { | ||
return err | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yay sanitizing :) |
||
|
||
// wildcard, change all | ||
if name == "*" { | ||
SetAllLoggers(lvl) | ||
return nil | ||
} | ||
|
||
// Check if we have a logger by that name | ||
// logging.SetLevel() can't tell us... | ||
_, ok := loggers[name] | ||
if !ok { | ||
return ErrNoSuchLogger | ||
} | ||
|
||
logging.SetLevel(lvl, name) | ||
|
||
return nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,17 +4,15 @@ import ( | |
"errors" | ||
"io" | ||
"math/rand" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
"time" | ||
|
||
ds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go" | ||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/mitchellh/go-homedir" | ||
) | ||
|
||
func init() { | ||
SetupLogging() | ||
} | ||
|
||
// Debug is a global flag for debugging. | ||
var Debug bool | ||
|
||
|
@@ -31,6 +29,9 @@ var ErrSearchIncomplete = errors.New("Error: Search Incomplete.") | |
// ErrNotFound is returned when a search fails to find anything | ||
var ErrNotFound = ds.ErrNotFound | ||
|
||
// ErrNoSuchLogger is returned when the util pkg is asked for a non existant logger | ||
var ErrNoSuchLogger = errors.New("Error: No such logger") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 yay named error :) |
||
|
||
// TildeExpansion expands a filename, which may begin with a tilde. | ||
func TildeExpansion(filename string) (string, error) { | ||
return homedir.Expand(filename) | ||
|
@@ -121,3 +122,9 @@ func (r *randGen) Read(p []byte) (n int, err error) { | |
|
||
panic("unreachable") | ||
} | ||
|
||
// GetenvBool is the way to check an env var as a boolean | ||
func GetenvBool(name string) bool { | ||
v := strings.ToLower(os.Getenv(name)) | ||
return v == "true" || v == "t" || v == "1" | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good call making this a util func. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Debug = true
should not be happening in here. It should probably be happening inmain()
:Then, maybe let's keep the old logic here and make this:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed that's cleaner (also the former note about calling
SetAllLoggers()
only once.