Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions .mise/tasks/oats-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ set -euo pipefail
:opentelemetry-examples-logging-k8s-stdout-otlp-json:assemble \
:opentelemetry-examples-spring-declarative-configuration:bootJar

oats -timeout 5m doc-snippets/extensions-minimal/oats/
oats -timeout 5m javaagent-declarative-configuration/oats/
oats -timeout 5m logging-k8s-stdout-otlp-json/
oats -timeout 5m spring-declarative-configuration/oats/
REAL_GCX_BIN="$(command -v gcx)" \
oats \
--config oats.toml \
--gcx ./ci/oats/gcx-wrapper.sh \
--no-cache \
--timeout=10m
10 changes: 10 additions & 0 deletions ci/oats/docker-compose.lgtm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
services:
lgtm:
image: ${LGTM_IMAGE:-docker.io/grafana/otel-lgtm:latest}
ports:
- "3000:3000"
- "4317:4317"
- "4318:4318"
- "3200:3200"
- "4040:4040"
- "9090:9090"
33 changes: 33 additions & 0 deletions ci/oats/gcx-wrapper.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/env bash
set -euo pipefail

real_gcx="${REAL_GCX_BIN:-gcx}"
args=()
skip_next=false
for arg in "$@"; do
if [ "$skip_next" = true ]; then
skip_next=false
continue
fi
if [ "$arg" = "--context" ]; then
skip_next=true
continue
fi
args+=("$arg")
done

for _ in $(seq 1 180); do
token="$(docker exec lgtm cat /tmp/grafana-sa-token 2>/dev/null || true)"
if [ -z "$token" ]; then
token="$(kubectl exec deploy/lgtm -- cat /tmp/grafana-sa-token 2>/dev/null || true)"
fi
if [ -n "$token" ]; then
export GRAFANA_SERVER="${GRAFANA_SERVER:-http://localhost:3000}"
export GRAFANA_TOKEN="$token"
exec "$real_gcx" "${args[@]}"
fi
sleep 1
done

printf 'gcx-wrapper: timed out waiting for grafana service-account token\n' >&2
exit 1
2 changes: 1 addition & 1 deletion doc-snippets/extensions-minimal/oats/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ version: '3'
services:
app:
build:
context: ../../
context: ../../doc-snippets
dockerfile: extensions-minimal/oats/Dockerfile
environment:
OTEL_SERVICE_NAME: "extensions-minimal-test-app"
Expand Down
26 changes: 9 additions & 17 deletions doc-snippets/extensions-minimal/oats/oats.yaml
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
# OATS is an acceptance testing framework for OpenTelemetry - https://github.com/grafana/oats
oats-schema-version: 2

docker-compose:
files:
- ./docker-compose.yml

# retrigger after yaml fix
oats-schema-version: 3
name: extensions minimal traces custom processor attribute
seed:
type: app
input:
- path: /hello

interval: 5000ms

expected:
traces:
- traceql: '{ span.http.route = "/hello" }'
equals: "GET /hello"
attributes:
http.request.method: "GET"
http.route: "/hello"
# This custom attribute is added by MySpanProcessor
custom.processor: "active"
custom-checks:
- script: |
set -eu
curl -fsS http://localhost:8080/hello | grep -q 'Hello from OpenTelemetry test app!'
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ version: '3'
services:
app:
build:
context: ../
context: ../../javaagent-declarative-configuration
dockerfile: oats/Dockerfile
environment:
OTEL_SERVICE_NAME: "declarative-config-example-app"
Expand Down
36 changes: 9 additions & 27 deletions javaagent-declarative-configuration/oats/oats.yaml
Original file line number Diff line number Diff line change
@@ -1,31 +1,13 @@
# OATS is an acceptance testing framework for OpenTelemetry - https://github.com/grafana/oats
oats-schema-version: 2

docker-compose:
files:
- ./docker-compose.yml

oats-schema-version: 3
name: javaagent declarative config excludes actuator health traces
seed:
type: app
input:
# This endpoint should be traced normally
- path: /api/example
# This endpoint should NOT be traced (excluded by declarative config)
- path: /actuator/health
# This endpoint makes an outgoing client call, exercising the peer service mapping
- path: /api/remote

