You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

182 lines
6.5 KiB

  1. // Copyright (c) 2015-2024 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. package cmd
  18. import (
  19. "context"
  20. "time"
  21. )
  22. const (
  23. usageSinceLastUpdateSeconds = "since_last_update_seconds"
  24. usageTotalBytes = "total_bytes"
  25. usageObjectsCount = "count"
  26. usageVersionsCount = "versions_count"
  27. usageDeleteMarkersCount = "delete_markers_count"
  28. usageBucketsCount = "buckets_count"
  29. usageSizeDistribution = "size_distribution"
  30. usageVersionCountDistribution = "version_count_distribution"
  31. )
  32. var (
  33. usageSinceLastUpdateSecondsMD = NewGaugeMD(usageSinceLastUpdateSeconds,
  34. "Time since last update of usage metrics in seconds")
  35. usageTotalBytesMD = NewGaugeMD(usageTotalBytes,
  36. "Total cluster usage in bytes")
  37. usageObjectsCountMD = NewGaugeMD(usageObjectsCount,
  38. "Total cluster objects count")
  39. usageVersionsCountMD = NewGaugeMD(usageVersionsCount,
  40. "Total cluster object versions (including delete markers) count")
  41. usageDeleteMarkersCountMD = NewGaugeMD(usageDeleteMarkersCount,
  42. "Total cluster delete markers count")
  43. usageBucketsCountMD = NewGaugeMD(usageBucketsCount,
  44. "Total cluster buckets count")
  45. usageObjectsDistributionMD = NewGaugeMD(usageSizeDistribution,
  46. "Cluster object size distribution", "range")
  47. usageVersionsDistributionMD = NewGaugeMD(usageVersionCountDistribution,
  48. "Cluster object version count distribution", "range")
  49. )
  50. // loadClusterUsageObjectMetrics - reads cluster usage metrics.
  51. //
  52. // This is a `MetricsLoaderFn`.
  53. func loadClusterUsageObjectMetrics(ctx context.Context, m MetricValues, c *metricsCache) error {
  54. dataUsageInfo, err := c.dataUsageInfo.Get()
  55. if err != nil {
  56. metricsLogIf(ctx, err)
  57. return nil
  58. }
  59. // data usage has not captured any data yet.
  60. if dataUsageInfo.LastUpdate.IsZero() {
  61. return nil
  62. }
  63. var (
  64. clusterSize uint64
  65. clusterBuckets uint64
  66. clusterObjectsCount uint64
  67. clusterVersionsCount uint64
  68. clusterDeleteMarkersCount uint64
  69. )
  70. clusterObjectSizesHistogram := map[string]uint64{}
  71. clusterVersionsHistogram := map[string]uint64{}
  72. for _, usage := range dataUsageInfo.BucketsUsage {
  73. clusterBuckets++
  74. clusterSize += usage.Size
  75. clusterObjectsCount += usage.ObjectsCount
  76. clusterVersionsCount += usage.VersionsCount
  77. clusterDeleteMarkersCount += usage.DeleteMarkersCount
  78. for k, v := range usage.ObjectSizesHistogram {
  79. clusterObjectSizesHistogram[k] += v
  80. }
  81. for k, v := range usage.ObjectVersionsHistogram {
  82. clusterVersionsHistogram[k] += v
  83. }
  84. }
  85. m.Set(usageSinceLastUpdateSeconds, time.Since(dataUsageInfo.LastUpdate).Seconds())
  86. m.Set(usageTotalBytes, float64(clusterSize))
  87. m.Set(usageObjectsCount, float64(clusterObjectsCount))
  88. m.Set(usageVersionsCount, float64(clusterVersionsCount))
  89. m.Set(usageDeleteMarkersCount, float64(clusterDeleteMarkersCount))
  90. m.Set(usageBucketsCount, float64(clusterBuckets))
  91. for k, v := range clusterObjectSizesHistogram {
  92. m.Set(usageSizeDistribution, float64(v), "range", k)
  93. }
  94. for k, v := range clusterVersionsHistogram {
  95. m.Set(usageVersionCountDistribution, float64(v), "range", k)
  96. }
  97. return nil
  98. }
  99. const (
  100. usageBucketQuotaTotalBytes = "quota_total_bytes"
  101. usageBucketTotalBytes = "total_bytes"
  102. usageBucketObjectsCount = "objects_count"
  103. usageBucketVersionsCount = "versions_count"
  104. usageBucketDeleteMarkersCount = "delete_markers_count"
  105. usageBucketObjectSizeDistribution = "object_size_distribution"
  106. usageBucketObjectVersionCountDistribution = "object_version_count_distribution"
  107. )
  108. var (
  109. usageBucketTotalBytesMD = NewGaugeMD(usageBucketTotalBytes,
  110. "Total bucket size in bytes", "bucket")
  111. usageBucketObjectsTotalMD = NewGaugeMD(usageBucketObjectsCount,
  112. "Total objects count in bucket", "bucket")
  113. usageBucketVersionsCountMD = NewGaugeMD(usageBucketVersionsCount,
  114. "Total object versions (including delete markers) count in bucket", "bucket")
  115. usageBucketDeleteMarkersCountMD = NewGaugeMD(usageBucketDeleteMarkersCount,
  116. "Total delete markers count in bucket", "bucket")
  117. usageBucketQuotaTotalBytesMD = NewGaugeMD(usageBucketQuotaTotalBytes,
  118. "Total bucket quota in bytes", "bucket")
  119. usageBucketObjectSizeDistributionMD = NewGaugeMD(usageBucketObjectSizeDistribution,
  120. "Bucket object size distribution", "range", "bucket")
  121. usageBucketObjectVersionCountDistributionMD = NewGaugeMD(
  122. usageBucketObjectVersionCountDistribution,
  123. "Bucket object version count distribution", "range", "bucket")
  124. )
  125. // loadClusterUsageBucketMetrics - `MetricsLoaderFn` to load bucket usage metrics.
  126. func loadClusterUsageBucketMetrics(ctx context.Context, m MetricValues, c *metricsCache) error {
  127. dataUsageInfo, err := c.dataUsageInfo.Get()
  128. if err != nil {
  129. metricsLogIf(ctx, err)
  130. return nil
  131. }
  132. // data usage has not been captured yet.
  133. if dataUsageInfo.LastUpdate.IsZero() {
  134. return nil
  135. }
  136. m.Set(usageSinceLastUpdateSeconds, float64(time.Since(dataUsageInfo.LastUpdate)))
  137. for bucket, usage := range dataUsageInfo.BucketsUsage {
  138. quota, err := globalBucketQuotaSys.Get(ctx, bucket)
  139. if err != nil {
  140. // Log and continue if we are unable to retrieve metrics for this
  141. // bucket.
  142. metricsLogIf(ctx, err)
  143. continue
  144. }
  145. m.Set(usageBucketTotalBytes, float64(usage.Size), "bucket", bucket)
  146. m.Set(usageBucketObjectsCount, float64(usage.ObjectsCount), "bucket", bucket)
  147. m.Set(usageBucketVersionsCount, float64(usage.VersionsCount), "bucket", bucket)
  148. m.Set(usageBucketDeleteMarkersCount, float64(usage.DeleteMarkersCount), "bucket", bucket)
  149. if quota != nil && quota.Quota > 0 {
  150. m.Set(usageBucketQuotaTotalBytes, float64(quota.Quota), "bucket", bucket)
  151. }
  152. for k, v := range usage.ObjectSizesHistogram {
  153. m.Set(usageBucketObjectSizeDistribution, float64(v), "range", k, "bucket", bucket)
  154. }
  155. for k, v := range usage.ObjectVersionsHistogram {
  156. m.Set(usageBucketObjectVersionCountDistribution, float64(v), "range", k, "bucket", bucket)
  157. }
  158. }
  159. return nil
  160. }