github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/cmd/data-usage-utils.go (about)

     1  // Copyright (c) 2015-2021 MinIO, Inc.
     2  //
     3  // This file is part of MinIO Object Storage stack
     4  //
     5  // This program is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Affero General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // This program is distributed in the hope that it will be useful
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  // GNU Affero General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Affero General Public License
    16  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17  
    18  package cmd
    19  
    20  import (
    21  	"sort"
    22  	"time"
    23  
    24  	"github.com/minio/madmin-go/v3"
    25  )
    26  
    27  // BucketTargetUsageInfo - bucket target usage info provides
    28  // - replicated size for all objects sent to this target
    29  // - replica size for all objects received from this target
    30  // - replication pending size for all objects pending replication to this target
    31  // - replication failed size for all objects failed replication to this target
    32  // - replica pending count
    33  // - replica failed count
    34  type BucketTargetUsageInfo struct {
    35  	ReplicationPendingSize  uint64 `json:"objectsPendingReplicationTotalSize"`
    36  	ReplicationFailedSize   uint64 `json:"objectsFailedReplicationTotalSize"`
    37  	ReplicatedSize          uint64 `json:"objectsReplicatedTotalSize"`
    38  	ReplicaSize             uint64 `json:"objectReplicaTotalSize"`
    39  	ReplicationPendingCount uint64 `json:"objectsPendingReplicationCount"`
    40  	ReplicationFailedCount  uint64 `json:"objectsFailedReplicationCount"`
    41  	ReplicatedCount         uint64 `json:"objectsReplicatedCount"`
    42  }
    43  
    44  // BucketUsageInfo - bucket usage info provides
    45  // - total size of the bucket
    46  // - total objects in a bucket
    47  // - object size histogram per bucket
    48  type BucketUsageInfo struct {
    49  	Size uint64 `json:"size"`
    50  	// Following five fields suffixed with V1 are here for backward compatibility
    51  	// Total Size for objects that have not yet been replicated
    52  	ReplicationPendingSizeV1 uint64 `json:"objectsPendingReplicationTotalSize"`
    53  	// Total size for objects that have witness one or more failures and will be retried
    54  	ReplicationFailedSizeV1 uint64 `json:"objectsFailedReplicationTotalSize"`
    55  	// Total size for objects that have been replicated to destination
    56  	ReplicatedSizeV1 uint64 `json:"objectsReplicatedTotalSize"`
    57  	// Total number of objects pending replication
    58  	ReplicationPendingCountV1 uint64 `json:"objectsPendingReplicationCount"`
    59  	// Total number of objects that failed replication
    60  	ReplicationFailedCountV1 uint64 `json:"objectsFailedReplicationCount"`
    61  
    62  	ObjectsCount            uint64                           `json:"objectsCount"`
    63  	ObjectSizesHistogram    map[string]uint64                `json:"objectsSizesHistogram"`
    64  	ObjectVersionsHistogram map[string]uint64                `json:"objectsVersionsHistogram"`
    65  	VersionsCount           uint64                           `json:"versionsCount"`
    66  	DeleteMarkersCount      uint64                           `json:"deleteMarkersCount"`
    67  	ReplicaSize             uint64                           `json:"objectReplicaTotalSize"`
    68  	ReplicaCount            uint64                           `json:"objectReplicaCount"`
    69  	ReplicationInfo         map[string]BucketTargetUsageInfo `json:"objectsReplicationInfo"`
    70  }
    71  
    72  // DataUsageInfo represents data usage stats of the underlying Object API
    73  type DataUsageInfo struct {
    74  	TotalCapacity     uint64 `json:"capacity,omitempty"`
    75  	TotalUsedCapacity uint64 `json:"usedCapacity,omitempty"`
    76  	TotalFreeCapacity uint64 `json:"freeCapacity,omitempty"`
    77  
    78  	// LastUpdate is the timestamp of when the data usage info was last updated.
    79  	// This does not indicate a full scan.
    80  	LastUpdate time.Time `json:"lastUpdate"`
    81  
    82  	// Objects total count across all buckets
    83  	ObjectsTotalCount uint64 `json:"objectsCount"`
    84  
    85  	// Versions total count across all buckets
    86  	VersionsTotalCount uint64 `json:"versionsCount"`
    87  
    88  	// Delete markers total count across all buckets
    89  	DeleteMarkersTotalCount uint64 `json:"deleteMarkersCount"`
    90  
    91  	// Objects total size across all buckets
    92  	ObjectsTotalSize uint64                           `json:"objectsTotalSize"`
    93  	ReplicationInfo  map[string]BucketTargetUsageInfo `json:"objectsReplicationInfo"`
    94  
    95  	// Total number of buckets in this cluster
    96  	BucketsCount uint64 `json:"bucketsCount"`
    97  
    98  	// Buckets usage info provides following information across all buckets
    99  	// - total size of the bucket
   100  	// - total objects in a bucket
   101  	// - object size histogram per bucket
   102  	BucketsUsage map[string]BucketUsageInfo `json:"bucketsUsageInfo"`
   103  	// Deprecated kept here for backward compatibility reasons.
   104  	BucketSizes map[string]uint64 `json:"bucketsSizes"`
   105  
   106  	// TierStats contains per-tier stats of all configured remote tiers
   107  	TierStats *allTierStats `json:"tierStats,omitempty"`
   108  }
   109  
   110  func (dui DataUsageInfo) tierStats() []madmin.TierInfo {
   111  	if dui.TierStats == nil {
   112  		return nil
   113  	}
   114  
   115  	if globalTierConfigMgr.Empty() {
   116  		return nil
   117  	}
   118  
   119  	ts := make(map[string]madmin.TierStats)
   120  	dui.TierStats.populateStats(ts)
   121  
   122  	infos := make([]madmin.TierInfo, 0, len(ts))
   123  	for tier, stats := range ts {
   124  		infos = append(infos, madmin.TierInfo{
   125  			Name:  tier,
   126  			Type:  globalTierConfigMgr.TierType(tier),
   127  			Stats: stats,
   128  		})
   129  	}
   130  
   131  	sort.Slice(infos, func(i, j int) bool {
   132  		if infos[i].Type == "internal" {
   133  			return true
   134  		}
   135  		if infos[j].Type == "internal" {
   136  			return false
   137  		}
   138  		return infos[i].Name < infos[j].Name
   139  	})
   140  	return infos
   141  }
   142  
   143  func (dui DataUsageInfo) tierMetrics() (metrics []MetricV2) {
   144  	if dui.TierStats == nil {
   145  		return nil
   146  	}
   147  	// e.g minio_cluster_ilm_transitioned_bytes{tier="S3TIER-1"}=136314880
   148  	//     minio_cluster_ilm_transitioned_objects{tier="S3TIER-1"}=1
   149  	//     minio_cluster_ilm_transitioned_versions{tier="S3TIER-1"}=3
   150  	for tier, st := range dui.TierStats.Tiers {
   151  		metrics = append(metrics, MetricV2{
   152  			Description:    getClusterTransitionedBytesMD(),
   153  			Value:          float64(st.TotalSize),
   154  			VariableLabels: map[string]string{"tier": tier},
   155  		})
   156  		metrics = append(metrics, MetricV2{
   157  			Description:    getClusterTransitionedObjectsMD(),
   158  			Value:          float64(st.NumObjects),
   159  			VariableLabels: map[string]string{"tier": tier},
   160  		})
   161  		metrics = append(metrics, MetricV2{
   162  			Description:    getClusterTransitionedVersionsMD(),
   163  			Value:          float64(st.NumVersions),
   164  			VariableLabels: map[string]string{"tier": tier},
   165  		})
   166  	}
   167  
   168  	return metrics
   169  }