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 option to change how the UI is rendered #1376

Open
imiric opened this issue Mar 30, 2020 · 6 comments
Open

Add option to change how the UI is rendered #1376

imiric opened this issue Mar 30, 2020 · 6 comments

Comments

@imiric
Copy link
Contributor

imiric commented Mar 30, 2020

Feature Description

In #1332 we experimented with a --ui-mode option to change how the progress bars were rendered, but after some discussion we agreed that it was best leaving that option (or a similarly named one) to change how the entire UI is rendered, and not just progress bars.

Suggested Solution

One possible value could be log, where instead of showing progress bars, k6 would output log messages, which might be useful for headless/CI environments.

A related option to this might be --ui-refresh-rate, which would control the update frequency (currently hard-coded to 100ms).

@na--
Copy link
Member

na-- commented Jul 31, 2020

My thoughts here are that, at the bare minimum, we should be able to control the following things through --ui-mode:

  • how progress is visualized, with at least the following 4 values: ASCII progressbars, percentage progressbars, log messages, or no progress displayed at all
  • the display of that frequency: 50ms, 1s, whatever
  • whether some UX elements like the logo, test and scenario descriptions are displayed at all

Users should be able to get their progress in log form, and hide all non-log data (logo, scenarios:, execution:, etc.) from their run - it will allow them to easily parse logs from CI k6 runs... and even if they don't parse them or pipe them to some log server, it will just look nicer and more consistent...

