log.go 3.42 KB
Newer Older
1 2 3 4
package commands

import (
	"fmt"
5
	"io"
6

Jakub Sztandera's avatar
Jakub Sztandera committed
7 8 9
	cmds "github.com/ipfs/go-ipfs-cmds"
	logging "github.com/ipfs/go-log"
	lwriter "github.com/ipfs/go-log/writer"
10 11
)

12 13 14 15 16 17
// Golang os.Args overrides * and replaces the character argument with
// an array which includes every file in the user's CWD. As a
// workaround, we use 'all' instead. The util library still uses * so
// we convert it at this step.
var logAllKeyword = "all"

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
18
var LogCmd = &cmds.Command{
Steven Allen's avatar
Steven Allen committed
19
	Helptext: cmds.HelpText{
rht's avatar
rht committed
20
		Tagline: "Interact with the daemon log output.",
21 22 23
		ShortDescription: `
'ipfs log' contains utility commands to affect or read the logging
output of a running daemon.
24 25 26

There are also two environmental variables that direct the logging 
system (not just for the daemon logs, but all commands):
27 28 29 30
    IPFS_LOGGING - sets the level of verbosity of the logging.
        One of: debug, info, warn, error, dpanic, panic, fatal
    IPFS_LOGGING_FMT - sets formatting of the log output.
        One of: color, nocolor
31 32 33 34 35
`,
	},

	Subcommands: map[string]*cmds.Command{
		"level": logLevelCmd,
Hector Sanjuan's avatar
Hector Sanjuan committed
36
		"ls":    logLsCmd,
37
		"tail":  logTailCmd,
38 39 40 41
	},
}

var logLevelCmd = &cmds.Command{
Steven Allen's avatar
Steven Allen committed
42
	Helptext: cmds.HelpText{
rht's avatar
rht committed
43
		Tagline: "Change the logging level.",
44
		ShortDescription: `
45 46
Change the verbosity of one or all subsystems log output. This does not affect
the event log.
47
`,
48
	},
49

Steven Allen's avatar
Steven Allen committed
50
	Arguments: []cmds.Argument{
51 52
		// TODO use a different keyword for 'all' because all can theoretically
		// clash with a subsystem name
Steven Allen's avatar
Steven Allen committed
53
		cmds.StringArg("subsystem", true, false, fmt.Sprintf("The subsystem logging identifier. Use '%s' for all subsystems.", logAllKeyword)),
54 55
		cmds.StringArg("level", true, false, `The log level, with 'debug' the most verbose and 'fatal' the least verbose.
			One of: debug, info, warn, error, dpanic, panic, fatal.
56
		`),
57
	},
58
	NoLocal: true,
59 60
	Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
		args := req.Arguments
61
		subsystem, level := args[0], args[1]
62 63 64 65 66

		if subsystem == logAllKeyword {
			subsystem = "*"
		}

Jeromy's avatar
Jeromy committed
67
		if err := logging.SetLogLevel(subsystem, level); err != nil {
68
			return err
69 70
		}

71
		s := fmt.Sprintf("Changed log level of '%s' to '%s'\n", subsystem, level)
72
		log.Info(s)
73 74

		return cmds.EmitOnce(res, &MessageOutput{s})
75
	},
76 77 78 79 80
	Encoders: cmds.EncoderMap{
		cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *MessageOutput) error {
			fmt.Fprint(w, out.Message)
			return nil
		}),
81
	},
82
	Type: MessageOutput{},
83
}
84

Hector Sanjuan's avatar
Hector Sanjuan committed
85
var logLsCmd = &cmds.Command{
Steven Allen's avatar
Steven Allen committed
86
	Helptext: cmds.HelpText{
Hector Sanjuan's avatar
Hector Sanjuan committed
87 88 89 90 91 92
		Tagline: "List the logging subsystems.",
		ShortDescription: `
'ipfs log ls' is a utility command used to list the logging
subsystems of a running daemon.
`,
	},
93
	Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
94
		return cmds.EmitOnce(res, &stringList{logging.GetSubsystems()})
Hector Sanjuan's avatar
Hector Sanjuan committed
95
	},
96 97 98 99 100 101 102
	Encoders: cmds.EncoderMap{
		cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, list *stringList) error {
			for _, s := range list.Strings {
				fmt.Fprintln(w, s)
			}
			return nil
		}),
Hector Sanjuan's avatar
Hector Sanjuan committed
103
	},
Richard Littauer's avatar
Richard Littauer committed
104
	Type: stringList{},
Hector Sanjuan's avatar
Hector Sanjuan committed
105 106
}

107
var logTailCmd = &cmds.Command{
Steven Allen's avatar
Steven Allen committed
108
	Helptext: cmds.HelpText{
109
		Tagline: "Read the event log.",
110
		ShortDescription: `
111
Outputs event log messages (not other log messages) as they are generated.
112 113 114
`,
	},

115 116
	Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
		ctx := req.Context
117
		r, w := io.Pipe()
118
		go func() {
119
			defer w.Close()
120
			<-ctx.Done()
121
		}()
122
		lwriter.WriterGroup.AddWriter(w)
123
		return res.Emit(r)
124 125
	},
}