| 
									
										
										
										
											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" | 
					
						
							| 
									
										
										
										
											2020-05-04 13:35:40 +08:00
										 |  |  | 	"sync/atomic" | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 	"time" | 
					
						
							| 
									
										
										
										
											2018-04-19 07:01:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-02 05:59:40 +08:00
										 |  |  | 	"github.com/minio/minio/internal/logger" | 
					
						
							| 
									
										
										
										
											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" | 
					
						
							| 
									
										
										
										
											2018-05-09 11:10:55 +08:00
										 |  |  | 	"github.com/prometheus/client_golang/prometheus/promhttp" | 
					
						
							| 
									
										
										
										
											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" | 
					
						
							|  |  |  | 	gatewayNamespace     = "gateway" | 
					
						
							|  |  |  | 	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
										 |  |  | 	gatewayMetricsPrometheus(ch) | 
					
						
							|  |  |  | 	healingMetricsPrometheus(ch) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | func nodeHealthMetricsPrometheus(ch chan<- prometheus.Metric) { | 
					
						
							| 
									
										
										
										
											2021-11-09 01:07:58 +08:00
										 |  |  | 	if globalIsGateway { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 	nodesUp, nodesDown := GetPeerOnlineCount() | 
					
						
							|  |  |  | 	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) { | 
					
						
							| 
									
										
										
										
											2020-06-13 11:04:01 +08:00
										 |  |  | 	if !globalIsErasure { | 
					
						
							| 
									
										
										
										
											2019-10-23 12:01:14 +08:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 	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 gateway specific metrics for MinIO instance in Prometheus specific format
 | 
					
						
							|  |  |  | // and sends to given channel
 | 
					
						
							|  |  |  | func gatewayMetricsPrometheus(ch chan<- prometheus.Metric) { | 
					
						
							| 
									
										
										
										
											2020-08-26 23:52:46 +08:00
										 |  |  | 	if !globalIsGateway || (globalGatewayName != S3BackendGateway && globalGatewayName != AzureBackendGateway && globalGatewayName != GCSBackendGateway) { | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-05-30 12:43:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-10 00:30:02 +08:00
										 |  |  | 	m, err := objLayer.GetMetrics(GlobalContext) | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-05-30 12:43:46 +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(gatewayNamespace, globalGatewayName, "bytes_received"), | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 			"Total number of bytes received by current MinIO Gateway "+globalGatewayName+" backend", | 
					
						
							| 
									
										
										
										
											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(m.GetBytesReceived()), | 
					
						
							| 
									
										
										
										
											2018-05-09 11:10:55 +08:00
										 |  |  | 	) | 
					
						
							| 
									
										
										
										
											2019-04-05 12:21:50 +08:00
										 |  |  | 	ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 		prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 			prometheus.BuildFQName(gatewayNamespace, globalGatewayName, "bytes_sent"), | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 			"Total number of bytes sent by current MinIO Gateway to "+globalGatewayName+" backend", | 
					
						
							| 
									
										
										
										
											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(m.GetBytesSent()), | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 	s := m.GetRequests() | 
					
						
							|  |  |  | 	ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 		prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 			prometheus.BuildFQName(gatewayNamespace, globalGatewayName, "requests"), | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 			"Total number of requests made to "+globalGatewayName+" by current MinIO Gateway", | 
					
						
							|  |  |  | 			[]string{"method"}, nil), | 
					
						
							|  |  |  | 		prometheus.CounterValue, | 
					
						
							| 
									
										
										
										
											2020-05-04 13:35:40 +08:00
										 |  |  | 		float64(atomic.LoadUint64(&s.Get)), | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 		http.MethodGet, | 
					
						
							| 
									
										
										
										
											2019-04-05 12:21:50 +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(gatewayNamespace, globalGatewayName, "requests"), | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 			"Total number of requests made to "+globalGatewayName+" by current MinIO Gateway", | 
					
						
							|  |  |  | 			[]string{"method"}, nil), | 
					
						
							|  |  |  | 		prometheus.CounterValue, | 
					
						
							| 
									
										
										
										
											2020-05-04 13:35:40 +08:00
										 |  |  | 		float64(atomic.LoadUint64(&s.Head)), | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 		http.MethodHead, | 
					
						
							|  |  |  | 	) | 
					
						
							| 
									
										
										
										
											2020-04-02 03:52:31 +08:00
										 |  |  | 	ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 		prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 			prometheus.BuildFQName(gatewayNamespace, globalGatewayName, "requests"), | 
					
						
							| 
									
										
										
										
											2020-04-02 03:52:31 +08:00
										 |  |  | 			"Total number of requests made to "+globalGatewayName+" by current MinIO Gateway", | 
					
						
							|  |  |  | 			[]string{"method"}, nil), | 
					
						
							|  |  |  | 		prometheus.CounterValue, | 
					
						
							| 
									
										
										
										
											2020-05-04 13:35:40 +08:00
										 |  |  | 		float64(atomic.LoadUint64(&s.Put)), | 
					
						
							| 
									
										
										
										
											2020-04-02 03:52:31 +08:00
										 |  |  | 		http.MethodPut, | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 	ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 		prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 			prometheus.BuildFQName(gatewayNamespace, globalGatewayName, "requests"), | 
					
						
							| 
									
										
										
										
											2020-04-02 03:52:31 +08:00
										 |  |  | 			"Total number of requests made to "+globalGatewayName+" by current MinIO Gateway", | 
					
						
							|  |  |  | 			[]string{"method"}, nil), | 
					
						
							|  |  |  | 		prometheus.CounterValue, | 
					
						
							| 
									
										
										
										
											2020-05-04 13:35:40 +08:00
										 |  |  | 		float64(atomic.LoadUint64(&s.Post)), | 
					
						
							| 
									
										
										
										
											2020-04-02 03:52:31 +08:00
										 |  |  | 		http.MethodPost, | 
					
						
							|  |  |  | 	) | 
					
						
							| 
									
										
										
										
											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"), | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 			"Total number of disk 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"), | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 			"Total number of disk 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"), | 
					
						
							|  |  |  | 				"Indicates total size of cache disk", | 
					
						
							|  |  |  | 				[]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 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-29 04:04:26 +08:00
										 |  |  | 	if globalIsGateway { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-27 21:45:43 +08:00
										 |  |  | 	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 { | 
					
						
							| 
									
										
										
										
											2021-04-04 00:03:42 +08:00
										 |  |  | 		stat := 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
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if globalIsGateway { | 
					
						
							|  |  |  | 		return | 
					
						
							| 
									
										
										
										
											2019-12-06 15:16:06 +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
										 |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	s, _ := objLayer.StorageInfo(GlobalContext) | 
					
						
							|  |  |  | 	// 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, | 
					
						
							| 
									
										
										
										
											2021-02-05 04:26:58 +08:00
										 |  |  | 		GetTotalUsableCapacity(server.Disks, s), | 
					
						
							| 
									
										
										
										
											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, | 
					
						
							| 
									
										
										
										
											2021-02-05 04:26:58 +08:00
										 |  |  | 		GetTotalUsableCapacityFree(server.Disks, s), | 
					
						
							| 
									
										
										
										
											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"), | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 			"Total number of offline disks in current MinIO server instance", | 
					
						
							|  |  |  | 			nil, nil), | 
					
						
							|  |  |  | 		prometheus.GaugeValue, | 
					
						
							|  |  |  | 		float64(offlineDisks.Sum()), | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// MinIO Total Disks per node
 | 
					
						
							|  |  |  | 	ch <- prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 		prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 			prometheus.BuildFQName(minioNamespace, "disks", "total"), | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 			"Total number of disks for current MinIO server instance", | 
					
						
							|  |  |  | 			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"), | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 				"Total disk storage used on the disk", | 
					
						
							|  |  |  | 				[]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"), | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 				"Total available space left on the disk", | 
					
						
							|  |  |  | 				[]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"), | 
					
						
							| 
									
										
										
										
											2020-03-25 13:40:45 +08:00
										 |  |  | 				"Total space on the disk", | 
					
						
							|  |  |  | 				[]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() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-27 01:36:54 +08:00
										 |  |  | 	err := registry.Register(minioVersionInfo) | 
					
						
							| 
									
										
										
										
											2020-04-10 00:30:02 +08:00
										 |  |  | 	logger.LogIf(GlobalContext, err) | 
					
						
							| 
									
										
										
										
											2019-06-27 01:36:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	err = registry.Register(httpRequestsDuration) | 
					
						
							| 
									
										
										
										
											2020-04-10 00:30:02 +08:00
										 |  |  | 	logger.LogIf(GlobalContext, err) | 
					
						
							| 
									
										
										
										
											2018-05-09 11:10:55 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	err = registry.Register(newMinioCollector()) | 
					
						
							| 
									
										
										
										
											2020-04-10 00:30:02 +08:00
										 |  |  | 	logger.LogIf(GlobalContext, err) | 
					
						
							| 
									
										
										
										
											2018-05-09 11:10:55 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	gatherers := prometheus.Gatherers{ | 
					
						
							|  |  |  | 		prometheus.DefaultGatherer, | 
					
						
							|  |  |  | 		registry, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// Delegate http serving to Prometheus client library, which will call collector.Collect.
 | 
					
						
							|  |  |  | 	return promhttp.InstrumentMetricHandler( | 
					
						
							|  |  |  | 		registry, | 
					
						
							|  |  |  | 		promhttp.HandlerFor(gatherers, | 
					
						
							|  |  |  | 			promhttp.HandlerOpts{ | 
					
						
							|  |  |  | 				ErrorHandling: promhttp.ContinueOnError, | 
					
						
							|  |  |  | 			}), | 
					
						
							|  |  |  | 	) | 
					
						
							| 
									
										
										
										
											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-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) { | 
					
						
							|  |  |  | 			w.WriteHeader(http.StatusForbidden) | 
					
						
							|  |  |  | 			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(), | 
					
						
							|  |  |  | 		}) { | 
					
						
							|  |  |  | 			w.WriteHeader(http.StatusForbidden) | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-09-22 22:57:12 +08:00
										 |  |  | 		h.ServeHTTP(w, r) | 
					
						
							|  |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2018-04-19 07:01:42 +08:00
										 |  |  | } |