|
| 1 | +package metrics |
| 2 | + |
| 3 | +import ( |
| 4 | + "context" |
| 5 | + "fmt" |
| 6 | + "github.com/prometheus/common/model" |
| 7 | + "github.com/serverledge-faas/serverledge/internal/config" |
| 8 | + "github.com/serverledge-faas/serverledge/internal/node" |
| 9 | + "log" |
| 10 | + "time" |
| 11 | + |
| 12 | + promapi "github.com/prometheus/client_golang/api" |
| 13 | + v1 "github.com/prometheus/client_golang/api/prometheus/v1" |
| 14 | +) |
| 15 | + |
| 16 | +var retrievedMetrics RetrievedMetrics |
| 17 | + |
| 18 | +func retrieveSingleValue(query string, api v1.API, ctx context.Context) (float64, error) { |
| 19 | + |
| 20 | + result, warnings, err := api.Query(ctx, query, time.Now()) |
| 21 | + if err != nil { |
| 22 | + return 0.0, fmt.Errorf("Failed query : %v\n", err) |
| 23 | + } |
| 24 | + |
| 25 | + if len(warnings) > 0 { |
| 26 | + log.Printf("Received warnings in the execution of the : %v\n", warnings) |
| 27 | + } |
| 28 | + |
| 29 | + vector, ok := result.(model.Vector) |
| 30 | + if !ok { |
| 31 | + return 0.0, fmt.Errorf("Could not convert the result of the query : %v\n", result) |
| 32 | + } |
| 33 | + if vector.Len() != 1 { |
| 34 | + return 0.0, fmt.Errorf("Expected 1 result; found %d\n", vector.Len()) |
| 35 | + } |
| 36 | + |
| 37 | + sample := vector[0] |
| 38 | + return float64(sample.Value), nil |
| 39 | +} |
| 40 | + |
| 41 | +func retrieveByFunction(query string, api v1.API, ctx context.Context) (map[string]float64, error) { |
| 42 | + |
| 43 | + result, warnings, err := api.Query(ctx, query, time.Now()) |
| 44 | + if err != nil { |
| 45 | + return nil, fmt.Errorf("Failed query : %v\n", err) |
| 46 | + } |
| 47 | + |
| 48 | + if len(warnings) > 0 { |
| 49 | + log.Printf("Received warnings in the execution of the : %v\n", warnings) |
| 50 | + } |
| 51 | + |
| 52 | + functionValues := make(map[string]float64) |
| 53 | + if vector, ok := result.(model.Vector); ok { |
| 54 | + for _, sample := range vector { |
| 55 | + value := float64(sample.Value) |
| 56 | + functionName, found := sample.Metric[model.LabelName("function")] |
| 57 | + if !found { |
| 58 | + log.Printf("Could not find the function name in the result : %v\n", sample) |
| 59 | + continue |
| 60 | + } else { |
| 61 | + functionValues[string(functionName)] = value |
| 62 | + } |
| 63 | + } |
| 64 | + } else { |
| 65 | + return nil, fmt.Errorf("Unexpected Result %v\n", result) |
| 66 | + } |
| 67 | + |
| 68 | + return functionValues, nil |
| 69 | +} |
| 70 | + |
| 71 | +func MetricsRetriever() { |
| 72 | + prometheusHost := config.GetString(config.METRICS_PROMETHEUS_HOST, "127.0.0.1") |
| 73 | + prometheusPort := config.GetInt(config.METRICS_PROMETHEUS_PORT, 9090) |
| 74 | + client, err := promapi.NewClient(promapi.Config{ |
| 75 | + Address: fmt.Sprintf("http://%s:%d", prometheusHost, prometheusPort), |
| 76 | + }) |
| 77 | + if err != nil { |
| 78 | + log.Printf("Error in Prometheus client creation: %v\n", err) |
| 79 | + return |
| 80 | + } |
| 81 | + |
| 82 | + // API of Prometheus |
| 83 | + api := v1.NewAPI(client) |
| 84 | + ctx := context.Background() |
| 85 | + |
| 86 | + ticker := time.NewTicker(time.Duration(config.GetInt(config.METRICS_RETRIEVER_INTERVAL, 10)) * time.Second) |
| 87 | + defer ticker.Stop() |
| 88 | + |
| 89 | + for { |
| 90 | + select { |
| 91 | + case <-ticker.C: |
| 92 | + |
| 93 | + query := fmt.Sprintf("%s{node=\"%s\"}", COMPLETIONS, node.NodeIdentifier) |
| 94 | + completionsPerFunction, err := retrieveByFunction(query, api, ctx) |
| 95 | + if err != nil { |
| 96 | + log.Printf("Error in retrieveByFunction: %v\n", err) |
| 97 | + } |
| 98 | + retrievedMetrics.Completions = completionsPerFunction |
| 99 | + |
| 100 | + query = fmt.Sprintf("%s_sum{node=\"%s\"}/%s_count{node=\"%s\"}", |
| 101 | + EXECUTION_TIME, node.NodeIdentifier, EXECUTION_TIME, node.NodeIdentifier) |
| 102 | + avgFunDuration, err := retrieveByFunction(query, api, ctx) |
| 103 | + if err != nil { |
| 104 | + log.Printf("Error in retrieveByFunction: %v\n", err) |
| 105 | + } |
| 106 | + retrievedMetrics.AvgExecutionTime = avgFunDuration |
| 107 | + |
| 108 | + fmt.Println("All queries completed") |
| 109 | + |
| 110 | + } |
| 111 | + } |
| 112 | + |
| 113 | +} |
| 114 | + |
| 115 | +func GetMetrics() RetrievedMetrics { |
| 116 | + // TODO: deep copy? |
| 117 | + return retrievedMetrics |
| 118 | +} |
0 commit comments