Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/grafana/xk6-client-tracing
A k6 extension for testing distributed tracing backends
https://github.com/grafana/xk6-client-tracing
distributed-tracing k6 opentelemetry tracing xk6
Last synced: 2 months ago
JSON representation
A k6 extension for testing distributed tracing backends
- Host: GitHub
- URL: https://github.com/grafana/xk6-client-tracing
- Owner: grafana
- License: agpl-3.0
- Created: 2021-10-29T09:07:51.000Z (about 3 years ago)
- Default Branch: main
- Last Pushed: 2024-05-22T14:56:19.000Z (7 months ago)
- Last Synced: 2024-05-22T18:35:51.071Z (7 months ago)
- Topics: distributed-tracing, k6, opentelemetry, tracing, xk6
- Language: Go
- Homepage:
- Size: 209 KB
- Stars: 34
- Watchers: 110
- Forks: 5
- Open Issues: 6
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
- awesome-k6 - xk6-client-tracing - Client for load testing distributed tracing backends. (Extensions / Official)
- awesome-k6 - xk6-client-tracing - Client for load testing distributed tracing backends. (Extensions / Official)
README
# xk6-client-tracing
> ### ⚠️ In Development
>
> This project is **in development** and changes a lot between commits. Use at your own risk.This extension provides k6 with the required functionality required to load test distributed tracing backends.
## Usage
Generating traces and sending them to an agent or backend requires two things: a client and a trace generator.
Generators have a method called `traces()` that can be used to generate traces.
The client provides a method `push()` which receives the generated traces as first parameter and sends them to the configured collector.Creating a client requires a client configuration:
```javascript
const config = {
endpoint: "localhost:4317",
exporter: tracing.EXPORTER_OTLP,
};
let client = new tracing.Client(config);
```The configuration is an object with the following schema:
```javascript
{
// The endpoint to which the traces are sent in the form of :
endpoint: string,
// The exporter protocol used for sending the traces: tracing.EXPORTER_OTLP or tracing.EXPORTER_JAEGER
exporter: string,
// Credentials used for authentication (optional)
authentication: { user: string, password: string },
// Additional headers sent by the client (optional)
headers: { string : string }
// TLS configuration
tls: {
// Whether insecure connections are allowed (optional, default: false)
insecure: boolean,
// Enable TLS but skip verification (optional, default: false)
insecure_skip_verify: boolean,
// The server name requested by the client (optional)
server_name: string,
// The path to the CA certificate file (optional)
ca_file: string,
// The path to the certificate file (optional)
cert_file: string,
// The path to the key file (optional)
key_file: string,
},
}
```There are two different types of generators which are described in the following sections.
### Parameterized trace generator
This generator creates traces consisting of completely randomized spans.
The spans contain a configurable number of random attributes with randomly assigned values.
The main purpose of this generator is to create a large amount of spans with few lines of code.An example can be found in [./examples/param](./examples/param).
### Templated trace generator
This generator creates realistically looking and traces that contain spans with span name, span kind, and attributes.
The trace is generated from a template configurations that describes how each should be generated.The following listing creates a generator that creates traces with a single span:
```javascript
const template = {
spans: [
{service: "article-service", name: "get-articles", attributes: {"http.method": "GET"}}
]
};
let gen = new tracing.TemplatedGenerator(template);
client.push(gen.traces());
```The generated span will have the name `get-articles`.
The generator will further assign a span kind as well as some commonly used attributes.
There will also be a corresponding resource span with the respective `service.name` attribute.The template has the following schema:
```javascript
{
// The defaults can be used to configure parameters that are applied to all spans (optional)
defaults: {
// Fixed attributes that are added to every generated span (optional)
attributes: { string : any },
// attributeSemantics can be set in order to generate attributes that follow a certain OpenTelemetry
// semantic convention. For example tracing.SEMANTICS_HTTP (optional)
attributeSemantics: string,
// Parameters to configure the creation of random attributes. If missing, no random attributes
// are added to the spans (optional)
randomAttributes: {
// The number of random attributes to generate
count: int,
// The number of distinct values to generate for each attribute (optional, default: 50)
cardinality: int
}
},
// Templates for the individual spans
spans: [
{
// Is used to set the service.name attribute of the corresponding resource span
service: string,
// The name of the span. If empty, the name will be randomly generated (optional)
name: string,
// The index of the parent span in `spans`. The index must be smaller than the
// own index. If empty, the parent is the span with the position directly before
// this span in `spans` (optional)
parentIdx: int,
// The interval for the generated span duration. If missing, a random duration is
// generated that is shorter than the duration of the parent span (optional)
duration: { min: int, max: int },
// Fixed attributes that are added to this (optional)
attributes: { string : any },
// attributeSemantics can be set in order to generate attributes that follow a certain OpenTelemetry
// semantic convention. For example tracing.SEMANTICS_HTTP (optional)
attributeSemantics: string,
// Parameters to configure the creation of random attributes. If missing, no random attributes
// are added to the span (optional)
randomAttributes: {
// The number of random attributes to generate
count: int,
// The number of distinct values to generate for each attribute (optional, default: 50)
cardinality: int
}
},
...
]
}
```An example with a templated generator can be found in [./examples/template](./examples/template).
## Getting started
To start using the k6 tracing extension, ensure you have the following prerequisites installed:
- Docker
- docker-compose
- make### Build docker image
The docker image is compiled using a multi-stage Docker build and does not require further dependencies.
To start the build process run:```shell
make docker
```After the command completed successfully the image `grafana/xk6-client-tracing:latest` is available.
### Run docker-compose example
> Note: before running the docker-compose example, make sure to complete the docker image build step above!
To run the example `cd` into the directory `examples/param` and run:
```shell
docker-compose up -d
```In the example `k6-tracing` uses the script `param.js` to generate spans and sends them to the `otel-collector`.
The generated spans can be observed by inspecting the collector's logs:```shell
docker-compose logs -f otel-collector
```The example uses the OTLP gRPC exporter.
If you want to use Jaeger gRPC, you can change `param.js` and use the following settings:```javascript
const client = new tracing.Client({
endpoint: "otel-collector:14250",
exporter: "jaeger",
insecure: true,
});
```> Note: HTTP exporters aren't supported (yet)
### Build locally
Building the extension locally has additional prerequisites:
- [Go toolchain](https://go101.org/article/go-toolchain.html)
- GitFurthermore, the build also requires [`xk6`](https://github.com/grafana/xk6) to compile k6 with the bundled tracing extension.
Run the following command to install `xk6`:```shell
go install go.k6.io/xk6/cmd/xk6@latest
```To build binary run:
```shell
make build
```The build step produces the `k6-tracing` binary.
To test the binary you first need to change the endpoint in the client configuration to:```javascript
const client = new tracing.Client({
endpoint: "localhost:4317",
exporter: "otlp",
insecure: true,
});
```Once you've your new binary and configuration ready, you can run a local OTEL collector:
```bash
docker run --rm -p 13133:13133 -p 14250:14250 -p 14268:14268 \
-p 55678-55679:55678-55679 -p 4317:4317 -p 9411:9411 \
-v "${PWD}/examples/shared/collector-config.yaml":/collector-config.yaml \
--name otelcol otel/opentelemetry-collector \
--config collector-config.yaml
```Once that's done, you can run a test like:
```
./k6-tracing run examples/basic/param.js
```And see the generated spans in the OTEL collector logs!
## Using the extension with Grafana Cloud
You can do that, by using the OTLP exporter and setting the required auth credentials:
```javascript
const client = new tracing.Client({
endpoint: "you-tempo-endpoint:443"
exporter: "otlp",
insecure: false,
authentication: {
user: "tenant-id",
password: "api-token"
}
});
```