diff options
| -rw-r--r-- | cmd/relay/main.go | 41 | ||||
| -rw-r--r-- | internal/metrics/dashboard.html | 16 |
2 files changed, 32 insertions, 25 deletions
diff --git a/cmd/relay/main.go b/cmd/relay/main.go index bd50e63..457a719 100644 --- a/cmd/relay/main.go +++ b/cmd/relay/main.go | |||
| @@ -54,7 +54,18 @@ func main() { | |||
| 54 | path, handler := nostrv1connect.NewNostrRelayHandler(connectHandler, connect.WithInterceptors()) | 54 | path, handler := nostrv1connect.NewNostrRelayHandler(connectHandler, connect.WithInterceptors()) |
| 55 | mux.Handle(path, handler) | 55 | mux.Handle(path, handler) |
| 56 | 56 | ||
| 57 | var serverOpts []grpc.ServerOption | 57 | var unaryInterceptors []grpc.UnaryServerInterceptor |
| 58 | var streamInterceptors []grpc.StreamServerInterceptor | ||
| 59 | |||
| 60 | var m *metrics.Metrics | ||
| 61 | if cfg.Metrics.Enabled { | ||
| 62 | m = metrics.New(cfg.Metrics.ToMetrics()) | ||
| 63 | unaryInterceptors = append(unaryInterceptors, metrics.UnaryServerInterceptor(m)) | ||
| 64 | streamInterceptors = append(streamInterceptors, metrics.StreamServerInterceptor(m)) | ||
| 65 | |||
| 66 | mux.Handle("/metrics", m.PrometheusHandler()) | ||
| 67 | mux.Handle("/dashboard", m.DashboardHandler()) | ||
| 68 | } | ||
| 58 | 69 | ||
| 59 | if cfg.Auth.Read.Enabled || cfg.Auth.Write.Enabled { | 70 | if cfg.Auth.Read.Enabled || cfg.Auth.Write.Enabled { |
| 60 | authOpts := &auth.InterceptorOptions{ | 71 | authOpts := &auth.InterceptorOptions{ |
| @@ -63,30 +74,22 @@ func main() { | |||
| 63 | TimestampWindow: cfg.Auth.TimestampWindow, | 74 | TimestampWindow: cfg.Auth.TimestampWindow, |
| 64 | SkipMethods: cfg.Auth.SkipMethods, | 75 | SkipMethods: cfg.Auth.SkipMethods, |
| 65 | } | 76 | } |
| 66 | serverOpts = append(serverOpts, | 77 | unaryInterceptors = append(unaryInterceptors, auth.NostrUnaryInterceptor(authOpts)) |
| 67 | grpc.UnaryInterceptor(auth.NostrUnaryInterceptor(authOpts)), | 78 | streamInterceptors = append(streamInterceptors, auth.NostrStreamInterceptor(authOpts)) |
| 68 | grpc.StreamInterceptor(auth.NostrStreamInterceptor(authOpts)), | ||
| 69 | ) | ||
| 70 | } | 79 | } |
| 71 | 80 | ||
| 72 | if cfg.RateLimit.Enabled { | 81 | if cfg.RateLimit.Enabled { |
| 73 | limiter := ratelimit.New(cfg.RateLimit.ToRateLimiter()) | 82 | limiter := ratelimit.New(cfg.RateLimit.ToRateLimiter()) |
| 74 | serverOpts = append(serverOpts, | 83 | unaryInterceptors = append(unaryInterceptors, ratelimit.UnaryInterceptor(limiter)) |
| 75 | grpc.ChainUnaryInterceptor(ratelimit.UnaryInterceptor(limiter)), | 84 | streamInterceptors = append(streamInterceptors, ratelimit.StreamInterceptor(limiter)) |
| 76 | grpc.ChainStreamInterceptor(ratelimit.StreamInterceptor(limiter)), | ||
| 77 | ) | ||
| 78 | } | 85 | } |
| 79 | 86 | ||
| 80 | var m *metrics.Metrics | 87 | var serverOpts []grpc.ServerOption |
| 81 | if cfg.Metrics.Enabled { | 88 | if len(unaryInterceptors) > 0 { |
| 82 | m = metrics.New(cfg.Metrics.ToMetrics()) | 89 | serverOpts = append(serverOpts, grpc.ChainUnaryInterceptor(unaryInterceptors...)) |
| 83 | serverOpts = append(serverOpts, | 90 | } |
| 84 | grpc.ChainUnaryInterceptor(metrics.UnaryServerInterceptor(m)), | 91 | if len(streamInterceptors) > 0 { |
| 85 | grpc.ChainStreamInterceptor(metrics.StreamServerInterceptor(m)), | 92 | serverOpts = append(serverOpts, grpc.ChainStreamInterceptor(streamInterceptors...)) |
| 86 | ) | ||
| 87 | |||
| 88 | mux.Handle("/metrics", m.PrometheusHandler()) | ||
| 89 | mux.Handle("/dashboard", m.DashboardHandler()) | ||
| 90 | } | 93 | } |
| 91 | 94 | ||
| 92 | wsHandler := wshandler.NewHandler(store, subManager) | 95 | wsHandler := wshandler.NewHandler(store, subManager) |
diff --git a/internal/metrics/dashboard.html b/internal/metrics/dashboard.html index 800b6df..e7af48c 100644 --- a/internal/metrics/dashboard.html +++ b/internal/metrics/dashboard.html | |||
| @@ -189,7 +189,7 @@ | |||
| 189 | </div> | 189 | </div> |
| 190 | 190 | ||
| 191 | <script> | 191 | <script> |
| 192 | let startTime = Date.now(); | 192 | let processStartTime = null; |
| 193 | 193 | ||
| 194 | function parsePrometheusMetrics(text) { | 194 | function parsePrometheusMetrics(text) { |
| 195 | const metrics = {}; | 195 | const metrics = {}; |
| @@ -294,8 +294,15 @@ | |||
| 294 | document.getElementById('event_deletions').textContent = | 294 | document.getElementById('event_deletions').textContent = |
| 295 | sumMetric(metrics, `${prefix}_relay_event_deletions_total`); | 295 | sumMetric(metrics, `${prefix}_relay_event_deletions_total`); |
| 296 | 296 | ||
| 297 | document.getElementById('uptime').textContent = | 297 | const processStart = sumMetric(metrics, 'process_start_time_seconds'); |
| 298 | formatUptime(Date.now() - startTime); | 298 | if (processStart > 0) { |
| 299 | if (!processStartTime) processStartTime = processStart; | ||
| 300 | const uptimeSeconds = Date.now() / 1000 - processStart; | ||
| 301 | document.getElementById('uptime').textContent = | ||
| 302 | formatUptime(uptimeSeconds * 1000); | ||
| 303 | } else { | ||
| 304 | document.getElementById('uptime').textContent = '--'; | ||
| 305 | } | ||
| 299 | 306 | ||
| 300 | document.getElementById('error').innerHTML = ''; | 307 | document.getElementById('error').innerHTML = ''; |
| 301 | } catch (error) { | 308 | } catch (error) { |
| @@ -306,9 +313,6 @@ | |||
| 306 | 313 | ||
| 307 | updateMetrics(); | 314 | updateMetrics(); |
| 308 | setInterval(updateMetrics, 5000); | 315 | setInterval(updateMetrics, 5000); |
| 309 | setInterval(() => { | ||
| 310 | document.getElementById('uptime').textContent = formatUptime(Date.now() - startTime); | ||
| 311 | }, 1000); | ||
| 312 | </script> | 316 | </script> |
| 313 | </body> | 317 | </body> |
| 314 | </html> | 318 | </html> |
