| 
									
										
										
										
											2021-04-19 03:41:13 +08:00
										 |  |  | // Copyright (c) 2015-2021 MinIO, Inc.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This file is part of MinIO Object Storage stack
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This program is free software: you can redistribute it and/or modify
 | 
					
						
							|  |  |  | // it under the terms of the GNU Affero General Public License as published by
 | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or
 | 
					
						
							|  |  |  | // (at your option) any later version.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This program is distributed in the hope that it will be useful
 | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					
						
							|  |  |  | // GNU Affero General Public License for more details.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // You should have received a copy of the GNU Affero General Public License
 | 
					
						
							|  |  |  | // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							| 
									
										
										
										
											2018-04-19 07:01:42 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | package cmd | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"net/http" | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 	"strings" | 
					
						
							|  |  |  | 	"time" | 
					
						
							| 
									
										
										
										
											2018-04-19 07:01:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-02 05:59:40 +08:00
										 |  |  | 	"github.com/minio/minio/internal/logger" | 
					
						
							| 
									
										
										
										
											2022-12-07 01:27:26 +08:00
										 |  |  | 	"github.com/minio/minio/internal/mcontext" | 
					
						
							| 
									
										
										
										
											2021-05-30 12:16:42 +08:00
										 |  |  | 	iampolicy "github.com/minio/pkg/iam/policy" | 
					
						
							| 
									
										
										
										
											2018-04-19 07:01:42 +08:00
										 |  |  | 	"github.com/prometheus/client_golang/prometheus" | 
					
						
							| 
									
										
										
										
											2022-07-02 04:18:39 +08:00
										 |  |  | 	"github.com/prometheus/common/expfmt" | 
					
						
							| 
									
										
										
										
											2018-04-19 07:01:42 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var ( | 
					
						
							|  |  |  | 	httpRequestsDuration = prometheus.NewHistogramVec( | 
					
						
							|  |  |  | 		prometheus.HistogramOpts{ | 
					
						
							| 
									
										
										
										
											2019-10-23 12:01:14 +08:00
										 |  |  | 			Name:    "s3_ttfb_seconds", | 
					
						
							| 
									
										
										
										
											2019-04-10 02:39:42 +08:00
										 |  |  | 			Help:    "Time taken by requests served by current MinIO server instance", | 
					
						
							| 
									
										
										
										
											2019-10-23 12:01:14 +08:00
										 |  |  | 			Buckets: []float64{.05, .1, .25, .5, 1, 2.5, 5, 10}, | 
					
						
							| 
									
										
										
										
											2018-04-19 07:01:42 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2019-10-23 12:01:14 +08:00
										 |  |  | 		[]string{"api"}, | 
					
						
							| 
									
										
										
										
											2018-04-19 07:01:42 +08:00
										 |  |  | 	) | 
					
						
							| 
									
										
										
										
											2019-06-27 01:36:54 +08:00
										 |  |  | 	minioVersionInfo = prometheus.NewGaugeVec( | 
					
						
							|  |  |  | 		prometheus.GaugeOpts{ | 
					
						
							|  |  |  | 			Namespace: "minio", | 
					
						
							|  |  |  | 			Name:      "version_info", | 
					
						
							|  |  |  | 			Help:      "Version of current MinIO server instance", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		[]string{ | 
					
						
							|  |  |  | 			// current version
 | 
					
						
							|  |  |  | 			"version", | 
					
						
							|  |  |  | 			// commit-id of the current version
 | 
					
						
							|  |  |  | 			"commit", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	) | 
					
						
							| 
									
										
										
										
											2018-04-19 07:01:42 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | const ( | 
					
						
							|  |  |  | 	healMetricsNamespace = "self_heal" | 
					
						
							|  |  |  | 	cacheNamespace       = "cache" | 
					
						
							|  |  |  | 	s3Namespace          = "s3" | 
					
						
							|  |  |  | 	bucketNamespace      = "bucket" | 
					
						
							|  |  |  | 	minioNamespace       = "minio" | 
					
						
							|  |  |  | 	diskNamespace        = "disk" | 
					
						
							|  |  |  | 	interNodeNamespace   = "internode" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-19 07:01:42 +08:00
										 |  |  | func init() { | 
					
						
							|  |  |  | 	prometheus.MustRegister(httpRequestsDuration) | 
					
						
							| 
									
										
										
										
											2018-05-09 11:10:55 +08:00
										 |  |  | 	prometheus.MustRegister(newMinioCollector()) | 
					
						
							| 
									
										
										
										
											2019-06-27 01:36:54 +08:00
										 |  |  | 	prometheus.MustRegister(minioVersionInfo) | 
					
						
							| 
									
										
										
										
											2018-04-19 07:01:42 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-09 11:10:55 +08:00
										 |  |  | // newMinioCollector describes the collector
 | 
					
						
							|  |  |  | // and returns reference of minioCollector
 | 
					
						
							|  |  |  | // It creates the Prometheus Description which is used
 | 
					
						
							|  |  |  | // to define metric and  help string
 | 
					
						
							|  |  |  | func newMinioCollector() *minioCollector { | 
					
						
							|  |  |  | 	return &minioCollector{ | 
					
						
							| 
									
										
										
										
											2019-04-10 02:39:42 +08:00
										 |  |  | 		desc: prometheus.NewDesc("minio_stats", "Statistics exposed by MinIO server", nil, nil), | 
					
						
							| 
									
										
										
										
											2018-05-09 11:10:55 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // minioCollector is the Custom Collector
 | 
					
						
							|  |  |  | type minioCollector struct { | 
					
						
							|  |  |  | 	desc *prometheus.Desc | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Describe sends the super-set of all possible descriptors of metrics
 | 
					
						
							|  |  |  | func (c *minioCollector) Describe(ch chan<- *prometheus.Desc) { | 
					
						
							|  |  |  | 	ch <- c.desc | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Collect is called by the Prometheus registry when collecting metrics.
 | 
					
						
							|  |  |  | func (c *minioCollector) Collect(ch chan<- prometheus.Metric) { | 
					
						
							| 
									
										
										
										
											2019-06-27 01:36:54 +08:00
										 |  |  | 	// Expose MinIO's version information
 | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 	minioVersionInfo.WithLabelValues(Version, CommitID).Set(1.0) | 
					
						
							| 
									
										
										
										
											2019-06-27 01:36:54 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 	storageMetricsPrometheus(ch) | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 	nodeHealthMetricsPrometheus(ch) | 
					
						
							| 
									
										
										
										
											2020-05-27 21:45:43 +08:00
										 |  |  | 	bucketUsageMetricsPrometheus(ch) | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 	networkMetricsPrometheus(ch) | 
					
						
							|  |  |  | 	httpMetricsPrometheus(ch) | 
					
						
							| 
									
										
										
										
											2020-05-13 23:15:26 +08:00
										 |  |  | 	cacheMetricsPrometheus(ch) | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 	healingMetricsPrometheus(ch) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | func nodeHealthMetricsPrometheus(ch chan<- prometheus.Metric) { | 
					
						
							| 
									
										
										
										
											2022-06-08 17:43:13 +08:00
										 |  |  | 	nodesUp, nodesDown := globalNotificationSys.GetPeerOnlineCount() | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 	ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 		prometheus.NewDesc( | 
					
						
							|  |  |  | 			prometheus.BuildFQName(minioNamespace, "nodes", "online"), | 
					
						
							|  |  |  | 			"Total number of MinIO nodes online", | 
					
						
							|  |  |  | 			nil, nil), | 
					
						
							|  |  |  | 		prometheus.GaugeValue, | 
					
						
							|  |  |  | 		float64(nodesUp), | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 	ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 		prometheus.NewDesc( | 
					
						
							|  |  |  | 			prometheus.BuildFQName(minioNamespace, "nodes", "offline"), | 
					
						
							|  |  |  | 			"Total number of MinIO nodes offline", | 
					
						
							|  |  |  | 			nil, nil), | 
					
						
							|  |  |  | 		prometheus.GaugeValue, | 
					
						
							|  |  |  | 		float64(nodesDown), | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | // collects healing specific metrics for MinIO instance in Prometheus specific format
 | 
					
						
							|  |  |  | // and sends to given channel
 | 
					
						
							|  |  |  | func healingMetricsPrometheus(ch chan<- prometheus.Metric) { | 
					
						
							|  |  |  | 	bgSeq, exists := globalBackgroundHealState.getHealSequenceByToken(bgHealingUUID) | 
					
						
							|  |  |  | 	if !exists { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-05-09 11:10:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-25 03:11:20 +08:00
										 |  |  | 	var dur time.Duration | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 	if !bgSeq.lastHealActivity.IsZero() { | 
					
						
							|  |  |  | 		dur = time.Since(bgSeq.lastHealActivity) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-10-23 12:01:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-20 11:51:33 +08:00
										 |  |  | 	ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 		prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 			prometheus.BuildFQName(healMetricsNamespace, "time", "since_last_activity"), | 
					
						
							|  |  |  | 			"Time elapsed (in nano seconds) since last self healing activity. This is set to -1 until initial self heal activity", | 
					
						
							| 
									
										
										
										
											2020-02-20 11:51:33 +08:00
										 |  |  | 			nil, nil), | 
					
						
							|  |  |  | 		prometheus.GaugeValue, | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 		float64(dur), | 
					
						
							| 
									
										
										
										
											2020-02-20 11:51:33 +08:00
										 |  |  | 	) | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 	for k, v := range bgSeq.getScannedItemsMap() { | 
					
						
							| 
									
										
										
										
											2019-10-23 12:01:14 +08:00
										 |  |  | 		ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 			prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 				prometheus.BuildFQName(healMetricsNamespace, "objects", "scanned"), | 
					
						
							|  |  |  | 				"Objects scanned in current self healing run", | 
					
						
							|  |  |  | 				[]string{"type"}, nil), | 
					
						
							| 
									
										
										
										
											2019-10-23 12:01:14 +08:00
										 |  |  | 			prometheus.GaugeValue, | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 			float64(v), string(k), | 
					
						
							| 
									
										
										
										
											2019-10-23 12:01:14 +08:00
										 |  |  | 		) | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	for k, v := range bgSeq.getHealedItemsMap() { | 
					
						
							| 
									
										
										
										
											2019-10-23 12:01:14 +08:00
										 |  |  | 		ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 			prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 				prometheus.BuildFQName(healMetricsNamespace, "objects", "healed"), | 
					
						
							|  |  |  | 				"Objects healed in current self healing run", | 
					
						
							|  |  |  | 				[]string{"type"}, nil), | 
					
						
							| 
									
										
										
										
											2019-10-23 12:01:14 +08:00
										 |  |  | 			prometheus.GaugeValue, | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 			float64(v), string(k), | 
					
						
							| 
									
										
										
										
											2019-10-23 12:01:14 +08:00
										 |  |  | 		) | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	for k, v := range bgSeq.gethealFailedItemsMap() { | 
					
						
							|  |  |  | 		// healFailedItemsMap stores the endpoint and volume state separated by comma,
 | 
					
						
							|  |  |  | 		// split the fields and pass to channel at correct index
 | 
					
						
							|  |  |  | 		s := strings.Split(k, ",") | 
					
						
							| 
									
										
										
										
											2019-10-23 12:01:14 +08:00
										 |  |  | 		ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 			prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 				prometheus.BuildFQName(healMetricsNamespace, "objects", "heal_failed"), | 
					
						
							|  |  |  | 				"Objects for which healing failed in current self healing run", | 
					
						
							|  |  |  | 				[]string{"mount_path", "volume_status"}, nil), | 
					
						
							| 
									
										
										
										
											2019-10-23 12:01:14 +08:00
										 |  |  | 			prometheus.GaugeValue, | 
					
						
							| 
									
										
										
										
											2021-05-25 00:28:19 +08:00
										 |  |  | 			float64(v), s[0], s[1], | 
					
						
							| 
									
										
										
										
											2019-10-23 12:01:14 +08:00
										 |  |  | 		) | 
					
						
							| 
									
										
										
										
											2018-05-30 12:43:46 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // collects cache metrics for MinIO server in Prometheus specific format
 | 
					
						
							|  |  |  | // and sends to given channel
 | 
					
						
							|  |  |  | func cacheMetricsPrometheus(ch chan<- prometheus.Metric) { | 
					
						
							|  |  |  | 	cacheObjLayer := newCachedObjectLayerFn() | 
					
						
							|  |  |  | 	// Service not initialized yet
 | 
					
						
							|  |  |  | 	if cacheObjLayer == nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-04-05 12:21:50 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 		prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 			prometheus.BuildFQName(cacheNamespace, "hits", "total"), | 
					
						
							| 
									
										
										
										
											2022-08-05 07:10:08 +08:00
										 |  |  | 			"Total number of drive cache hits in current MinIO instance", | 
					
						
							| 
									
										
										
										
											2019-04-05 12:21:50 +08:00
										 |  |  | 			nil, nil), | 
					
						
							| 
									
										
										
										
											2019-10-23 12:01:14 +08:00
										 |  |  | 		prometheus.CounterValue, | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 		float64(cacheObjLayer.CacheStats().getHits()), | 
					
						
							| 
									
										
										
										
											2019-04-05 12:21:50 +08:00
										 |  |  | 	) | 
					
						
							| 
									
										
										
										
											2018-05-09 11:10:55 +08:00
										 |  |  | 	ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 		prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 			prometheus.BuildFQName(cacheNamespace, "misses", "total"), | 
					
						
							| 
									
										
										
										
											2022-08-05 07:10:08 +08:00
										 |  |  | 			"Total number of drive cache misses in current MinIO instance", | 
					
						
							| 
									
										
										
										
											2018-05-09 11:10:55 +08:00
										 |  |  | 			nil, nil), | 
					
						
							| 
									
										
										
										
											2019-10-23 12:01:14 +08:00
										 |  |  | 		prometheus.CounterValue, | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 		float64(cacheObjLayer.CacheStats().getMisses()), | 
					
						
							| 
									
										
										
										
											2018-05-09 11:10:55 +08:00
										 |  |  | 	) | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 	ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 		prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 			prometheus.BuildFQName(cacheNamespace, "data", "served"), | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 			"Total number of bytes served from cache of current MinIO instance", | 
					
						
							|  |  |  | 			nil, nil), | 
					
						
							|  |  |  | 		prometheus.CounterValue, | 
					
						
							|  |  |  | 		float64(cacheObjLayer.CacheStats().getBytesServed()), | 
					
						
							|  |  |  | 	) | 
					
						
							| 
									
										
										
										
											2020-06-16 00:05:35 +08:00
										 |  |  | 	for _, cdStats := range cacheObjLayer.CacheStats().GetDiskStats() { | 
					
						
							|  |  |  | 		// Cache disk usage percentage
 | 
					
						
							|  |  |  | 		ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 			prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 				prometheus.BuildFQName(cacheNamespace, "usage", "percent"), | 
					
						
							| 
									
										
										
										
											2020-06-16 00:05:35 +08:00
										 |  |  | 				"Total percentage cache usage", | 
					
						
							|  |  |  | 				[]string{"disk"}, nil), | 
					
						
							|  |  |  | 			prometheus.GaugeValue, | 
					
						
							|  |  |  | 			float64(cdStats.UsagePercent), | 
					
						
							|  |  |  | 			cdStats.Dir, | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 		ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 			prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 				prometheus.BuildFQName(cacheNamespace, "usage", "high"), | 
					
						
							| 
									
										
										
										
											2020-06-16 00:05:35 +08:00
										 |  |  | 				"Indicates cache usage is high or low, relative to current cache 'quota' settings", | 
					
						
							|  |  |  | 				[]string{"disk"}, nil), | 
					
						
							|  |  |  | 			prometheus.GaugeValue, | 
					
						
							|  |  |  | 			float64(cdStats.UsageState), | 
					
						
							|  |  |  | 			cdStats.Dir, | 
					
						
							|  |  |  | 		) | 
					
						
							| 
									
										
										
										
											2020-12-08 08:35:11 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 			prometheus.NewDesc( | 
					
						
							|  |  |  | 				prometheus.BuildFQName("cache", "usage", "size"), | 
					
						
							|  |  |  | 				"Indicates current cache usage in bytes", | 
					
						
							|  |  |  | 				[]string{"disk"}, nil), | 
					
						
							|  |  |  | 			prometheus.GaugeValue, | 
					
						
							|  |  |  | 			float64(cdStats.UsageSize), | 
					
						
							|  |  |  | 			cdStats.Dir, | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 			prometheus.NewDesc( | 
					
						
							|  |  |  | 				prometheus.BuildFQName("cache", "total", "size"), | 
					
						
							| 
									
										
										
										
											2022-08-05 07:10:08 +08:00
										 |  |  | 				"Indicates total size of cache drive", | 
					
						
							| 
									
										
										
										
											2020-12-08 08:35:11 +08:00
										 |  |  | 				[]string{"disk"}, nil), | 
					
						
							|  |  |  | 			prometheus.GaugeValue, | 
					
						
							|  |  |  | 			float64(cdStats.TotalCapacity), | 
					
						
							|  |  |  | 			cdStats.Dir, | 
					
						
							|  |  |  | 		) | 
					
						
							| 
									
										
										
										
											2020-06-16 00:05:35 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-10-23 12:01:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | // collects http metrics for MinIO server in Prometheus specific format
 | 
					
						
							|  |  |  | // and sends to given channel
 | 
					
						
							|  |  |  | func httpMetricsPrometheus(ch chan<- prometheus.Metric) { | 
					
						
							| 
									
										
										
										
											2019-12-06 15:16:06 +08:00
										 |  |  | 	httpStats := globalHTTPStats.toServerHTTPStats() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 12:01:14 +08:00
										 |  |  | 	for api, value := range httpStats.CurrentS3Requests.APIStats { | 
					
						
							|  |  |  | 		ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 			prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 				prometheus.BuildFQName(s3Namespace, "requests", "current"), | 
					
						
							| 
									
										
										
										
											2019-10-23 12:01:14 +08:00
										 |  |  | 				"Total number of running s3 requests in current MinIO server instance", | 
					
						
							|  |  |  | 				[]string{"api"}, nil), | 
					
						
							|  |  |  | 			prometheus.CounterValue, | 
					
						
							|  |  |  | 			float64(value), | 
					
						
							|  |  |  | 			api, | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for api, value := range httpStats.TotalS3Requests.APIStats { | 
					
						
							|  |  |  | 		ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 			prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 				prometheus.BuildFQName(s3Namespace, "requests", "total"), | 
					
						
							| 
									
										
										
										
											2019-10-23 12:01:14 +08:00
										 |  |  | 				"Total number of s3 requests in current MinIO server instance", | 
					
						
							|  |  |  | 				[]string{"api"}, nil), | 
					
						
							|  |  |  | 			prometheus.CounterValue, | 
					
						
							|  |  |  | 			float64(value), | 
					
						
							|  |  |  | 			api, | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for api, value := range httpStats.TotalS3Errors.APIStats { | 
					
						
							|  |  |  | 		ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 			prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 				prometheus.BuildFQName(s3Namespace, "errors", "total"), | 
					
						
							| 
									
										
										
										
											2019-10-23 12:01:14 +08:00
										 |  |  | 				"Total number of s3 errors in current MinIO server instance", | 
					
						
							|  |  |  | 				[]string{"api"}, nil), | 
					
						
							|  |  |  | 			prometheus.CounterValue, | 
					
						
							|  |  |  | 			float64(value), | 
					
						
							|  |  |  | 			api, | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-03-25 01:25:27 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for api, value := range httpStats.TotalS3Canceled.APIStats { | 
					
						
							|  |  |  | 		ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 			prometheus.NewDesc( | 
					
						
							|  |  |  | 				prometheus.BuildFQName(s3Namespace, "canceled", "total"), | 
					
						
							|  |  |  | 				"Total number of client canceled s3 request in current MinIO server instance", | 
					
						
							|  |  |  | 				[]string{"api"}, nil), | 
					
						
							|  |  |  | 			prometheus.CounterValue, | 
					
						
							|  |  |  | 			float64(value), | 
					
						
							|  |  |  | 			api, | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-10-23 12:01:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | // collects network metrics for MinIO server in Prometheus specific format
 | 
					
						
							|  |  |  | // and sends to given channel
 | 
					
						
							|  |  |  | func networkMetricsPrometheus(ch chan<- prometheus.Metric) { | 
					
						
							|  |  |  | 	connStats := globalConnStats.toServerConnStats() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Network Sent/Received Bytes (internode)
 | 
					
						
							|  |  |  | 	ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 		prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 			prometheus.BuildFQName(interNodeNamespace, "tx", "bytes_total"), | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 			"Total number of bytes sent to the other peer nodes by current MinIO server instance", | 
					
						
							|  |  |  | 			nil, nil), | 
					
						
							|  |  |  | 		prometheus.CounterValue, | 
					
						
							|  |  |  | 		float64(connStats.TotalOutputBytes), | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 		prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 			prometheus.BuildFQName(interNodeNamespace, "rx", "bytes_total"), | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 			"Total number of internode bytes received by current MinIO server instance", | 
					
						
							|  |  |  | 			nil, nil), | 
					
						
							|  |  |  | 		prometheus.CounterValue, | 
					
						
							|  |  |  | 		float64(connStats.TotalInputBytes), | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Network Sent/Received Bytes (Outbound)
 | 
					
						
							|  |  |  | 	ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 		prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 			prometheus.BuildFQName(s3Namespace, "tx", "bytes_total"), | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 			"Total number of s3 bytes sent by current MinIO server instance", | 
					
						
							|  |  |  | 			nil, nil), | 
					
						
							|  |  |  | 		prometheus.CounterValue, | 
					
						
							|  |  |  | 		float64(connStats.S3OutputBytes), | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 		prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 			prometheus.BuildFQName(s3Namespace, "rx", "bytes_total"), | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 			"Total number of s3 bytes received by current MinIO server instance", | 
					
						
							|  |  |  | 			nil, nil), | 
					
						
							|  |  |  | 		prometheus.CounterValue, | 
					
						
							|  |  |  | 		float64(connStats.S3InputBytes), | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-27 21:45:43 +08:00
										 |  |  | // Populates prometheus with bucket usage metrics, this metrics
 | 
					
						
							| 
									
										
										
										
											2021-02-18 04:04:11 +08:00
										 |  |  | // is only enabled if scanner is enabled.
 | 
					
						
							| 
									
										
										
										
											2020-05-27 21:45:43 +08:00
										 |  |  | func bucketUsageMetricsPrometheus(ch chan<- prometheus.Metric) { | 
					
						
							| 
									
										
										
										
											2020-10-10 00:59:52 +08:00
										 |  |  | 	objLayer := newObjectLayerFn() | 
					
						
							| 
									
										
										
										
											2020-05-27 21:45:43 +08:00
										 |  |  | 	// Service not initialized yet
 | 
					
						
							|  |  |  | 	if objLayer == nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	dataUsageInfo, err := loadDataUsageFromBackend(GlobalContext, objLayer) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// data usage has not captured any data yet.
 | 
					
						
							|  |  |  | 	if dataUsageInfo.LastUpdate.IsZero() { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for bucket, usageInfo := range dataUsageInfo.BucketsUsage { | 
					
						
							| 
									
										
										
										
											2022-09-13 03:40:02 +08:00
										 |  |  | 		stat := globalReplicationStats.getLatestReplicationStats(bucket, usageInfo) | 
					
						
							| 
									
										
										
										
											2020-05-27 21:45:43 +08:00
										 |  |  | 		// Total space used by bucket
 | 
					
						
							|  |  |  | 		ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 			prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 				prometheus.BuildFQName(bucketNamespace, "usage", "size"), | 
					
						
							| 
									
										
										
										
											2020-05-27 21:45:43 +08:00
										 |  |  | 				"Total bucket size", | 
					
						
							|  |  |  | 				[]string{"bucket"}, nil), | 
					
						
							|  |  |  | 			prometheus.GaugeValue, | 
					
						
							|  |  |  | 			float64(usageInfo.Size), | 
					
						
							|  |  |  | 			bucket, | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 		ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 			prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 				prometheus.BuildFQName(bucketNamespace, "objects", "count"), | 
					
						
							| 
									
										
										
										
											2020-05-27 21:45:43 +08:00
										 |  |  | 				"Total number of objects in a bucket", | 
					
						
							|  |  |  | 				[]string{"bucket"}, nil), | 
					
						
							|  |  |  | 			prometheus.GaugeValue, | 
					
						
							|  |  |  | 			float64(usageInfo.ObjectsCount), | 
					
						
							|  |  |  | 			bucket, | 
					
						
							|  |  |  | 		) | 
					
						
							| 
									
										
										
										
											2020-12-08 05:47:48 +08:00
										 |  |  | 		ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 			prometheus.NewDesc( | 
					
						
							|  |  |  | 				prometheus.BuildFQName("bucket", "replication", "failed_size"), | 
					
						
							|  |  |  | 				"Total capacity failed to replicate at least once", | 
					
						
							|  |  |  | 				[]string{"bucket"}, nil), | 
					
						
							|  |  |  | 			prometheus.GaugeValue, | 
					
						
							| 
									
										
										
										
											2021-04-04 00:03:42 +08:00
										 |  |  | 			float64(stat.FailedSize), | 
					
						
							| 
									
										
										
										
											2020-12-08 05:47:48 +08:00
										 |  |  | 			bucket, | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 		ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 			prometheus.NewDesc( | 
					
						
							|  |  |  | 				prometheus.BuildFQName("bucket", "replication", "successful_size"), | 
					
						
							|  |  |  | 				"Total capacity replicated to destination", | 
					
						
							|  |  |  | 				[]string{"bucket"}, nil), | 
					
						
							|  |  |  | 			prometheus.GaugeValue, | 
					
						
							| 
									
										
										
										
											2021-04-04 00:03:42 +08:00
										 |  |  | 			float64(stat.ReplicatedSize), | 
					
						
							| 
									
										
										
										
											2020-12-08 05:47:48 +08:00
										 |  |  | 			bucket, | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 		ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 			prometheus.NewDesc( | 
					
						
							|  |  |  | 				prometheus.BuildFQName("bucket", "replication", "received_size"), | 
					
						
							|  |  |  | 				"Total capacity replicated to this instance", | 
					
						
							|  |  |  | 				[]string{"bucket"}, nil), | 
					
						
							|  |  |  | 			prometheus.GaugeValue, | 
					
						
							| 
									
										
										
										
											2021-04-04 00:03:42 +08:00
										 |  |  | 			float64(stat.ReplicaSize), | 
					
						
							|  |  |  | 			bucket, | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 		ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 			prometheus.NewDesc( | 
					
						
							|  |  |  | 				prometheus.BuildFQName("bucket", "replication", "failed_count"), | 
					
						
							|  |  |  | 				"Total replication operations failed", | 
					
						
							|  |  |  | 				[]string{"bucket"}, nil), | 
					
						
							|  |  |  | 			prometheus.GaugeValue, | 
					
						
							|  |  |  | 			float64(stat.FailedCount), | 
					
						
							| 
									
										
										
										
											2020-12-08 05:47:48 +08:00
										 |  |  | 			bucket, | 
					
						
							|  |  |  | 		) | 
					
						
							| 
									
										
										
										
											2020-05-27 21:45:43 +08:00
										 |  |  | 		for k, v := range usageInfo.ObjectSizesHistogram { | 
					
						
							|  |  |  | 			ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 				prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 					prometheus.BuildFQName(bucketNamespace, "objects", "histogram"), | 
					
						
							| 
									
										
										
										
											2020-05-27 21:45:43 +08:00
										 |  |  | 					"Total number of objects of different sizes in a bucket", | 
					
						
							|  |  |  | 					[]string{"bucket", "object_size"}, nil), | 
					
						
							|  |  |  | 				prometheus.GaugeValue, | 
					
						
							|  |  |  | 				float64(v), | 
					
						
							|  |  |  | 				bucket, | 
					
						
							|  |  |  | 				k, | 
					
						
							|  |  |  | 			) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | // collects storage metrics for MinIO server in Prometheus specific format
 | 
					
						
							|  |  |  | // and sends to given channel
 | 
					
						
							|  |  |  | func storageMetricsPrometheus(ch chan<- prometheus.Metric) { | 
					
						
							| 
									
										
										
										
											2020-10-10 00:59:52 +08:00
										 |  |  | 	objLayer := newObjectLayerFn() | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 	// Service not initialized yet
 | 
					
						
							|  |  |  | 	if objLayer == nil { | 
					
						
							|  |  |  | 		return | 
					
						
							| 
									
										
										
										
											2021-03-03 09:28:04 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-05 01:42:09 +08:00
										 |  |  | 	server := getLocalServerProperty(globalEndpoints, &http.Request{ | 
					
						
							| 
									
										
										
										
											2021-03-27 02:37:58 +08:00
										 |  |  | 		Host: globalLocalNodeName, | 
					
						
							| 
									
										
										
										
											2021-01-05 01:42:09 +08:00
										 |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-05 01:42:09 +08:00
										 |  |  | 	onlineDisks, offlineDisks := getOnlineOfflineDisksStats(server.Disks) | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 	totalDisks := offlineDisks.Merge(onlineDisks) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 	// Report total capacity
 | 
					
						
							|  |  |  | 	ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 		prometheus.NewDesc( | 
					
						
							|  |  |  | 			prometheus.BuildFQName(minioNamespace, "capacity_raw", "total"), | 
					
						
							|  |  |  | 			"Total capacity online in the cluster", | 
					
						
							|  |  |  | 			nil, nil), | 
					
						
							|  |  |  | 		prometheus.GaugeValue, | 
					
						
							| 
									
										
										
										
											2021-02-05 04:26:58 +08:00
										 |  |  | 		float64(GetTotalCapacity(server.Disks)), | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Report total capacity free
 | 
					
						
							|  |  |  | 	ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 		prometheus.NewDesc( | 
					
						
							|  |  |  | 			prometheus.BuildFQName(minioNamespace, "capacity_raw_free", "total"), | 
					
						
							|  |  |  | 			"Total free capacity online in the cluster", | 
					
						
							|  |  |  | 			nil, nil), | 
					
						
							|  |  |  | 		prometheus.GaugeValue, | 
					
						
							| 
									
										
										
										
											2021-02-05 04:26:58 +08:00
										 |  |  | 		float64(GetTotalCapacityFree(server.Disks)), | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-02 06:31:35 +08:00
										 |  |  | 	sinfo := objLayer.StorageInfo(GlobalContext) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 	// Report total usable capacity
 | 
					
						
							|  |  |  | 	ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 		prometheus.NewDesc( | 
					
						
							|  |  |  | 			prometheus.BuildFQName(minioNamespace, "capacity_usable", "total"), | 
					
						
							|  |  |  | 			"Total usable capacity online in the cluster", | 
					
						
							|  |  |  | 			nil, nil), | 
					
						
							|  |  |  | 		prometheus.GaugeValue, | 
					
						
							| 
									
										
										
										
											2022-12-02 06:31:35 +08:00
										 |  |  | 		float64(GetTotalUsableCapacity(server.Disks, sinfo)), | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 	) | 
					
						
							| 
									
										
										
										
											2022-12-02 06:31:35 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 	// Report total usable capacity free
 | 
					
						
							|  |  |  | 	ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 		prometheus.NewDesc( | 
					
						
							|  |  |  | 			prometheus.BuildFQName(minioNamespace, "capacity_usable_free", "total"), | 
					
						
							|  |  |  | 			"Total free usable capacity online in the cluster", | 
					
						
							|  |  |  | 			nil, nil), | 
					
						
							|  |  |  | 		prometheus.GaugeValue, | 
					
						
							| 
									
										
										
										
											2022-12-02 06:31:35 +08:00
										 |  |  | 		float64(GetTotalUsableCapacityFree(server.Disks, sinfo)), | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 	// MinIO Offline Disks per node
 | 
					
						
							|  |  |  | 	ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 		prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 			prometheus.BuildFQName(minioNamespace, "disks", "offline"), | 
					
						
							| 
									
										
										
										
											2022-08-05 07:10:08 +08:00
										 |  |  | 			"Total number of offline drives in current MinIO server instance", | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 			nil, nil), | 
					
						
							|  |  |  | 		prometheus.GaugeValue, | 
					
						
							|  |  |  | 		float64(offlineDisks.Sum()), | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// MinIO Total Disks per node
 | 
					
						
							|  |  |  | 	ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 		prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2022-08-05 07:10:08 +08:00
										 |  |  | 			prometheus.BuildFQName(minioNamespace, "drives", "total"), | 
					
						
							|  |  |  | 			"Total number of drives for current MinIO server instance", | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 			nil, nil), | 
					
						
							|  |  |  | 		prometheus.GaugeValue, | 
					
						
							|  |  |  | 		float64(totalDisks.Sum()), | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-05 01:42:09 +08:00
										 |  |  | 	for _, disk := range server.Disks { | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 		// Total disk usage by the disk
 | 
					
						
							| 
									
										
										
										
											2019-12-06 15:16:06 +08:00
										 |  |  | 		ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 			prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 				prometheus.BuildFQName(diskNamespace, "storage", "used"), | 
					
						
							| 
									
										
										
										
											2022-08-05 07:10:08 +08:00
										 |  |  | 				"Total disk storage used on the drive", | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 				[]string{"disk"}, nil), | 
					
						
							|  |  |  | 			prometheus.GaugeValue, | 
					
						
							| 
									
										
										
										
											2020-07-14 00:51:07 +08:00
										 |  |  | 			float64(disk.UsedSpace), | 
					
						
							|  |  |  | 			disk.DrivePath, | 
					
						
							| 
									
										
										
										
											2019-12-06 15:16:06 +08:00
										 |  |  | 		) | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// Total available space in the disk
 | 
					
						
							| 
									
										
										
										
											2019-12-07 13:51:52 +08:00
										 |  |  | 		ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 			prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 				prometheus.BuildFQName(diskNamespace, "storage", "available"), | 
					
						
							| 
									
										
										
										
											2022-08-05 07:10:08 +08:00
										 |  |  | 				"Total available space left on the drive", | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 				[]string{"disk"}, nil), | 
					
						
							|  |  |  | 			prometheus.GaugeValue, | 
					
						
							| 
									
										
										
										
											2020-07-14 00:51:07 +08:00
										 |  |  | 			float64(disk.AvailableSpace), | 
					
						
							|  |  |  | 			disk.DrivePath, | 
					
						
							| 
									
										
										
										
											2019-12-07 13:51:52 +08:00
										 |  |  | 		) | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// Total storage space of the disk
 | 
					
						
							| 
									
										
										
										
											2019-12-07 13:51:52 +08:00
										 |  |  | 		ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 			prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 				prometheus.BuildFQName(diskNamespace, "storage", "total"), | 
					
						
							| 
									
										
										
										
											2022-08-05 07:10:08 +08:00
										 |  |  | 				"Total space on the drive", | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 				[]string{"disk"}, nil), | 
					
						
							|  |  |  | 			prometheus.GaugeValue, | 
					
						
							| 
									
										
										
										
											2020-07-14 00:51:07 +08:00
										 |  |  | 			float64(disk.TotalSpace), | 
					
						
							|  |  |  | 			disk.DrivePath, | 
					
						
							| 
									
										
										
										
											2019-12-07 13:51:52 +08:00
										 |  |  | 		) | 
					
						
							| 
									
										
										
										
											2019-12-06 15:16:06 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-04-19 07:01:42 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-09 11:10:55 +08:00
										 |  |  | func metricsHandler() http.Handler { | 
					
						
							|  |  |  | 	registry := prometheus.NewRegistry() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-02 04:18:39 +08:00
										 |  |  | 	logger.CriticalIf(GlobalContext, registry.Register(minioVersionInfo)) | 
					
						
							| 
									
										
										
										
											2019-06-27 01:36:54 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-02 04:18:39 +08:00
										 |  |  | 	logger.CriticalIf(GlobalContext, registry.Register(newMinioCollector())) | 
					
						
							| 
									
										
										
										
											2018-05-09 11:10:55 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	gatherers := prometheus.Gatherers{ | 
					
						
							|  |  |  | 		prometheus.DefaultGatherer, | 
					
						
							|  |  |  | 		registry, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-07-02 04:18:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | 
					
						
							| 
									
										
										
										
											2022-12-07 01:27:26 +08:00
										 |  |  | 		tc, ok := r.Context().Value(mcontext.ContextTraceKey).(*mcontext.TraceCtxt) | 
					
						
							| 
									
										
										
										
											2022-07-02 04:18:39 +08:00
										 |  |  | 		if ok { | 
					
						
							| 
									
										
										
										
											2022-12-07 01:27:26 +08:00
										 |  |  | 			tc.FuncName = "handler.MetricsLegacy" | 
					
						
							|  |  |  | 			tc.ResponseRecorder.LogErrBody = true | 
					
						
							| 
									
										
										
										
											2022-07-02 04:18:39 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		mfs, err := gatherers.Gather() | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			if len(mfs) == 0 { | 
					
						
							|  |  |  | 				writeErrorResponseJSON(r.Context(), w, toAdminAPIErr(r.Context(), err), r.URL) | 
					
						
							|  |  |  | 				return | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		contentType := expfmt.Negotiate(r.Header) | 
					
						
							|  |  |  | 		w.Header().Set("Content-Type", string(contentType)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		enc := expfmt.NewEncoder(w, contentType) | 
					
						
							|  |  |  | 		for _, mf := range mfs { | 
					
						
							|  |  |  | 			if err := enc.Encode(mf); err != nil { | 
					
						
							| 
									
										
										
										
											2022-12-16 00:25:05 +08:00
										 |  |  | 				// client may disconnect for any reasons
 | 
					
						
							|  |  |  | 				// we do not have to log this.
 | 
					
						
							| 
									
										
										
										
											2022-07-02 04:18:39 +08:00
										 |  |  | 				return | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if closer, ok := enc.(expfmt.Closer); ok { | 
					
						
							|  |  |  | 			closer.Close() | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2019-09-22 22:57:12 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // AuthMiddleware checks if the bearer token is valid and authorized.
 | 
					
						
							|  |  |  | func AuthMiddleware(h http.Handler) http.Handler { | 
					
						
							|  |  |  | 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | 
					
						
							| 
									
										
										
										
											2022-12-07 01:27:26 +08:00
										 |  |  | 		tc, ok := r.Context().Value(mcontext.ContextTraceKey).(*mcontext.TraceCtxt) | 
					
						
							| 
									
										
										
										
											2022-07-02 04:18:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-15 00:09:22 +08:00
										 |  |  | 		claims, groups, owner, authErr := metricsRequestAuthenticate(r) | 
					
						
							| 
									
										
										
										
											2019-09-22 22:57:12 +08:00
										 |  |  | 		if authErr != nil || !claims.VerifyIssuer("prometheus", true) { | 
					
						
							| 
									
										
										
										
											2022-07-02 04:18:39 +08:00
										 |  |  | 			if ok { | 
					
						
							| 
									
										
										
										
											2022-12-07 01:27:26 +08:00
										 |  |  | 				tc.FuncName = "handler.MetricsAuth" | 
					
						
							|  |  |  | 				tc.ResponseRecorder.LogErrBody = true | 
					
						
							| 
									
										
										
										
											2022-07-02 04:18:39 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			writeErrorResponseJSON(r.Context(), w, toAdminAPIErr(r.Context(), errAuthentication), r.URL) | 
					
						
							| 
									
										
										
										
											2019-09-22 22:57:12 +08:00
										 |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-04-23 09:55:30 +08:00
										 |  |  | 		// For authenticated users apply IAM policy.
 | 
					
						
							|  |  |  | 		if !globalIAMSys.IsAllowed(iampolicy.Args{ | 
					
						
							|  |  |  | 			AccountName:     claims.AccessKey, | 
					
						
							| 
									
										
										
										
											2022-01-27 13:53:36 +08:00
										 |  |  | 			Groups:          groups, | 
					
						
							| 
									
										
										
										
											2021-04-23 09:55:30 +08:00
										 |  |  | 			Action:          iampolicy.PrometheusAdminAction, | 
					
						
							|  |  |  | 			ConditionValues: getConditionValues(r, "", claims.AccessKey, claims.Map()), | 
					
						
							|  |  |  | 			IsOwner:         owner, | 
					
						
							|  |  |  | 			Claims:          claims.Map(), | 
					
						
							|  |  |  | 		}) { | 
					
						
							| 
									
										
										
										
											2022-07-02 04:18:39 +08:00
										 |  |  | 			if ok { | 
					
						
							| 
									
										
										
										
											2022-12-07 01:27:26 +08:00
										 |  |  | 				tc.FuncName = "handler.MetricsAuth" | 
					
						
							|  |  |  | 				tc.ResponseRecorder.LogErrBody = true | 
					
						
							| 
									
										
										
										
											2022-07-02 04:18:39 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			writeErrorResponseJSON(r.Context(), w, toAdminAPIErr(r.Context(), errAuthentication), r.URL) | 
					
						
							| 
									
										
										
										
											2021-04-23 09:55:30 +08:00
										 |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-09-22 22:57:12 +08:00
										 |  |  | 		h.ServeHTTP(w, r) | 
					
						
							|  |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2018-04-19 07:01:42 +08:00
										 |  |  | } |