2022-07-05 17:45:49 -04:00
|
|
|
// Copyright (c) 2015-2022 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/>.
|
|
|
|
|
|
|
|
package cmd
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/minio/madmin-go"
|
2022-08-16 10:13:49 -04:00
|
|
|
"github.com/minio/minio/internal/disk"
|
2022-07-05 17:45:49 -04:00
|
|
|
)
|
|
|
|
|
2022-10-03 05:10:15 -04:00
|
|
|
type collectMetricsOpts struct {
|
|
|
|
hosts map[string]struct{}
|
|
|
|
disks map[string]struct{}
|
|
|
|
jobID string
|
2022-11-14 10:16:40 -05:00
|
|
|
depID string
|
2022-10-03 05:10:15 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
func collectLocalMetrics(types madmin.MetricType, opts collectMetricsOpts) (m madmin.RealtimeMetrics) {
|
2022-07-05 17:45:49 -04:00
|
|
|
if types == madmin.MetricsNone {
|
|
|
|
return
|
|
|
|
}
|
2022-08-16 10:13:49 -04:00
|
|
|
|
2022-10-03 05:10:15 -04:00
|
|
|
if len(opts.hosts) > 0 {
|
|
|
|
if _, ok := opts.hosts[globalMinioAddr]; !ok {
|
2022-07-05 17:45:49 -04:00
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
2022-08-16 10:13:49 -04:00
|
|
|
|
2022-10-03 05:10:15 -04:00
|
|
|
if types.Contains(madmin.MetricsDisk) {
|
2022-08-16 10:13:49 -04:00
|
|
|
m.ByDisk = make(map[string]madmin.DiskMetric)
|
|
|
|
aggr := madmin.DiskMetric{
|
|
|
|
CollectedAt: time.Now(),
|
|
|
|
}
|
2022-10-03 05:10:15 -04:00
|
|
|
for name, disk := range collectLocalDisksMetrics(opts.disks) {
|
2022-08-16 10:13:49 -04:00
|
|
|
m.ByDisk[name] = disk
|
|
|
|
aggr.Merge(&disk)
|
|
|
|
}
|
|
|
|
m.Aggregated.Disk = &aggr
|
|
|
|
}
|
|
|
|
|
2022-07-05 17:45:49 -04:00
|
|
|
if types.Contains(madmin.MetricsScanner) {
|
|
|
|
metrics := globalScannerMetrics.report()
|
|
|
|
m.Aggregated.Scanner = &metrics
|
|
|
|
}
|
|
|
|
if types.Contains(madmin.MetricsOS) {
|
|
|
|
metrics := globalOSMetrics.report()
|
|
|
|
m.Aggregated.OS = &metrics
|
|
|
|
}
|
2022-10-03 05:10:15 -04:00
|
|
|
if types.Contains(madmin.MetricsBatchJobs) {
|
|
|
|
m.Aggregated.BatchJobs = globalBatchJobsMetrics.report(opts.jobID)
|
|
|
|
}
|
2022-11-14 10:16:40 -05:00
|
|
|
if types.Contains(madmin.MetricsSiteResync) {
|
|
|
|
m.Aggregated.SiteResync = globalSiteResyncMetrics.report(opts.depID)
|
|
|
|
}
|
2022-07-05 17:45:49 -04:00
|
|
|
// Add types...
|
|
|
|
|
|
|
|
// ByHost is a shallow reference, so careful about sharing.
|
|
|
|
m.ByHost = map[string]madmin.Metrics{globalMinioAddr: m.Aggregated}
|
|
|
|
m.Hosts = append(m.Hosts, globalMinioAddr)
|
|
|
|
|
|
|
|
return m
|
|
|
|
}
|
|
|
|
|
2022-08-16 10:13:49 -04:00
|
|
|
func collectLocalDisksMetrics(disks map[string]struct{}) map[string]madmin.DiskMetric {
|
2022-07-05 17:45:49 -04:00
|
|
|
objLayer := newObjectLayerFn()
|
|
|
|
if objLayer == nil {
|
|
|
|
return nil
|
|
|
|
}
|
2022-08-16 10:13:49 -04:00
|
|
|
|
|
|
|
metrics := make(map[string]madmin.DiskMetric)
|
|
|
|
|
|
|
|
procStats, procErr := disk.GetAllDrivesIOStats()
|
|
|
|
if procErr != nil {
|
|
|
|
return metrics
|
|
|
|
}
|
|
|
|
|
2022-07-05 17:45:49 -04:00
|
|
|
// only need Disks information in server mode.
|
|
|
|
storageInfo, errs := objLayer.LocalStorageInfo(GlobalContext)
|
2022-08-16 10:13:49 -04:00
|
|
|
|
|
|
|
for i, d := range storageInfo.Disks {
|
|
|
|
if len(disks) != 0 {
|
|
|
|
_, ok := disks[d.Endpoint]
|
|
|
|
if !ok {
|
|
|
|
continue
|
|
|
|
}
|
2022-07-05 17:45:49 -04:00
|
|
|
}
|
2022-08-16 10:13:49 -04:00
|
|
|
|
2022-07-05 17:45:49 -04:00
|
|
|
if errs[i] != nil {
|
2022-08-16 10:13:49 -04:00
|
|
|
metrics[d.Endpoint] = madmin.DiskMetric{NDisks: 1, Offline: 1}
|
2022-07-05 17:45:49 -04:00
|
|
|
continue
|
|
|
|
}
|
2022-08-16 10:13:49 -04:00
|
|
|
|
|
|
|
var dm madmin.DiskMetric
|
|
|
|
dm.NDisks = 1
|
|
|
|
if d.Healing {
|
|
|
|
dm.Healing++
|
2022-07-05 17:45:49 -04:00
|
|
|
}
|
2022-08-16 10:13:49 -04:00
|
|
|
if d.Metrics != nil {
|
|
|
|
dm.LifeTimeOps = make(map[string]uint64, len(d.Metrics.APICalls))
|
|
|
|
for k, v := range d.Metrics.APICalls {
|
2022-07-05 17:45:49 -04:00
|
|
|
if v != 0 {
|
2022-08-16 10:13:49 -04:00
|
|
|
dm.LifeTimeOps[k] = v
|
2022-07-05 17:45:49 -04:00
|
|
|
}
|
|
|
|
}
|
2022-08-16 10:13:49 -04:00
|
|
|
dm.LastMinute.Operations = make(map[string]madmin.TimedAction, len(d.Metrics.APICalls))
|
|
|
|
for k, v := range d.Metrics.LastMinute {
|
2022-07-05 17:45:49 -04:00
|
|
|
if v.Count != 0 {
|
2022-08-16 10:13:49 -04:00
|
|
|
dm.LastMinute.Operations[k] = v
|
2022-07-05 17:45:49 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-08-16 10:13:49 -04:00
|
|
|
|
|
|
|
// get disk
|
|
|
|
if procErr == nil {
|
|
|
|
st := procStats[disk.DevID{Major: d.Major, Minor: d.Minor}]
|
|
|
|
dm.IOStats = madmin.DiskIOStats{
|
|
|
|
ReadIOs: st.ReadIOs,
|
|
|
|
ReadMerges: st.ReadMerges,
|
|
|
|
ReadSectors: st.ReadSectors,
|
|
|
|
ReadTicks: st.ReadTicks,
|
|
|
|
WriteIOs: st.WriteIOs,
|
|
|
|
WriteMerges: st.WriteMerges,
|
|
|
|
WriteSectors: st.WriteSectors,
|
|
|
|
WriteTicks: st.WriteTicks,
|
|
|
|
CurrentIOs: st.CurrentIOs,
|
|
|
|
TotalTicks: st.TotalTicks,
|
|
|
|
ReqTicks: st.ReqTicks,
|
|
|
|
DiscardIOs: st.DiscardIOs,
|
|
|
|
DiscardMerges: st.DiscardMerges,
|
|
|
|
DiscardSectors: st.DiscardSectors,
|
|
|
|
DiscardTicks: st.DiscardTicks,
|
|
|
|
FlushIOs: st.FlushIOs,
|
|
|
|
FlushTicks: st.FlushTicks,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
metrics[d.Endpoint] = dm
|
2022-07-05 17:45:49 -04:00
|
|
|
}
|
2022-08-16 10:13:49 -04:00
|
|
|
return metrics
|
2022-07-05 17:45:49 -04:00
|
|
|
}
|
|
|
|
|
2022-10-03 05:10:15 -04:00
|
|
|
func collectRemoteMetrics(ctx context.Context, types madmin.MetricType, opts collectMetricsOpts) (m madmin.RealtimeMetrics) {
|
2022-07-05 17:45:49 -04:00
|
|
|
if !globalIsDistErasure {
|
|
|
|
return
|
|
|
|
}
|
2022-10-03 05:10:15 -04:00
|
|
|
all := globalNotificationSys.GetMetrics(ctx, types, opts)
|
2022-07-05 17:45:49 -04:00
|
|
|
for _, remote := range all {
|
|
|
|
m.Merge(&remote)
|
|
|
|
}
|
|
|
|
return m
|
|
|
|
}
|