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

Add optional 'count' column to CLI summary output #1143

Merged
merged 4 commits into from Oct 30, 2019

Conversation

imiric
Copy link
Contributor

@imiric imiric commented Sep 4, 2019

This adds an optional count column for Trend metrics in the CLI summary output, while refactoring parts of ui/summary.go for code style (avoiding globals, explicit validation, etc.) and negligible performance improvements (using a map for column lookups).

To enable it run e.g. k6 run --summary-trend-stats 'avg,p(99.99),count' test.js.

This essentially makes the existing default Count metrics like "http_reqs" and "iterations" obsolete, so we might want to consider making count a default column after all and removing these two metrics from the output.

I added a test for SummarizeMetrics, so our coverage should improve a bit. :)

Closes #1087

ui/summary.go Outdated Show resolved Hide resolved
ui/summary.go Outdated Show resolved Hide resolved
ui/summary.go Outdated Show resolved Hide resolved
ui/summary.go Outdated Show resolved Hide resolved
ui/summary.go Show resolved Hide resolved
@codecov-io
Copy link

codecov-io commented Sep 4, 2019

Codecov Report

Merging #1143 into master will increase coverage by 1.33%.
The diff coverage is 87.09%.

Impacted file tree graph

@@            Coverage Diff            @@
##           master   #1143      +/-   ##
=========================================
+ Coverage   73.77%   75.1%   +1.33%     
=========================================
  Files         147     147              
  Lines       10695   10709      +14     
