{"id":48640396,"url":"https://github.com/reliablyobserve/loki-vl-proxy","last_synced_at":"2026-06-06T16:01:08.914Z","repository":{"id":348998783,"uuid":"1200665558","full_name":"ReliablyObserve/loki-vl-proxy","owner":"ReliablyObserve","description":"Loki-compatible API proxy for VictoriaLogs. Use Grafana's native Loki datasource, Explore, and Logs Drilldown with VictoriaLogs. No plugin required.","archived":false,"fork":false,"pushed_at":"2026-05-23T10:56:40.000Z","size":27458,"stargazers_count":25,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-23T11:37:21.924Z","etag":null,"topics":["golang","grafana","grafana-explore","grafana-loki","helm","helm-chart","kubernetes","logging","logql","logs-drilldown","loki","loki-compatible","observability","opentelemetry","proxy","reverse-proxy","victorialogs"],"latest_commit_sha":null,"homepage":"https://reliablyobserve.github.io/loki-vl-proxy/","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ReliablyObserve.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":"docs/roadmap.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-03T17:24:36.000Z","updated_at":"2026-05-23T10:53:36.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ReliablyObserve/loki-vl-proxy","commit_stats":null,"previous_names":["szibis/loki-vl-proxy","reliablyobserve/loki-vl-proxy"],"tags_count":201,"template":false,"template_full_name":null,"purl":"pkg:github/ReliablyObserve/loki-vl-proxy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ReliablyObserve%2Floki-vl-proxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ReliablyObserve%2Floki-vl-proxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ReliablyObserve%2Floki-vl-proxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ReliablyObserve%2Floki-vl-proxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ReliablyObserve","download_url":"https://codeload.github.com/ReliablyObserve/loki-vl-proxy/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ReliablyObserve%2Floki-vl-proxy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33538660,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"ssl_error","status_checked_at":"2026-05-26T15:22:15.568Z","response_time":63,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["golang","grafana","grafana-explore","grafana-loki","helm","helm-chart","kubernetes","logging","logql","logs-drilldown","loki","loki-compatible","observability","opentelemetry","proxy","reverse-proxy","victorialogs"],"created_at":"2026-04-09T18:19:09.237Z","updated_at":"2026-05-26T21:01:29.296Z","avatar_url":"https://github.com/ReliablyObserve.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Loki-VL-proxy\n\n\u003cp align=\"center\"\u003e\n  \u003cpicture\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"website/static/img/loki-vl-proxy-logo-white.jpg\"\u003e\n    \u003cimg src=\"website/static/img/loki-vl-proxy-logo-black.jpg\" alt=\"Loki-VL-proxy marketing logo\" width=\"340\"\u003e\n  \u003c/picture\u003e\n\u003c/p\u003e\n\n[![CI](https://github.com/ReliablyObserve/Loki-VL-proxy/actions/workflows/ci.yaml/badge.svg?branch=main\u0026event=push)](https://github.com/ReliablyObserve/Loki-VL-proxy/actions/workflows/ci.yaml)\n[![Go Report Card](https://goreportcard.com/badge/github.com/ReliablyObserve/Loki-VL-proxy)](https://goreportcard.com/report/github.com/ReliablyObserve/Loki-VL-proxy)\n[![Loki Compatibility](https://github.com/ReliablyObserve/Loki-VL-proxy/actions/workflows/compat-loki.yaml/badge.svg?branch=main\u0026event=push)](https://github.com/ReliablyObserve/Loki-VL-proxy/actions/workflows/compat-loki.yaml)\n[![Drilldown Compatibility](https://github.com/ReliablyObserve/Loki-VL-proxy/actions/workflows/compat-drilldown.yaml/badge.svg?branch=main\u0026event=push)](https://github.com/ReliablyObserve/Loki-VL-proxy/actions/workflows/compat-drilldown.yaml)\n[![VictoriaLogs Compatibility](https://github.com/ReliablyObserve/Loki-VL-proxy/actions/workflows/compat-vl.yaml/badge.svg?branch=main\u0026event=push)](https://github.com/ReliablyObserve/Loki-VL-proxy/actions/workflows/compat-vl.yaml)\n[![Go Version](https://img.shields.io/github/go-mod/go-version/ReliablyObserve/Loki-VL-proxy)](https://go.dev/)\n[![Release](https://img.shields.io/github/v/release/ReliablyObserve/Loki-VL-proxy)](https://github.com/ReliablyObserve/Loki-VL-proxy/releases)\n[![Docker Hub](https://img.shields.io/docker/pulls/reliablyobserve/loki-vl-proxy?label=Docker%20Hub%20pulls)](https://hub.docker.com/r/reliablyobserve/loki-vl-proxy)\n[![GHCR Pulls](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/ReliablyObserve/Loki-VL-proxy/badges/.github/badges/ghcr-pulls.json)](https://github.com/ReliablyObserve/Loki-VL-proxy/pkgs/container/loki-vl-proxy)\n[![Helm Chart Pulls](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/ReliablyObserve/Loki-VL-proxy/badges/.github/badges/ghcr-chart-pulls.json)](https://github.com/ReliablyObserve/Loki-VL-proxy/pkgs/container/charts%2Floki-vl-proxy)\n[![Source Code](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/ReliablyObserve/Loki-VL-proxy/badges/.github/badges/loc-code.json)](https://github.com/ReliablyObserve/Loki-VL-proxy)\n[![Test Code](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/ReliablyObserve/Loki-VL-proxy/badges/.github/badges/loc-tests.json)](https://github.com/ReliablyObserve/Loki-VL-proxy)\n[![Tests](https://img.shields.io/badge/tests-3479%20passed-brightgreen)](#tests)\n[![Coverage](https://img.shields.io/badge/coverage-85.3%25-green)](#tests)\n[![LogQL Coverage](https://img.shields.io/badge/LogQL%20coverage-100%25-brightgreen)](#logql-compatibility)\n[![License](https://img.shields.io/github/license/ReliablyObserve/Loki-VL-proxy)](LICENSE)\n[![CodeQL](https://github.com/ReliablyObserve/Loki-VL-proxy/actions/workflows/codeql.yaml/badge.svg?branch=main\u0026event=push)](https://github.com/ReliablyObserve/Loki-VL-proxy/actions/workflows/codeql.yaml)\n\n**Keep your entire Loki stack — Grafana Explore, Drilldown, dashboards, API tooling — and run it on VictoriaLogs.**\n\n- **Drop-in Loki API.** Point your existing Grafana Loki datasource at the proxy. Zero plugin changes, zero query rewrites.\n- **Measured resource difference.** At 310 GiB/day ingest: VL + proxy runs on **1.4 cores and 6.1 GiB RAM**. Loki's published minimum for that ingest class: 38 cores, 59 GiB. That gap is real — not a benchmark artifact.\n- **Proxy intelligence built in.** 4-tier cache, 1h window reuse, adaptive parallelism, circuit breaker, rate limits, tenant isolation. One ~14 MB static binary.\n\nProject site: `https://reliablyobserve.github.io/Loki-VL-proxy/`\n\n---\n\n## Query Performance\n\nMeasured head-to-head against tuned Loki: Apple M5 Pro (18 cores, 64 GB RAM), ~8 M log entries across 15 services, 7-day window.\n\n### Cold proxy — honest baseline\n\nNo cache, no coalescer. Pure translation overhead + HTTP proxying + VictoriaLogs response time. This is the floor — what you get before any caching kicks in.\n\n| Workload | Concurrency | Cold proxy | Loki | Ratio |\n|---|:---:|---:|---:|:---:|\n| Small metadata queries | c=10 | 1,212 req/s | ~880 req/s | **1.4× faster** |\n| Small metadata queries | c=50 | 1,583 req/s | ~780 req/s | **2× faster** |\n| Heavy pipeline queries | c=10 | 126–188 req/s | ~161–472 req/s | **~parity** |\n| Heavy pipeline queries | c=100 | 139 req/s | ~33 req/s | **4.2× faster** |\n| Long-range (6 h–72 h) | c=10 | 2× faster than Loki | — | parallel sub-window fetching |\n| Compute (rate, topk) | c=10 | 210 req/s | ~2,403 req/s | 0.09× — N VL calls per metric query |\n\n- **Small and metadata queries:** 1.4–2× faster than Loki cold — VL scans are faster than Loki's chunk store for label/series queries.\n- **Heavy pipeline queries:** parity to 4.2× faster depending on concurrency — `stats_query_range` fast path eliminates 39% cold CPU for `count_over_time`/`rate` queries.\n- **Long-range queries:** 2× faster cold — parallel sub-window fetching completes before Loki's sequential chunk scan.\n- **Compute aggregations (`quantile_over_time`, `topk`, multi-stage pipelines):** each metric query fans out to N VL calls; pprof-guided alloc fixes lifted cold throughput from 40 to 210 req/s. Historical sub-windows are cached on first fetch (24 h TTL), so repeated compute queries approach warm performance.\n\n### Warm cache — what production steady-state looks like\n\nGrafana dashboards auto-refresh every 30 s. After the first fetch, repeated queries are served from in-memory cache without touching VictoriaLogs. The numbers below are **100% cache-hit results** — they represent the ceiling, not the typical case. Real production performance sits between the cold floor above and these warm numbers depending on your dashboard diversity and refresh interval.\n\n| Workload | Concurrency | Loki req/s | Proxy cold req/s | Proxy warm req/s | Warm gain | P50 Loki | P50 cold | P50 warm | Latency gain |\n|---|:---:|---:|---:|---:|:---:|---:|---:|---:|:---:|\n| Small panels | c=10 | 2,011 | 1,201 | 15,626 | **7.8×** | 4 ms | 4 ms | 587 µs | **6.8×** |\n| Small panels | c=100 | 2,290 | — | 27,513 | **12×** | 42 ms | — | 3 ms | **14×** |\n| Heavy queries | c=10 | 407 | 179 | 5,944 | **14.6×** | 4 ms | 21 ms | 1 ms | **4×** |\n| Heavy queries | c=100 | 162† | — | 7,134 | **44×** | ~1,800 ms† | — | 12 ms | **150×** |\n| Long-range | c=10 | 8 | 19 | 157 | **18.7×** | 481 ms | 39 ms | 1 ms | **481×** |\n| Compute | c=10 | 2,803 | 352 | 11,162 | **4×** | 1 ms | 10 ms | 675 µs | **1.5×** |\n| Compute | c=100 | 1,611 | 366 | 16,456 | **10.2×** | 4 ms | 261 ms | 4 ms | parity |\n\nCPU: **6–408× less** than Loki under cache load. RAM: **1.7–3.9× less** for most workloads.\n\n† Loki heavy c=100 was saturated — P90=1,818 ms, P99=6,950 ms, delivering only 162 req/s vs 7,134 for the proxy.\n\n### Dashboard load spikes — request coalescer\n\nWhen many panels hit the same query simultaneously, the proxy collapses them into a single backend call. First-hit coalescing avoids the N-fan-out but pays one backend round-trip (cold proxy P50 for a single request); subsequent hits are served from cache.\n\n| Workload | Loki P50 | Proxy P50 (first hit) | Proxy P50 (warm) |\n|---|---:|---:|---:|\n| Metadata queries | 196 ms | **~4 ms** | **1 ms** |\n| Heavy aggregations | 2,399 ms | **~21 ms** | **1 ms** |\n| Content search | 13,415 ms | **~39 ms** | **1 ms** |\n\nFull throughput tables, P90/P99 latency, CPU and RSS breakdowns: [Benchmarks](docs/benchmarks.md) · [Performance](docs/performance.md)\n\n---\n\n## The Cost Case\n\nThis is a production deployment, not a synthetic benchmark. The numbers below come from a real VictoriaLogs installation running at **310 GiB/day** raw ingest with **800 M total log entries** and **7.1 days** of retention.\n\n**What VictoriaLogs actually consumed at that load:**\n\n| Component | Cores | Memory |\n|---|---:|---:|\n| `vlstorage` | 1.0 | 5.0 GiB |\n| `vlinsert` | 0.1 | 0.6 GiB |\n| `vlselect` | 0.1 | 0.25 GiB |\n| `loki-vl-proxy` | ~0.1–0.2 | ~0.15–0.26 GiB |\n| **VL + loki-vl-proxy, combined** | **~1.4** | **~6.1 GiB** |\n\nFor comparison, [Loki's own documentation](https://grafana.com/docs/loki/latest/setup/size/) puts the **minimum** hardware requirement at **38 cores and 59 GiB** for the same ingest class (`\u003c3 TB/day`). That's the floor — a minimal, single-tenant, non-HA deployment.\n\n**Caveat:** `vlselect` was measured at zero read concurrency — query load will add to that number. If you run heavy aggregation queries at scale, benchmark your own workload with `loki-bench` before sizing.\n\n**Storage:** 2,201 GiB of raw logs (310 GiB/day × 7.1 days) compressed to **40.5 GiB on disk — 54.9× compression**. TrueFoundry ran an independent migration and reported ~40% less storage versus their Loki deployment at the same retention.\n\n**Replication:** Loki's recommended production setup uses RF=3 — tripling write load, disk, and cross-AZ egress. VictoriaLogs is designed for AZ-local deployment with no mandatory replication. If you're paying for cross-AZ data transfer today, that alone can outweigh compute savings.\n\n**Migration cost:** Zero changes to Grafana, dashboards, alerts, or any Loki API client. The proxy handles translation transparently; remove it and point back at Loki if needed.\n\nFull cost worksheet, scaling projections, and EC2/GCP sizing tables: [Cost Model](docs/cost-model.md) · [Scaling](docs/scaling.md)\n\n---\n\n## Quick Start\n\n### Docker\n\n```bash\ndocker run -p 3100:3100 \\\n  ghcr.io/reliablyobserve/loki-vl-proxy:latest \\\n  -backend=http://victorialogs:9428\n```\n\n### Helm\n\n```bash\nhelm install loki-vl-proxy oci://ghcr.io/reliablyobserve/charts/loki-vl-proxy \\\n  --version \u003crelease\u003e \\\n  --set extraArgs.backend=http://victorialogs:9428 \\\n  --set extraArgs.patterns-enabled=true\n```\n\n### Grafana Datasource\n\nPoint your existing Loki datasource at the proxy — no other changes needed.\n\n```yaml\ndatasources:\n  - name: Loki (via VL proxy)\n    type: loki\n    access: proxy\n    url: http://loki-vl-proxy:3100\n    jsonData:\n      httpHeaderName1: X-Scope-OrgID\n    secureJsonData:\n      httpHeaderValue1: team-alpha\n```\n\nThat's it. Grafana Explore, Drilldown, and all dashboards work immediately.\n\nFor StatefulSet persistence, peer-cache fleet setup, OTLP push wiring, and image source options, see [Getting Started](docs/getting-started.md) and [Operations](docs/operations.md).\n\n---\n\n## Why It's Fast\n\n**4-tier cache:**\n- **Tier0** — compatibility-edge cache for safe GET responses (no backend hit at all)\n- **L1** — in-memory hot path\n- **L2** — disk (bbolt), survives restarts, warms historical windows across large working sets\n- **L3** — peer cache, lets warm fleet replicas share results instead of all hitting the backend\n\n**Window reuse.** Long `query_range` requests are split into 1h windows. Historical windows are served from cache; only the live edge fetches from VictoriaLogs. A 7-day query with warm cache may hit the backend for a single window.\n\n**Adaptive parallelism.** Parallel window fetches use EWMA-based backpressure — ramps up when VictoriaLogs is fast, backs off automatically before it becomes a problem.\n\n**Request coalescing.** Concurrent identical queries collapse into one upstream request.\n\n---\n\n## What Works Out of the Box\n\n- Grafana Explore — log browsing, filtering, live tail\n- Grafana Logs Drilldown — patterns, service view, field breakdown\n- Dashboards — all LogQL panel types\n- Multi-tenant — `X-Scope-OrgID` isolation with per-tenant rate limits\n- Live tail — native WebSocket tail or synthetic polling fallback\n- Rules and alerts — read bridge to vmalert (no write lifecycle)\n- LogQL — 100% coverage: stream selectors, filters, parsers, metric queries, range functions, vector operators\n- OTel labels — dotted structured metadata exposed correctly in detected fields, underscore-safe in stream labels\n\n---\n\n## Production Features\n\n- **Circuit breaker** — opens on backend failure, closes automatically on recovery\n- **Per-client rate limits** — token bucket, configurable per tenant\n- **Tenant isolation** — strict `X-Scope-OrgID` fanout guardrails; no cross-tenant data bleed\n- **TLS / mTLS** — configurable on both northbound (client) and southbound (backend) boundaries\n- **OTLP push** — proxy emits its own traces to any OTLP endpoint\n- **Operator dashboard** — packaged Grafana dashboard covering Client → Proxy → VictoriaLogs, cache behavior, fanout, and resource utilization\n- **Runbook-backed alerts** — 13 alert rules, each with a linked runbook\n- **100+ Prometheus metrics** — all under `loki_vl_proxy_*` prefix\n- **Read-only by default** — `/push` blocked, delete gated, debug/admin disabled unless explicitly enabled\n- **Cold storage routing** — time-boundary split to Victoria Lakehouse for long-range queries\n\n---\n\n## High-Level Flow\n\n```mermaid\nflowchart LR\n    A[Clients\u003cbr/\u003eGrafana, Loki API tools, MCP/LLM, scripts]\n    B[Loki-VL-proxy\u003cbr/\u003eLoki API compatibility + translation + shaping + cache]\n    C[Upstream\u003cbr/\u003eVictoriaLogs data + vmalert rules/alerts]\n\n    A --\u003e B --\u003e C\n\n    classDef client fill:#1f2937,stroke:#60a5fa,color:#f3f4f6,stroke-width:2px;\n    classDef proxy fill:#172554,stroke:#22d3ee,color:#f8fafc,stroke-width:2px;\n    classDef upstream fill:#052e16,stroke:#34d399,color:#ecfeff,stroke-width:2px;\n    class A client;\n    class B proxy;\n    class C upstream;\n```\n\n## Detailed Architecture\n\n```mermaid\nflowchart TD\n    subgraph L1[\"Clients\"]\n        G[\"Grafana\u003cbr/\u003eExplore / Drilldown / Dashboards\"]\n        M[\"MCP / LLM / API Tools\"]\n        C[\"CLI / SDK Consumers\"]\n    end\n\n    subgraph L2[\"Loki Compatibility Layer (Proxy)\"]\n        API[\"Loki HTTP + WS API\u003cbr/\u003equery / query_range / labels / tail / rules / alerts\"]\n        GUARD[\"Tenant guardrails + auth context + rate limits + policy checks\"]\n        EDGE[\"Compatibility-edge cache (Tier0)\u003cbr/\u003esafe GET response cache\"]\n    end\n\n    subgraph L3[\"Execution Paths\"]\n        Q[\"Query translation + shaping\"]\n        T[\"Tail path (native or synthetic)\"]\n        R[\"Rules / alerts read bridge\"]\n        RESP[\"Loki-compatible response\"]\n    end\n\n    subgraph L4[\"Cache Tiers\"]\n        L1C[\"L1 memory cache\"]\n        L2C[\"L2 disk cache (optional)\"]\n        L3C[\"L3 peer cache (optional)\"]\n    end\n\n    subgraph L5[\"Upstream Systems\"]\n        VL[\"VictoriaLogs\u003cbr/\u003ehot backend\"]\n        Lakehouse[(\"Victoria Lakehouse\u003cbr/\u003ecold backend, optional\")]\n        VMA[\"vmalert\u003cbr/\u003erules / alerts state\"]\n        VM[\"VictoriaMetrics (optional)\u003cbr/\u003erecording rule outputs\"]\n    end\n\n    G --\u003e API\n    M --\u003e API\n    C --\u003e API\n\n    API --\u003e GUARD\n    GUARD --\u003e EDGE\n    EDGE --\u003e|hit| RESP\n    EDGE --\u003e|miss| Q\n\n    GUARD --\u003e T\n    GUARD --\u003e R\n\n    Q --\u003e L1C\n    L1C --\u003e|miss| L2C\n    L2C --\u003e|miss| L3C\n    L3C --\u003e|miss| VL\n    L3C -. cold queries ≥ boundary .-\u003e Lakehouse\n    VL --\u003e Q\n    Lakehouse -. cold results .-\u003e Q\n    Q --\u003e RESP\n\n    T --\u003e VL\n    R --\u003e VMA\n    VMA -. optional remote write .-\u003e VM\n\n    classDef client fill:#1f2937,stroke:#93c5fd,color:#f3f4f6,stroke-width:2px;\n    classDef api fill:#0f172a,stroke:#22d3ee,color:#f8fafc,stroke-width:2px;\n    classDef exec fill:#172554,stroke:#818cf8,color:#eef2ff,stroke-width:2px;\n    classDef cache fill:#3f1d2e,stroke:#f472b6,color:#fdf2f8,stroke-width:2px;\n    classDef upstream fill:#052e16,stroke:#34d399,color:#ecfdf5,stroke-width:2px;\n    classDef cold fill:#1c1917,stroke:#a8a29e,color:#f5f5f4,stroke-width:1px,stroke-dasharray:4 4;\n\n    class G,M,C client;\n    class API,GUARD,EDGE api;\n    class Q,T,R,RESP exec;\n    class L1C,L2C,L3C cache;\n    class VL,VMA,VM upstream;\n    class Lakehouse cold;\n```\n\n---\n\n## Compatibility\n\nLoki-VL-proxy is validated continuously in CI against three separate tracks: Loki API, Grafana Logs Drilldown, and VictoriaLogs integration.\n\n### Label and Field Compatibility\n\n| Profile | Stream labels (`/labels`) | Detected fields / metadata | Best for |\n|---|---|---|---|\n| Loki-compatible (default) | underscore-only | translated underscore aliases | strict Loki UX, Grafana Explore/Drilldown |\n| Mixed | underscore-only | dotted + translated aliases | Grafana + OTel correlation |\n| Native-field | underscore-only (`label-style=underscores`) | dotted-native only | VL/OTel-native field workflows |\n\nDefault flags: `-label-style=underscores`, `-metadata-field-mode=translated`. Grafana query builder works best with underscore aliases; code mode accepts dotted expressions and translates them to VL-native field matching.\n\n**Tuple safety:** Default responses return strict `[timestamp, line]` 2-tuples. 3-tuple metadata mode activates only when the client sends `X-Loki-Response-Encoding-Flags: categorize-labels`. Cache keys are segregated by tuple mode.\n\n### LogQL Compatibility\n\nStream selectors, filters, parser pipelines, metric queries, range functions, scalar bool comparisons, vector set operators, and invalid LogQL error forms are all covered and machine-validated in CI against a real Loki oracle. The suite spans 316 exhaustive LogQL parity test cases with machine-validated compatibility scores.\n\n**Typed LogQL parser:** The proxy includes a fully typed recursive-descent LogQL parser (`internal/logql`) that produces a structured AST for query validation, structural routing, and drop/keep extraction — replacing the previous regex-based approach. The parser enforces Loki-compatible semantic constraints (missing `| unwrap` in `rate_counter`, invalid `ip()` filter addresses, unclosed template delimiters, etc.) and generates the exact error messages Loki 3.x returns, so Grafana datasource clients receive the expected error shape.\n\nFor full detail: [Loki Compatibility](docs/compatibility-loki.md), [Translation Reference](docs/translation-reference.md), [LogQL Parser](docs/logql-parser.md), [Known Issues](docs/KNOWN_ISSUES.md)\n\n---\n\n## Observability\n\n- **100+ Prometheus metrics** under `loki_vl_proxy_*` — cache hit ratios, window fetch latency, fanout behavior, per-tenant and per-client pressure, circuit breaker state\n- **Packaged operator dashboard** — rows for Client-Side Loki API Visibility, Proxy Internal, and Backend-Side VictoriaLogs fanout; fast incident attribution\n- **13 runbook-backed alert rules** — backend latency, backend unreachable, circuit breaker open, high error rate, rate limiting, tenant isolation, and more\n- **Structured JSON logs** — route-aware, semconv-aligned, with user-pattern attribution from trusted Grafana headers\n- **OTLP tracing** — proxy emits traces to any OTLP endpoint\n\nSee [Observability](docs/observability.md) and [Alert Runbooks Index](docs/runbooks/alerts.md).\n\n---\n\n## Security\n\n- Read-only API surface by default: `/push` blocked, delete gated, debug/admin disabled\n- Non-root runtime image, read-only root filesystem, restricted Helm security contexts\n- Hardening headers on all HTTP responses including 404s and disabled routes\n- CI security gates: `gitleaks`, `gosec`, Trivy, `actionlint`, `hadolint`, OpenSSF Scorecard, OWASP ZAP, curated Nuclei\n- Proxy-specific coverage: tenant isolation, cache boundary enforcement, browser-origin checks on `/tail`, forwarded auth handling\n\nSee [Security](docs/security.md) and [Security Policy](SECURITY.md).\n\n---\n\n## UI Gallery\n\nVictoriaLogs backend with Loki-VL-proxy as the Loki-compatible query layer.\n\n\u003ca href=\"docs/images/ui/explore-main.png\"\u003e\n  \u003cimg src=\"docs/images/ui/explore-main.png\" alt=\"Grafana Explore main view\" width=\"240\" /\u003e\n\u003c/a\u003e\n\u003ca href=\"docs/images/ui/explore-details.png\"\u003e\n  \u003cimg src=\"docs/images/ui/explore-details.png\" alt=\"Grafana Explore details view\" width=\"240\" /\u003e\n\u003c/a\u003e\n\u003ca href=\"docs/images/ui/drilldown-main.png\"\u003e\n  \u003cimg src=\"docs/images/ui/drilldown-main.png\" alt=\"Grafana Logs Drilldown main view\" width=\"240\" /\u003e\n\u003c/a\u003e\n\u003ca href=\"docs/images/ui/drilldown-service.png\"\u003e\n  \u003cimg src=\"docs/images/ui/drilldown-service.png\" alt=\"Grafana Logs Drilldown service detail view\" width=\"240\" /\u003e\n\u003c/a\u003e\n\u003ca href=\"docs/images/ui/explore-tail-multitenant.png\"\u003e\n  \u003cimg src=\"docs/images/ui/explore-tail-multitenant.png\" alt=\"Grafana Explore multi-tenant view\" width=\"240\" /\u003e\n\u003c/a\u003e\n\n---\n\n## Documentation Map\n\n### Core\n- [Getting Started](docs/getting-started.md)\n- [Configuration](docs/configuration.md)\n- [Operations](docs/operations.md)\n- [Architecture](docs/architecture.md)\n- [API Reference](docs/api-reference.md)\n- [Security](docs/security.md)\n- [Observability](docs/observability.md)\n- [Performance](docs/performance.md)\n- [Scaling](docs/scaling.md)\n\n### Compatibility\n- [Compatibility Matrix](docs/compatibility-matrix.md)\n- [Loki Compatibility](docs/compatibility-loki.md)\n- [Logs Drilldown Compatibility](docs/compatibility-drilldown.md)\n- [Grafana Loki Datasource Compatibility](docs/compatibility-grafana-datasource.md)\n- [VictoriaLogs Compatibility](docs/compatibility-victorialogs.md)\n- [Translation Modes Guide](docs/translation-modes.md)\n- [Translation Reference](docs/translation-reference.md)\n\n### Cache and Runtime Design\n- [Fleet Cache](docs/fleet-cache.md)\n- [Peer Cache Design](docs/peer-cache-design.md)\n- [Benchmarks](docs/benchmarks.md)\n\n### Runbooks\n- [Alert Runbooks Index](docs/runbooks/alerts.md)\n- [Deployment Best Practices](docs/runbooks/deployment-best-practices.md)\n- [Backend High Latency](docs/runbooks/loki-vl-proxy-backend-high-latency.md)\n- [Backend Unreachable](docs/runbooks/loki-vl-proxy-backend-unreachable.md)\n- [Circuit Breaker Open](docs/runbooks/loki-vl-proxy-circuit-breaker-open.md)\n- [Client Bad Request Burst](docs/runbooks/loki-vl-proxy-client-bad-request-burst.md)\n- [Proxy Down](docs/runbooks/loki-vl-proxy-down.md)\n- [Grafana Tuple Contract](docs/runbooks/loki-vl-proxy-grafana-tuple-contract.md)\n- [High Error Rate](docs/runbooks/loki-vl-proxy-high-error-rate.md)\n- [High Latency](docs/runbooks/loki-vl-proxy-high-latency.md)\n- [Rate Limiting](docs/runbooks/loki-vl-proxy-rate-limiting.md)\n- [Operational Resources](docs/runbooks/loki-vl-proxy-system-resources.md)\n- [Tenant High Error Rate](docs/runbooks/loki-vl-proxy-tenant-high-error-rate.md)\n\n### Testing and Release\n- [Testing](docs/testing.md)\n- [Release Info](docs/release-info.md)\n\n### Migration and Project Status\n- [Rules And Alerts Migration](docs/rules-alerts-migration.md)\n- [Known Issues](docs/KNOWN_ISSUES.md)\n- [Roadmap](docs/roadmap.md)\n- [Changelog](CHANGELOG.md)\n\n---\n\n## License\n\nApache License 2.0. See [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freliablyobserve%2Floki-vl-proxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freliablyobserve%2Floki-vl-proxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freliablyobserve%2Floki-vl-proxy/lists"}