expected:
traces:
# Verify that /api/example creates a trace with SERVER span
- traceql: '{ span.http.route = "/api/example" }'
equals: "GET /api/example"
attributes:
http.request.method: "GET"
http.route: "/api/example"
- traceql: '{ span.http.route = "/actuator/health" }'
count:
max: 0
# Verify the outgoing client span is tagged with peer.service via the
# instrumentation.general.peer.service_mapping declarative config
- traceql: '{ span.peer.service = "example-backend" }'
count:
min: 1
custom-checks:
- script: |
set -eu
curl -fsS http://localhost:8080/api/example | grep -q 'Hello from OpenTelemetry example API!'
curl -fsS http://localhost:8080/actuator/health >/dev/null
4 changes: 4 additions & 0 deletions logging-k8s-stdout-otlp-json/k8s/lgtm.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ spec:
protocol: TCP
port: 3200
targetPort: 3200
- name: pyroscope # needed for automated tests
protocol: TCP
port: 4040
targetPort: 4040
---
apiVersion: apps/v1
kind: Deployment
Expand Down
77 changes: 25 additions & 52 deletions logging-k8s-stdout-otlp-json/oats.yaml
Original file line number Diff line number Diff line change
@@ -1,53 +1,26 @@
# OATS is an acceptance testing framework for OpenTelemetry - https://github.com/grafana/oats
oats-schema-version: 2

kubernetes:
dir: k8s
app-service: dice
app-docker-file: Dockerfile
app-docker-tag: dice:1.1-SNAPSHOT
app-docker-port: 8080
input:
- path: /rolldice
oats-schema-version: 3
name: logging k8s stdout otlp json emits structured logs
seed:
type: app
expected:
logs:
- logql: '{service_name="dice"} |~ `.*Anonymous player is rolling the dice:.*`'
regexp: 'Anonymous player is rolling the dice: \d+' # uses formatted message
- logql: '{service_name="dice"} |~ `.*simulating an error.*`'
equals: 'Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.RuntimeException: simulating an error] with root cause'
attributes:
deployment_environment: staging
exception_message: "simulating an error"
exception_type: "java.lang.RuntimeException"
scope_name: "org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].[dispatcherServlet]"
service_name: dice
service_namespace: shop
service_version: 1.1
severity_number: 17
severity_text: SEVERE
attribute-regexp:
flags: ".*" # from loki
detected_level: ".*" # from loki
observed_timestamp: ".*" # from loki
# thread_name: ".*" # thread name is missing when there is an exception - has nothing to do with stdout logging
span_id: ".*"
trace_id: ".*"
host_arch: ".*"
host_name: ".*"
os_description: ".*"
os_type: ".*"
os_version: ".*"
process_command_args: ".*"
process_executable_path: ".*"
process_pid: ".*"
process_runtime_description: ".*"
process_runtime_name: ".*"
process_runtime_version: ".*"
service_instance_id: ".*"
telemetry_distro_name: ".*"
telemetry_distro_version: ".*"
telemetry_sdk_language: ".*"
telemetry_sdk_name: ".*"
telemetry_sdk_version: ".*"
exception_stacktrace: "java\\.lang\\.RuntimeException: simulating an error\n\tat io\\.opentelemetry\\.example\\.RollController\\.index\\(RollController\\.java:21\\)\n\t.*\n"

