Skip to content

Commit f5d3c6a

Browse files
authored
Merge pull request #4 from stoewer/build-system-and-docker
Basic build system using make and Docker
2 parents a0073e0 + ab0d36c commit f5d3c6a

9 files changed

+187
-32
lines changed

.dockerignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/examples
2+
*.md
3+
Dockerfile

Dockerfile

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
FROM golang:alpine AS xk6-client-tracing-build
2+
3+
RUN apk add --no-cache \
4+
build-base \
5+
gcc \
6+
git \
7+
make
8+
9+
RUN go install go.k6.io/xk6/cmd/xk6@latest \
10+
&& wget -O- -nv https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v1.50.0 \
11+
&& golangci-lint --version
12+
13+
WORKDIR /opt/xk6-client-tracing
14+
COPY go.mod go.sum ./
15+
RUN go mod download
16+
17+
COPY . .
18+
RUN make build
19+
20+
FROM alpine:latest
21+
22+
COPY --from=xk6-client-tracing-build /opt/xk6-client-tracing/k6-tracing /k6-tracing
23+
ENTRYPOINT [ "/k6-tracing" ]

Makefile

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
BINARY ?= k6-tracing
2+
IMAGE ?= grafana/xk6-client-tracing
3+
IMAGE_TAG ?= latest
4+
5+
GO_MODULE := $(shell head -n1 go.mod | cut -d' ' -f2)
6+
GO_TEST_OPTS := -race -count=1 -cover
7+
GO_LINT_OPTS := --config ./golangci.yml
8+
XK6_BUILD_OPTS := --output ./$(BINARY)
9+
10+
.PHONY: build
11+
build:
12+
xk6 build $(XK6_BUILD_OPTS) --with $(GO_MODULE)=.
13+
14+
.PHONY: test
15+
test:
16+
go test $(GO_TEST_OPTS) ./...
17+
18+
.PHONY: lint
19+
lint:
20+
golangci-lint run $(GO_LINT_OPTS) ./...
21+
22+
.PHONY: docker
23+
docker:
24+
docker build . -t $(IMAGE):$(IMAGE_TAG)
25+
26+
.PHONY: clean
27+
clean:
28+
go clean -cache -testcache
29+
docker rmi -f $(IMAGE)

README.md

+71-23
Original file line numberDiff line numberDiff line change
@@ -6,55 +6,105 @@
66
77
This extension provides k6 with the required functionality required to load test distributed tracing backends.
88

9-
## Getting started
9+
## Getting started
1010

11-
To start using k6 with the extension, ensure you have the prerequisites:
11+
To start using the k6 tracing extension, ensure you have the following prerequisites installed:
12+
13+
- Docker
14+
- docker-compose
15+
- make
16+
17+
### Build docker image
18+
19+
The docker image is compiled using a multi-stage Docker build and does not require further dependencies.
20+
To start the build process run:
21+
22+
```shell
23+
make docker
24+
```
25+
26+
After the command completed successfully the image `grafana/xk6-client-tracing:latest` is available.
27+
28+
### Run docker-compose example
29+
30+
> Note: before running the docker-compose example, make sure to complete the docker image build step above!
31+
32+
To run the example `cd` into the directory `examples/basic` and run:
33+
34+
```shell
35+
docker-compose up -d
36+
```
37+
38+
In the example `k6-tracing` uses the script `basic.js` to generate spans and sends them to the `otel-collector`.
39+
The generated spans can be observed by inspecting the collector's logs:
40+
41+
```shell
42+
docker-compose logs -f otel-collector
43+
```
44+
45+
The example uses the OTLP gRPC exporter.
46+
If you want to use Jaeger gRPC, you can change `basic.js` and use the following settings:
47+
48+
```javascript
49+
const client = new tracing.Client({
50+
endpoint: "otel-collector:14250",
51+
exporter: "jaeger",
52+
insecure: true,
53+
});
54+
```
55+
56+
> Note: HTTP exporters aren't supported (yet)
57+
58+
### Build locally
59+
60+
Building the extension locally has additional prerequisites:
1261

