Integrations
Metric export (OpenTelemetry)
Push your AI-coding spend, savings and token counts into Datadog, Grafana Cloud, New Relic, Honeycomb, Coralogix or your own OpenTelemetry Collector, so cost sits on the same dashboards as the rest of your engineering telemetry.
Not generally available yet. The metric export sits behind a feature flag while we finish it, so its page will not appear in your dashboard unless your account has been switched on. Ask us before you provision an ingestion token, or you will have a credential and nowhere to paste it.
Connect your backend
- 1Get an OTLP endpoint from your observability vendor. Copy it rather than guessing: Datadog's host depends on your Datadog site, and Grafana warns that the gateway host differs depending on when your stack's region was created, so you should take it from your stack's OpenTelemetry tile.
- 2Get an ingestion credential. Grafana Cloud issues an access-policy token scoped
metrics:writealongside an instance ID; Datadog uses an API key; New Relic uses a licence key; Honeycomb uses an API key; Coralogix uses a Send-Your-Data API key. - 3In the Lineman dashboard, open Integrations, then Metric export. Pick your destination, paste the endpoint and the credential, and press Save. For Grafana Cloud you can paste
instanceID:tokenexactly as the tile shows it; we encode it as a Basic credential for you, which is the step people most often miss. - 4Press Send a test datapoint. It pushes one real metric called
lineman.export.testand tells you the exact URL it went to.
Either form of the endpoint works. Some vendors publish a base URL and expect the exporter to append /v1/metrics; others publish the full metrics URL and expect it used as-is. That distinction is the single biggest source of 404s on this path, so Lineman accepts both and adds the signal path only when it is missing.
Delta or cumulative
This is the one thing you cannot work around by trying harder. Datadog's OTLP intake accepts delta only and errors on cumulative. Grafana Cloud stores metrics in Prometheus, which is cumulative. Temporality is a property of the series rather than of a request, so a single export cannot serve both. Lineman sets it from the destination you pick and refuses a combination the backend cannot store, rather than letting it fail on ingest where you would never see the error.
If you need both, point Lineman at your own OpenTelemetry Collector using the custom destination and fan out from there. A Collector converts between the two with the deltatocumulative processor, and it is also the route we would suggest for Datadog in production, since Datadog still badges its direct OTLP intake as Preview and recommends an Agent or Collector with the Datadog Exporter.
What gets exported
Company totals for spend, savings and tokens, plus per-developer and per-repo breakdowns of each. Money is in USD. Token series carry a token.type label of input, output or cache.
| Lineman metric | In Grafana Cloud | What it measures |
|---|---|---|
lineman.spend | lineman_spend_USD_total | AI-coding spend Lineman attributed in the period |
lineman.savings | lineman_savings_USD_total | Token spend Lineman avoided in the period |
lineman.tokens | lineman_tokens_total | Tokens attributed, labelled by input, output or cache |
lineman.spend.by_developer | lineman_spend_by_developer_USD_total | The same spend split by developer, labelled with their email |
lineman.spend.by_repo | lineman_spend_by_repo_USD_total | The same spend split by repository |
Grafana Cloud rewrites these names on ingest. Dots and dashes become underscores, and a unit and _total suffix are added per Prometheus convention, so you query lineman_spend_USD_total rather than lineman.spend. Resource attributes such as service.name land on target_info rather than on the series. Build your dashboards against the converted names. Cache tokens are reported at company level only: the per-developer and per-repo token series cover input and output, because they come from the same breakdown the rest of your Lineman dashboard uses and a separately-computed cache figure here would disagree with it.
Per-destination notes
- Grafana Cloud. Endpoint
https://otlp-gateway-<region>.grafana.net/otlp, cumulative, authenticated withAuthorization: Basicover your instance ID and an access-policy token scopedmetrics:write. - Datadog. Delta only, authenticated with the
dd-api-keyheader, and the host depends on your Datadog site. Payloads are capped at 512 KiB. Datadog still describes direct OTLP intake as Preview and recommends an Agent or Collector with the Datadog Exporter for production workloads. - New Relic. Delta,
api-keyheader with a licence key. Usehttps://otlp.eu01.nr-data.netif your account is in the EU region. - Honeycomb. Delta,
x-honeycomb-teamheader. Metrics are a Pro-and-above feature, so on a free plan this export cannot be received at all and the failure is quiet. Check your plan before connecting. - Coralogix. Delta,
Authorization: Bearerwith a Send-Your-Data API key, on a region-specific host such ashttps://ingress.eu2.coralogix.com/v1/metrics. - Custom OTLP endpoint. Anything that speaks OTLP over HTTP with a protobuf body, including your own OpenTelemetry Collector, Splunk, Dynatrace, SigNoz and Prometheus's OTLP receiver. You name the auth header yourself.
How often it runs
Every 15 minutes. Each run exports everything since the last push the destination accepted, so a failed run loses nothing: the next one simply covers a wider window. A long outage is caught up across successive runs rather than in one enormous request.
Breakdowns are capped at the 100 highest-spending developers and the 100 highest-spending repositories. Without a cap a cumulative export grows without bound and eventually breaches the destination's payload limit, at which point nothing gets through at all, including the company totals.
Always send a test
A metric export that is wrong fails silently forever. There is no bounced message and no error anywhere you would look; the dashboard you were building simply stays empty. The test pushes one real datapoint and reports the exact URL it reached, which is what makes a base-URL-versus-full-path mistake obvious straight away.