mirror of
https://github.com/containers/podman.git
synced 2025-08-06 03:19:52 +08:00
stats: add a interval parameter to cli and api stream mode
podman stats polled by default in a 1 sec period. This can put quite some load on a machine if you run many containers. The default value is now 5 seconds. You can change this interval with a new, optional, --interval, -i cli flag. The api request got also a interval query parameter for the same purpose. Additionally a unused const was removed. Api and cli will fail the request if a 0 or negative value is passed in. Signed-off-by: Thomas Weber <towe75@googlemail.com>
This commit is contained in:
@ -5,6 +5,7 @@ import (
|
||||
"os"
|
||||
|
||||
tm "github.com/buger/goterm"
|
||||
"github.com/containers/common/pkg/completion"
|
||||
"github.com/containers/common/pkg/report"
|
||||
"github.com/containers/podman/v3/cmd/podman/common"
|
||||
"github.com/containers/podman/v3/cmd/podman/registry"
|
||||
@ -55,6 +56,7 @@ type statsOptionsCLI struct {
|
||||
Latest bool
|
||||
NoReset bool
|
||||
NoStream bool
|
||||
Interval int
|
||||
}
|
||||
|
||||
var (
|
||||
@ -72,6 +74,9 @@ func statFlags(cmd *cobra.Command) {
|
||||
|
||||
flags.BoolVar(&statsOptions.NoReset, "no-reset", false, "Disable resetting the screen between intervals")
|
||||
flags.BoolVar(&statsOptions.NoStream, "no-stream", false, "Disable streaming stats and only pull the first result, default setting is false")
|
||||
intervalFlagName := "interval"
|
||||
flags.IntVarP(&statsOptions.Interval, intervalFlagName, "i", 5, "Time in seconds between stats reports")
|
||||
_ = cmd.RegisterFlagCompletionFunc(intervalFlagName, completion.AutocompleteNone)
|
||||
}
|
||||
|
||||
func init() {
|
||||
@ -122,8 +127,9 @@ func stats(cmd *cobra.Command, args []string) error {
|
||||
// Convert to the entities options. We should not leak CLI-only
|
||||
// options into the backend and separate concerns.
|
||||
opts := entities.ContainerStatsOptions{
|
||||
Latest: statsOptions.Latest,
|
||||
Stream: !statsOptions.NoStream,
|
||||
Latest: statsOptions.Latest,
|
||||
Stream: !statsOptions.NoStream,
|
||||
Interval: statsOptions.Interval,
|
||||
}
|
||||
statsChan, err := registry.ContainerEngine().ContainerStats(registry.Context(), args, opts)
|
||||
if err != nil {
|
||||
|
@ -37,6 +37,10 @@ Do not clear the terminal/screen in between reporting intervals
|
||||
|
||||
Disable streaming stats and only pull the first result, default setting is false
|
||||
|
||||
#### **--interval**=*seconds*, **-i**=*seconds*
|
||||
|
||||
Time in seconds between stats reports, defaults to 5 seconds.
|
||||
|
||||
#### **--format**=*template*
|
||||
|
||||
Pretty-print container statistics to JSON or using a Go template
|
||||
|
@ -3,7 +3,6 @@ package libpod
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/containers/podman/v3/libpod"
|
||||
"github.com/containers/podman/v3/pkg/api/handlers/utils"
|
||||
@ -14,8 +13,6 @@ import (
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const DefaultStatsPeriod = 5 * time.Second
|
||||
|
||||
func StatsContainer(w http.ResponseWriter, r *http.Request) {
|
||||
runtime := r.Context().Value("runtime").(*libpod.Runtime)
|
||||
decoder := r.Context().Value("decoder").(*schema.Decoder)
|
||||
@ -23,8 +20,10 @@ func StatsContainer(w http.ResponseWriter, r *http.Request) {
|
||||
query := struct {
|
||||
Containers []string `schema:"containers"`
|
||||
Stream bool `schema:"stream"`
|
||||
Interval int `schema:"interval"`
|
||||
}{
|
||||
Stream: true,
|
||||
Stream: true,
|
||||
Interval: 5,
|
||||
}
|
||||
if err := decoder.Decode(&query, r.URL.Query()); err != nil {
|
||||
utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
|
||||
@ -36,7 +35,8 @@ func StatsContainer(w http.ResponseWriter, r *http.Request) {
|
||||
containerEngine := abi.ContainerEngine{Libpod: runtime}
|
||||
|
||||
statsOptions := entities.ContainerStatsOptions{
|
||||
Stream: query.Stream,
|
||||
Stream: query.Stream,
|
||||
Interval: query.Interval,
|
||||
}
|
||||
|
||||
// Stats will stop if the connection is closed.
|
||||
|
@ -1106,6 +1106,11 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error {
|
||||
// type: boolean
|
||||
// default: true
|
||||
// description: Stream the output
|
||||
// - in: query
|
||||
// name: interval
|
||||
// type: integer
|
||||
// default: 5
|
||||
// description: Time in seconds between stats reports
|
||||
// produces:
|
||||
// - application/json
|
||||
// responses:
|
||||
|
@ -165,7 +165,8 @@ type StartOptions struct {
|
||||
//go:generate go run ../generator/generator.go StatsOptions
|
||||
// StatsOptions are optional options for getting stats on containers
|
||||
type StatsOptions struct {
|
||||
Stream *bool
|
||||
Stream *bool
|
||||
Interval *int
|
||||
}
|
||||
|
||||
//go:generate go run ../generator/generator.go TopOptions
|
||||
|
@ -35,3 +35,19 @@ func (o *StatsOptions) GetStream() bool {
|
||||
}
|
||||
return *o.Stream
|
||||
}
|
||||
|
||||
// WithInterval
|
||||
func (o *StatsOptions) WithInterval(value int) *StatsOptions {
|
||||
v := &value
|
||||
o.Interval = v
|
||||
return o
|
||||
}
|
||||
|
||||
// GetInterval
|
||||
func (o *StatsOptions) GetInterval() int {
|
||||
var interval int
|
||||
if o.Interval == nil {
|
||||
return interval
|
||||
}
|
||||
return *o.Interval
|
||||
}
|
||||
|
@ -435,6 +435,8 @@ type ContainerStatsOptions struct {
|
||||
Latest bool
|
||||
// Stream stats.
|
||||
Stream bool
|
||||
// Interval in seconds
|
||||
Interval int
|
||||
}
|
||||
|
||||
// ContainerStatsReport is used for streaming container stats.
|
||||
|
@ -1281,6 +1281,9 @@ func (ic *ContainerEngine) Shutdown(_ context.Context) {
|
||||
}
|
||||
|
||||
func (ic *ContainerEngine) ContainerStats(ctx context.Context, namesOrIds []string, options entities.ContainerStatsOptions) (statsChan chan entities.ContainerStatsReport, err error) {
|
||||
if options.Interval < 1 {
|
||||
return nil, errors.New("Invalid interval, must be a positive number greater zero")
|
||||
}
|
||||
statsChan = make(chan entities.ContainerStatsReport, 1)
|
||||
|
||||
containerFunc := ic.Libpod.GetRunningContainers
|
||||
@ -1361,7 +1364,7 @@ func (ic *ContainerEngine) ContainerStats(ctx context.Context, namesOrIds []stri
|
||||
return
|
||||
}
|
||||
|
||||
time.Sleep(time.Second)
|
||||
time.Sleep(time.Second * time.Duration(options.Interval))
|
||||
goto stream
|
||||
}()
|
||||
|
||||
|
@ -871,7 +871,7 @@ func (ic *ContainerEngine) ContainerStats(ctx context.Context, namesOrIds []stri
|
||||
if options.Latest {
|
||||
return nil, errors.New("latest is not supported for the remote client")
|
||||
}
|
||||
return containers.Stats(ic.ClientCtx, namesOrIds, new(containers.StatsOptions).WithStream(options.Stream))
|
||||
return containers.Stats(ic.ClientCtx, namesOrIds, new(containers.StatsOptions).WithStream(options.Stream).WithInterval(options.Interval))
|
||||
}
|
||||
|
||||
// ShouldRestart reports back whether the container will restart
|
||||
|
Reference in New Issue
Block a user