Introducing Lightstep UQL to PromQL Translator

The Sunset of Lightstep and the Migration Challenge

Lightstep is sunsetting. For teams that built their observability infrastructure around it, this means migrating thousands of telemetry queries, dashboards, and alerts to a new backend. At Zalando, we faced exactly this problem when transitioning to Dash0, our new PromQL-based telemetry vendor.

The task is straightforward but challenging: rewriting UQL (Unified Query Language) queries into PromQL. Doing this manually is slow and error-prone. Even with LLMs, the translations are unpredictable and often produce subtle bugs that break production alerts. When you're dealing with thousands of queries that monitor critical systems, you need automation that produces correct and consistent results.

Introducing the Lightstep UQL to PromQL Translator

To solve this, I built a production-ready translator that converts Lightstep UQL queries to PromQL. The tool is written in Go and designed to be used in two ways: as a library (SDK) for translation in your own code, and as an HTTP server with a Web UI for interactive ad-hoc translation.

The translator implements a full parsing pipeline: a lexer tokenizes UQL queries, a parser builds an abstract syntax tree (AST), an optimizer applies transformations to simplify the query structure, and finally the translator generates clean PromQL output.

The project is available at github.com/zalando/lightstep-uql-to-promql-translator.

How to Use the Translator

Web UI and REST API

The simplest way to start is running the HTTP server. It provides both a browser-based UI for interactive translation and a REST API for automation.

First, configure your metric types in cmd/main.go:

package main

import (
    "log"
    "github.com/zalando/lightstep-uql-to-promql-translator/pkg/model"
    "github.com/zalando/lightstep-uql-to-promql-translator/pkg/promql"
    "github.com/zalando/lightstep-uql-to-promql-translator/pkg/server"
)

func TranslateUQLToPromQL(query string) (string, *model.Error) {
    metricTypes := map[string]promql.MetricType{
        "http_requests_total": promql.METRIC_TYPE_SUM,
        "cpu_usage":           promql.METRIC_TYPE_GAUGE,
        "request_duration":    promql.METRIC_TYPE_HISTOGRAM,
    }

    metricConfig := promql.SpecialMetricConfig{
        SpansCount:           "spans.count",
        SpansLatency:         "spans.latency",
        SpansCountUnadjusted: "spans.count_unadjusted",
        LogsCount:            "logs.count",
    }

    return promql.Translate(query, metricTypes, metricConfig)
}

func main() {
    srv := server.New(":8080", TranslateUQLToPromQL)
    log.Fatal(srv.Start())
}

Then start the server:

go run cmd/main.go

The Web UI will be available at http://localhost:8080. You can paste UQL queries and see the PromQL translation instantly, with detailed error messages if something goes wrong.

For programmatic access, use the REST API:

curl -X POST http://localhost:8080/api/translate \
     -d '{"query": "metric http_requests_total | rate 5m"}'

Go SDK

For embedding translation logic directly into your tools or CI pipelines, use the SDK:

package main

import (
    "fmt"
    "log"
    "github.com/zalando/lightstep-uql-to-promql-translator/pkg/promql"
)

func main() {
    query := "metric http_requests_total | rate 5m | group_by [method], sum"

    metricTypes := map[string]promql.MetricType{
        "http_requests_total": promql.METRIC_TYPE_SUM,
    }

    metricConfig := promql.SpecialMetricConfig{
        SpansCount:   "spans.count",
        SpansLatency: "spans.latency",
    }

    promqlQuery, err := promql.Translate(query, metricTypes, metricConfig)
    if err != nil {
        log.Fatalf("Translation error: %s at position %d", err.Status, err.SourceIndex)
    }

    fmt.Println("PromQL:", promqlQuery)
}

For more details on configuration options and advanced usage, see the project repository.

Internal Impact: Powering Move to Dash0

At Zalando, this translator was one of the core tools that were driving our migration from Lightstep to Dash0. We deployed an internal instance of the Web UI that engineering teams used for self-service query translation. The SDK was integrated into automation tools that converted existing alerts and dashboard queries. The translator handled the full range of UQL queries we had in production: from simple metric fetches to complex joins with multiple subqueries.

The Business Value

The main value is time saved. Manually translating thousands of queries would take weeks or months of engineering time. More importantly, it eliminates translation errors. Production alerts need to work correctly - a broken alert means incidents go unnoticed. Manual translation introduces bugs. LLM-based translation is unpredictable and produces subtly wrong queries that only fail under specific conditions. A deterministic translator that parses the query structure and applies robust transformation rules was the only reliable approach.

Helping the Community Transition

Since Lightstep is sunsetting, many organizations face the same migration challenge. Releasing this tool as open source helps the engineering community transition to PromQL-based backends - whether that's Prometheus, Dash0, or any other vendor supporting PromQL. The project is production-ready and actively used at Zalando.

If you're migrating from Lightstep, you can start using the translator today: project repository.

Community contributions are welcome!


We're hiring! Do you like working in an ever evolving organization such as Zalando? Consider joining our teams as a Backend Engineer!


Related posts

Rejecting Invalid Ingress Routes at Apply Time

How Zalando used Skipper as a validating admission webhook to reject invalid filters and predicates at apply time,... Read more...

Introducing Lightstep Receiver for OpenTelemetry Collector

OpenTelemetry Lightstep Receiver helps you ingest traces generated by legacy Lightstep tracers in a simple way. Read more...

12 Golden Signals To Discover Anomalies And Performance Issues on Your AWS RDS Fleet

Automate anomaly detection for AWS RDS at scale. Read more...

首页 - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-06-09 10:43
浙ICP备14020137号-1 $访客地图$