=========================================
+ Hits         7890    8043     +153     
+ Misses       2345    2200     -145     
- Partials      460     466       +6
Impacted Files Coverage Δ
lib/options.go 93.14% <ø> (ø) ⬆️
cmd/run.go 9.57% <0%> (+0.03%) ⬆️
cmd/config.go 78.26% <100%> (+0.55%) ⬆️
cmd/options.go 70.4% <66.66%> (+2.63%) ⬆️
ui/summary.go 88.94% <97.14%> (+71.23%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a948b4d...51e88e0. Read the comment docs.

@na-- na-- added this to the v0.26.0 milestone Sep 4, 2019
@imiric imiric requested a review from cuonglm September 5, 2019 08:15
ui/summary.go Outdated Show resolved Hide resolved
ui/summary.go Show resolved Hide resolved
ui/summary_test.go Show resolved Hide resolved
cmd/run.go Outdated Show resolved Hide resolved
ui/summary.go Show resolved Hide resolved
ui/summary.go Show resolved Hide resolved
ui/summary.go Show resolved Hide resolved
ui/summary.go Outdated
if err == nil {
newTrendColumns = append(newTrendColumns, TrendColumn{stat, percentileTrendColumn})
// Validate checks if defined trend columns are valid
func (s *Summary) Validate() error {
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 can technically be private, since it's called implicitly in NewSummary() and not used anywhere else, but validation functions should probably be public.

Copy link
Member

Choose a reason for hiding this comment

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

I'm wondering if this shouldn't actually be a separate function, not a method of Summary? That way you can use it in the config handling without having to go through the NewSummary invocation and result discarding...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks @na--, I like that. Will change.

Copy link
Contributor Author

@imiric imiric Oct 15, 2019

Choose a reason for hiding this comment

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

Resolved by b4a776d, but it's a bit sloppy since getDefaultResolvers() is now a thing. But it's certainly nicer than before. Thanks for the suggestion.

Though this file and ui in general need a bigger cleanup out of scope for this PR.

Feel free to resolve this if there's nothing pending.

@imiric imiric requested a review from na-- September 30, 2019 17:20
cmd/options.go Outdated Show resolved Hide resolved
ui/summary.go Show resolved Hide resolved
cmd/run.go Outdated Show resolved Hide resolved
ui/summary.go Show resolved Hide resolved
ui/summary.go Outdated
"min": func(s *stats.TrendSink) interface{} { return s.Min },
"med": func(s *stats.TrendSink) interface{} { return s.Med },
"max": func(s *stats.TrendSink) interface{} { return s.Max },
"p(90)": func(s *stats.TrendSink) interface{} { return s.P(0.90) },
Copy link
Member

Choose a reason for hiding this comment

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

Are these actually necessary, given the fact that we have a way to generate arbitrary percentiles in generateCustomTrendValueResolvers()?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I considered that, but decided against it since p(90) and p(95) will pretty much always be the default percentiles, so it doesn't make sense to conditionally create them. This way it clearly shows what the defaults are.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah I am wondering the same ... given the code below, won't removing those two line .... continue to work as before ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mstoykov Yes, it will, but like I said, I think it's clearer defining them upfront. Generating them muddles up the default vs. custom concept (though we could just call it generatePercentileResolvers), and it would have to go through validatePercentile for no reason.

But let me know if you feel strongly about it and I'll remove them.

Copy link
Collaborator

Choose a reason for hiding this comment

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

To be honest I think that https://github.com/loadimpact/k6/pull/1143/files#diff-cc7288c8b0cb64e706ac188a9e524b7fR82 should be set in https://github.com/loadimpact/k6/pull/1143/files#diff-b5b20214939c9d689266a9dccbd0c47cR66 as the default and it should this should not be named getDefaultResolvers, but something like: getCustomResolvers/ getNonPercentileResolvers ?

Copy link
Collaborator

@mstoykov mstoykov Oct 17, 2019

Choose a reason for hiding this comment

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

I would think that with #961 we are probably going to add some way for all the non percentile ones to be parsed directly from the name like avg or even avg+count(totally useless). (and yes I know that the issue is about thresholds parsing not summary columns but I would argue that code will be reused).
At which point this map will be ... removed :). So from that perspective I don't know if it's actually worth the effort, to do it now.
At least for me (@na-- might still think that it's worth to do most of the mentioned things above, now). Adding the defaults to the message is probably the only thing that we should do right now. Everything else seems (given that issue I linked and it's apparent relevance to this code) not too important ... especially given that it creates even more code to be refactored when we start to fix the configuration ...

On the other hand I do agree with the first comment of @na-- as this lines are definitely not needed and again ... the defaults are defined few lines after this ... we just aren't calling them that, there ;)

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, to me getDefaultResolvers() doesn't make a lot of sense. We basically have 2 things:

  1. The possible values that can be configured as trend columns in the summary. This includes a mix of static (min, max, etc.) and dynamic ( p(??)) columns, as well as default and non-default (count) values so each value should be validated by a function. And each value corresponds to a "resolver", i.e. something that returns its actual value.
  2. The default values that will be displayed - this is an ordered subset of 1, so an unordered map can't be it (and why getDefaultResolvers()) is a bad name. This should be just a simple list (i.e. a slice), and yeah, the best UX would be to display its default value it in the CLI help, so the Fix handling cli options default value #1092 workaround may be necessary 😞

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK, that sounds good.

So to summarize what needs to be done in this PR:

  1. Remove the pre-generated percentile resolvers and rename getDefaultResolvers to ...? @na-- you need to be the tie-breaker here with a good name suggestion, since @mstoykov doesn't like mine and I don't like his, so... 😄

  2. Move the definition of columns to show as the default value for --summary-trend-stats, and apply the Fix handling cli options default value #1092 fix (whatever that is, still need to grok how it works).

Would that cover it?

Copy link
Member

Choose a reason for hiding this comment

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

  1. Remove the pre-generated percentile resolvers and rename getDefaultResolvers to getStaticResolvers(), or to just heave it a simple map, since this map will always be the same...
  2. The Fix handling cli options default value #1092 fix is that:
    • we set the CLI flag default value to nil, but we manually set the help text there to include the actual default value (see systemTagsCliHelpText in that PR)
    • we have an applyDefault function that is called at the end of the config consolidation - it applies the default value for any complex types (SystemTags in that PR, SummaryTrendStats in this) that are still nil (i.e. that the user hasn't specified)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Let me know if b91229a resolves this.

There are some new globals (I kept in line with the SystemTags implementation) and ad-hoc repeated validation and just general suckiness, but the configuration system is a pain to work with...

And I need to rebase and fix the merge conflicts, but I'm waiting on the final approvals before doing so.

ui/summary.go Outdated
if err == nil {
newTrendColumns = append(newTrendColumns, TrendColumn{stat, percentileTrendColumn})
// Validate checks if defined trend columns are valid
func (s *Summary) Validate() error {
Copy link
Member

Choose a reason for hiding this comment

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

I'm wondering if this shouldn't actually be a separate function, not a method of Summary? That way you can use it in the config handling without having to go through the NewSummary invocation and result discarding...

ui/summary.go Show resolved Hide resolved
imiric pushed a commit that referenced this pull request Oct 15, 2019
As per [1], it would be preferable to keep this struct. Though I renamed
some fields and removed the dependency on the entire lib.Options, since
it only requires one value.

This also renames Summary.Write to Summary.SummarizeMetrics, as it's a
more accurate description of what happens, despite of the
"Summary.Summarize" stutter.

[1]: #1143 (comment)
imiric pushed a commit that referenced this pull request Oct 15, 2019
@imiric imiric force-pushed the feat/1087-show-trend-counts branch from e76e2a9 to 855843e Compare October 15, 2019 10:42
@imiric
Copy link
Contributor Author

imiric commented Oct 15, 2019

Apologies for force-pushing. I wanted to rebase on master.

imiric pushed a commit that referenced this pull request Oct 15, 2019

s.SummarizeMetrics(&w, " ", SummaryData{
Metrics: metrics,
RootGroup: nil,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you add a RootGroup to cover even more of the code

Copy link
Collaborator

@mstoykov mstoykov left a comment

Choose a reason for hiding this comment

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

Looks okay to me, apart from the p(90)... comment from @na-- .
Can you run the test before and after the changes (with obviously some changes to the test code) in order to confirm that nothing has changed, apart from adding that count ?

ui/summary.go Outdated
"min": func(s *stats.TrendSink) interface{} { return s.Min },
"med": func(s *stats.TrendSink) interface{} { return s.Med },
"max": func(s *stats.TrendSink) interface{} { return s.Max },
"p(90)": func(s *stats.TrendSink) interface{} { return s.P(0.90) },
Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah I am wondering the same ... given the code below, won't removing those two line .... continue to work as before ?

@imiric
Copy link
Contributor Author

imiric commented Oct 16, 2019

Can you run the test before and after the changes (with obviously some changes to the test code) in order to confirm that nothing has changed, apart from adding that count ?

Good idea @mstoykov. It wasn't that difficult, take a look. That passes on current master, and the test is unchanged apart from the global handling nastiness and skipping of the count-specific tests.

If this wasn't going to be merged soon, I'd create a PR for that test anyway. :)

cuonglm
cuonglm previously approved these changes Oct 25, 2019
@imiric imiric requested a review from mstoykov October 25, 2019 10:47
mstoykov
mstoykov previously approved these changes Oct 28, 2019
Copy link
Collaborator

@mstoykov mstoykov left a comment

Choose a reason for hiding this comment

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

LGTM, but wait for @na-- as this is quite a big change

cmd/config.go Outdated Show resolved Hide resolved
cmd/config.go Outdated Show resolved Hide resolved
@na--
Copy link
Member

na-- commented Oct 30, 2019

Besides the two minor nits I noted above, this LGTM

imiric pushed a commit that referenced this pull request Oct 30, 2019
imiric pushed a commit that referenced this pull request Oct 30, 2019
@imiric imiric dismissed stale reviews from mstoykov and cuonglm via 8bbc027 October 30, 2019 09:35
@imiric imiric requested a review from na-- October 30, 2019 09:38
na--
na-- previously approved these changes Oct 30, 2019
mstoykov
mstoykov previously approved these changes Oct 30, 2019
Ivan Mirić added 4 commits October 30, 2019 11:41
This adds an optional count column for Trend metrics in the CLI summary
output, while refactoring parts of ui/summary.go for code style
(avoiding globals, explicit validation, etc.) and negligible performance
improvements (using a map for column lookups).

To enable it run e.g. `k6 run --summary-trend-stats 'avg,p(99.99),count' test.js`.

Closes #1087
Resolves: b91229a#r35621359

This changes current behavior on `master`, but as discussed above, it makes
sense to respect whatever the user specifies, so this can be considered a fix.
Also add a few missing summary-trend-stats tests.

Resolves: #1143 (comment)
@imiric imiric dismissed stale reviews from mstoykov and na-- via 51e88e0 October 30, 2019 10:45
@imiric imiric force-pushed the feat/1087-show-trend-counts branch from 8bbc027 to 51e88e0 Compare October 30, 2019 10:45
@imiric imiric merged commit df2469a into master Oct 30, 2019
@imiric imiric deleted the feat/1087-show-trend-counts branch October 30, 2019 11:03
srguglielmo pushed a commit to srguglielmo/k6 that referenced this pull request Nov 3, 2019
We were using a very old version (Jan 2017), and the new one includes
fixes like kelseyhightower/envconfig#119 ,
which would avoid workarounds in PRs like grafana#1143.
srguglielmo pushed a commit to srguglielmo/k6 that referenced this pull request Nov 3, 2019
Also add a few missing summary-trend-stats tests.

Resolves: grafana#1143 (comment)
srguglielmo pushed a commit to srguglielmo/k6 that referenced this pull request Nov 3, 2019
@na-- na-- mentioned this pull request Oct 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Show metric counts for Trend metrics
6 participants