Files
query-orchestration/cmd/metricsExample_test/main.go
T
Michael McGuinness bbd86fb4ea Merged in feature/CollectorBuildVersion (pull request #100)
Collector Build Version

* lint

* fixtests
2025-03-11 18:15:49 +00:00

223 lines
6.9 KiB
Go

// This main.go serves as an example of how to use the custom Prometheus metrics package.
//
// It demonstrates:
//
// 1. Setting up metrics with proper context handling
//
// 2. Configuring different types of metrics (Counter, Gauge, Histogram, Summary)
//
// 3. Recording metrics safely in a concurrent environment
//
// 4. Implementing graceful shutdown
//
// 5. Proper error handling
package main
import (
"context"
"fmt"
"log"
"math/rand"
"os"
"os/signal"
"syscall"
"time"
"queryorchestration/internal/serviceconfig/build"
"queryorchestration/internal/serviceconfig/observability/prometheus"
)
func getMetricsConfig() prometheus.MetricsConfig {
standardDefinitions := prometheus.NewStandardMetricDefinitions()
// Define metrics configuration using StandardMetricDefinitions
config := prometheus.MetricsConfig{
Port: 8080,
Namespace: "myapp",
Subsystem: "api",
ServeHttp: true,
// Start with standard metrics and append our custom one
Definitions: append(standardDefinitions,
prometheus.MetricDefinition{
Type: prometheus.Counter,
Name: "test_custom_events_total",
Help: "Total number of custom test events",
Labels: []string{
"event_type",
"priority",
},
},
),
}
return config
}
func main() {
rawVersion := build.GetVersion()
fmt.Printf("Version: %s\n", rawVersion)
timeVersion := build.GetVersionTimestamp()
fmt.Printf("Version Timestamp: %s\n", timeVersion.String())
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// Define metrics configuration using StandardMetricDefinitions
config := getMetricsConfig()
metrics, err := prometheus.New(ctx, config)
if err != nil {
log.Fatalf("Failed to create metrics: %v", err)
}
go simulateMetrics(ctx, metrics)
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
fmt.Println("Running... Press Ctrl+C to exit")
<-sigChan
fmt.Println("\nShutting down...")
cancel()
shutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), 5*time.Second)
defer shutdownCancel()
if err := metrics.Shutdown(shutdownCtx); err != nil {
log.Printf("Error shutting down metrics server: %v", err)
}
}
// simulateMetrics demonstrates how to record different types of metrics
func simulateMetrics(ctx context.Context, metrics *prometheus.Metrics) {
// Sample data for simulation
endpoints := []string{"/api/users", "/api/products", "/api/orders"}
methods := []string{"GET", "POST", "PUT", "DELETE"}
statuses := []string{"200", "400", "500"}
errorTypes := []string{"none", "validation", "database", "timeout"}
dependencies := []string{"database", "cache", "auth-service", "email-service"}
cacheOperations := []string{"hit", "miss", "set", "eviction"}
taskTypes := []string{"cleanup", "indexing", "backup", "sync"}
taskStatuses := []string{"running", "queued", "failed"}
results := []string{"success", "failure", "timeout"}
components := []string{"api", "database", "cache", "auth"}
queueNames := []string{"main-queue", "background-queue", "notification-queue"}
resourceTypes := []string{"cpu", "memory", "disk", "network"}
// Custom metric sample data
eventTypes := []string{"scheduled", "triggered", "manual"}
priorities := []string{"low", "medium", "high"}
ticker := time.NewTicker(2 * time.Second)
defer ticker.Stop()
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
// Simulate standard metrics
// 1. Requests total
endpoint := endpoints[rand.Intn(len(endpoints))]
method := methods[rand.Intn(len(methods))]
status := statuses[rand.Intn(len(statuses))]
errorType := errorTypes[rand.Intn(len(errorTypes))]
err := metrics.RecordRequestsTotal(1.0, endpoint, method, endpoint, status, errorType)
if err != nil {
log.Printf("Error recording requests metric: %v", err)
}
// 2. Request duration
duration := rand.Float64() * 3 // Random duration between 0 and 3 seconds
err = metrics.RecordRequestDurationSeconds(duration, endpoint, method, endpoint, status)
if err != nil {
log.Printf("Error recording duration metric: %v", err)
}
// 3. Active operations
activeOps := rand.Float64() * 50
err = metrics.RecordActiveOperations(activeOps, method)
if err != nil {
log.Printf("Error recording active operations metric: %v", err)
}
// 4. Resource usage
resourceType := resourceTypes[rand.Intn(len(resourceTypes))]
err = metrics.RecordResourceUsage(rand.Float64()*100, resourceType, "main-instance")
if err != nil {
log.Printf("Error recording resource usage metric: %v", err)
}
// 5. Dependency health
dep := dependencies[rand.Intn(len(dependencies))]
health := rand.Float64() // Random health score between 0 and 1
err = metrics.RecordDependencyHealth(health, dep, "external_service")
if err != nil {
log.Printf("Error recording dependency health metric: %v", err)
}
// 6. Cache operations
cacheOp := cacheOperations[rand.Intn(len(cacheOperations))]
result := results[rand.Intn(len(results))]
err = metrics.RecordCacheOperationsTotal(1.0, cacheOp, "main-cache", result)
if err != nil {
log.Printf("Error recording cache operations metric: %v", err)
}
// 7. Cache operation duration
err = metrics.RecordCacheOperationDurationSeconds(rand.Float64()*0.1, cacheOp, result)
if err != nil {
log.Printf("Error recording cache duration metric: %v", err)
}
// 8. Background tasks
taskType := taskTypes[rand.Intn(len(taskTypes))]
taskStatus := taskStatuses[rand.Intn(len(taskStatuses))]
err = metrics.RecordBackgroundTasks(rand.Float64()*10, taskType, taskStatus)
if err != nil {
log.Printf("Error recording background tasks metric: %v", err)
}
// 9. Active connections
err = metrics.RecordActiveConnections(rand.Float64()*100, "http")
if err != nil {
log.Printf("Error recording active connections metric: %v", err)
}
// 10. Queue length
queueName := queueNames[rand.Intn(len(queueNames))]
err = metrics.RecordQueueLength(rand.Float64()*50, queueName)
if err != nil {
log.Printf("Error recording queue length metric: %v", err)
}
// 11. Errors total
component := components[rand.Intn(len(components))]
err = metrics.RecordErrorsTotal(1.0, component, errorType)
if err != nil {
log.Printf("Error recording errors total metric: %v", err)
}
// 12. Items in progress
err = metrics.RecordItemsInProgress(rand.Float64()*20, endpoint, component)
if err != nil {
log.Printf("Error recording items in progress metric: %v", err)
}
// Custom metric (still using RecordMetric since it's not part of the generated stubs)
eventType := eventTypes[rand.Intn(len(eventTypes))]
priority := priorities[rand.Intn(len(priorities))]
err = metrics.RecordMetric("test_custom_events_total", 1, map[string]string{
"event_type": eventType,
"priority": priority,
})
if err != nil {
log.Printf("Error recording custom event metric: %v", err)
}
}
}
}