-
Notifications
You must be signed in to change notification settings - Fork 550
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement profiling command to start & download profiling data of a standalone or all nodes of a cluster. ``` 1. Start CPU profiling $ mc admin profiling start --type "cpu" myminio/ 2. Download latest profiling data under save under profiling.zip $ mc admin profiling stop myminio/ ```
- Loading branch information
1 parent
c707a17
commit 0dd32c1
Showing
7 changed files
with
300 additions
and
72 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,6 +37,7 @@ var adminCmd = cli.Command{ | |
adminCredsCmd, | ||
adminConfigCmd, | ||
adminHealCmd, | ||
adminProfilingCmd, | ||
}, | ||
} | ||
|
||
|
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 @@ | ||
/* | ||
* Minio Client (C) 2018 Minio, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package cmd | ||
|
||
import ( | ||
"strings" | ||
|
||
"github.com/minio/cli" | ||
"github.com/minio/mc/pkg/console" | ||
"github.com/minio/mc/pkg/probe" | ||
"github.com/minio/minio/pkg/madmin" | ||
) | ||
|
||
var adminProfilingStartFlags = []cli.Flag{ | ||
cli.StringFlag{ | ||
Name: "type", | ||
Usage: "Profiler type, possible values are: `cpu`, `mem`, `block`, `mutex` and `trace`", | ||
Value: "mem", | ||
}, | ||
} | ||
|
||
var adminProfilingStartCmd = cli.Command{ | ||
Name: "start", | ||
Usage: "Start recording profiling data", | ||
Action: mainAdminProfilingStart, | ||
Before: setGlobalsFromContext, | ||
Flags: append(adminProfilingStartFlags, globalFlags...), | ||
HideHelpCommand: true, | ||
CustomHelpTemplate: `NAME: | ||
{{.HelpName}} - {{.Usage}} | ||
USAGE: | ||
{{.HelpName}} [FLAGS] TARGET | ||
FLAGS: | ||
{{range .VisibleFlags}}{{.}} | ||
{{end}} | ||
EXAMPLES: | ||
1. Start CPU profiling | ||
$ {{.HelpName}} --type cpu myminio/ | ||
`, | ||
} | ||
|
||
func checkAdminProfilingStartSyntax(ctx *cli.Context) { | ||
// Check flags combinations | ||
if len(ctx.Args()) != 1 { | ||
cli.ShowCommandHelpAndExit(ctx, "start", 1) // last argument is exit code | ||
} | ||
|
||
profilerTypes := []madmin.ProfilerType{ | ||
madmin.ProfilerCPU, | ||
madmin.ProfilerMEM, | ||
madmin.ProfilerBlock, | ||
madmin.ProfilerMutex, | ||
madmin.ProfilerTrace, | ||
} | ||
|
||
// Check if the provided profiler type is known and supported | ||
supportedProfiler := false | ||
profilerType := strings.ToLower(ctx.String("type")) | ||
for _, profiler := range profilerTypes { | ||
if profilerType == string(profiler) { | ||
supportedProfiler = true | ||
break | ||
} | ||
} | ||
if !supportedProfiler { | ||
fatalIf(errDummy(), "Profiler type unrecognized. Possible values are: %v.", profilerTypes) | ||
} | ||
} | ||
|
||
// mainAdminProfilingStart - the entry function of profiling command | ||
func mainAdminProfilingStart(ctx *cli.Context) error { | ||
// Check for command syntax | ||
checkAdminProfilingStartSyntax(ctx) | ||
|
||
// Get the alias parameter from cli | ||
args := ctx.Args() | ||
aliasedURL := args.Get(0) | ||
|
||
profilerType := ctx.String("type") | ||
|
||
// Create a new Minio Admin Client | ||
client, err := newAdminClient(aliasedURL) | ||
if err != nil { | ||
fatalIf(err.Trace(aliasedURL), "Cannot initialize admin client.") | ||
return nil | ||
} | ||
|
||
// Start profiling | ||
_, cmdErr := client.StartProfiling(madmin.ProfilerType(profilerType)) | ||
fatalIf(probe.NewError(cmdErr), "Unable to start profiling.") | ||
|
||
console.Infoln("Profiling data successfully started.") | ||
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,106 @@ | ||
/* | ||
* Minio Client (C) 2018 Minio, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package cmd | ||
|
||
import ( | ||
"io" | ||
"io/ioutil" | ||
"os" | ||
"time" | ||
|
||
"github.com/minio/cli" | ||
"github.com/minio/mc/pkg/console" | ||
"github.com/minio/mc/pkg/probe" | ||
) | ||
|
||
var adminProfilingStopCmd = cli.Command{ | ||
Name: "stop", | ||
Usage: "Stop and download profiling data", | ||
Action: mainAdminProfilingStop, | ||
Before: setGlobalsFromContext, | ||
Flags: globalFlags, | ||
HideHelpCommand: true, | ||
CustomHelpTemplate: `NAME: | ||
{{.HelpName}} - {{.Usage}} | ||
USAGE: | ||
{{.HelpName}} [FLAGS] TARGET | ||
FLAGS: | ||
{{range .VisibleFlags}}{{.}} | ||
{{end}} | ||
EXAMPLES: | ||
2. Download latest profiling data in the current directory | ||
$ {{.HelpName}} myminio/ | ||
`, | ||
} | ||
|
||
func checkAdminProfilingStopSyntax(ctx *cli.Context) { | ||
if len(ctx.Args()) != 1 { | ||
cli.ShowCommandHelpAndExit(ctx, "stop", 1) // last argument is exit code | ||
} | ||
} | ||
|
||
// mainAdminProfilingStop - the entry function of profiling stop command | ||
func mainAdminProfilingStop(ctx *cli.Context) error { | ||
// Check for command syntax | ||
checkAdminProfilingStopSyntax(ctx) | ||
|
||
// Get the alias parameter from cli | ||
args := ctx.Args() | ||
aliasedURL := args.Get(0) | ||
|
||
// Create a new Minio Admin Client | ||
client, err := newAdminClient(aliasedURL) | ||
if err != nil { | ||
fatalIf(err.Trace(aliasedURL), "Cannot initialize admin client.") | ||
return nil | ||
} | ||
|
||
// Create profiling zip file | ||
tmpFile, e := ioutil.TempFile("", "mc-profiling-") | ||
fatalIf(probe.NewError(e), "Unable to download profiling data.") | ||
|
||
// Ask for profiling data, which will come compressed with zip format | ||
zippedData, adminErr := client.DownloadProfilingData() | ||
fatalIf(probe.NewError(adminErr), "Unable to download profiling data.") | ||
|
||
// Copy zip content to target download file | ||
_, e = io.Copy(tmpFile, zippedData) | ||
fatalIf(probe.NewError(e), "Unable to download profiling data.") | ||
|
||
// Close everything | ||
zippedData.Close() | ||
tmpFile.Close() | ||
|
||
downloadPath := "profiling.zip" | ||
|
||
fi, e := os.Stat(downloadPath) | ||
if e == nil && !fi.IsDir() { | ||
e = os.Rename(downloadPath, downloadPath+"."+time.Now().Format("2006-01-02T15:04:05.999999-07:00")) | ||
fatalIf(probe.NewError(e), "Unable to create a backup of profiling.zip") | ||
} else { | ||
if !os.IsNotExist(e) { | ||
fatal(probe.NewError(e), "Unable to download profiling data.") | ||
} | ||
} | ||
|
||
fatalIf(probe.NewError(os.Rename(tmpFile.Name(), downloadPath)), "Unable to download profiling data.") | ||
|
||
console.Infof("Profiling data successfully downloaded as %s\n", downloadPath) | ||
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,40 @@ | ||
/* | ||
* Minio Client (C) 2018 Minio, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package cmd | ||
|
||
import ( | ||
"github.com/minio/cli" | ||
) | ||
|
||
var adminProfilingCmd = cli.Command{ | ||
Name: "profiling", | ||
Usage: "Generate profiling data for debugging purposes", | ||
Action: mainAdminProfiling, | ||
Before: setGlobalsFromContext, | ||
Flags: globalFlags, | ||
Subcommands: []cli.Command{ | ||
adminProfilingStartCmd, | ||
adminProfilingStopCmd, | ||
}, | ||
HideHelpCommand: true, | ||
} | ||
|
||
// mainAdminProfiling is the handle for "mc admin profiling" command. | ||
func mainAdminProfiling(ctx *cli.Context) error { | ||
cli.ShowCommandHelp(ctx, ctx.Args().First()) | ||
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
Oops, something went wrong.