v0.24.0 is here! :tada:

Another intermediary release that was mostly focused on refactoring and bugfixes, but also has quite a few new features, including the ability to output metrics to StatsD and Datadog!

Thanks to @cheesedosa, @ivoreis, @bookmoons, and @oboukili for contributing to this release!

## New Features!

### Redirect `console` messages to a file (#833)

You can now specify a file to which all things logged by `console.log()` and other `console` methods will get written to. The CLI flag to specify the output file path is `--console-output`, and you can also do it via the `K6_CONSOLE_OUTPUT` environment variable. For security reasons, there's no way to configure this from inside of the script.

Thanks to @cheesedosa for both proposing and implementing this!

### New result outputs: StatsD and Datadog (#915)

You can now output any metrics k6 collects to StatsD or Datadog by running `k6 run --out statsd script.js` or `k6 run --out datadog script.js` respectively. Both are very similar, but Datadog has a concept of metric tags, the key-value metadata pairs that will allow you to distinguish between requests for different URLs, response statuses, different groups, etc.

Some details:
- By default both outputs send metrics to a local agent listening on `localhost:8125` (currently only UDP is supported as a transport). You can change this address via the `K6_DATADOG_ADDR` or `K6_STATSD_ADDR` environment variables, by setting their values in the format of `address:port`.
- The new outputs also support adding a `namespace` - a prefix before all the metric names. You can set it via the `K6_DATADOG_NAMESPACE` or `K6_STATSD_NAMESPACE` environment variables respectively. Its default value is `k6.` - notice the dot at the end.
- You can configure how often data batches are sent via the  `K6_STATSD_PUSH_INTERVAL` / `K6_DATADOG_PUSH_INTEVAL` environment variables. The default value is `1s`.
- Another performance tweak can be done by changing the default buffer size of 20 through `K6_STATSD_BUFFER_SIZE` / `K6_DATADOG_BUFFER_SIZE`.
- In the case of Datadog, there is an additional configuration `K6_DATADOG_TAG_BLACKLIST`, which by default is equal to `` (nothing). This is a comma separated list of tags that should *NOT* be sent to Datadog. All other metric tags that k6 emits will be sent.

Thanks to @ivoreis for their work on this!

### k6/crypto: random bytes method (#922)
This feature adds a method to return an array with a number of cryptographically random bytes. It will either return exactly the amount of bytes requested or will throw an exception if something went wrong.

```js
import crypto from "k6/crypto";

export default function() {
    var bytes = crypto.randomBytes(42);
}
```

Thanks to @bookmoons for their work on this!

### k6/crypto: add a `binary` output encoding to the crypto functions (#952)

Besides `hex` and `base64`, you can now also use `binary` as the encoding parameter for the [k6 crypto](https://docs.k6.io/docs/k6crypto) hashing and HMAC functions.

### New feature: unified error codes (#907)

Error codes are unique numbers that can be used to identify and handle different application and network errors more easily. For the moment, these error codes are applicable only for errors that happen during HTTP requests, but they will be reused and extended to support other protocols in future k6 releases.

When an error occurs, its code is determined and returned as both the `error_code` field of the [`http.Response`](https://docs.k6.io/docs/response-k6http) object, and also attached as the `error_code` [tag](https://docs.k6.io/docs/tags-and-groups#section-system-tags) to any [metrics](https://docs.k6.io/docs/result-metrics#section-http-specific-built-in-metrics) associated with that request. Additionally, for more details, the `error` metric tag and `http.Response` field will still contain the actual string error message.

Error codes for different errors are as distinct as possible, but for easier handling and grouping, codes in different error categories are also grouped in broad ranges. The current error code ranges are:

- 1000-1099 - General errors
- 1100-1199 - DNS errors
- 1200-1299 - TCP errors
- 1300-1399 - TLS errors
- 1400-1499 - HTTP 4xx errors
- 1500-1599 - HTTP 5xx errors
- 1600-1699 - HTTP/2 specific errors

For a list of all current error codes, see the docs page [here](https://docs.k6.io/docs/error-codes).

## Internals

- Improvements in the integration with [loadimpact.com](https://loadimpact.com/). (#910 and #934)
- Most of the HTTP request code has been refactored out of the `js` packages and is now independent from the goja JS runtime. This was done mostly so we can implement the error codes feature (#907), but will allow us more flexibility in the future. (#928)
- As a preparation for the upcoming big refactoring of how VUs are scheduled in k6, including the arrival-rate based execution, we've added the future `execution` configuration framework. It currently doesn't do anything besides warn users that use execution option combinations that won't be supported in future k6 versions. See the Breaking Changes section in these release notes for more information. (#913)
- Switched to [golangci-lint](https://github.com/golangci/golangci-lint) via [golangci.com](https://golangci.com/) for code linting in this repo. The gometalinter check in CircleCI is still enabled as well, but it will be removed in the following few weeks. (#943)
- Switched to Go 1.12.1 for building and testing k6, removed official support for 1.10. (#944 and #966)

## Bugs fixed!

* JS: Consistently report setup/teardown timeouts as such and switch the error message to be more expressive. (#890)
* JS: Correctly exit with non zero exit code when setup or teardown timeouts. (#892)
* Thresholds: When outputting metrics to [loadimpact.com](https://loadimpact.com/), fix the incorrect reporting of threshold statuses at the end of the test. (#894)
- UX: `--quiet`/`-q` doesn't hide the summary stats at the end of the test. When necessary, they can still be hidden via the explicit `--no-summary` flag. Thanks, @oboukili! (#937)

## Breaking changes

None in this release, but in preparation for the next one, some execution option combinations will emit warnings, since they will no longer be supported in future k6 releases. Specifically, you won't be able to simultaneously run k6 with `stages` and `duration` set, or with `iterations` and `stages`, or with `duration` and `iterations`, or with all three. These VU schedulers (and much more, including arrival-rate based ones!) will still be supported in future k6 releases. They will just be independent from each other, unlike their current implementation where there's one scheduler with 3 different conflicting constraints.