diff --git a/dev/config/api.toml b/dev/config/api.toml
index 11c68ff44f..14e432db53 100644
--- a/dev/config/api.toml
+++ b/dev/config/api.toml
@@ -8,7 +8,6 @@ primary = "unkey:password@tcp(mysql:3306)/unkey?parseTime=true"
[clickhouse]
url = "clickhouse://default:password@clickhouse:9000?secure=false&skip_verify=true"
analytics_url = "http://clickhouse:8123/default"
-proxy_token = "chproxy-test-token-123"
[vault]
url = "http://vault:8060"
diff --git a/dev/k8s/manifests/api.yaml b/dev/k8s/manifests/api.yaml
index 4220154838..556505097c 100644
--- a/dev/k8s/manifests/api.yaml
+++ b/dev/k8s/manifests/api.yaml
@@ -22,7 +22,6 @@ data:
[clickhouse]
url = "clickhouse://default:password@clickhouse:9000?secure=false&skip_verify=true"
analytics_url = "http://clickhouse:8123/default"
- proxy_token = "chproxy-test-token-123"
[gossip]
lan_port = 7946
diff --git a/internal/services/keys/BUILD.bazel b/internal/services/keys/BUILD.bazel
index be47012de3..9e9e7dde65 100644
--- a/internal/services/keys/BUILD.bazel
+++ b/internal/services/keys/BUILD.bazel
@@ -18,6 +18,7 @@ go_library(
visibility = ["//:__subpackages__"],
deps = [
"//internal/services/caches",
+ "//internal/services/keys/metrics",
"//internal/services/ratelimit",
"//internal/services/usagelimiter",
"//pkg/assert",
@@ -31,7 +32,6 @@ go_library(
"//pkg/hash",
"//pkg/logger",
"//pkg/otel/tracing",
- "//pkg/prometheus/metrics",
"//pkg/ptr",
"//pkg/rbac",
"//pkg/zen",
diff --git a/internal/services/keys/metrics/BUILD.bazel b/internal/services/keys/metrics/BUILD.bazel
new file mode 100644
index 0000000000..f9f683c4be
--- /dev/null
+++ b/internal/services/keys/metrics/BUILD.bazel
@@ -0,0 +1,12 @@
+load("@rules_go//go:def.bzl", "go_library")
+
+go_library(
+ name = "metrics",
+ srcs = ["prometheus.go"],
+ importpath = "github.com/unkeyed/unkey/internal/services/keys/metrics",
+ visibility = ["//:__subpackages__"],
+ deps = [
+ "@com_github_prometheus_client_golang//prometheus",
+ "@com_github_prometheus_client_golang//prometheus/promauto",
+ ],
+)
diff --git a/pkg/prometheus/metrics/keys.go b/internal/services/keys/metrics/prometheus.go
similarity index 77%
rename from pkg/prometheus/metrics/keys.go
rename to internal/services/keys/metrics/prometheus.go
index bb846c43fb..aeda35ceef 100644
--- a/pkg/prometheus/metrics/keys.go
+++ b/internal/services/keys/metrics/prometheus.go
@@ -19,11 +19,10 @@ var (
// metrics.KeyVerificationsTotal.WithLabelValues("root_key", "VALID").Inc()
KeyVerificationsTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "key",
- Name: "verifications_total",
- Help: "Total number of Key verifications processed.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "key",
+ Name: "verifications_total",
+ Help: "Total number of Key verifications processed.",
},
[]string{"type", "code"},
)
@@ -37,11 +36,10 @@ var (
// metrics.KeyVerificationErrorsTotal.WithLabelValues("root_key").Inc()
KeyVerificationErrorsTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "key",
- Name: "verification_errors_total",
- Help: "Total number of key verification errors",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "key",
+ Name: "verification_errors_total",
+ Help: "Total number of key verification errors",
},
[]string{"type"},
)
diff --git a/internal/services/keys/verifier.go b/internal/services/keys/verifier.go
index ebf6591ae1..cac2fec017 100644
--- a/internal/services/keys/verifier.go
+++ b/internal/services/keys/verifier.go
@@ -4,12 +4,12 @@ import (
"context"
"time"
+ "github.com/unkeyed/unkey/internal/services/keys/metrics"
"github.com/unkeyed/unkey/internal/services/ratelimit"
"github.com/unkeyed/unkey/internal/services/usagelimiter"
"github.com/unkeyed/unkey/pkg/clickhouse"
"github.com/unkeyed/unkey/pkg/clickhouse/schema"
"github.com/unkeyed/unkey/pkg/db"
- "github.com/unkeyed/unkey/pkg/prometheus/metrics"
"github.com/unkeyed/unkey/pkg/rbac"
"github.com/unkeyed/unkey/pkg/zen"
)
diff --git a/internal/services/ratelimit/BUILD.bazel b/internal/services/ratelimit/BUILD.bazel
index 5e057c57e9..ce14237833 100644
--- a/internal/services/ratelimit/BUILD.bazel
+++ b/internal/services/ratelimit/BUILD.bazel
@@ -16,6 +16,7 @@ go_library(
importpath = "github.com/unkeyed/unkey/internal/services/ratelimit",
visibility = ["//:__subpackages__"],
deps = [
+ "//internal/services/ratelimit/metrics",
"//pkg/assert",
"//pkg/buffer",
"//pkg/circuitbreaker",
@@ -23,7 +24,6 @@ go_library(
"//pkg/counter",
"//pkg/logger",
"//pkg/otel/tracing",
- "//pkg/prometheus/metrics",
"//pkg/repeat",
"@io_opentelemetry_go_otel//attribute",
],
diff --git a/internal/services/ratelimit/bucket.go b/internal/services/ratelimit/bucket.go
index cfd0a6c265..0ee14d50e6 100644
--- a/internal/services/ratelimit/bucket.go
+++ b/internal/services/ratelimit/bucket.go
@@ -5,7 +5,7 @@ import (
"sync"
"time"
- "github.com/unkeyed/unkey/pkg/prometheus/metrics"
+ "github.com/unkeyed/unkey/internal/services/ratelimit/metrics"
)
// bucket maintains rate limit state for a specific identifier+limit+duration combination.
diff --git a/internal/services/ratelimit/janitor.go b/internal/services/ratelimit/janitor.go
index e51da5ab11..dbc53633d7 100644
--- a/internal/services/ratelimit/janitor.go
+++ b/internal/services/ratelimit/janitor.go
@@ -3,7 +3,7 @@ package ratelimit
import (
"time"
- "github.com/unkeyed/unkey/pkg/prometheus/metrics"
+ "github.com/unkeyed/unkey/internal/services/ratelimit/metrics"
"github.com/unkeyed/unkey/pkg/repeat"
)
diff --git a/internal/services/ratelimit/metrics/BUILD.bazel b/internal/services/ratelimit/metrics/BUILD.bazel
new file mode 100644
index 0000000000..214ac1368d
--- /dev/null
+++ b/internal/services/ratelimit/metrics/BUILD.bazel
@@ -0,0 +1,12 @@
+load("@rules_go//go:def.bzl", "go_library")
+
+go_library(
+ name = "metrics",
+ srcs = ["prometheus.go"],
+ importpath = "github.com/unkeyed/unkey/internal/services/ratelimit/metrics",
+ visibility = ["//:__subpackages__"],
+ deps = [
+ "@com_github_prometheus_client_golang//prometheus",
+ "@com_github_prometheus_client_golang//prometheus/promauto",
+ ],
+)
diff --git a/pkg/prometheus/metrics/ratelimit.go b/internal/services/ratelimit/metrics/prometheus.go
similarity index 67%
rename from pkg/prometheus/metrics/ratelimit.go
rename to internal/services/ratelimit/metrics/prometheus.go
index 767f051c99..1db4c45fbb 100644
--- a/pkg/prometheus/metrics/ratelimit.go
+++ b/internal/services/ratelimit/metrics/prometheus.go
@@ -10,6 +10,27 @@ import (
"github.com/prometheus/client_golang/prometheus/promauto"
)
+// Standard histogram buckets for latency metrics in seconds
+var latencyBuckets = []float64{
+ 0.001, // 1ms
+ 0.002, // 2ms
+ 0.005, // 5ms
+ 0.01, // 10ms
+ 0.02, // 20ms
+ 0.05, // 50ms
+ 0.1, // 100ms
+ 0.2, // 200ms
+ 0.3, // 300ms
+ 0.4, // 400ms
+ 0.5, // 500ms
+ 0.75, // 750ms
+ 1.0, // 1s
+ 2.0, // 2s
+ 3.0, // 3s
+ 5.0, // 5s
+ 10.0, // 10s
+}
+
var (
// RatelimitBuckets tracks how many rate-limit buckets are currently active.
@@ -19,11 +40,10 @@ var (
// metrics.RatelimitBuckets.Set(float64(activeBuckets))
RatelimitBuckets = promauto.NewGauge(
prometheus.GaugeOpts{
- Namespace: "unkey",
- Subsystem: "ratelimit",
- Name: "buckets",
- Help: "Current number of active rate-limit buckets.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "ratelimit",
+ Name: "buckets",
+ Help: "Current number of active rate-limit buckets.",
},
)
@@ -34,11 +54,10 @@ var (
// metrics.RatelimitWindows.Set(float64(activeWindows))
RatelimitWindows = promauto.NewGauge(
prometheus.GaugeOpts{
- Namespace: "unkey",
- Subsystem: "ratelimit",
- Name: "windows",
- Help: "Current number of rate-limit windows.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "ratelimit",
+ Name: "windows",
+ Help: "Current number of rate-limit windows.",
},
)
@@ -49,11 +68,10 @@ var (
// metrics.RatelimitBucketsCreated.Inc()
RatelimitBucketsCreated = promauto.NewCounter(
prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "ratelimit",
- Name: "buckets_created_total",
- Help: "Total number of rate-limit buckets created.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "ratelimit",
+ Name: "buckets_created_total",
+ Help: "Total number of rate-limit buckets created.",
},
)
@@ -64,11 +82,10 @@ var (
// metrics.RatelimitBucketsEvicted.Inc()
RatelimitBucketsEvicted = promauto.NewCounter(
prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "ratelimit",
- Name: "buckets_evicted_total",
- Help: "Total number of rate-limit buckets evicted.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "ratelimit",
+ Name: "buckets_evicted_total",
+ Help: "Total number of rate-limit buckets evicted.",
},
)
@@ -79,11 +96,10 @@ var (
// metrics.RatelimitWindowsCreated.Inc()
RatelimitWindowsCreated = promauto.NewCounter(
prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "ratelimit",
- Name: "windows_created_total",
- Help: "Total number of rate-limit time windows created.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "ratelimit",
+ Name: "windows_created_total",
+ Help: "Total number of rate-limit time windows created.",
},
)
@@ -94,11 +110,10 @@ var (
// metrics.RatelimitWindowsEvicted.Inc()
RatelimitWindowsEvicted = promauto.NewCounter(
prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "ratelimit",
- Name: "windows_evicted_total",
- Help: "Total number of rate-limit time windows evicted.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "ratelimit",
+ Name: "windows_evicted_total",
+ Help: "Total number of rate-limit time windows evicted.",
},
)
@@ -111,11 +126,10 @@ var (
// metrics.RatelimitDecisions.WithLabelValues("origin", "denied").Inc()
RatelimitDecision = promauto.NewCounterVec(
prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "ratelimit",
- Name: "decisions_total",
- Help: "Total number of rate-limit decisions.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "ratelimit",
+ Name: "decisions_total",
+ Help: "Total number of rate-limit decisions.",
},
[]string{"source", "outcome"},
)
@@ -127,11 +141,10 @@ var (
// metrics.RatelimitRefreshFromOrigin.Inc()
RatelimitRefreshFromOrigin = promauto.NewCounter(
prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "ratelimit",
- Name: "refresh_from_origin_total",
- Help: "Total number of refreshes from an origin.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "ratelimit",
+ Name: "refresh_from_origin_total",
+ Help: "Total number of refreshes from an origin.",
},
)
@@ -145,12 +158,11 @@ var (
// defer timer.ObserveDuration()
RatelimitOriginSyncLatency = promauto.NewHistogram(
prometheus.HistogramOpts{
- Namespace: "unkey",
- Subsystem: "ratelimit",
- Name: "origin_sync_latency_seconds",
- Help: "Histogram of origin sync latencies in seconds.",
- Buckets: latencyBuckets,
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "ratelimit",
+ Name: "origin_sync_latency_seconds",
+ Help: "Histogram of origin sync latencies in seconds.",
+ Buckets: latencyBuckets,
},
)
@@ -161,11 +173,10 @@ var (
// metrics.RatelimitRefreshFromOriginErrorsTotal.Inc()
RatelimitRefreshFromOriginErrorsTotal = promauto.NewCounter(
prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "ratelimit",
- Name: "refresh_from_origin_errors_total",
- Help: "Total number of errors when refreshing from an origin.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "ratelimit",
+ Name: "refresh_from_origin_errors_total",
+ Help: "Total number of errors when refreshing from an origin.",
},
)
)
diff --git a/internal/services/ratelimit/replay.go b/internal/services/ratelimit/replay.go
index b4d8b68199..da6ac92cbb 100644
--- a/internal/services/ratelimit/replay.go
+++ b/internal/services/ratelimit/replay.go
@@ -7,7 +7,8 @@ import (
"github.com/unkeyed/unkey/pkg/assert"
"github.com/unkeyed/unkey/pkg/logger"
"github.com/unkeyed/unkey/pkg/otel/tracing"
- "github.com/unkeyed/unkey/pkg/prometheus/metrics"
+
+ "github.com/unkeyed/unkey/internal/services/ratelimit/metrics"
)
// replayRequests processes buffered rate limit events by synchronizing them with
diff --git a/internal/services/ratelimit/service.go b/internal/services/ratelimit/service.go
index bf7d9e83a9..ec5e15957c 100644
--- a/internal/services/ratelimit/service.go
+++ b/internal/services/ratelimit/service.go
@@ -12,7 +12,8 @@ import (
"github.com/unkeyed/unkey/pkg/counter"
"github.com/unkeyed/unkey/pkg/logger"
"github.com/unkeyed/unkey/pkg/otel/tracing"
- "github.com/unkeyed/unkey/pkg/prometheus/metrics"
+
+ "github.com/unkeyed/unkey/internal/services/ratelimit/metrics"
"go.opentelemetry.io/otel/attribute"
)
diff --git a/internal/services/ratelimit/window.go b/internal/services/ratelimit/window.go
index e3aecc4136..45689e1fcf 100644
--- a/internal/services/ratelimit/window.go
+++ b/internal/services/ratelimit/window.go
@@ -3,7 +3,7 @@ package ratelimit
import (
"time"
- "github.com/unkeyed/unkey/pkg/prometheus/metrics"
+ "github.com/unkeyed/unkey/internal/services/ratelimit/metrics"
)
type window struct {
diff --git a/internal/services/usagelimiter/BUILD.bazel b/internal/services/usagelimiter/BUILD.bazel
index 8da6213517..165835b2bd 100644
--- a/internal/services/usagelimiter/BUILD.bazel
+++ b/internal/services/usagelimiter/BUILD.bazel
@@ -12,6 +12,7 @@ go_library(
importpath = "github.com/unkeyed/unkey/internal/services/usagelimiter",
visibility = ["//:__subpackages__"],
deps = [
+ "//internal/services/usagelimiter/metrics",
"//pkg/assert",
"//pkg/buffer",
"//pkg/circuitbreaker",
@@ -19,7 +20,6 @@ go_library(
"//pkg/db",
"//pkg/logger",
"//pkg/otel/tracing",
- "//pkg/prometheus/metrics",
"//pkg/repeat",
],
)
diff --git a/internal/services/usagelimiter/limit.go b/internal/services/usagelimiter/limit.go
index 94a0368b30..22c3feab33 100644
--- a/internal/services/usagelimiter/limit.go
+++ b/internal/services/usagelimiter/limit.go
@@ -4,9 +4,9 @@ import (
"context"
"database/sql"
+ "github.com/unkeyed/unkey/internal/services/usagelimiter/metrics"
"github.com/unkeyed/unkey/pkg/db"
"github.com/unkeyed/unkey/pkg/otel/tracing"
- "github.com/unkeyed/unkey/pkg/prometheus/metrics"
)
func (s *service) Limit(ctx context.Context, req UsageRequest) (UsageResponse, error) {
diff --git a/internal/services/usagelimiter/metrics/BUILD.bazel b/internal/services/usagelimiter/metrics/BUILD.bazel
new file mode 100644
index 0000000000..265f302ad7
--- /dev/null
+++ b/internal/services/usagelimiter/metrics/BUILD.bazel
@@ -0,0 +1,12 @@
+load("@rules_go//go:def.bzl", "go_library")
+
+go_library(
+ name = "metrics",
+ srcs = ["prometheus.go"],
+ importpath = "github.com/unkeyed/unkey/internal/services/usagelimiter/metrics",
+ visibility = ["//:__subpackages__"],
+ deps = [
+ "@com_github_prometheus_client_golang//prometheus",
+ "@com_github_prometheus_client_golang//prometheus/promauto",
+ ],
+)
diff --git a/pkg/prometheus/metrics/usagelimiter.go b/internal/services/usagelimiter/metrics/prometheus.go
similarity index 66%
rename from pkg/prometheus/metrics/usagelimiter.go
rename to internal/services/usagelimiter/metrics/prometheus.go
index a396453803..0a4150dc9f 100644
--- a/pkg/prometheus/metrics/usagelimiter.go
+++ b/internal/services/usagelimiter/metrics/prometheus.go
@@ -10,6 +10,27 @@ import (
"github.com/prometheus/client_golang/prometheus/promauto"
)
+// Standard histogram buckets for latency metrics in seconds
+var latencyBuckets = []float64{
+ 0.001, // 1ms
+ 0.002, // 2ms
+ 0.005, // 5ms
+ 0.01, // 10ms
+ 0.02, // 20ms
+ 0.05, // 50ms
+ 0.1, // 100ms
+ 0.2, // 200ms
+ 0.3, // 300ms
+ 0.4, // 400ms
+ 0.5, // 500ms
+ 0.75, // 750ms
+ 1.0, // 1s
+ 2.0, // 2s
+ 3.0, // 3s
+ 5.0, // 5s
+ 10.0, // 10s
+}
+
var (
// UsagelimiterDecisions counts usage limiter decisions by outcome (allowed/denied) and source (redis/db)
// This counter helps understand the distribution of decisions and fallback patterns.
@@ -19,11 +40,10 @@ var (
// metrics.UsagelimiterDecisions.WithLabelValues("db", "denied").Inc()
UsagelimiterDecisions = promauto.NewCounterVec(
prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "usagelimiter",
- Name: "decisions_total",
- Help: "Total number of usage limiter decisions.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "usagelimiter",
+ Name: "decisions_total",
+ Help: "Total number of usage limiter decisions.",
},
[]string{"source", "outcome"},
)
@@ -36,11 +56,10 @@ var (
// metrics.UsagelimiterReplayOperations.WithLabelValues("error").Inc()
UsagelimiterReplayOperations = promauto.NewCounterVec(
prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "usagelimiter",
- Name: "replay_operations_total",
- Help: "Total number of credit replay operations to database.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "usagelimiter",
+ Name: "replay_operations_total",
+ Help: "Total number of credit replay operations to database.",
},
[]string{"status"},
)
@@ -54,12 +73,11 @@ var (
// }(time.Now())
UsagelimiterReplayLatency = promauto.NewHistogram(
prometheus.HistogramOpts{
- Namespace: "unkey",
- Subsystem: "usagelimiter",
- Name: "replay_latency_seconds",
- Help: "Histogram of replay operation latencies in seconds.",
- Buckets: latencyBuckets,
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "usagelimiter",
+ Name: "replay_latency_seconds",
+ Help: "Histogram of replay operation latencies in seconds.",
+ Buckets: latencyBuckets,
},
)
)
diff --git a/internal/services/usagelimiter/redis.go b/internal/services/usagelimiter/redis.go
index 5479a928ce..cdb7b3f8ee 100644
--- a/internal/services/usagelimiter/redis.go
+++ b/internal/services/usagelimiter/redis.go
@@ -6,6 +6,7 @@ import (
"fmt"
"time"
+ "github.com/unkeyed/unkey/internal/services/usagelimiter/metrics"
"github.com/unkeyed/unkey/pkg/assert"
"github.com/unkeyed/unkey/pkg/buffer"
"github.com/unkeyed/unkey/pkg/circuitbreaker"
@@ -13,7 +14,6 @@ import (
"github.com/unkeyed/unkey/pkg/db"
"github.com/unkeyed/unkey/pkg/logger"
"github.com/unkeyed/unkey/pkg/otel/tracing"
- "github.com/unkeyed/unkey/pkg/prometheus/metrics"
"github.com/unkeyed/unkey/pkg/repeat"
)
diff --git a/pkg/batch/BUILD.bazel b/pkg/batch/BUILD.bazel
index a2e8d37fcd..196d4370d4 100644
--- a/pkg/batch/BUILD.bazel
+++ b/pkg/batch/BUILD.bazel
@@ -9,7 +9,7 @@ go_library(
importpath = "github.com/unkeyed/unkey/pkg/batch",
visibility = ["//visibility:public"],
deps = [
+ "//pkg/batch/metrics",
"//pkg/buffer",
- "//pkg/prometheus/metrics",
],
)
diff --git a/pkg/batch/metrics/BUILD.bazel b/pkg/batch/metrics/BUILD.bazel
new file mode 100644
index 0000000000..8ef8478eb2
--- /dev/null
+++ b/pkg/batch/metrics/BUILD.bazel
@@ -0,0 +1,12 @@
+load("@rules_go//go:def.bzl", "go_library")
+
+go_library(
+ name = "metrics",
+ srcs = ["prometheus.go"],
+ importpath = "github.com/unkeyed/unkey/pkg/batch/metrics",
+ visibility = ["//visibility:public"],
+ deps = [
+ "@com_github_prometheus_client_golang//prometheus",
+ "@com_github_prometheus_client_golang//prometheus/promauto",
+ ],
+)
diff --git a/pkg/prometheus/metrics/batch.go b/pkg/batch/metrics/prometheus.go
similarity index 80%
rename from pkg/prometheus/metrics/batch.go
rename to pkg/batch/metrics/prometheus.go
index 7c34610cb5..7395c3e7cb 100644
--- a/pkg/prometheus/metrics/batch.go
+++ b/pkg/batch/metrics/prometheus.go
@@ -30,12 +30,11 @@ var (
// metrics.BatchSizeDistribution.WithLabelValues("database_writes", "size_limit").Observe(float64(len(batch)))
BatchSizeDistribution = promauto.NewHistogramVec(
prometheus.HistogramOpts{
- Namespace: "unkey",
- Subsystem: "batch",
- Name: "size_distribution",
- Help: "Distribution of batch sizes when flushed",
- Buckets: batchSizeBuckets,
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "batch",
+ Name: "size_distribution",
+ Help: "Distribution of batch sizes when flushed",
+ Buckets: batchSizeBuckets,
},
[]string{"name", "trigger"},
)
@@ -58,11 +57,10 @@ var (
// metrics.BatchOperationsTotal.WithLabelValues("log_entries", "time_interval", "error").Inc()
BatchOperationsTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "batch",
- Name: "operations_total",
- Help: "Total number of batch flush operations processed",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "batch",
+ Name: "operations_total",
+ Help: "Total number of batch flush operations processed",
},
[]string{"name", "trigger", "status"},
)
@@ -76,11 +74,10 @@ var (
// metrics.BatchItemsProcessedTotal.WithLabelValues("database_writes").Add(float64(len(batch)))
BatchItemsProcessedTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "batch",
- Name: "items_processed_total",
- Help: "Total number of items processed through batches",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "batch",
+ Name: "items_processed_total",
+ Help: "Total number of items processed through batches",
},
[]string{"name"},
)
@@ -93,11 +90,10 @@ var (
// metrics.BatchItemsProcessedErrorsTotal.WithLabelValues("database_writes").Add(float64(errorCount))
BatchItemsProcessedErrorsTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "batch",
- Name: "items_processed_errors_total",
- Help: "Total number of items processed through batches that resulted in an error",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "batch",
+ Name: "items_processed_errors_total",
+ Help: "Total number of items processed through batches that resulted in an error",
},
[]string{"name"},
)
diff --git a/pkg/batch/process.go b/pkg/batch/process.go
index 1621ee7e0d..7030bb8a01 100644
--- a/pkg/batch/process.go
+++ b/pkg/batch/process.go
@@ -4,8 +4,8 @@ import (
"context"
"time"
+ "github.com/unkeyed/unkey/pkg/batch/metrics"
"github.com/unkeyed/unkey/pkg/buffer"
- "github.com/unkeyed/unkey/pkg/prometheus/metrics"
)
// BatchProcessor provides a more configurable batching implementation compared to
diff --git a/pkg/buffer/BUILD.bazel b/pkg/buffer/BUILD.bazel
index 4c109e6fce..5eeaa11aaa 100644
--- a/pkg/buffer/BUILD.bazel
+++ b/pkg/buffer/BUILD.bazel
@@ -9,7 +9,7 @@ go_library(
importpath = "github.com/unkeyed/unkey/pkg/buffer",
visibility = ["//visibility:public"],
deps = [
- "//pkg/prometheus/metrics",
+ "//pkg/buffer/metrics",
"//pkg/repeat",
],
)
diff --git a/pkg/buffer/buffer.go b/pkg/buffer/buffer.go
index 0b1f17289d..addc38d3c9 100644
--- a/pkg/buffer/buffer.go
+++ b/pkg/buffer/buffer.go
@@ -5,7 +5,7 @@ import (
"sync"
"time"
- "github.com/unkeyed/unkey/pkg/prometheus/metrics"
+ "github.com/unkeyed/unkey/pkg/buffer/metrics"
"github.com/unkeyed/unkey/pkg/repeat"
)
diff --git a/pkg/buffer/metrics/BUILD.bazel b/pkg/buffer/metrics/BUILD.bazel
new file mode 100644
index 0000000000..ff4f7b1dbf
--- /dev/null
+++ b/pkg/buffer/metrics/BUILD.bazel
@@ -0,0 +1,12 @@
+load("@rules_go//go:def.bzl", "go_library")
+
+go_library(
+ name = "metrics",
+ srcs = ["prometheus.go"],
+ importpath = "github.com/unkeyed/unkey/pkg/buffer/metrics",
+ visibility = ["//visibility:public"],
+ deps = [
+ "@com_github_prometheus_client_golang//prometheus",
+ "@com_github_prometheus_client_golang//prometheus/promauto",
+ ],
+)
diff --git a/pkg/prometheus/metrics/buffer.go b/pkg/buffer/metrics/prometheus.go
similarity index 73%
rename from pkg/prometheus/metrics/buffer.go
rename to pkg/buffer/metrics/prometheus.go
index 9b238664a3..3741b9f190 100644
--- a/pkg/prometheus/metrics/buffer.go
+++ b/pkg/buffer/metrics/prometheus.go
@@ -23,11 +23,10 @@ var (
// metrics.BufferInserts.WithLabelValues(b.String(), "buffered").Inc()
BufferState = promauto.NewCounterVec(
prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "buffer",
- Name: "state_total",
- Help: "Number of buffer inserts by name and state",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "buffer",
+ Name: "state_total",
+ Help: "Number of buffer inserts by name and state",
},
[]string{"name", "state"},
)
@@ -39,11 +38,10 @@ var (
// metrics.BufferSize.WithLabelValues(b.String(), "true").Set(float64(capacity)/float64(maxCapacity))
BufferSize = promauto.NewGaugeVec(
prometheus.GaugeOpts{
- Namespace: "unkey",
- Subsystem: "buffer",
- Name: "size_percentage",
- Help: "Percentage of buffered fill capacity between 0.0 and 1.0",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "buffer",
+ Name: "size_percentage",
+ Help: "Percentage of buffered fill capacity between 0.0 and 1.0",
},
[]string{"name", "drop"},
)
@@ -55,11 +53,10 @@ var (
// metrics.BufferErrorsTotal.WithLabelValues("batch_writer", "write_failed").Inc()
BufferErrorsTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "buffer",
- Name: "errors_total",
- Help: "Total number of buffer operation errors by name and state.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "buffer",
+ Name: "errors_total",
+ Help: "Total number of buffer operation errors by name and state.",
},
[]string{"name", "state"},
)
diff --git a/pkg/cache/BUILD.bazel b/pkg/cache/BUILD.bazel
index 4e9cecaac8..9b645a8363 100644
--- a/pkg/cache/BUILD.bazel
+++ b/pkg/cache/BUILD.bazel
@@ -15,11 +15,11 @@ go_library(
visibility = ["//visibility:public"],
deps = [
"//pkg/assert",
+ "//pkg/cache/metrics",
"//pkg/clock",
"//pkg/db",
"//pkg/fault",
"//pkg/logger",
- "//pkg/prometheus/metrics",
"//pkg/repeat",
"//pkg/timing",
"@com_github_maypok86_otter//:otter",
diff --git a/pkg/cache/cache.go b/pkg/cache/cache.go
index a8b692ad57..cae5195e06 100644
--- a/pkg/cache/cache.go
+++ b/pkg/cache/cache.go
@@ -10,11 +10,11 @@ import (
"github.com/maypok86/otter"
"github.com/unkeyed/unkey/pkg/assert"
+ "github.com/unkeyed/unkey/pkg/cache/metrics"
"github.com/unkeyed/unkey/pkg/clock"
"github.com/unkeyed/unkey/pkg/db"
"github.com/unkeyed/unkey/pkg/fault"
"github.com/unkeyed/unkey/pkg/logger"
- "github.com/unkeyed/unkey/pkg/prometheus/metrics"
"github.com/unkeyed/unkey/pkg/repeat"
"github.com/unkeyed/unkey/pkg/timing"
)
diff --git a/pkg/cache/metrics/BUILD.bazel b/pkg/cache/metrics/BUILD.bazel
new file mode 100644
index 0000000000..bf2387bee2
--- /dev/null
+++ b/pkg/cache/metrics/BUILD.bazel
@@ -0,0 +1,12 @@
+load("@rules_go//go:def.bzl", "go_library")
+
+go_library(
+ name = "metrics",
+ srcs = ["prometheus.go"],
+ importpath = "github.com/unkeyed/unkey/pkg/cache/metrics",
+ visibility = ["//visibility:public"],
+ deps = [
+ "@com_github_prometheus_client_golang//prometheus",
+ "@com_github_prometheus_client_golang//prometheus/promauto",
+ ],
+)
diff --git a/pkg/prometheus/metrics/cache.go b/pkg/cache/metrics/prometheus.go
similarity index 66%
rename from pkg/prometheus/metrics/cache.go
rename to pkg/cache/metrics/prometheus.go
index 09fa4abefa..4149d7b221 100644
--- a/pkg/prometheus/metrics/cache.go
+++ b/pkg/cache/metrics/prometheus.go
@@ -1,8 +1,3 @@
-/*
-Package metrics provides Prometheus metric collectors for monitoring application performance.
-
-This file contains cache-related metrics for tracking cache efficiency, performance, and resource usage.
-*/
package metrics
import (
@@ -19,11 +14,10 @@ var (
// metrics.CacheHits.WithLabelValues("user_profile")
CacheReads = promauto.NewCounterVec(
prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "cache",
- Name: "reads_total",
- Help: "Number of cache reads by resource type and hit status.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "cache",
+ Name: "reads_total",
+ Help: "Number of cache reads by resource type and hit status.",
},
[]string{"resource", "hit"},
)
@@ -36,11 +30,10 @@ var (
// metrics.CacheWrites.WithLabelValues("user_profile").Set(float64(writeCount))
CacheWrites = promauto.NewGaugeVec(
prometheus.GaugeOpts{
- Namespace: "unkey",
- Subsystem: "cache",
- Name: "writes",
- Help: "Number of cache writes by resource type.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "cache",
+ Name: "writes",
+ Help: "Number of cache writes by resource type.",
},
[]string{"resource"},
)
@@ -54,11 +47,10 @@ var (
// metrics.CacheDeleted.WithLabelValues("user_profile", "capacity").Set(float64(evictionCount))
CacheDeleted = promauto.NewCounterVec(
prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "cache",
- Name: "deleted_total",
- Help: "Number of cache entries deleted by resource type and reason.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "cache",
+ Name: "deleted_total",
+ Help: "Number of cache entries deleted by resource type and reason.",
},
[]string{"resource", "reason"},
)
@@ -70,11 +62,10 @@ var (
// metrics.CacheSize.WithLabelValues("user_profile").Set(float64(cacheSize))
CacheSize = promauto.NewGaugeVec(
prometheus.GaugeOpts{
- Namespace: "unkey",
- Subsystem: "cache",
- Name: "size",
- Help: "Current number of entries in the cache by resource type.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "cache",
+ Name: "size",
+ Help: "Current number of entries in the cache by resource type.",
},
[]string{"resource"},
)
@@ -86,11 +77,10 @@ var (
// metrics.CacheCapacity.WithLabelValues("user_profile").Set(float64(cacheCapacity))
CacheCapacity = promauto.NewGaugeVec(
prometheus.GaugeOpts{
- Namespace: "unkey",
- Subsystem: "cache",
- Name: "capacity",
- Help: "Maximum capacity of the cache by resource type.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "cache",
+ Name: "capacity",
+ Help: "Maximum capacity of the cache by resource type.",
},
[]string{"resource"},
)
@@ -102,11 +92,10 @@ var (
// metrics.CacheRevalidations.WithLabelValues("user_profile").Inc()
CacheRevalidations = promauto.NewCounterVec(
prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "cache",
- Name: "revalidations_total",
- Help: "Total number of cache revalidations by resource type.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "cache",
+ Name: "revalidations_total",
+ Help: "Total number of cache revalidations by resource type.",
},
[]string{"resource"},
)
@@ -118,11 +107,10 @@ var (
// metrics.CacheReadsErrorsTotal.WithLabelValues("user_profile").Inc()
CacheReadsErrorsTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "cache",
- Name: "reads_errors_total",
- Help: "Total number of cache read errors by resource type.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "cache",
+ Name: "reads_errors_total",
+ Help: "Total number of cache read errors by resource type.",
},
[]string{"resource"},
)
@@ -134,11 +122,10 @@ var (
// metrics.CacheRevalidationsErrorsTotal.WithLabelValues("user_profile").Inc()
CacheRevalidationsErrorsTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "cache",
- Name: "revalidations_errors_total",
- Help: "Total number of cache revalidation errors by resource type.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "cache",
+ Name: "revalidations_errors_total",
+ Help: "Total number of cache revalidation errors by resource type.",
},
[]string{"resource"},
)
diff --git a/pkg/circuitbreaker/BUILD.bazel b/pkg/circuitbreaker/BUILD.bazel
index e353995c39..93007efbb2 100644
--- a/pkg/circuitbreaker/BUILD.bazel
+++ b/pkg/circuitbreaker/BUILD.bazel
@@ -11,9 +11,9 @@ go_library(
importpath = "github.com/unkeyed/unkey/pkg/circuitbreaker",
visibility = ["//visibility:public"],
deps = [
+ "//pkg/circuitbreaker/metrics",
"//pkg/clock",
"//pkg/logger",
- "//pkg/prometheus/metrics",
],
)
diff --git a/pkg/circuitbreaker/lib.go b/pkg/circuitbreaker/lib.go
index c6eed00f22..034f7d9f1b 100644
--- a/pkg/circuitbreaker/lib.go
+++ b/pkg/circuitbreaker/lib.go
@@ -5,9 +5,9 @@ import (
"sync"
"time"
+ "github.com/unkeyed/unkey/pkg/circuitbreaker/metrics"
"github.com/unkeyed/unkey/pkg/clock"
"github.com/unkeyed/unkey/pkg/logger"
- "github.com/unkeyed/unkey/pkg/prometheus/metrics"
)
// CB is the concrete implementation of [CircuitBreaker]. It tracks request
diff --git a/pkg/circuitbreaker/metrics/BUILD.bazel b/pkg/circuitbreaker/metrics/BUILD.bazel
new file mode 100644
index 0000000000..95d0162d49
--- /dev/null
+++ b/pkg/circuitbreaker/metrics/BUILD.bazel
@@ -0,0 +1,12 @@
+load("@rules_go//go:def.bzl", "go_library")
+
+go_library(
+ name = "metrics",
+ srcs = ["prometheus.go"],
+ importpath = "github.com/unkeyed/unkey/pkg/circuitbreaker/metrics",
+ visibility = ["//visibility:public"],
+ deps = [
+ "@com_github_prometheus_client_golang//prometheus",
+ "@com_github_prometheus_client_golang//prometheus/promauto",
+ ],
+)
diff --git a/pkg/prometheus/metrics/circuitbreaker.go b/pkg/circuitbreaker/metrics/prometheus.go
similarity index 69%
rename from pkg/prometheus/metrics/circuitbreaker.go
rename to pkg/circuitbreaker/metrics/prometheus.go
index 798270809b..f4268a2be4 100644
--- a/pkg/prometheus/metrics/circuitbreaker.go
+++ b/pkg/circuitbreaker/metrics/prometheus.go
@@ -12,11 +12,10 @@ var (
// Example usage:
// metrics.CircuitBreakerRequests.WithLabelValues("my_circuit_breaker", "open").Inc()
CircuitBreakerRequests = promauto.NewCounterVec(prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "circuitbreaker",
- Name: "requests_total",
- Help: "Tracks the number of requests made to the circuitbreaker by state.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "circuitbreaker",
+ Name: "requests_total",
+ Help: "Tracks the number of requests made to the circuitbreaker by state.",
}, []string{"service", "action"})
// CircuitBreakerErrorsTotal tracks the total number of circuit breaker errors,
@@ -25,10 +24,9 @@ var (
// Example usage:
// metrics.CircuitBreakerErrorsTotal.WithLabelValues("database", "timeout").Inc()
CircuitBreakerErrorsTotal = promauto.NewCounterVec(prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "circuitbreaker",
- Name: "errors_total",
- Help: "Total number of circuit breaker errors by service and action.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "circuitbreaker",
+ Name: "errors_total",
+ Help: "Total number of circuit breaker errors by service and action.",
}, []string{"service", "action"})
)
diff --git a/pkg/db/BUILD.bazel b/pkg/db/BUILD.bazel
index 7ba63cb994..f19f11ce6b 100644
--- a/pkg/db/BUILD.bazel
+++ b/pkg/db/BUILD.bazel
@@ -296,11 +296,11 @@ go_library(
deps = [
"//pkg/assert",
"//pkg/codes",
+ "//pkg/db/metrics",
"//pkg/db/types",
"//pkg/fault",
"//pkg/logger",
"//pkg/otel/tracing",
- "//pkg/prometheus/metrics",
"//pkg/retry",
"@com_github_go_sql_driver_mysql//:mysql",
"@io_opentelemetry_go_otel//attribute",
diff --git a/pkg/db/metrics/BUILD.bazel b/pkg/db/metrics/BUILD.bazel
new file mode 100644
index 0000000000..2e27a2ba29
--- /dev/null
+++ b/pkg/db/metrics/BUILD.bazel
@@ -0,0 +1,12 @@
+load("@rules_go//go:def.bzl", "go_library")
+
+go_library(
+ name = "metrics",
+ srcs = ["prometheus.go"],
+ importpath = "github.com/unkeyed/unkey/pkg/db/metrics",
+ visibility = ["//visibility:public"],
+ deps = [
+ "@com_github_prometheus_client_golang//prometheus",
+ "@com_github_prometheus_client_golang//prometheus/promauto",
+ ],
+)
diff --git a/pkg/prometheus/metrics/database.go b/pkg/db/metrics/prometheus.go
similarity index 70%
rename from pkg/prometheus/metrics/database.go
rename to pkg/db/metrics/prometheus.go
index 72e8f572bc..d609c0d066 100644
--- a/pkg/prometheus/metrics/database.go
+++ b/pkg/db/metrics/prometheus.go
@@ -11,6 +11,27 @@ import (
"github.com/prometheus/client_golang/prometheus/promauto"
)
+// Standard histogram buckets for latency metrics in seconds
+var latencyBuckets = []float64{
+ 0.001, // 1ms
+ 0.002, // 2ms
+ 0.005, // 5ms
+ 0.01, // 10ms
+ 0.02, // 20ms
+ 0.05, // 50ms
+ 0.1, // 100ms
+ 0.2, // 200ms
+ 0.3, // 300ms
+ 0.4, // 400ms
+ 0.5, // 500ms
+ 0.75, // 750ms
+ 1.0, // 1s
+ 2.0, // 2s
+ 3.0, // 3s
+ 5.0, // 5s
+ 10.0, // 10s
+}
+
var (
// DatabaseOperationsLatency tracks database operation latencies as a histogram,
// labeled by replica type (rw/ro), operation type, and success status.
@@ -23,12 +44,11 @@ var (
// defer timer.ObserveDuration()
DatabaseOperationsLatency = promauto.NewHistogramVec(
prometheus.HistogramOpts{
- Namespace: "unkey",
- Subsystem: "database",
- Name: "operations_latency_seconds",
- Help: "Histogram of database operation latencies in seconds.",
- Buckets: latencyBuckets,
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "database",
+ Name: "operations_latency_seconds",
+ Help: "Histogram of database operation latencies in seconds.",
+ Buckets: latencyBuckets,
},
[]string{"replica", "operation", "status"},
)
@@ -42,11 +62,10 @@ var (
// metrics.DatabaseOperationTotal.WithLabelValues("ro", "query", "error").Inc()
DatabaseOperationsTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "database",
- Name: "operations_total",
- Help: "Total number of database operations processed.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "database",
+ Name: "operations_total",
+ Help: "Total number of database operations processed.",
},
[]string{"replica", "operation", "status"},
)
@@ -58,10 +77,9 @@ var (
// Example usage:
// metrics.DatabaseOperationsErrorsTotal.WithLabelValues("rw", "exec").Inc()
DatabaseOperationsErrorsTotal = promauto.NewCounterVec(prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "database",
- Name: "operations_errors_total",
- Help: "Total number of database operation errors.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "database",
+ Name: "operations_errors_total",
+ Help: "Total number of database operation errors.",
}, []string{"replica", "operation"})
)
diff --git a/pkg/db/replica.go b/pkg/db/replica.go
index 2ca5dcfaae..0c9ea1181c 100644
--- a/pkg/db/replica.go
+++ b/pkg/db/replica.go
@@ -7,9 +7,9 @@ import (
"database/sql"
"time"
+ "github.com/unkeyed/unkey/pkg/db/metrics"
"github.com/unkeyed/unkey/pkg/logger"
"github.com/unkeyed/unkey/pkg/otel/tracing"
- "github.com/unkeyed/unkey/pkg/prometheus/metrics"
"go.opentelemetry.io/otel/attribute"
)
diff --git a/pkg/db/traced_tx.go b/pkg/db/traced_tx.go
index edfef6d108..36184e1b67 100644
--- a/pkg/db/traced_tx.go
+++ b/pkg/db/traced_tx.go
@@ -5,8 +5,8 @@ import (
"database/sql"
"time"
+ "github.com/unkeyed/unkey/pkg/db/metrics"
"github.com/unkeyed/unkey/pkg/otel/tracing"
- "github.com/unkeyed/unkey/pkg/prometheus/metrics"
"go.opentelemetry.io/otel/attribute"
)
diff --git a/pkg/prometheus/metrics/BUILD.bazel b/pkg/prometheus/metrics/BUILD.bazel
index 9f953ee750..63dde6b231 100644
--- a/pkg/prometheus/metrics/BUILD.bazel
+++ b/pkg/prometheus/metrics/BUILD.bazel
@@ -3,25 +3,12 @@ load("@rules_go//go:def.bzl", "go_library")
go_library(
name = "metrics",
srcs = [
- "batch.go",
- "buffer.go",
- "cache.go",
- "chproxy.go",
- "circuitbreaker.go",
- "database.go",
"doc.go",
- "http.go",
- "keys.go",
- "krane.go",
- "labels.go",
"panic.go",
- "ratelimit.go",
- "usagelimiter.go",
],
importpath = "github.com/unkeyed/unkey/pkg/prometheus/metrics",
visibility = ["//visibility:public"],
deps = [
- "//pkg/version",
"@com_github_prometheus_client_golang//prometheus",
"@com_github_prometheus_client_golang//prometheus/promauto",
],
diff --git a/pkg/prometheus/metrics/chproxy.go b/pkg/prometheus/metrics/chproxy.go
deleted file mode 100644
index 9631d41f55..0000000000
--- a/pkg/prometheus/metrics/chproxy.go
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
-Package metrics provides Prometheus metric collectors for monitoring application performance.
-
-This file contains ClickHouse proxy-related metrics for tracking event ingestion.
-*/
-package metrics
-
-import (
- "github.com/prometheus/client_golang/prometheus"
- "github.com/prometheus/client_golang/prometheus/promauto"
-)
-
-var (
- // ChproxyRequestsTotal tracks the total number of chproxy requests received, labeled by endpoint.
- // Use this counter to monitor ingestion traffic patterns.
- //
- // Example usage:
- // metrics.ChproxyRequestsTotal.WithLabelValues("verifications").Inc()
- ChproxyRequestsTotal = promauto.NewCounterVec(
- prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "chproxy",
- Name: "requests_total",
- Help: "Total number of ClickHouse proxy requests processed.",
- ConstLabels: constLabels,
- },
- []string{"endpoint"},
- )
-
- // ChproxyErrorsTotal tracks the total number of errors encountered by ClickHouse proxy,
- // labeled by endpoint. Use this counter to monitor error rates and identify problematic endpoints.
- //
- // Example usage:
- // metrics.ChproxyErrorsTotal.WithLabelValues("verifications").Inc()
- ChproxyErrorsTotal = promauto.NewCounterVec(
- prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "chproxy",
- Name: "errors_total",
- Help: "Total number of errors encountered by ClickHouse proxy.",
- ConstLabels: constLabels,
- },
- []string{"endpoint"},
- )
-
- // ChproxyRowsTotal tracks the total number of rows/events received in chproxy requests.
- // Use this counter to monitor data volume and ingestion patterns.
- //
- // Example usage:
- // metrics.ChproxyRowsTotal.WithLabelValues("verifications").Add(float64(len(events)))
- ChproxyRowsTotal = promauto.NewCounterVec(
- prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "chproxy",
- Name: "rows_total",
- Help: "Total number of rows/events processed by ClickHouse proxy.",
- ConstLabels: constLabels,
- },
- []string{"endpoint"},
- )
-
- // ChproxyRowsErrorsTotal tracks the total number of row processing errors in ClickHouse proxy,
- // labeled by endpoint. Use this counter to monitor row processing error rates.
- //
- // Example usage:
- // metrics.ChproxyRowsErrorsTotal.WithLabelValues("verifications").Inc()
- ChproxyRowsErrorsTotal = promauto.NewCounterVec(
- prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "chproxy",
- Name: "rows_errors_total",
- Help: "Total number of row processing errors in ClickHouse proxy.",
- ConstLabels: constLabels,
- },
- []string{"endpoint"},
- )
-)
diff --git a/pkg/prometheus/metrics/doc.go b/pkg/prometheus/metrics/doc.go
index 751f3db064..6534d972d0 100644
--- a/pkg/prometheus/metrics/doc.go
+++ b/pkg/prometheus/metrics/doc.go
@@ -1,47 +1,25 @@
// Package metrics provides Prometheus metric collectors for monitoring Unkey services.
//
-// All metrics are registered automatically via [promauto] and use the "unkey" namespace.
-// Metrics include constant labels for region and version to support multi-region deployments.
-//
-// # Metric Organization
-//
-// Metrics are organized by subsystem:
-// - Batch processing: [BatchSizeDistribution], [BatchOperationsTotal], [BatchItemsProcessedTotal]
-// - Buffer management: [BufferState], [BufferSize], [BufferErrorsTotal]
-// - Caching: [CacheReads], [CacheWrites], [CacheSize], [CacheCapacity]
-// - Circuit breaker: [CircuitBreakerRequests], [CircuitBreakerErrorsTotal]
-// - ClickHouse proxy: [ChproxyRequestsTotal], [ChproxyRowsTotal], [ChproxyErrorsTotal]
-// - Database operations: [DatabaseOperationsLatency], [DatabaseOperationsTotal]
-// - HTTP requests: [HTTPRequestLatency], [HTTPRequestTotal], [HTTPRequestBodySize]
-// - Key verification: [KeyVerificationsTotal], [KeyVerificationErrorsTotal]
-// - Krane orchestration: [KraneControlPlaneReconnectsTotal], [KraneReconcileOperationsTotal], [KraneSecretsRequestsTotal]
-// - Rate limiting: [RatelimitDecision], [RatelimitBuckets], [RatelimitWindows]
-// - Usage limiting: [UsagelimiterDecisions], [UsagelimiterReplayOperations]
-// - Internal: [PanicsTotal]
+// This package centralizes metric definitions to ensure consistent naming and labeling
+// across all services. Metrics are registered automatically via [promauto] with the
+// "unkey" namespace, making them available for scraping without manual registration.
//
-// # Usage
+// The package intentionally keeps metric definitions simple and focused. Each metric
+// serves a specific observability purpose and includes labels that enable meaningful
+// filtering and aggregation in dashboards and alerts.
//
-// Import the package and use the metric collectors directly:
+// # Available Metrics
//
-// import "github.com/unkeyed/unkey/pkg/prometheus/metrics"
+// [PanicsTotal] tracks recovered panics from HTTP handlers and background tasks.
+// Use it to monitor application stability and identify code paths that need attention.
//
-// // Increment a counter
-// metrics.HTTPRequestTotal.WithLabelValues("GET", "/v1/keys", "200").Inc()
+// # Usage
//
-// // Observe a latency
-// timer := prometheus.NewTimer(prometheus.ObserverFunc(func(v float64) {
-// metrics.HTTPRequestLatency.WithLabelValues("GET", "/v1/keys", "200").Observe(v)
-// }))
-// defer timer.ObserveDuration()
+// Increment the panic counter when recovering from a panic:
//
-// // Set a gauge
-// metrics.CacheSize.WithLabelValues("api_keys").Set(float64(cacheSize))
+// metrics.PanicsTotal.WithLabelValues("handlerName", "/api/path").Inc()
//
-// # Label Conventions
+// For background tasks, use a descriptive caller name and a synthetic path:
//
-// Common label patterns used across metrics:
-// - "status": Operation outcome, typically "success" or "error"
-// - "resource": Resource type being operated on (e.g., "user_profile", "api_key")
-// - "replica": Database replica type, "rw" for primary, "ro" for read-only
-// - "method", "path", "status": HTTP request attributes
+// metrics.PanicsTotal.WithLabelValues("repeat.Every", "background").Inc()
package metrics
diff --git a/pkg/prometheus/metrics/labels.go b/pkg/prometheus/metrics/labels.go
deleted file mode 100644
index a810219840..0000000000
--- a/pkg/prometheus/metrics/labels.go
+++ /dev/null
@@ -1,18 +0,0 @@
-package metrics
-
-import (
- "os"
-
- "github.com/prometheus/client_golang/prometheus"
- "github.com/unkeyed/unkey/pkg/version"
-)
-
-// We're using const labels as workaround for the prometheus->otel adapter
-// The adapter does not seem to export the resource lavels correctly and because
-// it's temporary, we take the pragmatic approach here.
-//
-// Remove these after we've moved to pull based prometheus metrics.
-var constLabels = prometheus.Labels{
- "region": os.Getenv("UNKEY_REGION"),
- "version": version.Version,
-}
diff --git a/pkg/prometheus/metrics/panic.go b/pkg/prometheus/metrics/panic.go
index 07c6c7950b..1c90f913cb 100644
--- a/pkg/prometheus/metrics/panic.go
+++ b/pkg/prometheus/metrics/panic.go
@@ -1,8 +1,3 @@
-/*
-Package metrics provides Prometheus metric collectors for monitoring application performance.
-
-This file contains a metric for tracking panics across http handlers.
-*/
package metrics
import (
@@ -22,10 +17,9 @@ var (
// Example usage:
// metrics.PanicsTotal.WithLabelValues("handleVerifyKey", "/v1/keys.verifyKey").Inc()
PanicsTotal = promauto.NewCounterVec(prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "internal",
- Name: "panics_total",
- Help: "Total number of panics recovered in HTTP handlers.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "internal",
+ Name: "panics_total",
+ Help: "Total number of panics recovered in HTTP handlers.",
}, []string{"caller", "path"})
)
diff --git a/pkg/zen/BUILD.bazel b/pkg/zen/BUILD.bazel
index 00baaa5594..b797fcad62 100644
--- a/pkg/zen/BUILD.bazel
+++ b/pkg/zen/BUILD.bazel
@@ -35,6 +35,7 @@ go_library(
"//pkg/prometheus/metrics",
"//pkg/tls",
"//pkg/uid",
+ "//pkg/zen/metrics",
"//pkg/zen/validation",
"//svc/api/openapi",
"@io_opentelemetry_go_otel//attribute",
diff --git a/pkg/zen/metrics/BUILD.bazel b/pkg/zen/metrics/BUILD.bazel
new file mode 100644
index 0000000000..26bb6d431b
--- /dev/null
+++ b/pkg/zen/metrics/BUILD.bazel
@@ -0,0 +1,12 @@
+load("@rules_go//go:def.bzl", "go_library")
+
+go_library(
+ name = "metrics",
+ srcs = ["prometheus.go"],
+ importpath = "github.com/unkeyed/unkey/pkg/zen/metrics",
+ visibility = ["//visibility:public"],
+ deps = [
+ "@com_github_prometheus_client_golang//prometheus",
+ "@com_github_prometheus_client_golang//prometheus/promauto",
+ ],
+)
diff --git a/pkg/prometheus/metrics/http.go b/pkg/zen/metrics/prometheus.go
similarity index 78%
rename from pkg/prometheus/metrics/http.go
rename to pkg/zen/metrics/prometheus.go
index 5cc98ab59e..6234f85766 100644
--- a/pkg/prometheus/metrics/http.go
+++ b/pkg/zen/metrics/prometheus.go
@@ -57,12 +57,11 @@ var (
// defer timer.ObserveDuration()
HTTPRequestLatency = promauto.NewHistogramVec(
prometheus.HistogramOpts{
- Namespace: "unkey",
- Subsystem: "http",
- Name: "request_latency_seconds",
- Help: "Histogram of HTTP request latencies in seconds.",
- Buckets: latencyBuckets,
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "http",
+ Name: "request_latency_seconds",
+ Help: "Histogram of HTTP request latencies in seconds.",
+ Buckets: latencyBuckets,
},
[]string{"method", "path", "status"},
)
@@ -74,11 +73,10 @@ var (
// metrics.HTTPRequestTotal.WithLabelValues("GET", "/users", "200").Inc()
HTTPRequestTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "http",
- Name: "requests_total",
- Help: "Total number of HTTP requests processed.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "http",
+ Name: "requests_total",
+ Help: "Total number of HTTP requests processed.",
},
[]string{"method", "path", "status"},
)
@@ -90,11 +88,10 @@ var (
// metrics.HTTPRequestErrorTotal.WithLabelValues("POST", "/api/keys", "500").Inc()
HTTPRequestErrorTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "http",
- Name: "requests_errors_total",
- Help: "Total number of HTTP request errors.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "http",
+ Name: "requests_errors_total",
+ Help: "Total number of HTTP request errors.",
},
[]string{"method", "path", "status"},
)
@@ -107,12 +104,11 @@ var (
// metrics.HTTPRequestBodySize.WithLabelValues("POST", "/api/upload", "200").Observe(float64(bodySize))
HTTPRequestBodySize = promauto.NewHistogramVec(
prometheus.HistogramOpts{
- Namespace: "unkey",
- Subsystem: "http",
- Name: "request_body_size_bytes",
- Help: "Histogram of HTTP request body sizes in bytes.",
- Buckets: bodySizeBuckets,
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "http",
+ Name: "request_body_size_bytes",
+ Help: "Histogram of HTTP request body sizes in bytes.",
+ Buckets: bodySizeBuckets,
},
[]string{"method", "path", "status"},
)
diff --git a/pkg/zen/middleware_observability.go b/pkg/zen/middleware_observability.go
index 159dcc21c9..0d5b9f8f32 100644
--- a/pkg/zen/middleware_observability.go
+++ b/pkg/zen/middleware_observability.go
@@ -6,7 +6,7 @@ import (
"time"
"github.com/unkeyed/unkey/pkg/otel/tracing"
- "github.com/unkeyed/unkey/pkg/prometheus/metrics"
+ "github.com/unkeyed/unkey/pkg/zen/metrics"
"go.opentelemetry.io/otel/attribute"
)
diff --git a/svc/api/config.go b/svc/api/config.go
index d976d5b2a2..80728c895b 100644
--- a/svc/api/config.go
+++ b/svc/api/config.go
@@ -23,10 +23,6 @@ type ClickHouseConfig struct {
// and a [VaultConfig] are configured.
// Example: "http://clickhouse:8123/default"
AnalyticsURL string `toml:"analytics_url"`
-
- // ProxyToken is the bearer token for authenticating against ClickHouse proxy
- // endpoints exposed by the API server itself.
- ProxyToken string `toml:"proxy_token"`
}
// Config holds the complete configuration for the API server. It is designed to
diff --git a/svc/api/integration/harness.go b/svc/api/integration/harness.go
index 4fb4847924..127523d934 100644
--- a/svc/api/integration/harness.go
+++ b/svc/api/integration/harness.go
@@ -150,7 +150,6 @@ func (h *Harness) RunAPI(config ApiConfig) *ApiCluster {
ClickHouse: api.ClickHouseConfig{
URL: clickhouseHostDSN,
AnalyticsURL: "",
- ProxyToken: "",
},
Observability: sharedconfig.Observability{
Tracing: nil,
diff --git a/svc/api/openapi/gen.go b/svc/api/openapi/gen.go
index 5cf5fc68cd..351fb4bb2e 100644
--- a/svc/api/openapi/gen.go
+++ b/svc/api/openapi/gen.go
@@ -95,33 +95,6 @@ type BaseError struct {
Type string `json:"type"`
}
-// ChproxyMetricsRequestBody Array of API request metric events to be processed
-type ChproxyMetricsRequestBody = []map[string]interface{}
-
-// ChproxyMetricsResponseBody defines model for ChproxyMetricsResponseBody.
-type ChproxyMetricsResponseBody struct {
- // Status Processing status
- Status string `json:"status"`
-}
-
-// ChproxyRatelimitsRequestBody Array of ratelimit events to be processed
-type ChproxyRatelimitsRequestBody = []map[string]interface{}
-
-// ChproxyRatelimitsResponseBody defines model for ChproxyRatelimitsResponseBody.
-type ChproxyRatelimitsResponseBody struct {
- // Status Processing status
- Status string `json:"status"`
-}
-
-// ChproxyVerificationsRequestBody Array of key verification events to be processed
-type ChproxyVerificationsRequestBody = []map[string]interface{}
-
-// ChproxyVerificationsResponseBody defines model for ChproxyVerificationsResponseBody.
-type ChproxyVerificationsResponseBody struct {
- // Status Processing status
- Status string `json:"status"`
-}
-
// ConflictErrorResponse Error response when the request conflicts with the current state of the resource. This occurs when:
// - Attempting to create a resource that already exists
// - Modifying a resource that has been changed by another operation
@@ -2351,15 +2324,6 @@ type VerifyKeyRatelimitData struct {
Reset int64 `json:"reset"`
}
-// ChproxyMetricsJSONRequestBody defines body for ChproxyMetrics for application/json ContentType.
-type ChproxyMetricsJSONRequestBody = ChproxyMetricsRequestBody
-
-// ChproxyRatelimitsJSONRequestBody defines body for ChproxyRatelimits for application/json ContentType.
-type ChproxyRatelimitsJSONRequestBody = ChproxyRatelimitsRequestBody
-
-// ChproxyVerificationsJSONRequestBody defines body for ChproxyVerifications for application/json ContentType.
-type ChproxyVerificationsJSONRequestBody = ChproxyVerificationsRequestBody
-
// AnalyticsGetVerificationsJSONRequestBody defines body for AnalyticsGetVerifications for application/json ContentType.
type AnalyticsGetVerificationsJSONRequestBody = V2AnalyticsGetVerificationsRequestBody
diff --git a/svc/api/openapi/openapi-generated.yaml b/svc/api/openapi/openapi-generated.yaml
index 876ba4edf6..94cb52a117 100644
--- a/svc/api/openapi/openapi-generated.yaml
+++ b/svc/api/openapi/openapi-generated.yaml
@@ -21,79 +21,6 @@ components:
scheme: bearer
type: http
schemas:
- ChproxyMetricsRequestBody:
- type: array
- description: Array of API request metric events to be processed
- items:
- type: object
- additionalProperties: true
- ChproxyMetricsResponseBody:
- type: object
- required:
- - status
- properties:
- status:
- type: string
- description: Processing status
- example: "OK"
- BadRequestErrorResponse:
- type: object
- required:
- - meta
- - error
- properties:
- meta:
- $ref: "#/components/schemas/Meta"
- error:
- $ref: "#/components/schemas/BadRequestErrorDetails"
- description: Error response for invalid requests that cannot be processed due to client-side errors. This typically occurs when request parameters are missing, malformed, or fail validation rules. The response includes detailed information about the specific errors in the request, including the location of each error and suggestions for fixing it. When receiving this error, check the 'errors' array in the response for specific validation issues that need to be addressed before retrying.
- InternalServerErrorResponse:
- type: object
- required:
- - meta
- - error
- properties:
- meta:
- $ref: "#/components/schemas/Meta"
- error:
- $ref: "#/components/schemas/BaseError"
- description: |-
- Error response when an unexpected error occurs on the server. This indicates a problem with Unkey's systems rather than your request.
-
- When you encounter this error:
- - The request ID in the response can help Unkey support investigate the issue
- - The error is likely temporary and retrying may succeed
- - If the error persists, contact Unkey support with the request ID
- ChproxyRatelimitsRequestBody:
- type: array
- description: Array of ratelimit events to be processed
- items:
- type: object
- additionalProperties: true
- ChproxyRatelimitsResponseBody:
- type: object
- required:
- - status
- properties:
- status:
- type: string
- description: Processing status
- example: "OK"
- ChproxyVerificationsRequestBody:
- type: array
- description: Array of key verification events to be processed
- items:
- type: object
- additionalProperties: true
- ChproxyVerificationsResponseBody:
- type: object
- required:
- - status
- properties:
- status:
- type: string
- description: Processing status
- example: "OK"
V2AnalyticsGetVerificationsRequestBody:
type: object
required:
@@ -115,6 +42,17 @@ components:
$ref: "#/components/schemas/Meta"
data:
$ref: "#/components/schemas/V2AnalyticsGetVerificationsResponseData"
+ BadRequestErrorResponse:
+ type: object
+ required:
+ - meta
+ - error
+ properties:
+ meta:
+ $ref: "#/components/schemas/Meta"
+ error:
+ $ref: "#/components/schemas/BadRequestErrorDetails"
+ description: Error response for invalid requests that cannot be processed due to client-side errors. This typically occurs when request parameters are missing, malformed, or fail validation rules. The response includes detailed information about the specific errors in the request, including the location of each error and suggestions for fixing it. When receiving this error, check the 'errors' array in the response for specific validation issues that need to be addressed before retrying.
UnauthorizedErrorResponse:
type: object
required:
@@ -202,6 +140,23 @@ components:
- Cache results where appropriate to reduce request frequency
- Check the error detail message for specific quota information
- Contact support if you need a higher quota for your use case
+ InternalServerErrorResponse:
+ type: object
+ required:
+ - meta
+ - error
+ properties:
+ meta:
+ $ref: "#/components/schemas/Meta"
+ error:
+ $ref: "#/components/schemas/BaseError"
+ description: |-
+ Error response when an unexpected error occurs on the server. This indicates a problem with Unkey's systems rather than your request.
+
+ When you encounter this error:
+ - The request ID in the response can help Unkey support investigate the issue
+ - The error is likely temporary and retrying may succeed
+ - If the error persists, contact Unkey support with the request ID
ServiceUnavailableErrorResponse:
type: object
required:
@@ -2176,6 +2131,20 @@ components:
type: string
additionalProperties: false
description: Metadata object included in every API response. This provides context about the request and is essential for debugging, audit trails, and support inquiries. The `requestId` is particularly important when troubleshooting issues with the Unkey support team.
+ V2AnalyticsGetVerificationsResponseData:
+ type: array
+ description: Array of verification rows returned by the query. Fields vary based on the SQL SELECT clause.
+ items:
+ type: object
+ additionalProperties: true
+ description: Dynamic row with fields determined by the query. Can include any combination of fields like time, outcome, count, key_id, etc.
+ example:
+ - outcome: "VALID"
+ count: 1234
+ time: 1696118400000
+ - outcome: "RATE_LIMITED"
+ count: 56
+ time: 1696118400000
BadRequestErrorDetails:
allOf:
- $ref: "#/components/schemas/BaseError"
@@ -2242,20 +2211,6 @@ components:
- message
type: object
description: Individual validation error details. Each validation error provides precise information about what failed, where it failed, and how to fix it, enabling efficient error resolution.
- V2AnalyticsGetVerificationsResponseData:
- type: array
- description: Array of verification rows returned by the query. Fields vary based on the SQL SELECT clause.
- items:
- type: object
- additionalProperties: true
- description: Dynamic row with fields determined by the query. Can include any combination of fields like time, outcome, count, key_id, etc.
- example:
- - outcome: "VALID"
- count: 1234
- time: 1696118400000
- - outcome: "RATE_LIMITED"
- count: 56
- time: 1696118400000
V2ApisCreateApiResponseData:
type: object
properties:
@@ -3751,120 +3706,6 @@ info:
version: 2.0.0
openapi: 3.1.0
paths:
- /_internal/chproxy/metrics:
- post:
- description: |-
- Internal endpoint for batching API request metric events to ClickHouse. This endpoint is used internally by the API to efficiently store request/response data for analytics and should not be used by external clients.
-
- This endpoint bypasses normal authentication and validation as it's intended for internal use only.
- operationId: chproxyMetrics
- requestBody:
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ChproxyMetricsRequestBody'
- required: true
- responses:
- "200":
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ChproxyMetricsResponseBody'
- description: Events successfully queued for processing
- "400":
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/BadRequestErrorResponse'
- description: Invalid request body or malformed events
- "529":
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/InternalServerErrorResponse'
- description: Service overloaded, unable to process events
- security: []
- summary: Internal ClickHouse proxy for API request metrics
- tags:
- - chproxy
- x-excluded: true
- x-speakeasy-ignore: true
- /_internal/chproxy/ratelimits:
- post:
- description: |-
- Internal endpoint for batching ratelimit events to ClickHouse. This endpoint is used internally by the API to efficiently store ratelimit data and should not be used by external clients.
-
- This endpoint bypasses normal authentication and validation as it's intended for internal use only.
- operationId: chproxyRatelimits
- requestBody:
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ChproxyRatelimitsRequestBody'
- required: true
- responses:
- "200":
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ChproxyRatelimitsResponseBody'
- description: Events successfully queued for processing
- "400":
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/BadRequestErrorResponse'
- description: Invalid request body or malformed events
- "529":
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/InternalServerErrorResponse'
- description: Service overloaded, unable to process events
- security: []
- summary: Internal ClickHouse proxy for ratelimit events
- tags:
- - chproxy
- x-excluded: true
- x-speakeasy-ignore: true
- /_internal/chproxy/verifications:
- post:
- description: |-
- Internal endpoint for batching key verification events to ClickHouse. This endpoint is used internally by the API to efficiently store verification data and should not be used by external clients.
-
- This endpoint bypasses normal authentication and validation as it's intended for internal use only. External clients should use the standard key verification endpoints instead.
- operationId: chproxyVerifications
- requestBody:
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ChproxyVerificationsRequestBody'
- required: true
- responses:
- "200":
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ChproxyVerificationsResponseBody'
- description: Events successfully queued for processing
- "400":
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/BadRequestErrorResponse'
- description: Invalid request body or malformed events
- "529":
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/InternalServerErrorResponse'
- description: Service overloaded, unable to process events
- security: []
- summary: Internal ClickHouse proxy for verification events
- tags:
- - chproxy
- x-excluded: true
- x-speakeasy-ignore: true
/v2/analytics.getVerifications:
post:
description: |
diff --git a/svc/api/openapi/openapi-split.yaml b/svc/api/openapi/openapi-split.yaml
index 08d2fe0fa8..82abc4afc2 100644
--- a/svc/api/openapi/openapi-split.yaml
+++ b/svc/api/openapi/openapi-split.yaml
@@ -217,14 +217,6 @@ paths:
/v2/permissions.deletePermission:
$ref: "./spec/paths/v2/permissions/deletePermission/index.yaml"
- # ClickHouse Proxy Endpoints (Internal)
- /_internal/chproxy/verifications:
- $ref: "./spec/paths/chproxy/verifications/index.yaml"
- /_internal/chproxy/metrics:
- $ref: "./spec/paths/chproxy/metrics/index.yaml"
- /_internal/chproxy/ratelimits:
- $ref: "./spec/paths/chproxy/ratelimits/index.yaml"
-
components:
securitySchemes:
rootKey:
diff --git a/svc/api/openapi/spec/paths/chproxy/metrics/ChproxyMetricsRequestBody.yaml b/svc/api/openapi/spec/paths/chproxy/metrics/ChproxyMetricsRequestBody.yaml
deleted file mode 100644
index a0b11fe565..0000000000
--- a/svc/api/openapi/spec/paths/chproxy/metrics/ChproxyMetricsRequestBody.yaml
+++ /dev/null
@@ -1,5 +0,0 @@
-type: array
-description: Array of API request metric events to be processed
-items:
- type: object
- additionalProperties: true
diff --git a/svc/api/openapi/spec/paths/chproxy/metrics/ChproxyMetricsResponseBody.yaml b/svc/api/openapi/spec/paths/chproxy/metrics/ChproxyMetricsResponseBody.yaml
deleted file mode 100644
index 0f02f3cb65..0000000000
--- a/svc/api/openapi/spec/paths/chproxy/metrics/ChproxyMetricsResponseBody.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-type: object
-required:
- - status
-properties:
- status:
- type: string
- description: Processing status
- example: "OK"
diff --git a/svc/api/openapi/spec/paths/chproxy/metrics/index.yaml b/svc/api/openapi/spec/paths/chproxy/metrics/index.yaml
deleted file mode 100644
index dd6ad53f7d..0000000000
--- a/svc/api/openapi/spec/paths/chproxy/metrics/index.yaml
+++ /dev/null
@@ -1,37 +0,0 @@
-post:
- x-speakeasy-ignore: true
- x-excluded: true
- tags:
- - chproxy
- security: []
- operationId: chproxyMetrics
- summary: Internal ClickHouse proxy for API request metrics
- description: |-
- Internal endpoint for batching API request metric events to ClickHouse. This endpoint is used internally by the API to efficiently store request/response data for analytics and should not be used by external clients.
-
- This endpoint bypasses normal authentication and validation as it's intended for internal use only.
- requestBody:
- required: true
- content:
- application/json:
- schema:
- "$ref": "./ChproxyMetricsRequestBody.yaml"
- responses:
- "200":
- content:
- application/json:
- schema:
- "$ref": "./ChproxyMetricsResponseBody.yaml"
- description: Events successfully queued for processing
- "400":
- content:
- application/json:
- schema:
- $ref: "../../../error/BadRequestErrorResponse.yaml"
- description: Invalid request body or malformed events
- "529":
- content:
- application/json:
- schema:
- $ref: "../../../error/InternalServerErrorResponse.yaml"
- description: Service overloaded, unable to process events
diff --git a/svc/api/openapi/spec/paths/chproxy/ratelimits/ChproxyRatelimitsRequestBody.yaml b/svc/api/openapi/spec/paths/chproxy/ratelimits/ChproxyRatelimitsRequestBody.yaml
deleted file mode 100644
index 67fc89413c..0000000000
--- a/svc/api/openapi/spec/paths/chproxy/ratelimits/ChproxyRatelimitsRequestBody.yaml
+++ /dev/null
@@ -1,5 +0,0 @@
-type: array
-description: Array of ratelimit events to be processed
-items:
- type: object
- additionalProperties: true
diff --git a/svc/api/openapi/spec/paths/chproxy/ratelimits/ChproxyRatelimitsResponseBody.yaml b/svc/api/openapi/spec/paths/chproxy/ratelimits/ChproxyRatelimitsResponseBody.yaml
deleted file mode 100644
index 0f02f3cb65..0000000000
--- a/svc/api/openapi/spec/paths/chproxy/ratelimits/ChproxyRatelimitsResponseBody.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-type: object
-required:
- - status
-properties:
- status:
- type: string
- description: Processing status
- example: "OK"
diff --git a/svc/api/openapi/spec/paths/chproxy/ratelimits/index.yaml b/svc/api/openapi/spec/paths/chproxy/ratelimits/index.yaml
deleted file mode 100644
index 1a24c4305f..0000000000
--- a/svc/api/openapi/spec/paths/chproxy/ratelimits/index.yaml
+++ /dev/null
@@ -1,37 +0,0 @@
-post:
- x-speakeasy-ignore: true
- x-excluded: true
- tags:
- - chproxy
- security: []
- operationId: chproxyRatelimits
- summary: Internal ClickHouse proxy for ratelimit events
- description: |-
- Internal endpoint for batching ratelimit events to ClickHouse. This endpoint is used internally by the API to efficiently store ratelimit data and should not be used by external clients.
-
- This endpoint bypasses normal authentication and validation as it's intended for internal use only.
- requestBody:
- required: true
- content:
- application/json:
- schema:
- "$ref": "./ChproxyRatelimitsRequestBody.yaml"
- responses:
- "200":
- content:
- application/json:
- schema:
- "$ref": "./ChproxyRatelimitsResponseBody.yaml"
- description: Events successfully queued for processing
- "400":
- content:
- application/json:
- schema:
- $ref: "../../../error/BadRequestErrorResponse.yaml"
- description: Invalid request body or malformed events
- "529":
- content:
- application/json:
- schema:
- $ref: "../../../error/InternalServerErrorResponse.yaml"
- description: Service overloaded, unable to process events
diff --git a/svc/api/openapi/spec/paths/chproxy/verifications/ChproxyVerificationsRequestBody.yaml b/svc/api/openapi/spec/paths/chproxy/verifications/ChproxyVerificationsRequestBody.yaml
deleted file mode 100644
index e9d9f7e763..0000000000
--- a/svc/api/openapi/spec/paths/chproxy/verifications/ChproxyVerificationsRequestBody.yaml
+++ /dev/null
@@ -1,5 +0,0 @@
-type: array
-description: Array of key verification events to be processed
-items:
- type: object
- additionalProperties: true
diff --git a/svc/api/openapi/spec/paths/chproxy/verifications/ChproxyVerificationsResponseBody.yaml b/svc/api/openapi/spec/paths/chproxy/verifications/ChproxyVerificationsResponseBody.yaml
deleted file mode 100644
index 0f02f3cb65..0000000000
--- a/svc/api/openapi/spec/paths/chproxy/verifications/ChproxyVerificationsResponseBody.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-type: object
-required:
- - status
-properties:
- status:
- type: string
- description: Processing status
- example: "OK"
diff --git a/svc/api/openapi/spec/paths/chproxy/verifications/index.yaml b/svc/api/openapi/spec/paths/chproxy/verifications/index.yaml
deleted file mode 100644
index 459ed7f763..0000000000
--- a/svc/api/openapi/spec/paths/chproxy/verifications/index.yaml
+++ /dev/null
@@ -1,37 +0,0 @@
-post:
- x-speakeasy-ignore: true
- x-excluded: true
- tags:
- - chproxy
- security: []
- operationId: chproxyVerifications
- summary: Internal ClickHouse proxy for verification events
- description: |-
- Internal endpoint for batching key verification events to ClickHouse. This endpoint is used internally by the API to efficiently store verification data and should not be used by external clients.
-
- This endpoint bypasses normal authentication and validation as it's intended for internal use only. External clients should use the standard key verification endpoints instead.
- requestBody:
- required: true
- content:
- application/json:
- schema:
- "$ref": "./ChproxyVerificationsRequestBody.yaml"
- responses:
- "200":
- content:
- application/json:
- schema:
- "$ref": "./ChproxyVerificationsResponseBody.yaml"
- description: Events successfully queued for processing
- "400":
- content:
- application/json:
- schema:
- $ref: "../../../error/BadRequestErrorResponse.yaml"
- description: Invalid request body or malformed events
- "529":
- content:
- application/json:
- schema:
- $ref: "../../../error/InternalServerErrorResponse.yaml"
- description: Service overloaded, unable to process events
diff --git a/svc/api/routes/BUILD.bazel b/svc/api/routes/BUILD.bazel
index 76fe7acdae..74ff267e94 100644
--- a/svc/api/routes/BUILD.bazel
+++ b/svc/api/routes/BUILD.bazel
@@ -22,9 +22,6 @@ go_library(
"//pkg/zen",
"//pkg/zen/validation",
"//svc/api/internal/middleware",
- "//svc/api/routes/chproxy_metrics",
- "//svc/api/routes/chproxy_ratelimits",
- "//svc/api/routes/chproxy_verifications",
"//svc/api/routes/openapi",
"//svc/api/routes/pprof",
"//svc/api/routes/reference",
diff --git a/svc/api/routes/chproxy_metrics/BUILD.bazel b/svc/api/routes/chproxy_metrics/BUILD.bazel
deleted file mode 100644
index b883f021b4..0000000000
--- a/svc/api/routes/chproxy_metrics/BUILD.bazel
+++ /dev/null
@@ -1,16 +0,0 @@
-load("@rules_go//go:def.bzl", "go_library")
-
-go_library(
- name = "chproxy_metrics",
- srcs = ["handler.go"],
- importpath = "github.com/unkeyed/unkey/svc/api/routes/chproxy_metrics",
- visibility = ["//visibility:public"],
- deps = [
- "//pkg/clickhouse",
- "//pkg/clickhouse/schema",
- "//pkg/codes",
- "//pkg/fault",
- "//pkg/prometheus/metrics",
- "//pkg/zen",
- ],
-)
diff --git a/svc/api/routes/chproxy_metrics/handler.go b/svc/api/routes/chproxy_metrics/handler.go
deleted file mode 100644
index 7facb795c1..0000000000
--- a/svc/api/routes/chproxy_metrics/handler.go
+++ /dev/null
@@ -1,64 +0,0 @@
-package chproxyMetrics
-
-import (
- "context"
- "crypto/subtle"
- "net/http"
-
- "github.com/unkeyed/unkey/pkg/clickhouse"
- "github.com/unkeyed/unkey/pkg/clickhouse/schema"
- "github.com/unkeyed/unkey/pkg/codes"
- "github.com/unkeyed/unkey/pkg/fault"
- "github.com/unkeyed/unkey/pkg/prometheus/metrics"
- "github.com/unkeyed/unkey/pkg/zen"
-)
-
-// Handler handles API request metric events for ClickHouse proxy
-type Handler struct {
- ClickHouse clickhouse.ClickHouse
- Token string
-}
-
-// Method returns the HTTP method this route responds to
-func (h *Handler) Method() string {
- return "POST"
-}
-
-// Path returns the URL path pattern this route matches
-func (h *Handler) Path() string {
- return "/_internal/chproxy/metrics"
-}
-
-// Handle processes the HTTP request
-func (h *Handler) Handle(ctx context.Context, s *zen.Session) error {
- s.DisableClickHouseLogging()
-
- // Authenticate using Bearer token
- token, err := zen.Bearer(s)
- if err != nil {
- return err
- }
-
- if subtle.ConstantTimeCompare([]byte(token), []byte(h.Token)) != 1 {
- return fault.New("invalid chproxy token",
- fault.Code(codes.Auth.Authentication.KeyNotFound.URN()),
- fault.Internal("chproxy token does not match"),
- fault.Public("The provided token is invalid."))
- }
-
- events, err := zen.BindBody[[]schema.ApiRequest](s)
- if err != nil {
- return err
- }
-
- // Record metrics
- metrics.ChproxyRequestsTotal.WithLabelValues("metrics").Inc()
- metrics.ChproxyRowsTotal.WithLabelValues("metrics").Add(float64(len(events)))
-
- // Buffer all events to ClickHouse
- for _, event := range events {
- h.ClickHouse.BufferApiRequest(event)
- }
-
- return s.Send(http.StatusOK, nil)
-}
diff --git a/svc/api/routes/chproxy_ratelimits/BUILD.bazel b/svc/api/routes/chproxy_ratelimits/BUILD.bazel
deleted file mode 100644
index 60e24eebbe..0000000000
--- a/svc/api/routes/chproxy_ratelimits/BUILD.bazel
+++ /dev/null
@@ -1,16 +0,0 @@
-load("@rules_go//go:def.bzl", "go_library")
-
-go_library(
- name = "chproxy_ratelimits",
- srcs = ["handler.go"],
- importpath = "github.com/unkeyed/unkey/svc/api/routes/chproxy_ratelimits",
- visibility = ["//visibility:public"],
- deps = [
- "//pkg/clickhouse",
- "//pkg/clickhouse/schema",
- "//pkg/codes",
- "//pkg/fault",
- "//pkg/prometheus/metrics",
- "//pkg/zen",
- ],
-)
diff --git a/svc/api/routes/chproxy_ratelimits/handler.go b/svc/api/routes/chproxy_ratelimits/handler.go
deleted file mode 100644
index bc54aea61a..0000000000
--- a/svc/api/routes/chproxy_ratelimits/handler.go
+++ /dev/null
@@ -1,64 +0,0 @@
-package chproxyRatelimits
-
-import (
- "context"
- "crypto/subtle"
- "net/http"
-
- "github.com/unkeyed/unkey/pkg/clickhouse"
- "github.com/unkeyed/unkey/pkg/clickhouse/schema"
- "github.com/unkeyed/unkey/pkg/codes"
- "github.com/unkeyed/unkey/pkg/fault"
- "github.com/unkeyed/unkey/pkg/prometheus/metrics"
- "github.com/unkeyed/unkey/pkg/zen"
-)
-
-// Handler handles ratelimit events for ClickHouse proxy
-type Handler struct {
- ClickHouse clickhouse.ClickHouse
- Token string
-}
-
-// Method returns the HTTP method this route responds to
-func (h *Handler) Method() string {
- return "POST"
-}
-
-// Path returns the URL path pattern this route matches
-func (h *Handler) Path() string {
- return "/_internal/chproxy/ratelimits"
-}
-
-// Handle processes the HTTP request
-func (h *Handler) Handle(ctx context.Context, s *zen.Session) error {
- s.DisableClickHouseLogging()
-
- // Authenticate using Bearer token
- token, err := zen.Bearer(s)
- if err != nil {
- return err
- }
-
- if subtle.ConstantTimeCompare([]byte(token), []byte(h.Token)) != 1 {
- return fault.New("invalid chproxy token",
- fault.Code(codes.Auth.Authentication.KeyNotFound.URN()),
- fault.Internal("chproxy token does not match"),
- fault.Public("The provided token is invalid."))
- }
-
- events, err := zen.BindBody[[]schema.Ratelimit](s)
- if err != nil {
- return err
- }
-
- // Record metrics
- metrics.ChproxyRequestsTotal.WithLabelValues("ratelimits").Inc()
- metrics.ChproxyRowsTotal.WithLabelValues("ratelimits").Add(float64(len(events)))
-
- // Buffer all events to ClickHouse
- for _, event := range events {
- h.ClickHouse.BufferRatelimit(event)
- }
-
- return s.Send(http.StatusOK, nil)
-}
diff --git a/svc/api/routes/chproxy_verifications/BUILD.bazel b/svc/api/routes/chproxy_verifications/BUILD.bazel
deleted file mode 100644
index 5b69182959..0000000000
--- a/svc/api/routes/chproxy_verifications/BUILD.bazel
+++ /dev/null
@@ -1,16 +0,0 @@
-load("@rules_go//go:def.bzl", "go_library")
-
-go_library(
- name = "chproxy_verifications",
- srcs = ["handler.go"],
- importpath = "github.com/unkeyed/unkey/svc/api/routes/chproxy_verifications",
- visibility = ["//visibility:public"],
- deps = [
- "//pkg/clickhouse",
- "//pkg/clickhouse/schema",
- "//pkg/codes",
- "//pkg/fault",
- "//pkg/prometheus/metrics",
- "//pkg/zen",
- ],
-)
diff --git a/svc/api/routes/chproxy_verifications/handler.go b/svc/api/routes/chproxy_verifications/handler.go
deleted file mode 100644
index 4b64059260..0000000000
--- a/svc/api/routes/chproxy_verifications/handler.go
+++ /dev/null
@@ -1,64 +0,0 @@
-package chproxyVerifications
-
-import (
- "context"
- "crypto/subtle"
- "net/http"
-
- "github.com/unkeyed/unkey/pkg/clickhouse"
- "github.com/unkeyed/unkey/pkg/clickhouse/schema"
- "github.com/unkeyed/unkey/pkg/codes"
- "github.com/unkeyed/unkey/pkg/fault"
- "github.com/unkeyed/unkey/pkg/prometheus/metrics"
- "github.com/unkeyed/unkey/pkg/zen"
-)
-
-// Handler handles key verification events for ClickHouse proxy
-type Handler struct {
- ClickHouse clickhouse.ClickHouse
- Token string
-}
-
-// Method returns the HTTP method this route responds to
-func (h *Handler) Method() string {
- return "POST"
-}
-
-// Path returns the URL path pattern this route matches
-func (h *Handler) Path() string {
- return "/_internal/chproxy/verifications"
-}
-
-// Handle processes the HTTP request
-func (h *Handler) Handle(ctx context.Context, s *zen.Session) error {
- s.DisableClickHouseLogging()
-
- // Authenticate using Bearer token
- token, err := zen.Bearer(s)
- if err != nil {
- return err
- }
-
- if subtle.ConstantTimeCompare([]byte(token), []byte(h.Token)) != 1 {
- return fault.New("invalid chproxy token",
- fault.Code(codes.Auth.Authentication.KeyNotFound.URN()),
- fault.Internal("chproxy token does not match"),
- fault.Public("The provided token is invalid."))
- }
-
- events, err := zen.BindBody[[]schema.KeyVerification](s)
- if err != nil {
- return err
- }
-
- // Record metrics
- metrics.ChproxyRequestsTotal.WithLabelValues("verifications").Inc()
- metrics.ChproxyRowsTotal.WithLabelValues("verifications").Add(float64(len(events)))
-
- // Buffer all events to ClickHouse
- for _, event := range events {
- h.ClickHouse.BufferKeyVerification(event)
- }
-
- return s.Send(http.StatusOK, nil)
-}
diff --git a/svc/api/routes/register.go b/svc/api/routes/register.go
index 01cb98709a..264a43584c 100644
--- a/svc/api/routes/register.go
+++ b/svc/api/routes/register.go
@@ -8,10 +8,6 @@ import (
"github.com/unkeyed/unkey/svc/api/routes/reference"
v2Liveness "github.com/unkeyed/unkey/svc/api/routes/v2_liveness"
- chproxyMetrics "github.com/unkeyed/unkey/svc/api/routes/chproxy_metrics"
- chproxyRatelimits "github.com/unkeyed/unkey/svc/api/routes/chproxy_ratelimits"
- chproxyVerifications "github.com/unkeyed/unkey/svc/api/routes/chproxy_verifications"
-
pprofRoute "github.com/unkeyed/unkey/svc/api/routes/pprof"
v2RatelimitDeleteOverride "github.com/unkeyed/unkey/svc/api/routes/v2_ratelimit_delete_override"
@@ -72,12 +68,10 @@ import (
// The function applies a default middleware stack to most routes: panic recovery,
// observability (tracing), metrics collection to ClickHouse, structured logging,
// error handling, a one-minute request timeout, and request validation. Internal
-// endpoints (chproxy, pprof) use reduced middleware stacks appropriate to their
+// endpoints (pprof) use reduced middleware stacks appropriate to their
// needs.
//
-// Conditional routes are registered based on [Services] configuration. Chproxy
-// endpoints require a non-empty ChproxyToken, and pprof endpoints require
-// PprofEnabled to be true.
+// Conditional routes are registered based on [Services] configuration.
func Register(srv *zen.Server, svc *Services, info zen.InstanceInfo) {
withObservability := zen.WithObservability()
withMetrics := zen.WithMetrics(svc.ClickHouse, info)
@@ -99,37 +93,6 @@ func Register(srv *zen.Server, svc *Services, info zen.InstanceInfo) {
srv.RegisterRoute(defaultMiddlewares, &v2Liveness.Handler{})
- // ---------------------------------------------------------------------------
- // chproxy (internal endpoints)
-
- if svc.ChproxyToken != "" {
- chproxyMiddlewares := []zen.Middleware{
- withMetrics,
- withLogging,
- withObservability,
- withPanicRecovery,
- withErrorHandling,
- }
-
- // chproxy/verifications - internal endpoint for key verification events
- srv.RegisterRoute(chproxyMiddlewares, &chproxyVerifications.Handler{
- ClickHouse: svc.ClickHouse,
- Token: svc.ChproxyToken,
- })
-
- // chproxy/metrics - internal endpoint for API request metrics
- srv.RegisterRoute(chproxyMiddlewares, &chproxyMetrics.Handler{
- ClickHouse: svc.ClickHouse,
- Token: svc.ChproxyToken,
- })
-
- // chproxy/ratelimits - internal endpoint for ratelimit events
- srv.RegisterRoute(chproxyMiddlewares, &chproxyRatelimits.Handler{
- ClickHouse: svc.ClickHouse,
- Token: svc.ChproxyToken,
- })
- }
-
// ---------------------------------------------------------------------------
// pprof (internal profiling endpoints)
diff --git a/svc/api/routes/services.go b/svc/api/routes/services.go
index 7125ec09e4..a4f30e8822 100644
--- a/svc/api/routes/services.go
+++ b/svc/api/routes/services.go
@@ -49,10 +49,6 @@ type Services struct {
// Vault provides encrypted storage for sensitive key material.
Vault vault.VaultServiceClient
- // ChproxyToken authenticates requests to internal chproxy endpoints.
- // When empty, chproxy routes are not registered.
- ChproxyToken string
-
// CtrlDeploymentClient communicates with the control plane for deployment
// operations like creating and managing deployments.
CtrlDeploymentClient ctrl.DeployServiceClient
diff --git a/svc/api/run.go b/svc/api/run.go
index 258d90e398..b729f71e5a 100644
--- a/svc/api/run.go
+++ b/svc/api/run.go
@@ -310,7 +310,6 @@ func Run(ctx context.Context, cfg Config) error {
Auditlogs: auditlogSvc,
Caches: caches,
Vault: vaultClient,
- ChproxyToken: cfg.ClickHouse.ProxyToken,
CtrlDeploymentClient: ctrlDeploymentClient,
PprofEnabled: cfg.Pprof != nil,
PprofUsername: pprofUsername,
diff --git a/svc/krane/pkg/metrics/BUILD.bazel b/svc/krane/pkg/metrics/BUILD.bazel
new file mode 100644
index 0000000000..a6c3dc3177
--- /dev/null
+++ b/svc/krane/pkg/metrics/BUILD.bazel
@@ -0,0 +1,12 @@
+load("@rules_go//go:def.bzl", "go_library")
+
+go_library(
+ name = "metrics",
+ srcs = ["prometheus.go"],
+ importpath = "github.com/unkeyed/unkey/svc/krane/pkg/metrics",
+ visibility = ["//visibility:public"],
+ deps = [
+ "@com_github_prometheus_client_golang//prometheus",
+ "@com_github_prometheus_client_golang//prometheus/promauto",
+ ],
+)
diff --git a/pkg/prometheus/metrics/krane.go b/svc/krane/pkg/metrics/prometheus.go
similarity index 76%
rename from pkg/prometheus/metrics/krane.go
rename to svc/krane/pkg/metrics/prometheus.go
index df1e53e722..9022336973 100644
--- a/pkg/prometheus/metrics/krane.go
+++ b/svc/krane/pkg/metrics/prometheus.go
@@ -12,6 +12,26 @@ import (
"github.com/prometheus/client_golang/prometheus/promauto"
)
+var latencyBuckets = []float64{
+ 0.001, // 1ms
+ 0.002, // 2ms
+ 0.005, // 5ms
+ 0.01, // 10ms
+ 0.02, // 20ms
+ 0.05, // 50ms
+ 0.1, // 100ms
+ 0.2, // 200ms
+ 0.3, // 300ms
+ 0.4, // 400ms
+ 0.5, // 500ms
+ 0.75, // 750ms
+ 1.0, // 1s
+ 2.0, // 2s
+ 3.0, // 3s
+ 5.0, // 5s
+ 10.0, // 10s
+}
+
var (
// ---------------------------------------------------------------------------
// Control Plane Connectivity
@@ -27,11 +47,10 @@ var (
// metrics.KraneControlPlaneReconnectsTotal.WithLabelValues("deployments").Inc()
KraneControlPlaneReconnectsTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "krane",
- Name: "controlplane_reconnects_total",
- Help: "Total number of control plane stream reconnection attempts.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "krane",
+ Name: "controlplane_reconnects_total",
+ Help: "Total number of control plane stream reconnection attempts.",
},
[]string{"controller"},
)
@@ -48,11 +67,10 @@ var (
// metrics.KraneControlPlaneRPCRequestsTotal.WithLabelValues("deployments", "ReportDeploymentStatus", "success").Inc()
KraneControlPlaneRPCRequestsTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "krane",
- Name: "controlplane_rpc_requests_total",
- Help: "Total number of outbound RPC requests to the control plane.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "krane",
+ Name: "controlplane_rpc_requests_total",
+ Help: "Total number of outbound RPC requests to the control plane.",
},
[]string{"controller", "method", "result"},
)
@@ -71,12 +89,11 @@ var (
// defer timer.ObserveDuration()
KraneControlPlaneRPCDurationSeconds = promauto.NewHistogramVec(
prometheus.HistogramOpts{
- Namespace: "unkey",
- Subsystem: "krane",
- Name: "controlplane_rpc_duration_seconds",
- Help: "Histogram of outbound RPC latencies to the control plane in seconds.",
- Buckets: latencyBuckets,
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "krane",
+ Name: "controlplane_rpc_duration_seconds",
+ Help: "Histogram of outbound RPC latencies to the control plane in seconds.",
+ Buckets: latencyBuckets,
},
[]string{"controller", "method"},
)
@@ -98,11 +115,10 @@ var (
// metrics.KraneK8sRequestsTotal.WithLabelValues("deployments", "patch", "replicaset", "success").Inc()
KraneK8sRequestsTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "krane",
- Name: "k8s_requests_total",
- Help: "Total number of Kubernetes API requests.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "krane",
+ Name: "k8s_requests_total",
+ Help: "Total number of Kubernetes API requests.",
},
[]string{"controller", "verb", "resource", "result"},
)
@@ -122,12 +138,11 @@ var (
// defer timer.ObserveDuration()
KraneK8sDurationSeconds = promauto.NewHistogramVec(
prometheus.HistogramOpts{
- Namespace: "unkey",
- Subsystem: "krane",
- Name: "k8s_duration_seconds",
- Help: "Histogram of Kubernetes API request latencies in seconds.",
- Buckets: latencyBuckets,
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "krane",
+ Name: "k8s_duration_seconds",
+ Help: "Histogram of Kubernetes API request latencies in seconds.",
+ Buckets: latencyBuckets,
},
[]string{"controller", "verb", "resource"},
)
@@ -149,11 +164,10 @@ var (
// metrics.KraneReconcileOperationsTotal.WithLabelValues("deployments", "apply", "success", "ws_123").Inc()
KraneReconcileOperationsTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "krane",
- Name: "reconcile_operations_total",
- Help: "Total number of reconciliation operations (apply/delete).",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "krane",
+ Name: "reconcile_operations_total",
+ Help: "Total number of reconciliation operations (apply/delete).",
},
[]string{"controller", "operation", "result", "workspace_id"},
)
@@ -172,12 +186,11 @@ var (
// defer timer.ObserveDuration()
KraneReconcileDurationSeconds = promauto.NewHistogramVec(
prometheus.HistogramOpts{
- Namespace: "unkey",
- Subsystem: "krane",
- Name: "reconcile_duration_seconds",
- Help: "Histogram of reconciliation operation latencies in seconds.",
- Buckets: latencyBuckets,
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "krane",
+ Name: "reconcile_duration_seconds",
+ Help: "Histogram of reconciliation operation latencies in seconds.",
+ Buckets: latencyBuckets,
},
[]string{"controller", "operation"},
)
@@ -197,11 +210,10 @@ var (
// metrics.KraneResyncCorrectionsTotal.WithLabelValues("deployments").Inc()
KraneResyncCorrectionsTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "krane",
- Name: "resync_corrections_total",
- Help: "Total number of corrections made by the resync loop (indicates missed streaming events).",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "krane",
+ Name: "resync_corrections_total",
+ Help: "Total number of corrections made by the resync loop (indicates missed streaming events).",
},
[]string{"controller"},
)
@@ -219,12 +231,11 @@ var (
// defer timer.ObserveDuration()
KraneResyncDurationSeconds = promauto.NewHistogramVec(
prometheus.HistogramOpts{
- Namespace: "unkey",
- Subsystem: "krane",
- Name: "resync_duration_seconds",
- Help: "Histogram of resync loop iteration durations in seconds.",
- Buckets: latencyBuckets,
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "krane",
+ Name: "resync_duration_seconds",
+ Help: "Histogram of resync loop iteration durations in seconds.",
+ Buckets: latencyBuckets,
},
[]string{"controller"},
)
@@ -243,11 +254,10 @@ var (
// metrics.KraneSecretsRequestsTotal.WithLabelValues("success").Inc()
KraneSecretsRequestsTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "krane",
- Name: "secrets_requests_total",
- Help: "Total number of secrets decryption requests.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "krane",
+ Name: "secrets_requests_total",
+ Help: "Total number of secrets decryption requests.",
},
[]string{"result"},
)
@@ -262,11 +272,10 @@ var (
// metrics.KraneSecretsErrorsTotal.WithLabelValues("unauthenticated").Inc()
KraneSecretsErrorsTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "krane",
- Name: "secrets_errors_total",
- Help: "Total number of secrets service errors by type.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "krane",
+ Name: "secrets_errors_total",
+ Help: "Total number of secrets service errors by type.",
},
[]string{"type"},
)
@@ -279,12 +288,11 @@ var (
// defer timer.ObserveDuration()
KraneSecretsDurationSeconds = promauto.NewHistogram(
prometheus.HistogramOpts{
- Namespace: "unkey",
- Subsystem: "krane",
- Name: "secrets_duration_seconds",
- Help: "Histogram of secrets decryption request latencies in seconds.",
- Buckets: latencyBuckets,
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "krane",
+ Name: "secrets_duration_seconds",
+ Help: "Histogram of secrets decryption request latencies in seconds.",
+ Buckets: latencyBuckets,
},
)
@@ -303,11 +311,10 @@ var (
// metrics.KraneRPCServerRequestsTotal.WithLabelValues("DecryptSecretsBlob", "ok").Inc()
KraneRPCServerRequestsTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
- Namespace: "unkey",
- Subsystem: "krane",
- Name: "rpc_server_requests_total",
- Help: "Total number of inbound RPC requests to krane server.",
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "krane",
+ Name: "rpc_server_requests_total",
+ Help: "Total number of inbound RPC requests to krane server.",
},
[]string{"method", "code"},
)
@@ -325,12 +332,11 @@ var (
// defer timer.ObserveDuration()
KraneRPCServerDurationSeconds = promauto.NewHistogramVec(
prometheus.HistogramOpts{
- Namespace: "unkey",
- Subsystem: "krane",
- Name: "rpc_server_duration_seconds",
- Help: "Histogram of inbound RPC request latencies in seconds.",
- Buckets: latencyBuckets,
- ConstLabels: constLabels,
+ Namespace: "unkey",
+ Subsystem: "krane",
+ Name: "rpc_server_duration_seconds",
+ Help: "Histogram of inbound RPC request latencies in seconds.",
+ Buckets: latencyBuckets,
},
[]string{"method"},
)
diff --git a/web/apps/engineering/content/docs/architecture/services/clickhouse-proxy.mdx b/web/apps/engineering/content/docs/architecture/services/clickhouse-proxy.mdx
deleted file mode 100644
index 851e3a50c9..0000000000
--- a/web/apps/engineering/content/docs/architecture/services/clickhouse-proxy.mdx
+++ /dev/null
@@ -1,77 +0,0 @@
----
-title: ClickHouse Proxy
----
-import {Github} from "@unkey/icons"
-import {Property} from "fumadocs-openapi/ui"
-
-Our ClickHouse Proxy is a go app runnng on AWS Apprunner. It's only purpose is to receive small batches - or even just single rows - to batch them before sending them in bulk to ClickHouse.
-It does this by implementing the same HTTP interface as ClickHouse and buffering rows in memory, flushing periodically either every few seconds or when the buffer is full.
-
-It's available at `clickhouse.unkey.cloud`.
-
-
-Using the proxy is optional in development, but it can be enabled by providing the `CLICKHOUSE_INSERT_URL` environment variable in our API.
-
-## IaC
-
-Our ClickHouse proxy is fully managed in [unkeyed/infra](https://github.com/unkeyed/infra).
-
-
-## Quickstart
-
-The service is entirely configured via environment variables.
-
-### Environment Variables
-
-
- The port to listen on.
-
- Default: `7123`
-
-
-
-
- Username and password in the form `:` (username and password separated by a colon), which will be used to authorize incoming requests.
-
- Basic auth was chosen because that's what ClickHouse uses and allows to reuse their SDKs.
- In your sdk, you can specify the url as `https://proxyUser:proxyPassword@host:port` and it will just work.
-
-
-
-
-
- The HTTP URL of your clickhouse cluster. Ensure this includes the username and password
-
- Example: `https://username:password@abc.us-east-1.aws.clickhouse.cloud:8123`
-
-
-### Running the service
-
-You can run the service either by compiling the go binary via:
-```bash
-cd /apps/chproxy
-go build -o chproxy .
-./chproxy
-```
-
-Or using the included [Dockerfile](https://github.com/unkeyed/unkey/blob/main/apps/chproxy/Dockerfile)
-
-See the [docker compose](https://github.com/unkeyed/unkey/blob/main/dev/docker-compose.yaml) reference for more.
-
-## References
-
-}>
-[https://github.com/unkeyed/unkey/tree/main/apps/chproxy](https://github.com/unkeyed/unkey/tree/main/apps/chproxy)
-
diff --git a/web/apps/engineering/content/docs/architecture/services/meta.json b/web/apps/engineering/content/docs/architecture/services/meta.json
index 8bb8fafeb1..082b2e0edc 100644
--- a/web/apps/engineering/content/docs/architecture/services/meta.json
+++ b/web/apps/engineering/content/docs/architecture/services/meta.json
@@ -6,7 +6,6 @@
"api",
"analytics",
"clickhouse",
- "clickhouse-proxy",
"cluster-service",
"ctrl",
"deploy",