1362
- [Go toolchain](https://go101.org/article/go-toolchain.html)
1463
- Git
1564

16-
Then:
65+
Furthermore, the build also requires [`xk6`](https://github.com/grafana/xk6) to compile k6 with the bundled tracing extension.
66+
Run the following command to install `xk6`:
1767

18-
1. Install `xk6`:
1968
```shell
2069
go install go.k6.io/xk6/cmd/xk6@latest
2170
```
2271

23-
2. Build the binary:
72+
To build binary run:
2473
```shell
25-
xk6 build --with github.com/grafana/xk6-client-tracing@latest
74+
make build
75+
```
76+
77+
The build step produces the `k6-tracing` binary.
78+
To test the binary you first need to change the endpoint in the client configuration in `examples/basic/basic.js`:
79+
80+
```javascript
81+
const client = new tracing.Client({
82+
endpoint: "localhost:4317",
83+
exporter: "otlp",
84+
insecure: true,
85+
});
2686
```
2787

28-
Once you've your new binary ready, you can run a local OTEL collector:
88+
Once you've your new binary and configuration ready, you can run a local OTEL collector:
2989
```bash
3090
docker run --rm -p 13133:13133 -p 14250:14250 -p 14268:14268 \
3191
-p 55678-55679:55678-55679 -p 4317:4317 -p 9411:9411 \
32-
-v "${PWD}/collector-config.yaml":/collector-config.yaml \
92+
-v "${PWD}/examples/shared/collector-config.yaml":/collector-config.yaml \
3393
--name otelcol otel/opentelemetry-collector \
3494
--config collector-config.yaml
3595
```
3696

3797
Once that's done, you can run a test like:
3898
```
39-
./k6 run examples/basic.js
99+
./k6-tracing run examples/basic/basic.js
40100
```
41101

42-
And see your spans on the OTEL collector logs!
43-
44-
The example uses the OTLP gRPC exporter. If you want to use Jaeger gRPC, you can use these settings:
45-
```javascript
46-
const client = new tracing.Client({
47-
endpoint: "0.0.0.0:14250",
48-
exporter: "jaeger",
49-
insecure: true,
50-
});
51-
```
52-
53-
> Note: HTTP exporters aren't supported (yet)
102+
And see the generated spans in the OTEL collector logs!
54103

55104
## Using the extension with Grafana Cloud
56105

57106
You can do that, by using the OTLP exporter and setting the required auth credentials:
107+
58108
```javascript
59109
const client = new tracing.Client({
60110
endpoint: "you-tempo-endpoint:443"
@@ -66,5 +116,3 @@ const client = new tracing.Client({
66116
}
67117
});
68118
```
69-
70-

examples/basic.js examples/basic/basic.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const traceIDs = new SharedArray('traceIDs', function () {
1717
});
1818

1919
const client = new tracing.Client({
20-
endpoint: "0.0.0.0:4317",
20+
endpoint: "otel-collector:4317",
2121
exporter: "otlp",
2222
insecure: true,
2323
});

examples/basic/docker-compose.yml

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
version: "3"
2+
3+
services:
4+
k6-tracing:
5+
image: grafana/xk6-client-tracing:latest
6+
command:
7+
- run
8+
- /basic.js
9+
volumes:
10+
- ./basic.js:/basic.js:ro
11+
depends_on:
12+
- otel-collector
13+
14+
otel-collector:
15+
image: otel/opentelemetry-collector:latest
16+
command:
17+
- --config=/collector-config.yaml
18+
volumes:
19+
- ../shared/collector-config.yaml:/collector-config.yaml:ro
20+
ports:
21+
- "13133:13133"
22+
- "14250:14250"
23+
- "14268:14268"
24+
- "55678-55679:55678-55679"
25+
- "4317:4317"
26+
- "9411:9411"
File renamed without changes.

golangci.yml

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
run:
2+
issues-exit-code: 1
3+
tests: true
4+
5+
linters:
6+
enable:
7+
- errcheck
8+
- goconst
9+
- gofmt
10+
- goimports
11+
- gosimple
12+
- govet
13+
- ineffassign
14+
- megacheck
15+
- misspell
16+
- revive
17+
- typecheck
18+
- unconvert
19+
- unparam
20+
- unused
21+
22+
linter-settings:
23+
24+
issues:
25+
exclude:
26+
- "var-naming: don't use an underscore in package name"

tracing.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,11 @@ func (r *tracingClientModule) NewModuleInstance(vu modules.VU) modules.Instance
4444
return &ClientTracing{vu: vu}
4545
}
4646

47-
func (r *ClientTracing) Exports() modules.Exports {
47+
func (ct *ClientTracing) Exports() modules.Exports {
4848
return modules.Exports{
4949
Named: map[string]interface{}{
50-
"Client": r.xclient,
51-
"generateRandomTraceID": r.generateRandomTraceID,
50+
"Client": ct.xclient,
51+
"generateRandomTraceID": ct.generateRandomTraceID,
5252
},
5353
}
5454
}
@@ -80,9 +80,9 @@ type Config struct {
8080
Headers map[string]string `json:"headers"`
8181
}
8282

83-
func (c *ClientTracing) xclient(g goja.ConstructorCall) *goja.Object {
83+
func (ct *ClientTracing) xclient(g goja.ConstructorCall) *goja.Object {
8484
var cfg Config
85-
rt := c.vu.Runtime()
85+
rt := ct.vu.Runtime()
8686
err := rt.ExportTo(g.Argument(0), &cfg)
8787
if err != nil {
8888
common.Throw(rt, fmt.Errorf("Client constructor expects first argument to be Config"))
@@ -140,7 +140,7 @@ func (c *ClientTracing) xclient(g goja.ConstructorCall) *goja.Object {
140140
if err != nil {
141141
log.Fatal(err)
142142
}
143-
exporter.Start(context.Background(), componenttest.NewNopHost())
143+
_ = exporter.Start(context.Background(), componenttest.NewNopHost())
144144

145145
if err != nil {
146146
log.Fatal(fmt.Errorf("failed to create exporter: %v", err))
@@ -149,11 +149,11 @@ func (c *ClientTracing) xclient(g goja.ConstructorCall) *goja.Object {
149149
return rt.ToValue(&Client{
150150
exporter: exporter,
151151
cfg: &cfg,
152-
vu: c.vu,
152+
vu: ct.vu,
153153
}).ToObject(rt)
154154
}
155155

156-
func (c *ClientTracing) generateRandomTraceID() string {
156+
func (ct *ClientTracing) generateRandomTraceID() string {
157157
bytes := make([]byte, 16)
158158
if _, err := rand.Read(bytes); err != nil {
159159
return ""

0 commit comments

Comments
 (0)