feat: add observability improvements (metrics, audit log, structured logging)
All checks were successful
Check / check (pull_request) Successful in 1m45s
All checks were successful
Check / check (pull_request) Successful in 1m45s
- Add Prometheus metrics package (internal/metrics) with deployment, container health, webhook, HTTP request, and audit counters/histograms - Add audit_log SQLite table via migration 007 - Add AuditEntry model with CRUD operations and query methods - Add audit service (internal/service/audit) for recording user actions - Instrument deploy service with deployment duration, count, and in-flight metrics; container health gauge updates on deploy completion - Instrument webhook service with event counters by app/type/matched - Instrument HTTP middleware with request count, duration, and response size metrics; also log response bytes in structured request logs - Add audit logging to all key handler operations: login/logout, app CRUD, deploy, cancel, rollback, restart/stop/start, webhook receipt, and initial setup - Add GET /api/audit endpoint for querying recent audit entries - Make /metrics endpoint always available (optionally auth-protected) - Add comprehensive tests for metrics, audit model, and audit service - Update existing test infrastructure with metrics and audit dependencies - Update README with Observability section documenting all metrics, audit log, and structured logging
This commit is contained in:
@@ -7,13 +7,14 @@ import (
|
||||
"github.com/go-chi/chi/v5"
|
||||
|
||||
"sneak.berlin/go/upaas/internal/models"
|
||||
"sneak.berlin/go/upaas/internal/service/audit"
|
||||
)
|
||||
|
||||
// maxWebhookBodySize is the maximum allowed size of a webhook request body (1MB).
|
||||
const maxWebhookBodySize = 1 << 20
|
||||
|
||||
// HandleWebhook handles incoming Gitea webhooks.
|
||||
func (h *Handlers) HandleWebhook() http.HandlerFunc {
|
||||
func (h *Handlers) HandleWebhook() http.HandlerFunc { //nolint:funlen // audit logging adds necessary length
|
||||
return func(writer http.ResponseWriter, request *http.Request) {
|
||||
secret := chi.URLParam(request, "secret")
|
||||
if secret == "" {
|
||||
@@ -56,6 +57,15 @@ func (h *Handlers) HandleWebhook() http.HandlerFunc {
|
||||
eventType = "push"
|
||||
}
|
||||
|
||||
// Log webhook receipt
|
||||
h.audit.LogFromRequest(request.Context(), request, audit.LogEntry{
|
||||
Username: "webhook",
|
||||
Action: models.AuditActionWebhookReceive,
|
||||
ResourceType: models.AuditResourceWebhook,
|
||||
ResourceID: application.ID,
|
||||
Detail: "webhook from app: " + application.Name + ", event: " + eventType,
|
||||
})
|
||||
|
||||
// Process webhook
|
||||
webhookErr := h.webhook.HandleWebhook(
|
||||
request.Context(),
|
||||
|
||||
Reference in New Issue
Block a user