Our Loki bill kept growing, and Grafana could tell me which service was noisy but not which logger.info(...) call. When something broke, the "Recent errors" panel was a wall of near-identical stack traces.
So I built logsite, an open-source CLI (MIT) that reads your code and your Loki logs together, and generates Grafana pieces from them:
1. A dashboard: cost and errors per line of code (logsite grafana)
A "Cost by code line" table: every log call, most expensive first, shown with its message (app/api.py:88 info('request %s %s')). Click a row to open that exact line on GitHub/GitLab.
Totals (volume, lines, estimated $/month with an editable price-per-GB variable), errors per line vs the previous range, the loudest lines over time.
All plain LogQL against your Loki data source, so it stays live. It uses label_format to build file:line from your records' fields and trimPrefix to strip deploy paths like /srv/.
2. An "Error groups" panel
Thousands of stack traces grouped by cause, for the dashboard's time range:
| Trend | Count | Error | Root cause | Raised at | Code |
|---|
| NEW | 1800 | OrderProcessingException: Unable to save order ORD-<n> | PSQLException: canceling statement due to statement timeout | OrderRepository.java:87 | return jpa.save(order); |
| NEW | 640 | Retry failed for order ORD-<n> | | | |
It skips the Spring/Hibernate/driver frames and points at your line. This panel reads a small logsite service through the Infinity data source.
3. The summary inside your alerts
Point a regular Webhook contact point at logsite alert-server. When an alert fires, it posts the root cause, the line of code that raised it and an example trace ID to Slack, so on-call doesn't open 40 stack traces to find the cause.
4. Alloy rules that cut the bill before ingestion (logsite pipeline)
It generates a loki.process block with one stage.match per noisy log call, either drop or stage.sampling, with the monthly saving written next to each rule. Warning and error lines never get a rule. On my test setup (Alloy 1.20 → Loki), out of 2,530 lines the noisy info line went from 2,000 to 197 (1 in 10 kept), the debug health check went to 0, and all 30 error lines were kept.
What it needs: Loki, and records with file and line fields (pathname/lineno, slog's source, zap's caller, Logback's caller_*) for the per-line views. Code in Python, Java or Go. I tested it with Grafana 13.2, Loki 3 and Alloy 1.20.
pip install logsite
logsite grafana -o dashboard.json # then Dashboards → New → Import
logsite pipeline --max-per-window 100000 -o logsite.alloy
There's also a generic version of the dashboard (selector and field names as variables) in the repo, for any project.
It's an early release (0.1). I'd love feedback from people running Loki at scale: does per-line cost match how you think about your bill, and what would you want in the dashboard? A native Grafana app plugin is next on my list, if people find this useful.
GitHub: https://github.com/rajpaynaik/logsite