mirror of
https://github.com/minio/mc.git
synced 2026-01-04 02:44:40 +03:00
change admin console to support logs show (#4132)
This commit is contained in:
committed by
GitHub
parent
b1d8ca83f2
commit
40ee1a4ed6
@@ -18,21 +18,13 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/minio/cli"
|
||||
json "github.com/minio/colorjson"
|
||||
"github.com/minio/madmin-go"
|
||||
"github.com/minio/mc/pkg/probe"
|
||||
"github.com/minio/pkg/console"
|
||||
)
|
||||
|
||||
const logTimeFormat string = "15:04:05 MST 01/02/2006"
|
||||
|
||||
var adminConsoleFlags = []cli.Flag{
|
||||
cli.IntFlag{
|
||||
Name: "limit, l",
|
||||
@@ -47,173 +39,35 @@ var adminConsoleFlags = []cli.Flag{
|
||||
}
|
||||
|
||||
var adminConsoleCmd = cli.Command{
|
||||
Name: "console",
|
||||
Usage: "show console logs for MinIO server",
|
||||
Action: mainAdminConsole,
|
||||
OnUsageError: onUsageError,
|
||||
Before: setGlobalsFromContext,
|
||||
Flags: append(adminConsoleFlags, globalFlags...),
|
||||
HideHelpCommand: true,
|
||||
CustomHelpTemplate: `NAME:
|
||||
{{.HelpName}} - {{.Usage}}
|
||||
|
||||
USAGE:
|
||||
{{.HelpName}} [FLAGS] TARGET [NODENAME]
|
||||
|
||||
FLAGS:
|
||||
{{range .VisibleFlags}}{{.}}
|
||||
{{end}}
|
||||
EXAMPLES:
|
||||
1. Show console logs for a MinIO server with alias 'play'
|
||||
{{.Prompt}} {{.HelpName}} play
|
||||
|
||||
2. Show last 5 log entries for node 'node1' on MinIO server with alias 'myminio'
|
||||
{{.Prompt}} {{.HelpName}} --limit 5 myminio node1
|
||||
|
||||
3. Show application error logs on MinIO server with alias 'play'
|
||||
{{.Prompt}} {{.HelpName}} --type application play
|
||||
`,
|
||||
}
|
||||
|
||||
func checkAdminLogSyntax(ctx *cli.Context) {
|
||||
if len(ctx.Args()) == 0 || len(ctx.Args()) > 3 {
|
||||
cli.ShowCommandHelpAndExit(ctx, "console", 1) // last argument is exit code
|
||||
}
|
||||
}
|
||||
|
||||
// Extend madmin.LogInfo to add String() and JSON() methods
|
||||
type logMessage struct {
|
||||
Status string `json:"status"`
|
||||
madmin.LogInfo
|
||||
}
|
||||
|
||||
// JSON - jsonify loginfo
|
||||
func (l logMessage) JSON() string {
|
||||
l.Status = "success"
|
||||
logJSON, err := json.MarshalIndent(&l, "", " ")
|
||||
fatalIf(probe.NewError(err), "Unable to marshal into JSON.")
|
||||
|
||||
return string(logJSON)
|
||||
}
|
||||
|
||||
func getLogTime(lt string) string {
|
||||
tm, err := time.Parse(time.RFC3339Nano, lt)
|
||||
if err != nil {
|
||||
return lt
|
||||
}
|
||||
return tm.Format(logTimeFormat)
|
||||
}
|
||||
|
||||
// String - return colorized loginfo as string.
|
||||
func (l logMessage) String() string {
|
||||
var hostStr string
|
||||
b := &strings.Builder{}
|
||||
if l.NodeName != "" {
|
||||
hostStr = fmt.Sprintf("%s ", colorizedNodeName(l.NodeName))
|
||||
}
|
||||
log := l.LogInfo
|
||||
if log.ConsoleMsg != "" {
|
||||
if strings.HasPrefix(log.ConsoleMsg, "\n") {
|
||||
fmt.Fprintf(b, "%s\n", hostStr)
|
||||
log.ConsoleMsg = strings.TrimPrefix(log.ConsoleMsg, "\n")
|
||||
}
|
||||
fmt.Fprintf(b, "%s %s", hostStr, log.ConsoleMsg)
|
||||
return b.String()
|
||||
}
|
||||
if l.API != nil {
|
||||
apiString := "API: " + l.API.Name + "("
|
||||
if l.API.Args != nil && l.API.Args.Bucket != "" {
|
||||
apiString = apiString + "bucket=" + l.API.Args.Bucket
|
||||
}
|
||||
if l.API.Args != nil && l.API.Args.Object != "" {
|
||||
apiString = apiString + ", object=" + l.API.Args.Object
|
||||
}
|
||||
apiString += ")"
|
||||
fmt.Fprintf(b, "\n%s %s", hostStr, console.Colorize("API", apiString))
|
||||
}
|
||||
if l.Time != "" {
|
||||
fmt.Fprintf(b, "\n%s Time: %s", hostStr, getLogTime(l.Time))
|
||||
}
|
||||
if l.DeploymentID != "" {
|
||||
fmt.Fprintf(b, "\n%s DeploymentID: %s", hostStr, l.DeploymentID)
|
||||
}
|
||||
if l.RequestID != "" {
|
||||
fmt.Fprintf(b, "\n%s RequestID: %s", hostStr, l.RequestID)
|
||||
}
|
||||
if l.RemoteHost != "" {
|
||||
fmt.Fprintf(b, "\n%s RemoteHost: %s", hostStr, l.RemoteHost)
|
||||
}
|
||||
if l.UserAgent != "" {
|
||||
fmt.Fprintf(b, "\n%s UserAgent: %s", hostStr, l.UserAgent)
|
||||
}
|
||||
if l.Trace != nil {
|
||||
if l.Trace.Message != "" {
|
||||
fmt.Fprintf(b, "\n%s Error: %s", hostStr, console.Colorize("LogMessage", l.Trace.Message))
|
||||
}
|
||||
if l.Trace.Variables != nil {
|
||||
for key, value := range l.Trace.Variables {
|
||||
if value != "" {
|
||||
fmt.Fprintf(b, "\n%s %s=%s", hostStr, key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
if l.Trace.Source != nil {
|
||||
traceLength := len(l.Trace.Source)
|
||||
for i, element := range l.Trace.Source {
|
||||
fmt.Fprintf(b, "\n%s %8v: %s", hostStr, traceLength-i, element)
|
||||
}
|
||||
}
|
||||
}
|
||||
logMsg := strings.TrimPrefix(b.String(), "\n")
|
||||
return fmt.Sprintf("%s\n", logMsg)
|
||||
Name: "console",
|
||||
Usage: "show MinIO logs",
|
||||
Action: mainAdminConsole,
|
||||
OnUsageError: onUsageError,
|
||||
Before: setGlobalsFromContext,
|
||||
Flags: append(adminConsoleFlags, globalFlags...),
|
||||
Hidden: true,
|
||||
HideHelpCommand: true,
|
||||
CustomHelpTemplate: "This command is not supported now and replaced by 'support logs show' command. Please use 'mc support logs show'.\n",
|
||||
}
|
||||
|
||||
// mainAdminConsole - the entry function of console command
|
||||
func mainAdminConsole(ctx *cli.Context) error {
|
||||
// Check for command syntax
|
||||
checkAdminLogSyntax(ctx)
|
||||
console.SetColor("LogMessage", color.New(color.Bold, color.FgRed))
|
||||
console.SetColor("Api", color.New(color.Bold, color.FgWhite))
|
||||
for _, c := range colors {
|
||||
console.SetColor(fmt.Sprintf("Node%d", c), color.New(c))
|
||||
}
|
||||
aliasedURL := ctx.Args().Get(0)
|
||||
var node string
|
||||
if len(ctx.Args()) > 1 {
|
||||
node = ctx.Args().Get(1)
|
||||
}
|
||||
var limit int
|
||||
newCmd := []string{"mc support logs show"}
|
||||
|
||||
var flgStr string
|
||||
|
||||
if ctx.IsSet("limit") {
|
||||
limit = ctx.Int("limit")
|
||||
if limit <= 0 {
|
||||
fatalIf(errInvalidArgument().Trace(ctx.Args()...), "please set a proper limit, for example: '--limit 5' to display last 5 logs, omit this flag to display all available logs")
|
||||
}
|
||||
}
|
||||
logType := strings.ToLower(ctx.String("type"))
|
||||
if logType != "minio" && logType != "application" && logType != "all" {
|
||||
fatalIf(errInvalidArgument().Trace(ctx.Args()...), "Invalid value for --type flag. Valid options are [minio, application, all]")
|
||||
}
|
||||
// Create a new MinIO Admin Client
|
||||
client, err := newAdminClient(aliasedURL)
|
||||
if err != nil {
|
||||
fatalIf(err.Trace(aliasedURL), "Unable to initialize admin client.")
|
||||
return nil
|
||||
flgStr = fmt.Sprintf("%s %d", "--last", ctx.Int("limit"))
|
||||
newCmd = append(newCmd, flgStr)
|
||||
}
|
||||
|
||||
ctxt, cancel := context.WithCancel(globalContext)
|
||||
defer cancel()
|
||||
|
||||
// Start listening on all console log activity.
|
||||
logCh := client.GetLogs(ctxt, node, limit, logType)
|
||||
for logInfo := range logCh {
|
||||
if logInfo.Err != nil {
|
||||
fatalIf(probe.NewError(logInfo.Err), "Unable to listen to console logs")
|
||||
}
|
||||
// drop nodeName from output if specified as cli arg
|
||||
if node != "" {
|
||||
logInfo.NodeName = ""
|
||||
}
|
||||
printMsg(logMessage{LogInfo: logInfo})
|
||||
if ctx.IsSet("type") {
|
||||
flgStr = fmt.Sprintf("%s %s", "--type", strings.ToLower(ctx.String("type")))
|
||||
newCmd = append(newCmd, flgStr)
|
||||
}
|
||||
newCmd = append(newCmd, ctx.Args()...)
|
||||
|
||||
msg := fmt.Sprintf("Please use '%s'", strings.Join(newCmd, " "))
|
||||
console.Infoln(msg)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -411,14 +411,17 @@ var completeCmds = map[string]complete.Predictor{
|
||||
"/alias/remove": aliasCompleter,
|
||||
"/alias/import": nil,
|
||||
|
||||
"/support/callhome": aliasCompleter,
|
||||
"/support/logs": aliasCompleter,
|
||||
"/support/register": aliasCompleter,
|
||||
"/support/diag": aliasCompleter,
|
||||
"/support/profile": aliasCompleter,
|
||||
"/support/inspect": aliasCompleter,
|
||||
"/support/perf": aliasCompleter,
|
||||
"/support/metrics": aliasCompleter,
|
||||
"/support/callhome": aliasCompleter,
|
||||
"/support/logs/enable": aliasCompleter,
|
||||
"/support/logs/disable": aliasCompleter,
|
||||
"/support/logs/status": aliasCompleter,
|
||||
"/support/logs/show": aliasCompleter,
|
||||
"/support/register": aliasCompleter,
|
||||
"/support/diag": aliasCompleter,
|
||||
"/support/profile": aliasCompleter,
|
||||
"/support/inspect": aliasCompleter,
|
||||
"/support/perf": aliasCompleter,
|
||||
"/support/metrics": aliasCompleter,
|
||||
|
||||
"/update": nil,
|
||||
}
|
||||
|
||||
49
cmd/support-logs-disable.go
Normal file
49
cmd/support-logs-disable.go
Normal file
@@ -0,0 +1,49 @@
|
||||
// Copyright (c) 2015-2022 MinIO, Inc.
|
||||
//
|
||||
// This file is part of MinIO Object Storage stack
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/minio/cli"
|
||||
)
|
||||
|
||||
var supportLogsDisableCmd = cli.Command{
|
||||
Name: "disable",
|
||||
Usage: "disable uploading MinIO logs to SUBNET",
|
||||
OnUsageError: onUsageError,
|
||||
Action: mainDisableLogs,
|
||||
Before: setGlobalsFromContext,
|
||||
Flags: logsConfigureFlags,
|
||||
CustomHelpTemplate: `NAME:
|
||||
{{.HelpName}} - {{.Usage}}
|
||||
USAGE:
|
||||
{{.HelpName}} ALIAS
|
||||
FLAGS:
|
||||
{{range .VisibleFlags}}{{.}}
|
||||
{{end}}
|
||||
EXAMPLES:
|
||||
1. Disable uploading logs for cluster with alias 'play' to SUBNET
|
||||
{{.Prompt}} {{.HelpName}} play
|
||||
`,
|
||||
}
|
||||
|
||||
func mainDisableLogs(ctx *cli.Context) error {
|
||||
setToggleMessageColor()
|
||||
alias := validateLogsToggleCmd(ctx, "disable")
|
||||
configureSubnetWebhook(alias, false)
|
||||
return nil
|
||||
}
|
||||
50
cmd/support-logs-enable.go
Normal file
50
cmd/support-logs-enable.go
Normal file
@@ -0,0 +1,50 @@
|
||||
// Copyright (c) 2015-2022 MinIO, Inc.
|
||||
//
|
||||
// This file is part of MinIO Object Storage stack
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/minio/cli"
|
||||
)
|
||||
|
||||
var supportLogsEnableCmd = cli.Command{
|
||||
Name: "enable",
|
||||
Usage: "enable uploading real-time MinIO logs to SUBNET",
|
||||
Action: mainEnableLogs,
|
||||
OnUsageError: onUsageError,
|
||||
Before: setGlobalsFromContext,
|
||||
Flags: logsConfigureFlags,
|
||||
HideHelpCommand: true,
|
||||
CustomHelpTemplate: `NAME:
|
||||
{{.HelpName}} - {{.Usage}}
|
||||
USAGE:
|
||||
{{.HelpName}} ALIAS
|
||||
FLAGS:
|
||||
{{range .VisibleFlags}}{{.}}
|
||||
{{end}}
|
||||
EXAMPLES:
|
||||
1. Enable uploading real-time logs for cluster with alias 'play' to SUBNET.
|
||||
{{.Prompt}} {{.HelpName}} play
|
||||
`,
|
||||
}
|
||||
|
||||
func mainEnableLogs(ctx *cli.Context) error {
|
||||
setToggleMessageColor()
|
||||
alias := validateLogsToggleCmd(ctx, "enable")
|
||||
configureSubnetWebhook(alias, true)
|
||||
return nil
|
||||
}
|
||||
215
cmd/support-logs-show.go
Normal file
215
cmd/support-logs-show.go
Normal file
@@ -0,0 +1,215 @@
|
||||
// Copyright (c) 2015-2022 MinIO, Inc.
|
||||
//
|
||||
// This file is part of MinIO Object Storage stack
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/minio/cli"
|
||||
json "github.com/minio/colorjson"
|
||||
"github.com/minio/madmin-go"
|
||||
"github.com/minio/mc/pkg/probe"
|
||||
"github.com/minio/pkg/console"
|
||||
)
|
||||
|
||||
const logTimeFormat string = "15:04:05 MST 01/02/2006"
|
||||
|
||||
var logsShowFlags = []cli.Flag{
|
||||
cli.IntFlag{
|
||||
Name: "last, l",
|
||||
Usage: "show last n log entries",
|
||||
Value: 10,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "type, t",
|
||||
Usage: "list error logs by type. Valid options are '[minio, application, all]'",
|
||||
Value: "all",
|
||||
},
|
||||
}
|
||||
|
||||
var supportLogsShowCmd = cli.Command{
|
||||
Name: "show",
|
||||
Usage: "show MinIO logs",
|
||||
Action: mainLogsShowConsole,
|
||||
OnUsageError: onUsageError,
|
||||
Before: setGlobalsFromContext,
|
||||
Flags: append(logsShowFlags, globalFlags...),
|
||||
HideHelpCommand: true,
|
||||
CustomHelpTemplate: `NAME:
|
||||
{{.HelpName}} - {{.Usage}}
|
||||
USAGE:
|
||||
{{.HelpName}} [FLAGS] TARGET [NODENAME]
|
||||
FLAGS:
|
||||
{{range .VisibleFlags}}{{.}}
|
||||
{{end}}
|
||||
EXAMPLES:
|
||||
1. Show logs for a MinIO server with alias 'play'
|
||||
{{.Prompt}} {{.HelpName}} play
|
||||
2. Show last 5 log entries for node 'node1' for a MinIO server with alias 'myminio'
|
||||
{{.Prompt}} {{.HelpName}} --last 5 myminio node1
|
||||
3. Show application errors in logs for a MinIO server with alias 'play'
|
||||
{{.Prompt}} {{.HelpName}} --type application play
|
||||
`,
|
||||
}
|
||||
|
||||
func checkLogsShowSyntax(ctx *cli.Context) {
|
||||
if len(ctx.Args()) == 0 || len(ctx.Args()) > 3 {
|
||||
cli.ShowCommandHelpAndExit(ctx, "show", 1) // last argument is exit code
|
||||
}
|
||||
}
|
||||
|
||||
// Extend madmin.LogInfo to add String() and JSON() methods
|
||||
type logMessage struct {
|
||||
Status string `json:"status"`
|
||||
madmin.LogInfo
|
||||
}
|
||||
|
||||
// JSON - jsonify loginfo
|
||||
func (l logMessage) JSON() string {
|
||||
l.Status = "success"
|
||||
logJSON, err := json.MarshalIndent(&l, "", " ")
|
||||
fatalIf(probe.NewError(err), "Unable to marshal into JSON.")
|
||||
|
||||
return string(logJSON)
|
||||
}
|
||||
|
||||
func getLogTime(lt string) string {
|
||||
tm, err := time.Parse(time.RFC3339Nano, lt)
|
||||
if err != nil {
|
||||
return lt
|
||||
}
|
||||
return tm.Format(logTimeFormat)
|
||||
}
|
||||
|
||||
// String - return colorized loginfo as string.
|
||||
func (l logMessage) String() string {
|
||||
var hostStr string
|
||||
b := &strings.Builder{}
|
||||
if l.NodeName != "" {
|
||||
hostStr = fmt.Sprintf("%s ", colorizedNodeName(l.NodeName))
|
||||
}
|
||||
log := l.LogInfo
|
||||
if log.ConsoleMsg != "" {
|
||||
if strings.HasPrefix(log.ConsoleMsg, "\n") {
|
||||
fmt.Fprintf(b, "%s\n", hostStr)
|
||||
log.ConsoleMsg = strings.TrimPrefix(log.ConsoleMsg, "\n")
|
||||
}
|
||||
fmt.Fprintf(b, "%s %s", hostStr, log.ConsoleMsg)
|
||||
return b.String()
|
||||
}
|
||||
if l.API != nil {
|
||||
apiString := "API: " + l.API.Name + "("
|
||||
if l.API.Args != nil && l.API.Args.Bucket != "" {
|
||||
apiString = apiString + "bucket=" + l.API.Args.Bucket
|
||||
}
|
||||
if l.API.Args != nil && l.API.Args.Object != "" {
|
||||
apiString = apiString + ", object=" + l.API.Args.Object
|
||||
}
|
||||
apiString += ")"
|
||||
fmt.Fprintf(b, "\n%s %s", hostStr, console.Colorize("API", apiString))
|
||||
}
|
||||
if l.Time != "" {
|
||||
fmt.Fprintf(b, "\n%s Time: %s", hostStr, getLogTime(l.Time))
|
||||
}
|
||||
if l.DeploymentID != "" {
|
||||
fmt.Fprintf(b, "\n%s DeploymentID: %s", hostStr, l.DeploymentID)
|
||||
}
|
||||
if l.RequestID != "" {
|
||||
fmt.Fprintf(b, "\n%s RequestID: %s", hostStr, l.RequestID)
|
||||
}
|
||||
if l.RemoteHost != "" {
|
||||
fmt.Fprintf(b, "\n%s RemoteHost: %s", hostStr, l.RemoteHost)
|
||||
}
|
||||
if l.UserAgent != "" {
|
||||
fmt.Fprintf(b, "\n%s UserAgent: %s", hostStr, l.UserAgent)
|
||||
}
|
||||
if l.Trace != nil {
|
||||
if l.Trace.Message != "" {
|
||||
fmt.Fprintf(b, "\n%s Error: %s", hostStr, console.Colorize("LogMessage", l.Trace.Message))
|
||||
}
|
||||
if l.Trace.Variables != nil {
|
||||
for key, value := range l.Trace.Variables {
|
||||
if value != "" {
|
||||
fmt.Fprintf(b, "\n%s %s=%s", hostStr, key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
if l.Trace.Source != nil {
|
||||
traceLength := len(l.Trace.Source)
|
||||
for i, element := range l.Trace.Source {
|
||||
fmt.Fprintf(b, "\n%s %8v: %s", hostStr, traceLength-i, element)
|
||||
}
|
||||
}
|
||||
}
|
||||
logMsg := strings.TrimPrefix(b.String(), "\n")
|
||||
return fmt.Sprintf("%s\n", logMsg)
|
||||
}
|
||||
|
||||
// mainLogsShowConsole - the entry function of support logs show
|
||||
func mainLogsShowConsole(ctx *cli.Context) error {
|
||||
// Check for command syntax
|
||||
checkLogsShowSyntax(ctx)
|
||||
console.SetColor("LogMessage", color.New(color.Bold, color.FgRed))
|
||||
console.SetColor("Api", color.New(color.Bold, color.FgWhite))
|
||||
for _, c := range colors {
|
||||
console.SetColor(fmt.Sprintf("Node%d", c), color.New(c))
|
||||
}
|
||||
aliasedURL := ctx.Args().Get(0)
|
||||
var node string
|
||||
if len(ctx.Args()) > 1 {
|
||||
node = ctx.Args().Get(1)
|
||||
}
|
||||
var last int
|
||||
if ctx.IsSet("last") {
|
||||
last = ctx.Int("last")
|
||||
if last <= 0 {
|
||||
fatalIf(errInvalidArgument().Trace(ctx.Args()...), "please set a proper limit, for example: '--last 5' to display last 5 logs, omit this flag to display all available logs")
|
||||
}
|
||||
}
|
||||
logType := strings.ToLower(ctx.String("type"))
|
||||
if logType != "minio" && logType != "application" && logType != "all" {
|
||||
fatalIf(errInvalidArgument().Trace(ctx.Args()...), "Invalid value for --type flag. Valid options are [minio, application, all]")
|
||||
}
|
||||
// Create a new MinIO Admin Client
|
||||
client, err := newAdminClient(aliasedURL)
|
||||
if err != nil {
|
||||
fatalIf(err.Trace(aliasedURL), "Unable to initialize admin client.")
|
||||
return nil
|
||||
}
|
||||
|
||||
ctxt, cancel := context.WithCancel(globalContext)
|
||||
defer cancel()
|
||||
|
||||
// Start listening on all console log activity.
|
||||
logCh := client.GetLogs(ctxt, node, last, logType)
|
||||
for logInfo := range logCh {
|
||||
if logInfo.Err != nil {
|
||||
fatalIf(probe.NewError(logInfo.Err), "Unable to listen to console logs")
|
||||
}
|
||||
// drop nodeName from output if specified as cli arg
|
||||
if node != "" {
|
||||
logInfo.NodeName = ""
|
||||
}
|
||||
printMsg(logMessage{LogInfo: logInfo})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
54
cmd/support-logs-status.go
Normal file
54
cmd/support-logs-status.go
Normal file
@@ -0,0 +1,54 @@
|
||||
// Copyright (c) 2015-2022 MinIO, Inc.
|
||||
//
|
||||
// This file is part of MinIO Object Storage stack
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/minio/cli"
|
||||
)
|
||||
|
||||
var supportLogsStatusCmd = cli.Command{
|
||||
Name: "status",
|
||||
Usage: "show current status of MinIO logs",
|
||||
OnUsageError: onUsageError,
|
||||
Action: mainStatusLogs,
|
||||
Before: setGlobalsFromContext,
|
||||
Flags: logsConfigureFlags,
|
||||
CustomHelpTemplate: `NAME:
|
||||
{{.HelpName}} - {{.Usage}}
|
||||
USAGE:
|
||||
{{.HelpName}} ALIAS
|
||||
FLAGS:
|
||||
{{range .VisibleFlags}}{{.}}
|
||||
{{end}}
|
||||
EXAMPLES:
|
||||
1. Show current status of MinIO logs with alias 'play', whether
|
||||
it is uploading to SUBNET or not
|
||||
{{.Prompt}} {{.HelpName}} play
|
||||
`,
|
||||
}
|
||||
|
||||
func mainStatusLogs(ctx *cli.Context) error {
|
||||
setToggleMessageColor()
|
||||
alias := validateLogsToggleCmd(ctx, "status")
|
||||
enabled := isFeatureEnabled(alias, "logger_webhook", "logger_webhook:subnet")
|
||||
printMsg(supportLogsMessage{
|
||||
Logs: featureStatusStr(enabled),
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -26,43 +26,28 @@ import (
|
||||
"github.com/minio/pkg/console"
|
||||
)
|
||||
|
||||
var logsFlags = append(globalFlags, cli.BoolFlag{
|
||||
var supportLogsSubcommands = []cli.Command{
|
||||
supportLogsEnableCmd,
|
||||
supportLogsDisableCmd,
|
||||
supportLogsStatusCmd,
|
||||
supportLogsShowCmd,
|
||||
}
|
||||
|
||||
var logsConfigureFlags = append(globalFlags, cli.BoolFlag{
|
||||
Name: "dev",
|
||||
Usage: "development mode - talks to local SUBNET",
|
||||
Hidden: true,
|
||||
})
|
||||
|
||||
var supportLogsCmd = cli.Command{
|
||||
Name: "logs",
|
||||
Usage: "configure logs settings",
|
||||
OnUsageError: onUsageError,
|
||||
Action: mainLogs,
|
||||
Before: setGlobalsFromContext,
|
||||
Flags: logsFlags,
|
||||
CustomHelpTemplate: `NAME:
|
||||
{{.HelpName}} - {{.Usage}}
|
||||
|
||||
USAGE:
|
||||
{{.HelpName}} enable|disable|status ALIAS
|
||||
|
||||
OPTIONS:
|
||||
enable - Enable pushing MinIO logs to SUBNET in real-time
|
||||
disable - Disable pushing MinIO logs to SUBNET
|
||||
status - Display logs settings
|
||||
|
||||
FLAGS:
|
||||
{{range .VisibleFlags}}{{.}}
|
||||
{{end}}
|
||||
EXAMPLES:
|
||||
1. Enable logs for cluster with alias 'play'
|
||||
{{.Prompt}} {{.HelpName}} enable play
|
||||
|
||||
2. Disable logs for cluster with alias 'play'
|
||||
{{.Prompt}} {{.HelpName}} disable play
|
||||
|
||||
3. Check logs status for cluster with alias 'play'
|
||||
{{.Prompt}} {{.HelpName}} status play
|
||||
`,
|
||||
Name: "logs",
|
||||
Usage: "configure/display MinIO console logs",
|
||||
OnUsageError: onUsageError,
|
||||
Action: mainLogs,
|
||||
Before: setGlobalsFromContext,
|
||||
Flags: globalFlags,
|
||||
HideHelpCommand: true,
|
||||
Subcommands: supportLogsSubcommands,
|
||||
}
|
||||
|
||||
type supportLogsMessage struct {
|
||||
@@ -85,23 +70,6 @@ func (s supportLogsMessage) JSON() string {
|
||||
return string(jsonBytes)
|
||||
}
|
||||
|
||||
func mainLogs(ctx *cli.Context) error {
|
||||
setToggleMessageColor()
|
||||
alias, arg := checkToggleCmdSyntax(ctx, "logs")
|
||||
|
||||
if arg == "status" {
|
||||
enabled := isFeatureEnabled(alias, "logger_webhook", "logger_webhook:subnet")
|
||||
printMsg(supportLogsMessage{
|
||||
Logs: featureStatusStr(enabled),
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
configureSubnetWebhook(alias, arg == "enable")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func configureSubnetWebhook(alias string, enable bool) {
|
||||
// Create a new MinIO Admin Client
|
||||
client, err := newAdminClient(alias)
|
||||
@@ -126,3 +94,18 @@ func configureSubnetWebhook(alias string, enable bool) {
|
||||
MsgPfx: "Logging to support is now ",
|
||||
})
|
||||
}
|
||||
|
||||
func validateLogsToggleCmd(ctx *cli.Context, cmdName string) string {
|
||||
if len(ctx.Args()) != 1 {
|
||||
cli.ShowCommandHelpAndExit(ctx, cmdName, 1) // last argument is exit code
|
||||
}
|
||||
alias, _ := url2Alias(ctx.Args().Get(0))
|
||||
return alias
|
||||
}
|
||||
|
||||
// mainLogs is the handle for "mc support logs" command.
|
||||
func mainLogs(ctx *cli.Context) error {
|
||||
commandNotFound(ctx, supportLogsSubcommands)
|
||||
return nil
|
||||
// Sub-commands like "enable", "disable", "status", "print" have their own main.
|
||||
}
|
||||
|
||||
@@ -708,34 +708,7 @@ mc admin trace myminio
|
||||
|
||||
<a name="console"></a>
|
||||
### Command `console` - show console logs for MinIO server
|
||||
`console` command displays server logs of one or all MinIO servers (under distributed cluster)
|
||||
|
||||
```sh
|
||||
NAME:
|
||||
mc admin console - show console logs for MinIO server
|
||||
|
||||
FLAGS:
|
||||
--limit value, -l value show last n log entries (default: 10)
|
||||
--help, -h show help
|
||||
```
|
||||
|
||||
*Example: Display MinIO server http trace.*
|
||||
|
||||
```sh
|
||||
mc admin console myminio
|
||||
|
||||
API: SYSTEM(bucket=images)
|
||||
Time: 22:48:06 PDT 09/05/2019
|
||||
DeploymentID: 6faeded5-5cf3-4133-8a37-07c5d500207c
|
||||
RequestID: <none>
|
||||
RemoteHost: <none>
|
||||
UserAgent: <none>
|
||||
Error: ARN 'arn:minio:sqs:us-east-1:1:webhook' not found
|
||||
4: cmd/notification.go:1189:cmd.readNotificationConfig()
|
||||
3: cmd/notification.go:780:cmd.(*NotificationSys).refresh()
|
||||
2: cmd/notification.go:815:cmd.(*NotificationSys).Init()
|
||||
1: cmd/server-main.go:375:cmd.serverMain()
|
||||
```
|
||||
This command is deprecated and will be removed in a future release. Use 'mc support logs show' instead.
|
||||
|
||||
<a name="prometheus"></a>
|
||||
|
||||
|
||||
@@ -1922,6 +1922,7 @@ NAME:
|
||||
mc support perf analyze object, network and drive performance
|
||||
mc support inspect upload raw object contents for analysis
|
||||
mc support profile generate profile data for debugging
|
||||
mc support logs configure/display MinIO console logs
|
||||
|
||||
```
|
||||
|
||||
@@ -1953,4 +1954,14 @@ mc support diag play
|
||||
Get CPU profiling for 2 minutes
|
||||
```
|
||||
mc support profile --type cpu --duration 120 myminio/
|
||||
```
|
||||
|
||||
Print last 5 application error logs entries for node 'node1' on MinIO server with alias 'myminio'
|
||||
```
|
||||
mc support logs show --last 5 --type application myminio node1
|
||||
```
|
||||
|
||||
Enable logs for cluster with alias 'play'
|
||||
```
|
||||
mc support logs enable play
|
||||
```
|
||||
Reference in New Issue
Block a user