- Admin layout: SVG icons, active highlight, divider between nav sections - Scrape page: status filter pills with counts, text + status combined search - Audio page: status filter pills, cancel jobs, retry failed jobs, mobile cards for cache tab - Translation page: status filter pills (incl. cancelled), cancel + retry jobs, mobile cancel/retry cards, i18n for all labels - AI Jobs page: fix concurrent cancel (Set instead of single slot), per-job cancel errors inline, full mobile card layout, i18n title/heading - Text-gen page: tagline editable input + copy, warnings copy, i18n title/heading - Book page: chapter cover Save button, audio monitor link, currentShelf pre-populated from server - pocketbase.ts: add getBookShelf(), shelf field on UserLibraryEntry - New API route: POST /api/admin/translation/bulk (proxy for translation retry) - i18n: 15 new admin_translation_*, admin_ai_jobs_*, admin_text_gen_* keys across all 5 locales
82 lines
2.2 KiB
Plaintext
82 lines
2.2 KiB
Plaintext
// Grafana Alloy — Faro RUM receiver + OTel log bridge
|
|
//
|
|
// Receives browser telemetry (Web Vitals, traces, logs, exceptions) from the
|
|
// LibNovel SvelteKit frontend via the @grafana/faro-web-sdk.
|
|
//
|
|
// Also receives OTLP logs from the backend and runner services, and forwards
|
|
// them to Loki in the native push format (solving the OTLP→Loki gap).
|
|
//
|
|
// Pipeline:
|
|
// faro.receiver → receives HTTP POST /collect from browsers
|
|
// otelcol.receiver.otlp → receives OTLP logs from backend/runner (HTTP :4318)
|
|
// otelcol.exporter.otlphttp → forwards traces to OTel Collector → Tempo
|
|
// loki.write → forwards Faro logs/exceptions to Loki
|
|
// otelcol.exporter.loki → forwards OTel logs to Loki (native format)
|
|
//
|
|
// The Faro endpoint is exposed publicly at faro.libnovel.cc via cloudflared.
|
|
|
|
faro.receiver "faro" {
|
|
server {
|
|
listen_address = "0.0.0.0"
|
|
listen_port = 12347
|
|
|
|
cors_allowed_origins = ["https://libnovel.cc", "https://www.libnovel.cc"]
|
|
}
|
|
|
|
output {
|
|
logs = [loki.write.faro.receiver]
|
|
traces = [otelcol.exporter.otlphttp.faro.input]
|
|
}
|
|
}
|
|
|
|
// Receive OTLP traces and logs from backend/runner
|
|
otelcol.receiver.otlp "otel_logs" {
|
|
http {
|
|
endpoint = "0.0.0.0:4318"
|
|
}
|
|
|
|
output {
|
|
logs = [otelcol.exporter.loki.otel_logs.input]
|
|
traces = [otelcol.exporter.otlphttp.otel_logs.input]
|
|
}
|
|
}
|
|
|
|
// Convert OTel logs to Loki format and forward to loki.write
|
|
otelcol.exporter.loki "otel_logs" {
|
|
forward_to = [loki.write.otel_logs.receiver]
|
|
}
|
|
|
|
// Send backend/runner traces to the OTel Collector → Tempo
|
|
otelcol.exporter.otlphttp "otel_logs" {
|
|
client {
|
|
endpoint = "http://otel-collector:4318"
|
|
tls {
|
|
insecure = true
|
|
}
|
|
}
|
|
}
|
|
|
|
// Push backend/runner logs to Loki (native push format)
|
|
loki.write "otel_logs" {
|
|
endpoint {
|
|
url = "http://loki:3100/loki/api/v1/push"
|
|
}
|
|
}
|
|
|
|
// Forward Faro traces to the OTel Collector (which routes to Tempo)
|
|
otelcol.exporter.otlphttp "faro" {
|
|
client {
|
|
endpoint = "http://otel-collector:4318"
|
|
tls {
|
|
insecure = true
|
|
}
|
|
}
|
|
}
|
|
|
|
// Forward Faro logs/exceptions directly to Loki
|
|
loki.write "faro" {
|
|
endpoint {
|
|
url = "http://loki:3100/loki/api/v1/push"
|
|
}
|
|
}
|