-
Notifications
You must be signed in to change notification settings - Fork 301
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
b/340244046 initial port collect command from master to 2.4
Although this port copies the code from master to 2.4, there are issues related to permissions making it non-functional. This is a partial cherry-pick of the following PR's on master: DAOS-10625 control: Create the tool to collect the logs/config for support purpose (#11094) DAOS-13759 control: Update support collect-log tool. (#12906) DAOS-13763 control: Fix daos_metrics collection for support collect-log. (#12555) DAOS-13936 support: Collect the specific logs and Time range log for support (#13325) Change-Id: I168c14e177a5003c4e315595b1bf154e84cef473
- Loading branch information
Showing
37 changed files
with
4,141 additions
and
112 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
// | ||
// (C) Copyright 2022-2023 Intel Corporation. | ||
// | ||
// SPDX-License-Identifier: BSD-2-Clause-Patent | ||
// | ||
|
||
package main | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
"time" | ||
|
||
"github.com/daos-stack/daos/src/control/common/cmdutil" | ||
"github.com/daos-stack/daos/src/control/lib/support" | ||
) | ||
|
||
// supportCmd is the struct representing the top-level support subcommand. | ||
type supportCmd struct { | ||
CollectLog collectLogCmd `command:"collect-log" description:"Collect logs from client"` | ||
agentConfigPath string | ||
} | ||
|
||
// collectLogCmd is the struct representing the command to collect the log from client side. | ||
type collectLogCmd struct { | ||
supportAgentConfigCmd | ||
cmdutil.LogCmd | ||
support.CollectLogSubCmd | ||
} | ||
|
||
func (cmd *collectLogCmd) Execute(_ []string) error { | ||
err := cmd.DateTimeValidate() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
var LogCollection = map[int32][]string{ | ||
support.CopyAgentConfigEnum: {""}, | ||
support.CollectAgentLogEnum: {""}, | ||
support.CollectAgentCmdEnum: support.AgentCmd, | ||
support.CollectClientLogEnum: {""}, | ||
support.CollectSystemCmdEnum: support.SystemCmd, | ||
} | ||
|
||
// Default 3 steps of log/conf collection. | ||
progress := support.ProgressBar{ | ||
Total: len(LogCollection), | ||
NoDisplay: false, | ||
} | ||
|
||
if cmd.Archive { | ||
progress.Total++ | ||
} | ||
|
||
// Copy the custom log folder | ||
if cmd.ExtraLogsDir != "" { | ||
LogCollection[support.CollectExtraLogsDirEnum] = []string{""} | ||
progress.Total++ | ||
} | ||
|
||
if cmd.TargetFolder == "" { | ||
folderName := fmt.Sprintf("daos_support_client_logs_%s", time.Now().Format(time.RFC3339)) | ||
cmd.TargetFolder = filepath.Join(os.TempDir(), folderName) | ||
} | ||
|
||
cmd.Infof("Support Logs will be copied to %s", cmd.TargetFolder) | ||
|
||
progress.Steps = 100 / progress.Total | ||
params := support.CollectLogsParams{} | ||
params.TargetFolder = cmd.TargetFolder | ||
params.ExtraLogsDir = cmd.ExtraLogsDir | ||
params.Config = cmd.getSupportConf() | ||
params.LogStartDate = cmd.LogStartDate | ||
params.LogEndDate = cmd.LogEndDate | ||
params.LogStartTime = cmd.LogStartTime | ||
params.LogEndTime = cmd.LogEndTime | ||
for logFunc, logCmdSet := range LogCollection { | ||
for _, logCmd := range logCmdSet { | ||
cmd.Debugf("Log Function Enum = %d -- Log Collect Cmd = %s ", logFunc, logCmd) | ||
params.LogFunction = logFunc | ||
params.LogCmd = logCmd | ||
|
||
err := support.CollectSupportLog(cmd.Logger, params) | ||
if err != nil { | ||
fmt.Println(err) | ||
if cmd.StopOnError { | ||
return err | ||
} | ||
} | ||
} | ||
fmt.Printf(progress.Display()) | ||
} | ||
|
||
if cmd.Archive { | ||
cmd.Debugf("Archiving the Log Folder %s", cmd.TargetFolder) | ||
err := support.ArchiveLogs(cmd.Logger, params) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// FIXME: DAOS-13290 Workaround for files held open | ||
for i := 1; i < 3; i++ { | ||
os.RemoveAll(cmd.TargetFolder) | ||
} | ||
} | ||
|
||
fmt.Printf(progress.Display()) | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
// | ||
// (C) Copyright 2024 Intel Corporation. | ||
// | ||
// SPDX-License-Identifier: BSD-2-Clause-Patent | ||
// | ||
|
||
package main | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"io" | ||
"os" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/google/go-cmp/cmp" | ||
|
||
"github.com/daos-stack/daos/src/control/common/cmdutil" | ||
"github.com/daos-stack/daos/src/control/common/test" | ||
"github.com/daos-stack/daos/src/control/logging" | ||
) | ||
|
||
type jsonCmdTest struct { | ||
name string | ||
cmd string | ||
setHelpers func(opts *mainOpts) | ||
expOut interface{} // JSON encoded data should output. | ||
expErr error | ||
} | ||
|
||
func runJSONCmdTests(t *testing.T, log *logging.LeveledLogger, cmdTests []jsonCmdTest) { | ||
t.Helper() | ||
|
||
for _, tc := range cmdTests { | ||
t.Run(tc.name, func(t *testing.T) { | ||
t.Helper() | ||
|
||
// Replace os.Stdout so that we can verify the generated output. | ||
var result bytes.Buffer | ||
r, w, _ := os.Pipe() | ||
done := make(chan struct{}) | ||
go func() { | ||
_, _ = io.Copy(&result, r) | ||
close(done) | ||
}() | ||
stdout := os.Stdout | ||
defer func() { | ||
os.Stdout = stdout | ||
}() | ||
os.Stdout = w | ||
|
||
var opts mainOpts | ||
if tc.setHelpers != nil { | ||
tc.setHelpers(&opts) | ||
} | ||
test.CmpErr(t, tc.expErr, parseOpts(strings.Split(tc.cmd, " "), &opts, log)) | ||
|
||
w.Close() | ||
<-done | ||
|
||
// Verify only JSON gets printed. | ||
if !json.Valid(result.Bytes()) { | ||
t.Fatalf("invalid JSON in response: %s", result.String()) | ||
} | ||
|
||
var sb strings.Builder | ||
if err := cmdutil.OutputJSON(&sb, tc.expOut, tc.expErr); err != nil { | ||
if err != tc.expErr { | ||
t.Fatalf("OutputJSON: %s", err) | ||
} | ||
} | ||
|
||
if diff := cmp.Diff(sb.String(), result.String()); diff != "" { | ||
t.Fatalf("unexpected stdout (-want, +got):\n%s\n", diff) | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
// | ||
// (C) Copyright 2022-2023 Intel Corporation. | ||
// | ||
// SPDX-License-Identifier: BSD-2-Clause-Patent | ||
// | ||
|
||
package main | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
"time" | ||
|
||
"github.com/daos-stack/daos/src/control/common/cmdutil" | ||
"github.com/daos-stack/daos/src/control/lib/support" | ||
) | ||
|
||
// supportCmd is the struct representing the top-level support subcommand. | ||
type supportCmd struct { | ||
CollectLog collectLogCmd `command:"collect-log" description:"Collect logs from server"` | ||
} | ||
|
||
// collectLogCmd is the struct representing the command to collect the Logs/config for support purpose | ||
type collectLogCmd struct { | ||
cfgCmd | ||
cmdutil.LogCmd | ||
support.CollectLogSubCmd | ||
support.LogTypeSubCmd | ||
} | ||
|
||
func (cmd *collectLogCmd) Execute(_ []string) error { | ||
var LogCollection = map[int32][]string{} | ||
err := cmd.DateTimeValidate() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// Only collect the specific logs Admin,Control or Engine. | ||
// This will ignore the system information collection. | ||
if cmd.LogType != "" { | ||
LogCollection[support.CollectServerLogEnum], err = cmd.LogTypeValidate() | ||
if err != nil { | ||
return err | ||
} | ||
} else { | ||
LogCollection[support.CopyServerConfigEnum] = []string{""} | ||
LogCollection[support.CollectSystemCmdEnum] = support.SystemCmd | ||
LogCollection[support.CollectDaosServerCmdEnum] = support.DaosServerCmd | ||
LogCollection[support.CollectServerLogEnum], err = cmd.LogTypeValidate() | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
|
||
// Default 4 steps of log/conf collection. | ||
progress := support.ProgressBar{ | ||
Total: len(LogCollection), | ||
NoDisplay: false, | ||
} | ||
|
||
if cmd.Archive { | ||
progress.Total++ | ||
} | ||
|
||
// Copy custom log folder | ||
if cmd.ExtraLogsDir != "" { | ||
LogCollection[support.CollectExtraLogsDirEnum] = []string{""} | ||
progress.Total++ | ||
} | ||
|
||
if cmd.TargetFolder == "" { | ||
folderName := fmt.Sprintf("daos_support_server_logs_%s", time.Now().Format(time.RFC3339)) | ||
cmd.TargetFolder = filepath.Join(os.TempDir(), folderName) | ||
} | ||
cmd.Infof("Support logs will be copied to %s", cmd.TargetFolder) | ||
|
||
progress.Steps = 100 / progress.Total | ||
params := support.CollectLogsParams{} | ||
params.Config = cmd.configPath() | ||
params.TargetFolder = cmd.TargetFolder | ||
params.ExtraLogsDir = cmd.ExtraLogsDir | ||
params.LogStartDate = cmd.LogStartDate | ||
params.LogEndDate = cmd.LogEndDate | ||
params.LogStartTime = cmd.LogStartTime | ||
params.LogEndTime = cmd.LogEndTime | ||
for logFunc, logCmdSet := range LogCollection { | ||
for _, logCmd := range logCmdSet { | ||
cmd.Debugf("Log Function Enum = %d -- Log Collect Cmd = %s ", logFunc, logCmd) | ||
params.LogFunction = logFunc | ||
params.LogCmd = logCmd | ||
|
||
err := support.CollectSupportLog(cmd.Logger, params) | ||
if err != nil { | ||
fmt.Println(err) | ||
if cmd.StopOnError { | ||
return err | ||
} | ||
} | ||
} | ||
fmt.Printf(progress.Display()) | ||
} | ||
|
||
if cmd.Archive { | ||
cmd.Debugf("Archiving the Log Folder %s", cmd.TargetFolder) | ||
err := support.ArchiveLogs(cmd.Logger, params) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// FIXME: DAOS-13290 Workaround for files held open | ||
for i := 1; i < 3; i++ { | ||
os.RemoveAll(cmd.TargetFolder) | ||
} | ||
} | ||
|
||
fmt.Printf(progress.Display()) | ||
|
||
return nil | ||
} |
Oops, something went wrong.