mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-21 10:27:46 +08:00
Some checks are pending
CodeQL / codeql (push) Waiting to run
Docker Build / docker-build (push) Waiting to run
Gateway Conformance / gateway-conformance (push) Waiting to run
Gateway Conformance / gateway-conformance-libp2p-experiment (push) Waiting to run
Go Build / go-build (push) Waiting to run
Go Check / go-check (push) Waiting to run
Go Lint / go-lint (push) Waiting to run
Go Test / go-test (push) Waiting to run
Interop / interop-prep (push) Waiting to run
Interop / helia-interop (push) Blocked by required conditions
Interop / ipfs-webui (push) Blocked by required conditions
Sharness / sharness-test (push) Waiting to run
Spell Check / spellcheck (push) Waiting to run
* chore: update to go-log/v2 go-log v2 has been out for quite a while now and it is time to deprecate v1. Replace all use of go-log with go-log/v2 Makes /api/v0/log/tail useful over HTTP Updates dependencies that have moved to go-lov/v2 Removes support for ContextWithLoggable as this is not needed for tracing-like functionality - Replaces: PR #8765 - Closes issue #8753 - Closes issue #9245 - Closes issue #10809 Other fixes: * update go-ipfs-cmds * update http logs test * fix test * Read/send one line of log data at a time * Update -log-level docs
149 lines
4.1 KiB
Go
149 lines
4.1 KiB
Go
package commands
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
|
|
cmds "github.com/ipfs/go-ipfs-cmds"
|
|
logging "github.com/ipfs/go-log/v2"
|
|
)
|
|
|
|
// 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"
|
|
|
|
var LogCmd = &cmds.Command{
|
|
Helptext: cmds.HelpText{
|
|
Tagline: "Interact with the daemon log output.",
|
|
ShortDescription: `
|
|
'ipfs log' contains utility commands to affect or read the logging
|
|
output of a running daemon.
|
|
|
|
There are also two environmental variables that direct the logging
|
|
system (not just for the daemon logs, but all commands):
|
|
GOLOG_LOG_LEVEL - sets the level of verbosity of the logging.
|
|
One of: debug, info, warn, error, dpanic, panic, fatal
|
|
GOLOG_LOG_FMT - sets formatting of the log output.
|
|
One of: color, nocolor, json
|
|
`,
|
|
},
|
|
|
|
Subcommands: map[string]*cmds.Command{
|
|
"level": logLevelCmd,
|
|
"ls": logLsCmd,
|
|
"tail": logTailCmd,
|
|
},
|
|
}
|
|
|
|
var logLevelCmd = &cmds.Command{
|
|
Helptext: cmds.HelpText{
|
|
Tagline: "Change the logging level.",
|
|
ShortDescription: `
|
|
Change the verbosity of one or all subsystems log output. This does not affect
|
|
the event log.
|
|
`,
|
|
},
|
|
|
|
Arguments: []cmds.Argument{
|
|
// TODO use a different keyword for 'all' because all can theoretically
|
|
// clash with a subsystem name
|
|
cmds.StringArg("subsystem", true, false, fmt.Sprintf("The subsystem logging identifier. Use '%s' for all subsystems.", logAllKeyword)),
|
|
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.
|
|
`),
|
|
},
|
|
NoLocal: true,
|
|
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
|
|
args := req.Arguments
|
|
subsystem, level := args[0], args[1]
|
|
|
|
if subsystem == logAllKeyword {
|
|
subsystem = "*"
|
|
}
|
|
|
|
if err := logging.SetLogLevel(subsystem, level); err != nil {
|
|
return err
|
|
}
|
|
|
|
s := fmt.Sprintf("Changed log level of '%s' to '%s'\n", subsystem, level)
|
|
log.Info(s)
|
|
|
|
return cmds.EmitOnce(res, &MessageOutput{s})
|
|
},
|
|
Encoders: cmds.EncoderMap{
|
|
cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *MessageOutput) error {
|
|
fmt.Fprint(w, out.Message)
|
|
return nil
|
|
}),
|
|
},
|
|
Type: MessageOutput{},
|
|
}
|
|
|
|
var logLsCmd = &cmds.Command{
|
|
Helptext: cmds.HelpText{
|
|
Tagline: "List the logging subsystems.",
|
|
ShortDescription: `
|
|
'ipfs log ls' is a utility command used to list the logging
|
|
subsystems of a running daemon.
|
|
`,
|
|
},
|
|
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
|
|
return cmds.EmitOnce(res, &stringList{logging.GetSubsystems()})
|
|
},
|
|
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
|
|
}),
|
|
},
|
|
Type: stringList{},
|
|
}
|
|
|
|
const logLevelOption = "log-level"
|
|
|
|
var logTailCmd = &cmds.Command{
|
|
Status: cmds.Experimental,
|
|
Helptext: cmds.HelpText{
|
|
Tagline: "Read and outpt log messages.",
|
|
ShortDescription: `
|
|
Outputs log messages as they are generated.
|
|
|
|
NOTE: --log-level requires the server to be logging at least at this level
|
|
|
|
Example:
|
|
|
|
GOLOG_LOG_LEVEL="error,bitswap=debug" ipfs daemon
|
|
ipfs log tail --log-level info
|
|
|
|
This will only return 'info' logs from bitswap and skip 'debug'.
|
|
`,
|
|
},
|
|
|
|
Options: []cmds.Option{
|
|
cmds.StringOption(logLevelOption, "Log level to listen to.").WithDefault(""),
|
|
},
|
|
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
|
|
var pipeReader *logging.PipeReader
|
|
logLevelString, _ := req.Options[logLevelOption].(string)
|
|
if logLevelString != "" {
|
|
logLevel, err := logging.LevelFromString(logLevelString)
|
|
if err != nil {
|
|
return fmt.Errorf("setting log level %s: %w", logLevelString, err)
|
|
}
|
|
pipeReader = logging.NewPipeReader(logging.PipeLevel(logLevel))
|
|
} else {
|
|
pipeReader = logging.NewPipeReader()
|
|
}
|
|
|
|
go func() {
|
|
<-req.Context.Done()
|
|
pipeReader.Close()
|
|
}()
|
|
return res.Emit(pipeReader)
|
|
},
|
|
}
|