Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Podman Stats additional features #10696

Merged
merged 1 commit into from
Jun 23, 2021

Conversation

cdoern
Copy link
Contributor

@cdoern cdoern commented Jun 16, 2021

Added Avg CPU calculation and CPU up time to podman stats. Adding different feature sets in different PRs, CPU first.

The CPU track array is used to keep track of all CPU usage values to tally up. AvgCPU contains the average CPU percent usage which is calculated using cgroupStats.CPU.Usage.Total. Lastly, the Start and UpTime stats keep track of when the CPU tracking was started and how long the CPU has been active for since that tracking began.

resolves #9258

Signed-off-by: cdoern [email protected]

@@ -146,7 +146,9 @@ func stats(cmd *cobra.Command, args []string) error {
func outputStats(reports []define.ContainerStats) error {
headers := report.Headers(define.ContainerStats{}, map[string]string{
"ID": "ID",
"UpTime": "CPU TIME (S)",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is UpTime really correect? I've always heard that as the total duration a system has been running for, not cumulative CPU time?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the result of podman stats

ID            NAME            CPU TIME (S)     CPU %   AVG CPU %  MEM USAGE / LIMIT  MEM %   NET IO   BLOCK IO  PIDS
f10ae061aa6b  thirsty_colden  14m1.261643561s  1.28%   6.60%      729.4MB / 16.02GB  4.55%   -- / --  -- / --   117

I made it so that the CPU time pulls the container creation time if the variable is time's zero value. I assumed that CPU time just basically meant up time of the container? If I was wrong I can go back and adjust accordingly.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, CPU time is the number of seconds or CPU time the container has actively used, not seconds it has been alive.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mheon I think most recent commit fixed this. I didn't realize cgroupStats.CPU.Usage.Total was a duration in ns of how much up time the group had. I switched around some things with avg CPU % given this information as well.

@cdoern cdoern force-pushed the libpodStats branch 3 times, most recently from 2e63a56 to a45ae91 Compare June 16, 2021 20:11
libpod/stats.go Outdated
stats.CPU = calculateCPUPercent(cgroupStats, previousCPU, now, previousStats.SystemNano)
stats.AvgCPU = calculateAvgCPU(stats.CPU, previousStats.CPUTrack)
stats.CPUTrack = append(previousStats.CPUTrack, float64(cgroupStats.CPU.Usage.Total))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any risk that this can grow indefinitely or use outdated info (or should the average computed using all the available data points)?

If we need all data points, could we just store the current average and number of data points to calculate the incremental average?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, i will store number of datapoints and the current average I am pretty sure I can do ((oldAvg * numDataPoints) + newData) / (numDataPoints + 1)

@cdoern cdoern force-pushed the libpodStats branch 2 times, most recently from e2bee36 to 6878875 Compare June 17, 2021 13:37
Copy link
Member

@giuseppe giuseppe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@openshift-ci openshift-ci bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jun 18, 2021
libpod/stats.go Outdated

// calculateAvgCPU calculates the avg CPU percentage given the previous average and the number of data points.
func calculateAvgCPU(statsCPU float64, prevAvg float64, prevData int64) float64 {
total := prevAvg
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why add a temporary variable? Why not just use prevAvg?

Expect(session.ExitCode()).To(Equal(0))
session = podmanTest.Podman([]string{"stats", "--all", "--no-stream", "--format", "\"{{.ID}} {{.UpTime}} {{.AVGCPU}}\""})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you look for the header in the the output?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rhatdan do you mean something like

session = podmanTest.Podman([]string{"stats", "--all", "--no-stream", "--format", "\"{{.ID}} {{.UpTime}} {{.AVGCPU}}\""})
out := session.OutputToStringArray()
Expect(len(out)).To(BeNumerically("==", 3))

or would that not work? It seems that none of the stats tests actually validate the output too much.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No I just want you to make sure the headings you expect show up in the output.
Expect(session.LineInOutputContains("UpTime").To(BeTrue())
Expect(session.LineInOutputContains("AVGCPU").To(BeTrue())

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Jun 18, 2021

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: cdoern, giuseppe, rhatdan

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@@ -166,7 +168,7 @@ func outputStats(reports []define.ContainerStats) error {
if report.IsJSON(statsOptions.Format) {
return outputJSON(stats)
}
format := "{{.ID}}\t{{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.MemPerc}}\t{{.NetIO}}\t{{.BlockIO}}\t{{.PIDS}}\n"
format := "{{.ID}}\t{{.Name}}\t{{.UpTime}}\t{{.CPUPerc}}\t{{.AVGCPU}}\t{{.MemUsage}}\t{{.MemPerc}}\t{{.NetIO}}\t{{.BlockIO}}\t{{.PIDS}}\n"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing the default format would break docker compat. Not sure if this is desired. @mheon @rhatdan WDYT?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure I would classify this as a breaking change to compat, but it would probbaly be best if we added the new fields to the end of the output, that way, if someone built a script for docker that expected the second field to be CPUPerc, we would not break it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want me to switch around the ordering? I feel like that would make the output look strange though to have CPU data all scattered throughout.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, I think we need to @cdoern

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add an --alpha flag which would then show the stats in alphabetical order left to right? Or if you really want to go off the rails, make it all selectable by the caller.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TomSweeneyRedHat working on an alpha flag right now, should it simply just be an if/else around format:=... with two different options?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TomSweeneyRedHat I don't see the value for an extra alpha flag, the user can always change the output format with --format

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tend to agree - I don't see a strong case for this until and unless we get a user request to add it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, so we are not going to move the new data to the end of stats? And just tell users if they want a specific format to use --format. I guess I am good with this. Make the default look good for the user.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Luap99 The value in my eye is just typing --alpha rather than working it out in the --format option. YMMV. I think it would be a good addition, but not a biggy.

@cdoern cdoern force-pushed the libpodStats branch 5 times, most recently from 82c21c3 to 79a7aa6 Compare June 21, 2021 17:38
@@ -75,6 +76,7 @@ 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")
flags.BoolVar(&statsOptions.Alpha, "alpha", false, "Decides whether or not to alphabetize the output")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought we decided to not add the --alpha flag?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, sorry. Just removed it.

@baude
Copy link
Member

baude commented Jun 22, 2021

lgtm

cmd/podman/containers/stats.go Outdated Show resolved Hide resolved
cmd/podman/containers/stats.go Outdated Show resolved Hide resolved
cmd/podman/containers/stats.go Outdated Show resolved Hide resolved
added Avg Cpu calculation and CPU up time to podman stats. Adding different feature sets in different PRs, CPU first.

resolves containers#9258

Signed-off-by: cdoern <[email protected]>
@rhatdan
Copy link
Member

rhatdan commented Jun 23, 2021

/lgtm
/hold

@openshift-ci openshift-ci bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jun 23, 2021
@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Jun 23, 2021
@rhatdan
Copy link
Member

rhatdan commented Jun 23, 2021

/hold cancel

@openshift-ci openshift-ci bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jun 23, 2021
@openshift-merge-robot openshift-merge-robot merged commit 2b850ef into containers:master Jun 23, 2021
Copy link
Contributor

@srcshelton srcshelton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've patched this on top of podman-3.2.2, and I'm always getting exactly the same value for .CPUPerc and the new .AVGCPU at all times - is this expected to be fully hooked-up at this point (or dependent on another patch on top of 3.2.2 to function), or have I missed something?

(Also, if the manpages/docs aren't auto-generated from the code, could a doc update for these additions please also be added?)

@cdoern
Copy link
Contributor Author

cdoern commented Jun 29, 2021

@srcshelton running now and I can't seem to recreate this. Can I see how you're running this/your output?

@srcshelton
Copy link
Contributor

I've patched this on top of podman-3.2.2, and I'm always getting exactly the same value for .CPUPerc and the new .AVGCPU at all times - is this expected to be fully hooked-up at this point (or dependent on another patch on top of 3.2.2 to function), or have I missed something?

I've realised that this is likely because I'm running podman stats with the --no-stream option in a loop, to integrate other data into the eventual output.

I'd suggest that the '{{.AVGCPU}}' option must gather data persistently beyond the podman invocation which outputs the current counters!

@github-actions github-actions bot added the locked - please file new issue/PR Assist humans wanting to comment on an old issue or PR with locked comments. label Sep 23, 2023
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 23, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged. locked - please file new issue/PR Assist humans wanting to comment on an old issue or PR with locked comments.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Additional podman stats metrics
10 participants