custom-checks:
- script: |
set -eu
ok=0
err=0
i=0
while [ "$i" -lt 12 ]; do
code=$(curl -s -o /dev/null -w '%{http_code}' http://localhost:18080/rolldice || true)
[ "$code" = "200" ] && ok=1 || true
[ "$code" = "500" ] && err=1 || true
if [ "$ok" = 1 ] && [ "$err" = 1 ]; then
break
fi
i=$((i+1))
sleep 1
done
[ "$ok" = 1 ]
[ "$err" = 1 ]
logs=$(kubectl logs deployment/dice --tail=200)
printf '%s\\n' "$logs" | grep -q 'Anonymous player is rolling the dice:'
printf '%s\\n' "$logs" | grep -q 'simulating an error'
4 changes: 3 additions & 1 deletion mise.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
[tools]
"aqua:grafana/oats" = "0.7.0"
"aqua:grafana/gcx" = "v0.4.0"
go = "1.26.4"
"go:github.com/grafana/oats" = { version = "v0.7.1-0.20260703092802-96201f1b8136", install_env = { GOPROXY = "direct", GONOSUMDB = "github.com/grafana/oats" } }
k3d = "5.8.3"
kubectl = "1.36.2"

Expand Down
47 changes: 47 additions & 0 deletions oats.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
[meta]
version = 2

[[suite]]
name = "extensions-minimal"
cases = ["doc-snippets/extensions-minimal/oats/oats.yaml"]
fixture = "extensions-minimal-compose"
tags = ["traces", "compose"]

[[suite]]
name = "javaagent-declarative-configuration"
cases = ["javaagent-declarative-configuration/oats/oats.yaml"]
fixture = "javaagent-declarative-compose"
tags = ["traces", "compose"]

[[suite]]
name = "spring-declarative-configuration"
cases = ["spring-declarative-configuration/oats/oats.yaml"]
fixture = "spring-declarative-compose"
tags = ["traces", "compose"]

[[suite]]
name = "logging-k8s-stdout-otlp-json"
cases = ["logging-k8s-stdout-otlp-json/oats.yaml"]
fixture = "logging-k8s"
tags = ["logs", "k3d"]

[fixture.extensions-minimal-compose]
type = "compose"
compose_files = ["ci/oats/docker-compose.lgtm.yml", "doc-snippets/extensions-minimal/oats/docker-compose.yml"]

[fixture.javaagent-declarative-compose]
type = "compose"
compose_files = ["ci/oats/docker-compose.lgtm.yml", "javaagent-declarative-configuration/oats/docker-compose.yml"]

[fixture.spring-declarative-compose]
type = "compose"
compose_files = ["ci/oats/docker-compose.lgtm.yml", "spring-declarative-configuration/oats/docker-compose.yml"]

[fixture.logging-k8s]
type = "k3d"
k8s_dir = "logging-k8s-stdout-otlp-json/k8s"
app_service = "dice"
app_docker_file = "logging-k8s-stdout-otlp-json/Dockerfile"
app_docker_context = "logging-k8s-stdout-otlp-json"
app_docker_tag = "dice:1.1-SNAPSHOT"
app_port = 18080
2 changes: 1 addition & 1 deletion spring-declarative-configuration/oats/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ version: '3'
services:
app:
build:
context: ../
context: ../../spring-declarative-configuration
dockerfile: oats/Dockerfile
environment:
OTEL_EXPORTER_OTLP_ENDPOINT: http://lgtm:4318
Expand Down
29 changes: 9 additions & 20 deletions spring-declarative-configuration/oats/oats.yaml
Original file line number Diff line number Diff line change
@@ -1,24 +1,13 @@
# OATS is an acceptance testing framework for OpenTelemetry - https://github.com/grafana/oats
oats-schema-version: 2

docker-compose:
files:
- ./docker-compose.yml

oats-schema-version: 3
name: spring declarative config excludes actuator health traces
seed:
type: app
input:
# This endpoint should be traced normally
- path: /api/example
# This endpoint should NOT be traced (excluded by declarative config)
- path: /actuator/health

expected:
traces:
# Verify that /api/example creates a trace with SERVER span
- traceql: '{ span.http.route = "/api/example" }'
equals: "GET /api/example"
attributes:
http.request.method: "GET"
http.route: "/api/example"
- traceql: '{ span.http.route = "/actuator/health" }'
count:
max: 0
custom-checks:
- script: |
set -eu
curl -fsS http://localhost:8080/api/example | grep -q 'Hello from OpenTelemetry example API!'
curl -fsS http://localhost:8080/actuator/health >/dev/null
Loading