Files
garage-ui/internal/handlers/monitoring.go
T

146 lines
4.5 KiB
Go

package handlers
import (
"Noooste/garage-ui/internal/models"
"Noooste/garage-ui/internal/services"
"github.com/gofiber/fiber/v3"
)
// MonitoringHandler handles monitoring operations
type MonitoringHandler struct {
adminService *services.GarageAdminService
s3Service *services.S3Service
}
// NewMonitoringHandler creates a new monitoring handler
func NewMonitoringHandler(adminService *services.GarageAdminService, s3Service *services.S3Service) *MonitoringHandler {
return &MonitoringHandler{
adminService: adminService,
s3Service: s3Service,
}
}
// GetMetrics retrieves system metrics from the Admin API
//
// @Summary Get system metrics
// @Description Retrieves system metrics from the Garage Admin API for monitoring purposes
// @Tags Monitoring
// @Accept json
// @Produce text/plain
// @Success 200 {string} string "System metrics in plain text format"
// @Failure 500 {object} models.APIResponse{error=models.APIError} "Failed to retrieve metrics"
// @Router /api/v1/monitoring/metrics [get]
func (h *MonitoringHandler) GetMetrics(c fiber.Ctx) error {
ctx := c.Context()
metrics, err := h.adminService.GetMetrics(ctx)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(
models.ErrorResponse(models.ErrCodeInternalError, "Failed to get metrics: "+err.Error()),
)
}
// Return metrics as plain text
c.Set("Content-Type", "text/plain; charset=utf-8")
return c.SendString(metrics)
}
// CheckAdminHealth checks if the Admin API is reachable
//
// @Summary Check Admin API health
// @Description Performs a health check on the Garage Admin API to verify connectivity and availability
// @Tags Monitoring
// @Accept json
// @Produce json
// @Success 200 {object} models.APIResponse{data=object{status=string,message=string}} "Admin API is healthy"
// @Failure 503 {object} models.APIResponse{error=models.APIError} "Admin API health check failed"
// @Router /api/v1/monitoring/admin-health [get]
func (h *MonitoringHandler) CheckAdminHealth(c fiber.Ctx) error {
ctx := c.Context()
err := h.adminService.HealthCheck(ctx)
if err != nil {
return c.Status(fiber.StatusServiceUnavailable).JSON(
models.ErrorResponse(models.ErrCodeInternalError, "Admin API health check failed: "+err.Error()),
)
}
return c.JSON(models.SuccessResponse(map[string]interface{}{
"status": "healthy",
"message": "Admin API is reachable",
}))
}
// GetDashboardMetrics retrieves aggregated dashboard metrics
//
// @Summary Get dashboard metrics
// @Description Retrieves aggregated metrics for the dashboard including storage, buckets, and request metrics
// @Tags Monitoring
// @Accept json
// @Produce json
// @Success 200 {object} models.APIResponse{data=models.DashboardMetrics} "Successfully retrieved dashboard metrics"
// @Failure 500 {object} models.APIResponse{error=models.APIError} "Failed to get dashboard metrics"
// @Router /api/v1/monitoring/dashboard [get]
func (h *MonitoringHandler) GetDashboardMetrics(c fiber.Ctx) error {
ctx := c.Context()
// Get bucket list
buckets, err := h.adminService.ListBuckets(ctx)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(
models.ErrorResponse(models.ErrCodeInternalError, "Failed to get buckets: "+err.Error()),
)
}
// Calculate aggregated metrics
var totalSize int64
var totalObjects int64
usageByBucket := make([]models.BucketUsage, 0)
for _, bucket := range buckets {
// Get bucket info to calculate size and object count
bucketInfo, err := h.adminService.GetBucketInfo(ctx, bucket.ID)
if err != nil {
continue // Skip buckets we can't access
}
// Get size and object count from bucket info
bucketSize := bucketInfo.Bytes
objectCount := bucketInfo.Objects
totalSize += bucketSize
totalObjects += objectCount
// Get bucket name from aliases
bucketName := bucket.ID
if len(bucket.LocalAliases) > 0 {
bucketName = bucket.LocalAliases[0].Alias
} else if len(bucket.GlobalAliases) > 0 {
bucketName = bucket.GlobalAliases[0]
}
usageByBucket = append(usageByBucket, models.BucketUsage{
BucketName: bucketName,
Size: bucketSize,
ObjectCount: objectCount,
})
}
// Calculate percentages
for i := range usageByBucket {
if totalSize > 0 {
usageByBucket[i].Percentage = float64(usageByBucket[i].Size) / float64(totalSize) * 100
}
}
dashboardMetrics := models.DashboardMetrics{
TotalSize: totalSize,
ObjectCount: totalObjects,
BucketCount: len(buckets),
UsageByBucket: usageByBucket,
}
return c.JSON(models.SuccessResponse(dashboardMetrics))
}