Closed
Conversation
- Add Event and MessagePublisher interface with MessagePublisherManager - Add event type enum (internal/datatypes/event_type.go) for feedback_record and future webhook event types - Add placeholder EmailDeliveryService implementing MessagePublisher - Wire FeedbackRecordsService to publish events on create/update/delete - Wire message manager in main and integration tests (no webhook provider yet) Co-authored-by: Cursor <cursoragent@cursor.com>
- Use goose for app schema (migrations/001, 002_webhooks) - Single 002_webhooks.sql migration with full webhooks table and indexes - Keep river-migrate target and add to CI after init-db - AGENTS.md: document river-migrate for webhook delivery Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds optional Prometheus metrics for the Hub API: HTTP request count/duration, webhook job enqueue/delivery/disabled counters, and dropped-event counters. Metrics are exposed on a separate HTTP server (no API key). Also adds a readiness probe and metrics/docs improvements.
Changes
Observability
internal/observability/metrics.goRecordRequest,RecordEventDropped,RecordWebhookJobsEnqueued,RecordWebhookEnqueueError,RecordWebhookDelivery,RecordWebhookDisabled.http.server.durationandwebhook_delivery_duration_seconds.NewMeterProvider(fail fast on misconfiguration).event_type,outcome,reason); unknown values become"unknown".nilis passed and all call sites guard withif metrics != nil.internal/api/middleware/metrics.go{id}) and status class (2xx/4xx/5xx).GET /health) is measured.Config and wiring
internal/config/config.goPROMETHEUS_ENABLED: true for1/true/yes/on(case-insensitive).PROMETHEUS_EXPORTER_PORT(default9464).cmd/api/main.goPROMETHEUS_ENABLED=1: creates MeterProvider and a second HTTP server on the exporter port serving onlyGET /metrics; defers shutdown of that server and MeterProvider.metrics(ornil) into MessagePublisherManager, WebhookProvider, WebhookSenderImpl, WebhookDispatchWorker, andmiddleware.Metrics(metrics).Readiness and health
internal/api/handlers/health_handler.goGET /readyis registered on the main server (withGET /health); both are covered by the metrics middleware.Documentation
docs/reference/environment-variables.mdx:PROMETHEUS_ENABLED,PROMETHEUS_EXPORTER_PORT, health/ready endpoints; link to metrics reference.docs/reference/metrics.mdx: Full metrics reference—list of metrics, labels, when recorded, histogram buckets, normalized values, example Prometheus queries.docs/webhooks-todo.md: Observability, dropped-events, and main (observability + readiness) items marked done.Tests
internal/observability/metrics_test.go: Unit tests fornormalizeEventType,normalizeOutcome,normalizeDisabledReason.tests/metrics_integration_test.go: Creates MeterProvider, records one sample per metric type, calls the metrics handler, asserts response contains expected metric name stems.Lint and formatting
.golangci.yml: lll (line length) linter enabled; limit configurable underlinters.settings.lll.line-length; exclude rules for_test.goandtests/for lll.tests/integration_test.go: Long lines fixed by extracting URLs into variables beforehttp.NewRequestWithContext(keeps lines under the configured limit).Configuration
PROMETHEUS_ENABLED1to enable the metrics server and custom metrics.PROMETHEUS_EXPORTER_PORT9464GET /metrics).GET http://<host>:<PROMETHEUS_EXPORTER_PORT>/metrics(no auth).GET /health(liveness),GET /ready(readiness, DB ping).Testing
With
PROMETHEUS_ENABLED=1and the app running:Checklist
PROMETHEUS_ENABLEDis unset.make fmtandmake lintpass.