PureStorage-OpenConnect / pure-fb-openmetrics-exporter

Pure Storage OpenMetrics exporter for FlashBlade
Apache License 2.0
12 stars 10 forks source link

add "account" to exposed metrics for buckets #74

Closed tylergmuir closed 2 months ago

tylergmuir commented 2 months ago

I have a use case where it would be helpful to know the "account" associated with each bucket on a FlashBlade. I think the easiest option would be to add a new label to the purefb_bucket_* metrics called account.

This could be used to make an "account" level dashboard as multiple buckets in the same account are likely related.

The other option would be to have another set of metrics that can be used to map the buckets by account. Such as purefb_account_info where there would be a line per bucket where one of the labels would be the account and one of the labels would be the bucket name. This would also allow for creating a metric for purefb_account_quota_space_bytes since you can set a quota at the account leave that is shared across multiple buckets and this is not currently captured under purefb_buckets_quota_space_bytes.

mboeckelmann commented 2 months ago

@tylergmuir I have tested adding account to metrics by modifying the internal/openmetrics-exporter/buckets_space_collector.go file like below in my own dev env. The account name is already in the bucket data model. You can recompile your container or rebuild your binary after this change.

func (c *BucketsSpaceCollector) Collect(ch chan<- prometheus.Metric) {
    if len(c.Buckets.Items) == 0 {
        return
    }
    for _, bucket := range c.Buckets.Items {
        ch <- prometheus.MustNewConstMetric(
            c.ReductionDesc,
            prometheus.GaugeValue,
            float64(bucket.Space.DataReduction),
            bucket.Name, bucket.Account.Name,
        )
        ch <- prometheus.MustNewConstMetric(
            c.SpaceDesc,
            prometheus.GaugeValue,
            float64(bucket.Space.Snapshots),
            bucket.Name, bucket.Account.Name, "snapshots",
        )
        ch <- prometheus.MustNewConstMetric(
            c.SpaceDesc,
            prometheus.GaugeValue,
            float64(bucket.Space.TotalPhysical),
            bucket.Name, bucket.Account.Name, "total_physical",
        )
        ch <- prometheus.MustNewConstMetric(
            c.SpaceDesc,
            prometheus.GaugeValue,
            float64(bucket.Space.Unique),
            bucket.Name, bucket.Account.Name, "unique",
        )
        ch <- prometheus.MustNewConstMetric(
            c.SpaceDesc,
            prometheus.GaugeValue,
            float64(bucket.Space.Virtual),
            bucket.Name, bucket.Account.Name, "virtual",
        )
        ch <- prometheus.MustNewConstMetric(
            c.SpaceDesc,
            prometheus.GaugeValue,
            float64(bucket.ObjectCount),
            bucket.Name, bucket.Account.Name, "object_count",
        )
        ch <- prometheus.MustNewConstMetric(
            c.BucketObjectCountDesc,
            prometheus.GaugeValue,
            float64(bucket.ObjectCount),
            bucket.Name, bucket.Account.Name,
        )
        ch <- prometheus.MustNewConstMetric(
            c.BucketQuotaDesc,
            prometheus.GaugeValue,
            float64(bucket.QuotaLimit),
            bucket.Name, bucket.Account.Name, strconv.FormatBool(bucket.HardLimitEnabled),
        )
    }
}

func NewBucketsSpaceCollector(bl *client.BucketsList) *BucketsSpaceCollector {
    return &BucketsSpaceCollector{
        ReductionDesc: prometheus.NewDesc(
            "purefb_buckets_space_data_reduction_ratio",
            "FlashBlade buckets space data reduction",
            []string{"name", "account"},
            prometheus.Labels{},
        ),
        SpaceDesc: prometheus.NewDesc(
            "purefb_buckets_space_bytes",
            "FlashBlade buckets space in bytes",
            []string{"name", "account", "space"},
            prometheus.Labels{},
        ),
        BucketQuotaDesc: prometheus.NewDesc(
            "purefb_buckets_quota_space_bytes",
            "FlashBlade buckets quota space in bytes",
            []string{"name", "account", "hard_limit_enabled"},
            prometheus.Labels{},
        ),
        BucketObjectCountDesc: prometheus.NewDesc(
            "purefb_buckets_object_count",
            "FlashBlade buckets object count",
            []string{"name", "account"},
            prometheus.Labels{},
        ),
        Buckets: bl,
    }
}
sdodsley commented 2 months ago

@mboeckelmann i do not see a PR for this change, nor does the current master branch have your amended code in it. Comiling from this repo will not give the expected result.

mboeckelmann commented 2 months ago

@sdodsley apologies. It should read, I have tested a change with this and seen the expected result in my built binary that @tylergmuir is looking for. I haven't changed anything in this repo as I cannot create branches to open a PR against. I will correct the phrasing above comment.

chrroberts-pure commented 2 months ago

@mboeckelmann you are able to open up PRs based off of your forks in your account without having branch access of the origin. I'm happy to show you how, please send me a PM. Thanks.

mboeckelmann commented 2 months ago

@chrroberts-pure @sdodsley thanks for the info. I'll get the PR upped soon. appreciate it.

mboeckelmann commented 2 months ago

77 PR opened for this.

chrroberts-pure commented 2 months ago

Great shout @tylergmuir , if you wish to contribute to our grafana dashboards for an object store account overview - our PRs are always open.

I really like the idea of having a discrete accounts instrument, there's a purity api for GET /object-store-accounts for those metrics if you'd like to implement in the future, though it may be redundant to pull the metrics for each bucket individually per account, it would be good for account space totals.

chrroberts-pure commented 2 months ago

changes merged, will be included in v1.0.13