提交 f0571d32 作者: Juan Batiz-Benet

Merge pull request #179 from cryptix/improveLogging

Improve logging
...@@ -63,6 +63,7 @@ Use "ipfs help <command>" for more information about a command. ...@@ -63,6 +63,7 @@ Use "ipfs help <command>" for more information about a command.
cmdIpfsBootstrap, cmdIpfsBootstrap,
cmdIpfsDiag, cmdIpfsDiag,
cmdIpfsBlock, cmdIpfsBlock,
cmdIpfsLog,
}, },
Flag: *flag.NewFlagSet("ipfs", flag.ExitOnError), Flag: *flag.NewFlagSet("ipfs", flag.ExitOnError),
} }
...@@ -73,7 +74,7 @@ var log = u.Logger("cmd/ipfs") ...@@ -73,7 +74,7 @@ var log = u.Logger("cmd/ipfs")
func init() { func init() {
config, err := config.PathRoot() config, err := config.PathRoot()
if err != nil { if err != nil {
u.POut("Failure initializing the default Config Directory: ", err) fmt.Fprintln(os.Stderr, "Failure initializing the default Config Directory: ", err)
os.Exit(1) os.Exit(1)
} }
CmdIpfs.Flag.String("c", config, "specify config directory") CmdIpfs.Flag.String("c", config, "specify config directory")
...@@ -85,10 +86,7 @@ func ipfsCmd(c *commander.Command, args []string) error { ...@@ -85,10 +86,7 @@ func ipfsCmd(c *commander.Command, args []string) error {
} }
func main() { func main() {
u.Debug = false u.Debug = u.GetenvBool("IPFS_DEBUG")
// setup logging
// u.SetupLogging() done in an init() block now.
// if debugging, setup profiling. // if debugging, setup profiling.
if u.Debug { if u.Debug {
......
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,
})
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
}
...@@ -43,7 +43,7 @@ func printRefs(n *core.IpfsNode, nd *mdag.Node, refSeen map[u.Key]bool, recursiv ...@@ -43,7 +43,7 @@ func printRefs(n *core.IpfsNode, nd *mdag.Node, refSeen map[u.Key]bool, recursiv
if recursive { if recursive {
nd, err := n.DAG.Get(u.Key(link.Hash)) nd, err := n.DAG.Get(u.Key(link.Hash))
if err != nil { if err != nil {
u.PErr("error: cannot retrieve %s (%s)\n", link.Hash.B58String(), err) log.Error("error: cannot retrieve %s (%s)\n", link.Hash.B58String(), err)
return return
} }
......
...@@ -137,10 +137,13 @@ func (dl *DaemonListener) handleConnection(conn manet.Conn) { ...@@ -137,10 +137,13 @@ func (dl *DaemonListener) handleConnection(conn manet.Conn) {
err = commands.BlockGet(dl.node, command.Args, command.Opts, conn) err = commands.BlockGet(dl.node, command.Args, command.Opts, conn)
case "blockPut": case "blockPut":
err = commands.BlockPut(dl.node, command.Args, command.Opts, conn) err = commands.BlockPut(dl.node, command.Args, command.Opts, conn)
case "log":
err = commands.Log(dl.node, command.Args, command.Opts, conn)
default: default:
err = fmt.Errorf("Invalid Command: '%s'", command.Command) err = fmt.Errorf("Invalid Command: '%s'", command.Command)
} }
if err != nil { if err != nil {
log.Error("%s: %s", command.Command, err)
fmt.Fprintln(conn, err) fmt.Fprintln(conn, err)
} }
} }
......
...@@ -37,7 +37,7 @@ func init() { ...@@ -37,7 +37,7 @@ func init() {
var err error var err error
currentVersion, err = semver.NewVersion(Version) currentVersion, err = semver.NewVersion(Version)
if err != nil { if err != nil {
u.PErr("The const Version literal in version.go needs to be in semver format: %s \n", Version) log.Error("The const Version literal in version.go needs to be in semver format: %s \n", Version)
os.Exit(1) os.Exit(1)
} }
} }
......
...@@ -11,17 +11,14 @@ func init() { ...@@ -11,17 +11,14 @@ func init() {
SetupLogging() SetupLogging()
} }
var log = Logger("util")
// LogFormat is the format used for our logger. // LogFormat is the format used for our logger.
var LogFormat = "%{color}%{time:2006-01-02 15:04:05.999999} %{shortfile} %{level}: %{color:reset}%{message}" 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 // loggers is the set of loggers in the system
var loggers = map[string]*logging.Logger{} 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. // POut is a shorthand printing function to output to Stdout.
func POut(format string, a ...interface{}) { func POut(format string, a ...interface{}) {
fmt.Fprintf(os.Stdout, format, a...) fmt.Fprintf(os.Stdout, format, a...)
...@@ -35,31 +32,61 @@ func SetupLogging() { ...@@ -35,31 +32,61 @@ func SetupLogging() {
lvl := logging.ERROR lvl := logging.ERROR
var err error
if logenv := os.Getenv("IPFS_LOGGING"); logenv != "" { if logenv := os.Getenv("IPFS_LOGGING"); logenv != "" {
var err error
lvl, err = logging.LogLevel(logenv) lvl, err = logging.LogLevel(logenv)
if err != nil { if err != nil {
PErr("invalid logging level: %s\n", logenv) log.Error("logging.LogLevel() Error: %q", err)
PErr("using logging.DEBUG\n") lvl = logging.ERROR // reset to ERROR, could be undefined now(?)
lvl = logging.DEBUG
} }
} }
if Debug {
lvl = logging.DEBUG
}
SetAllLoggers(lvl) SetAllLoggers(lvl)
} }
// SetAllLoggers changes the logging.Level of all loggers to lvl
func SetAllLoggers(lvl logging.Level) { func SetAllLoggers(lvl logging.Level) {
logging.SetLevel(lvl, "") logging.SetLevel(lvl, "")
for n, log := range loggers { for n, log := range loggers {
logging.SetLevel(lvl, n) 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 { func Logger(name string) *logging.Logger {
log := logging.MustGetLogger(name) log := logging.MustGetLogger(name)
// logging.SetLevel(lvl, name) // can't set level here.
loggers[name] = log loggers[name] = log
return 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
}
// 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
}
...@@ -4,17 +4,15 @@ import ( ...@@ -4,17 +4,15 @@ import (
"errors" "errors"
"io" "io"
"math/rand" "math/rand"
"os"
"path/filepath" "path/filepath"
"strings"
"time" "time"
ds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go" 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" "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/mitchellh/go-homedir"
) )
func init() {
SetupLogging()
}
// Debug is a global flag for debugging. // Debug is a global flag for debugging.
var Debug bool var Debug bool
...@@ -31,6 +29,9 @@ var ErrSearchIncomplete = errors.New("Error: Search Incomplete.") ...@@ -31,6 +29,9 @@ var ErrSearchIncomplete = errors.New("Error: Search Incomplete.")
// ErrNotFound is returned when a search fails to find anything // ErrNotFound is returned when a search fails to find anything
var ErrNotFound = ds.ErrNotFound 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")
// TildeExpansion expands a filename, which may begin with a tilde. // TildeExpansion expands a filename, which may begin with a tilde.
func TildeExpansion(filename string) (string, error) { func TildeExpansion(filename string) (string, error) {
return homedir.Expand(filename) return homedir.Expand(filename)
...@@ -121,3 +122,9 @@ func (r *randGen) Read(p []byte) (n int, err error) { ...@@ -121,3 +122,9 @@ func (r *randGen) Read(p []byte) (n int, err error) {
panic("unreachable") 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"
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论