aboutsummaryrefslogtreecommitdiff
path: root/cmd/podman
diff options
context:
space:
mode:
authorAdrian Reber <areber@redhat.com>2021-11-09 09:15:50 +0000
committerAdrian Reber <areber@redhat.com>2021-11-15 11:50:24 +0000
commit6202e8102b9728f89c2ab7bb504306a2bd007878 (patch)
treee5233ba6f948d62a59f2338b7f34827f6ff76eb2 /cmd/podman
parentcca6df428cb9ce187ae1341740ac1137c7a67a75 (diff)
downloadpodman-6202e8102b9728f89c2ab7bb504306a2bd007878.tar.gz
podman-6202e8102b9728f89c2ab7bb504306a2bd007878.tar.bz2
podman-6202e8102b9728f89c2ab7bb504306a2bd007878.zip
Added optional container checkpointing statistics
This adds the parameter '--print-stats' to 'podman container checkpoint'. With '--print-stats' Podman will measure how long Podman itself, the OCI runtime and CRIU requires to create a checkpoint and print out these information. CRIU already creates checkpointing statistics which are just read in addition to the added measurements. In contrast to just printing out the ID of the checkpointed container, Podman will now print out JSON: # podman container checkpoint --latest --print-stats { "podman_checkpoint_duration": 360749, "container_statistics": [ { "Id": "25244244bf2efbef30fb6857ddea8cb2e5489f07eb6659e20dda117f0c466808", "runtime_checkpoint_duration": 177222, "criu_statistics": { "freezing_time": 100657, "frozen_time": 60700, "memdump_time": 8162, "memwrite_time": 4224, "pages_scanned": 20561, "pages_written": 2129 } } ] } The output contains 'podman_checkpoint_duration' which contains the number of microseconds Podman required to create the checkpoint. The output also includes 'runtime_checkpoint_duration' which is the time the runtime needed to checkpoint that specific container. Each container also includes 'criu_statistics' which displays the timing information collected by CRIU. Signed-off-by: Adrian Reber <areber@redhat.com>
Diffstat (limited to 'cmd/podman')
-rw-r--r--cmd/podman/containers/checkpoint.go34
1 files changed, 33 insertions, 1 deletions
diff --git a/cmd/podman/containers/checkpoint.go b/cmd/podman/containers/checkpoint.go
index 4fa72d520..d92bc3e5e 100644
--- a/cmd/podman/containers/checkpoint.go
+++ b/cmd/podman/containers/checkpoint.go
@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"strings"
+ "time"
"github.com/containers/common/pkg/completion"
"github.com/containers/podman/v3/cmd/podman/common"
@@ -40,6 +41,11 @@ var (
var checkpointOptions entities.CheckpointOptions
+type checkpointStatistics struct {
+ PodmanDuration int64 `json:"podman_checkpoint_duration"`
+ ContainerStatistics []*entities.CheckpointReport `json:"container_statistics"`
+}
+
func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Command: checkpointCommand,
@@ -63,11 +69,19 @@ func init() {
flags.StringP("compress", "c", "zstd", "Select compression algorithm (gzip, none, zstd) for checkpoint archive.")
_ = checkpointCommand.RegisterFlagCompletionFunc("compress", common.AutocompleteCheckpointCompressType)
+ flags.BoolVar(
+ &checkpointOptions.PrintStats,
+ "print-stats",
+ false,
+ "Display checkpoint statistics",
+ )
+
validate.AddLatestFlag(checkpointCommand, &checkpointOptions.Latest)
}
func checkpoint(cmd *cobra.Command, args []string) error {
var errs utils.OutputErrors
+ podmanStart := time.Now()
if cmd.Flags().Changed("compress") {
if checkpointOptions.Export == "" {
return errors.Errorf("--compress can only be used with --export")
@@ -102,12 +116,30 @@ func checkpoint(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
+ podmanFinished := time.Now()
+
+ var statistics checkpointStatistics
+
for _, r := range responses {
if r.Err == nil {
- fmt.Println(r.Id)
+ if checkpointOptions.PrintStats {
+ statistics.ContainerStatistics = append(statistics.ContainerStatistics, r)
+ } else {
+ fmt.Println(r.Id)
+ }
} else {
errs = append(errs, r.Err)
}
}
+
+ if checkpointOptions.PrintStats {
+ statistics.PodmanDuration = podmanFinished.Sub(podmanStart).Microseconds()
+ j, err := json.MarshalIndent(statistics, "", " ")
+ if err != nil {
+ return err
+ }
+ fmt.Println(string(j))
+ }
+
return errs.PrintErrors()
}