Implementation-wise, I suggest these things should be configurable from a single CLI flag (or environment variable) and use strvals format (albeit, maybe with our own implementation because #926). And this should be a runtime option, not a part of lib.Options, since it probably doesn't make sense to store this properly in the archive bundles. This will allow us the greatest amount of flexibility and future extension, without an explosion of new configuration options for every little UI tweak (and, thus, worsening of the issues from #883).

It can look somewhat like this:

k6 run --ui-mode "nologo,nodescription,progress=log,progress_freq=5s" script.js # suitable for CI runs
k6 run --ui-mode "progress=responsive-ascii,progres_freq=1s" script.js # long-running local run
K6_UI_MODE="nologo,progress=log" k6 run script.js  # some dockerized environment
k6 cloud --ui-mode "progress=log" script.js
# ... 

Edit: forgot about terminal width.... Given the issues we've had recently (#1559, #1579), an option to specify term width will be useful for people running k6 on funky TTY-like terminals...

@imiric
Copy link
Contributor Author

imiric commented Jul 31, 2020

Instinctively I'm not a big fan of the option grouping with strvals in this case, and would prefer separate options prefixed with --ui-*, e.g. --ui-refresh-rate=1s, --ui-responsive, --ui-[no]description, --ui-[no]header, etc., but understand that we want to avoid the option explosion you mention, so sounds good.

Regarding terminals, if we want to be consistent with other tools, the standard approach is a -i/--interactive flag (see Bash, Docker, etc.) or -t/--tty, though we can't use the short form as they're already used in k6 run. So if we're going with the strvals approach, those keywords should be in there.

@na--
Copy link
Member

na-- commented Jul 31, 2020

Yeah, a flag for forcing k6 in interactive/non-interractive mode may also be very useful! Though k6 is different from docker and bash in that you don't really have to interact with scripts, i.e. you can't type things like how you can in docker. So, for the moment, whether we're on a TTY only controls how we display things like the progress bars and terminal colors, the same things that would be controlled via --ui-mode (or multiple options, depending on how we implement it). So, essentially, when this issue is implemented, TTY/non-TTY would just change the default --ui-mode, if the user hasn't specified something manually, right?

And I'm not completely discounting individual flags, they have their advantages, but they definitely also have their disadvantages... I wouldn't mind more individual flags, assuming we put them in RuntimeOptions (no more globals) and we organize the k6 run --help page... Right now it looks like this:

Start a load test.

This also exposes a REST API to interact with it. Various k6 subcommands offer
a commandline interface for interacting with it.

Usage:
  k6 run [flags]

Examples:
  # Run a single VU, once.
  k6 run script.js

  # Run a single VU, 10 times.
  k6 run -i 10 script.js

  # Run 5 VUs, splitting 10 iterations between them.
  k6 run -u 5 -i 10 script.js

  # Run 5 VUs for 10s.
  k6 run -u 5 -d 10s script.js

  # Ramp VUs from 0 to 100 over 10s, stay there for 60s, then 10s down to 0.
  k6 run -u 0 -s 10s:100 -s 60s -s 10s:0

  # Send metrics to an influxdb server
  k6 run -o influxdb=http://1.2.3.4:8086/k6

Flags:
  -u, --vus int                             number of virtual users (default 1)
  -d, --duration duration                   test duration limit
  -i, --iterations int                      script total iteration limit (among all VUs)
  -s, --stage stage                         add a stage, as `[duration]:[target]`
      --execution-segment string            limit execution to the specified segment, e.g. 10%, 1/3, 0.2:2/3
      --execution-segment-sequence string   the execution segment sequence
  -p, --paused                              start the test in a paused state
      --no-setup                            don't run setup()
      --no-teardown                         don't run teardown()
      --max-redirects int                   follow at most n redirects (default 10)
      --batch int                           max parallel batch reqs (default 20)
      --batch-per-host int                  max parallel batch reqs per host (default 6)
      --rps int                             limit requests per second
      --user-agent string                   user agent for http requests (default "k6/0.27.1 (https://k6.io/)")
      --http-debug string[="headers"]       log all HTTP requests and responses. Excludes body by default. To include body use '--http-debug=full'
      --insecure-skip-tls-verify            skip verification of TLS certificates
      --no-connection-reuse                 disable keep-alive connections
      --no-vu-connection-reuse              don't reuse connections between iterations
      --min-iteration-duration duration     minimum amount of time k6 will take executing a single iteration
  -w, --throw                               throw warnings (like failed http requests) as errors
      --blacklist-ip ip range               blacklist an ip range from being called
      --summary-trend-stats stats           define stats for trend metrics (response times), one or more as 'avg,p(95),...' (default 'avg,min,med,max,p(90),p(95)')
      --summary-time-unit string            define the time unit used to display the trend stats. Possible units are: 's', 'ms' and 'us'
      --system-tags strings                 only include these system tags in metrics (default "proto,subproto,status,method,url,name,group,check,error,error_code,tls_version,scenario")
      --tag tag                             add a tag to be applied to all samples, as `[name]=[value]`
      --console-output string               redirects the console logging to the provided output file
      --discard-response-bodies             Read but don't process or save HTTP response bodies
      --include-system-env-vars             pass the real system environment variables to the runtime (default true)
      --compatibility-mode string           JavaScript compiler compatibility mode, "extended" or "base"
                                            base: pure Golang JS VM supporting ES5.1+
                                            extended: base + Babel with ES2015 preset + core.js v2,
                                                      slower and memory consuming but with greater JS support
                                             (default "extended")
  -e, --env VAR=value                       add/override environment variable with VAR=value
  -o, --out uri                             uri for an external metrics database
  -l, --linger                              keep the API server alive past test end
      --no-usage-report                     don't send anonymous stats to the developers
      --no-thresholds                       don't run thresholds
      --no-summary                          don't show the summary at the end of the test
      --summary-export string               output the end-of-test summary report to JSON file
  -t, --type type                           override file type, "js" or "archive"
  -h, --help                                help for run

Global Flags:
  -a, --address string     address for the api server (default "localhost:6565")
  -c, --config string      JSON config file (default "/home/user/.config/loadimpact/k6/config.json")
      --logformat string   log output format
      --no-color           disable colored output
  -q, --quiet              disable progress updates
  -v, --verbose            enable debug logging

It's a jumbled mix of peripheral and formatting options, and script-affecting/HTTP options, and misc stuff, with no grouping and not a lot of consistency in naming them 😞 If we group things together and order this page somewhat, it wouldn't be all that opposed to discrete options for all things UI.

Another reason for this approach, besides the simplicity of having each option affect just one thing, is that we already have a few discrete UI-related options: --no-color, --logformat, --quiet, --verbose, --no-summary, --summary-time-unit can be considered UI or UI-adjacent options. So, yeah, if we bring some order into this chaos and avoid making #883 worse, discrete options might be the way to go...

@robingustafsson
Copy link
Member

Just noting that we got a request, through Aha, for being able to optionally turn off the display of the logo: https://loadimpact.ideas.aha.io/ideas/LI-I-64

@na--
Copy link
Member

na-- commented Jan 27, 2021

As evidenced by #1748, we probably need a way to tell k6 to use simplified (i.e. ASCII instead of UTF8) terminal UI and output characters. Some of those glitches could be masked if we just let users hide the logo + --no-color + custom handleSummary() (#1768), so it's not certain if we should add such an option, but it's worth considering.

@na-- na-- modified the milestones: v0.31.0, v1.0.0 Feb 24, 2021
@na-- na-- removed this from the v1.0.0 milestone Jul 14, 2022
@na--
Copy link
Member

na-- commented Jul 14, 2022

#2056 is potentially another reason for having an non-unicode (i.e. pure ASCII) mode of k6. Though I am not sure if utf is the case, maybe it's something else, terminal control codes or whatever, I don't have a way to test it so 🤷‍♂️ Having universal fallbacks for fancy features in general is probably a good idea when we can't detect feature support (to have the CLI equivalent of progressive enhancement 😅 )...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants