All jobs

Add Custom Span Attributes with OpenTelemetry from a Linear Issue

Yes. An agent picks up the Linear issue, adds app.order.amount and app.order.items.count on the PlaceOrder span, tests them and opens a pull request.

Run this on RushIn a Project that has your repository.

What the agent does

The run starts from the repository URL in resources: the agent clones it into its own cloud sandbox and reads the checkout service the way a new maintainer would. In a polyglot store like open-telemetry/opentelemetry-demo the checkout service lives under src/checkout/, is Go 1.26.0 per go.mod, and pulls go.opentelemetry.io/otel at v1.47.0. The service README tells a developer to build with docker compose build checkout from the repo root, and compose.yaml already names the checkout image and sets OTEL_SERVICE_NAME=checkout.

PlaceOrder is the span the issue names. In src/checkout/main.go, PlaceOrder already sets user.id, currency, payment fields, then later demo.order.id, demo.shipping.amount, demo.order.amount and demo.order.items.count on the active span via span.SetAttributes. The issue asks for the app.* names specifically: app.order.amount and app.order.items.count on that same PlaceOrder span, so a dashboard or alert that keys on the app namespace can find them without parsing the demo.* keys.

The agent adds those two attributes next to the existing order totals, using attribute.Float64 for the amount and attribute.Int for the item count, sourced from the same totalPriceFloat and len(prep.orderItems) values the demo attributes already use. It leaves the demo.* keys in place so existing demo dashboards keep working, and it does not touch the Kafka producer spans or the shipping preparation helper.

Proving it means extending src/checkout/main_test.go, which today covers email timeout bounds, health checks and graceful gRPC stop, not span attributes. The agent adds a test that drives PlaceOrder against a checkout with stubbed cart, currency, payment and shipping clients, reads the recorded span through the OpenTelemetry SDK's in-memory exporter, and asserts both app.order.amount and app.order.items.count are present with the expected types. Then it runs go test ./... in src/checkout and docker compose build checkout from the root.

Start it with one API call

POST https://api.prix.dev/o/{org}/sessions with this body:

{
  "agent": "claude",
  "input": "A Linear issue labeled agent says: \"Add Custom Span Attributes with OpenTelemetry. In the checkout service, add app.order.amount and app.order.items.count attributes to the PlaceOrder span and a test that asserts they are set.\" Do the work in this repository, add tests for it, run docker compose build for the touched services, and open a pull request that links back to the issue.",
  "resources": [
    {
      "url": "https://github.com/your-org/your-app"
    }
  ]
}
  1. Get an API key. In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
  2. Send the request. POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
  3. Read what came back. Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.

What comes back

What comes back is a pull request. Its diff touches src/checkout/main.go with the two app.order.* attributes on PlaceOrder, and src/checkout/main_test.go with a span-attribute assertion. The description quotes the issue and links back to it.

The checks on the pull request run go test for checkout and the compose build the service README documents. A reviewer reads the diff for three things: the attribute keys match the issue exactly, the values come from the order total and item count already computed in PlaceOrder, and the test fails if either attribute is removed. The existing demo.order.amount and demo.order.items.count attributes stay.

The session read keeps the record behind the pull request: every command the agent ran with its output, including the Go test and the compose build. Anyone who questions the checks can read exactly how they were run.

Run it on every Linear issue labelled agent

The Project's automation turns the label into the run. In the console, add an automation with a Linear trigger on linear.issue.labeled filtered to the agent label and this prompt; each labelled observability issue starts its own run in its own sandbox and opens its own pull request against the demo monorepo.

If the automation is not wanted, a small server can do the same: receive Linear's issue webhook, put the issue text into input in place of the quoted text, and POST to /o/{org}/sessions with the OpenTelemetry demo repository in resources. A run.completed webhook on the API key then posts the result URL when the span-attribute change is ready to review.

The use case this job follows, with its automation and trigger: Turn a Linear label into a PR.

Why run it on Rush?

On a laptop this job is a chain of setup: a deep clone of a multi-service demo, a Go toolchain that matches go 1.26.0, and Docker available for docker compose build checkout. Each run on Rush boots its own sandbox with that already in reach, runs go test and the compose build itself, and keeps every command and its output, so the proof of the span attributes is the run's own record rather than a paste into a pull request comment.

Instrumentation tickets rarely wait for a quiet afternoon. Issues labelled in one triage pass become one run each, in one sandbox each, each on its own branch with its own pull request, instead of several engineers sharing one Docker daemon and one checkout of the demo.

Frequently asked questions

The PlaceOrder span already sets demo.order.amount. What changes?

Those demo.* attributes stay. The issue asks for app.order.amount and app.order.items.count as well, so tools that filter on the app namespace can find the order total and item count without depending on the demo prefix.

Which service does the agent change?

Only src/checkout/. The agent reads go.mod and main.go there, extends PlaceOrder and main_test.go, and builds with docker compose build checkout. Other services in the demo are left alone.

How are the attributes tested without a live collector?

The new test records spans with the OpenTelemetry SDK's in-memory exporter inside the Go test process. No Jaeger or OTLP endpoint has to be up for the assertion to run.

Will the agent regenerate protobufs?

No. The attribute change is in the Go handler, not in pb/ or genproto/. The agent does not run make docker-generate-protobuf unless the issue asks for a schema change.