# OpenTelemetry

> Check what your services report through OpenTelemetry: the spans of what a scenario did, the logs that came with them, and their metrics.

Source: https://axx.nimbusxr.us/next/references/packs/otel/

Check what your services report through OpenTelemetry: the spans of what a scenario did, the logs that came with them, and their metrics.

Your service exports OTLP, over gRPC or HTTP, to a real [Collector](https://opentelemetry.io/docs/collector/) in your test environment, and the Collector's `file` exporter writes it where Axx reads it. You can run that Collector with no tests at all, and send it on to Jaeger or Grafana as well. Register what it writes, usually in the `Background`:

```gherkin
Given the parcels-api telemetry with the following properties:
  | url     | file://.axx/otel/telemetry.jsonl |
  | service | parcels-api                      |
```

- **`the trace` is this scenario's own,** whatever runs beside it: once telemetry is registered, the requests the scenario sends carry one `traceparent` header, with a trace ID of the scenario's own, and a service that follows W3C Trace Context puts its spans and logs in that trace. A request that sets its own `traceparent` keeps it.
- **Metrics are shared.** A scenario sees what was counted since it registered the telemetry, whether the metric is cumulative or delta, but scenarios running at the same time count together: give a check attributes that are its scenario's own.
- **Checks wait.** A check that something arrived waits 10 seconds, or `within {duration}`. A check that nothing did looks once, so put it after one that waits. A count higher than the check's fails at once.
- **Metrics take their time:** SDKs export them every 60 seconds by default, so set `OTEL_METRIC_EXPORT_INTERVAL`, in milliseconds, in the service's test environment.

Add it to a project with `axx pack add otel`.

## Steps

Each step's expression and what it does. Its documentation, parameters and examples: `axx steps show <id>` (offline, for the axx installed), or this page in full: https://axx.nimbusxr.us/next/references/packs/otel.full.md. The pack's steps, whether the project uses it or not: `axx pack show otel`.

- `otel.telemetry`: `Given the {word} telemetry with the following properties: | property | value |` Register what a Collector's `file` exporter writes.
- `otel.trace.span`: `Then [[within {duration} ]]the trace has a span where: | field | value |` Check that this scenario's trace has a span with those values.
- `otel.trace.nospan`: `Then the trace has no span where: | field | value |` Check that this scenario's trace has no span with those values.
- `otel.trace.child`: `Then the {string} span is a child of the {string} span` Check that a span of this scenario's trace has the other for its parent, waiting for them for 10 seconds.
- `otel.trace.took`: `Then the {string} span took less than {duration}` Check how long a span of this scenario's trace took, waiting for it for 10 seconds.
- `otel.trace.log`: `Then [[within {duration} ]]the trace has a log where: | field | value |` Check that this scenario's trace has a log record with those values.
- `otel.counted`: `Then [[within {duration} ]]the {telemetry} telemetry counted {int} {word}[[ where:]]` Check what a counter has counted since the telemetry was registered, cumulative or delta.
- `otel.recorded`: `Then [[within {duration} ]]the {telemetry} telemetry recorded {int} {word} values[[ where:]]` Check how many values a histogram has recorded since the telemetry was registered.
- `otel.gauge`: `Then [[within {duration} ]]the {telemetry} telemetry's {word} gauge is {gaugeValue}[[ where:]]` Check the latest value a gauge reported since the telemetry was registered.
- `otel.contains.not`: `Then the telemetry does not contain {string}` Check that nothing the services reported since the telemetry was registered contains that text: what must stay out of your telemetry, like a person's name.

## Parameter types

| Parameter | Takes | Values | For example |
|---|---|---|---|
| `{gaugeValue}` | a gauge's value, of its type: `4` an integer, and `4.0` a decimal |  | `4`, `4.5` |
| `{telemetry}` | the name of telemetry registered in the scenario |  | `parcels-api` |
