github.com/minio/madmin-go/v3@v3.0.51/prometheus_metrics.go (about) 1 // 2 // Copyright (c) 2015-2023 MinIO, Inc. 3 // 4 // This file is part of MinIO Object Storage stack 5 // 6 // This program is free software: you can redistribute it and/or modify 7 // it under the terms of the GNU Affero General Public License as 8 // published by the Free Software Foundation, either version 3 of the 9 // License, or (at your option) any later version. 10 // 11 // This program is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU Affero General Public License for more details. 15 // 16 // You should have received a copy of the GNU Affero General Public License 17 // along with this program. If not, see <http://www.gnu.org/licenses/>. 18 // 19 20 package madmin 21 22 import ( 23 "context" 24 "fmt" 25 "io" 26 "net/http" 27 28 "github.com/dustin/go-humanize" 29 "github.com/prometheus/common/expfmt" 30 "github.com/prometheus/prom2json" 31 ) 32 33 // MetricsRespBodyLimit sets the top level limit to the size of the 34 // metrics results supported by this library. 35 var ( 36 MetricsRespBodyLimit = int64(humanize.GiByte) 37 ) 38 39 // NodeMetrics - returns Node Metrics in Prometheus format 40 // 41 // The client needs to be configured with the endpoint of the desired node 42 func (client *MetricsClient) NodeMetrics(ctx context.Context) ([]*prom2json.Family, error) { 43 return client.GetMetrics(ctx, "node") 44 } 45 46 // ClusterMetrics - returns Cluster Metrics in Prometheus format 47 func (client *MetricsClient) ClusterMetrics(ctx context.Context) ([]*prom2json.Family, error) { 48 return client.GetMetrics(ctx, "cluster") 49 } 50 51 // BucketMetrics - returns Bucket Metrics in Prometheus format 52 func (client *MetricsClient) BucketMetrics(ctx context.Context) ([]*prom2json.Family, error) { 53 return client.GetMetrics(ctx, "bucket") 54 } 55 56 // ResourceMetrics - returns Resource Metrics in Prometheus format 57 func (client *MetricsClient) ResourceMetrics(ctx context.Context) ([]*prom2json.Family, error) { 58 return client.GetMetrics(ctx, "resource") 59 } 60 61 // GetMetrics - returns Metrics of given subsystem in Prometheus format 62 func (client *MetricsClient) GetMetrics(ctx context.Context, subSystem string) ([]*prom2json.Family, error) { 63 reqData := metricsRequestData{ 64 relativePath: "/v2/metrics/" + subSystem, 65 } 66 67 // Execute GET on /minio/v2/metrics/<subSys> 68 resp, err := client.executeGetRequest(ctx, reqData) 69 if err != nil { 70 return nil, err 71 } 72 defer closeResponse(resp) 73 74 if resp.StatusCode != http.StatusOK { 75 return nil, httpRespToErrorResponse(resp) 76 } 77 78 return ParsePrometheusResults(io.LimitReader(resp.Body, MetricsRespBodyLimit)) 79 } 80 81 func ParsePrometheusResults(reader io.Reader) (results []*prom2json.Family, err error) { 82 // We could do further content-type checks here, but the 83 // fallback for now will anyway be the text format 84 // version 0.0.4, so just go for it and see if it works. 85 var parser expfmt.TextParser 86 metricFamilies, err := parser.TextToMetricFamilies(reader) 87 if err != nil { 88 return nil, fmt.Errorf("reading text format failed: %v", err) 89 } 90 results = make([]*prom2json.Family, 0, len(metricFamilies)) 91 for _, mf := range metricFamilies { 92 results = append(results, prom2json.NewFamily(mf)) 93 } 94 return results, nil 95 }