Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add metric for disk info & last update #83

Merged
merged 4 commits into from
Jan 22, 2024
Merged

Conversation

dannykopping
Copy link
Contributor

@dannykopping dannykopping commented Jan 17, 2024

This PR adds a unused_disks_last_used_at metric which exports the disk, PVC, and PV identifiers. The value of the gauge is the last time the disk was mounted (although this is only available on GCP for now).

I want to use this metric to create an alert for a PVC which exists without its underlying disk/volume, which happened to my team recently when we ran a script to cleanup unused disks (but it didn't clean up the associated PVCs).

To my knowledge, neither opencost nor kube-state-metrics export a metric which allows 3-way correlation between PVCs, PVs, and their underlying disks.

Signed-off-by: Danny Kopping <[email protected]>
Copy link
Contributor

@fedordikarev fedordikarev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That looks great to me 👍
Thanks for introducing methods for Meta, that's very helpful!

@dannykopping
Copy link
Contributor Author

Thanks @fedordikarev
Do we need anyone else's approval before we merge?

Copy link
Contributor Author

@dannykopping dannykopping left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aws/provider.go Show resolved Hide resolved
@fedordikarev
Copy link
Contributor

@dannykopping one review was enough for the past PRs
from what I see on changes:

  • allign aws provider with other providers by adding logging
  • helpers functions for Meta
  • adding new prometheus metric similar to existing ones
    my guess is that such changes shouldn't require much efforts (well, maybe an issue created but with detailed PR description that also could be not required here).

we may wait for @inkel review as he is initial author of the tool and introduced structure for code and modules.

Pokom
Pokom previously approved these changes Jan 19, 2024
Copy link
Contributor

@Pokom Pokom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a minor nit and suggestion to add some tests for the new meta methods. Tested locally and was able to see the metrics, thanks Danny!

cmd/unused-exporter/exporter.go Outdated Show resolved Hide resolved
Comment on lines +66 to +97
func (m Meta) CreatedForPV() string {
return m.coalesce("kubernetes.io/created-for/pv/name", "kubernetes.io-created-for-pv-name")
}

func (m Meta) CreatedForPVC() string {
return m.coalesce("kubernetes.io/created-for/pvc/name", "kubernetes.io-created-for-pvc-name")
}

func (m Meta) CreatedForNamespace() string {
return m.coalesce("kubernetes.io/created-for/pvc/namespace", "kubernetes.io-created-for-pvc-namespace")
}

func (m Meta) CreatedBy() string {
return m.coalesce("storage.gke.io/created-by", "created-by")
}

func (m Meta) Zone() string {
return m.coalesce("zone", "location")
}

func (m Meta) coalesce(keys ...string) string {
for _, k := range keys {
v, ok := m[k]
if !ok {
continue
}

return v
}

return ""
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great and really like how it cleaned up the outside code. Do you think there's value in creating a small test suite for these?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, please.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be clear: do you just want a test suite for the coalesce function?
I don't see much value in testing the getters.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

coalesce and Meta.Equal 🙏🏽

Copy link
Collaborator

@inkel inkel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @dannykopping for your contribution! In general LGTM, but I've some questions before merging this one. Also I'd like to see @Pokom comments addressed too, particularly regarding the tests for the new Meta methods.

aws/provider.go Show resolved Hide resolved
cmd/unused-exporter/exporter.go Outdated Show resolved Hide resolved
meta.go Outdated
Comment on lines 36 to 44
akeys := m.Keys()
bkeys := b.Keys()

if len(akeys) != len(bkeys) {
return false
}

sort.Strings(akeys)
sort.Strings(bkeys)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why pulling and sorting the keys? They don't seem to be used at all. The same could be achieved in a more performant way like this:

Suggested change
akeys := m.Keys()
bkeys := b.Keys()
if len(akeys) != len(bkeys) {
return false
}
sort.Strings(akeys)
sort.Strings(bkeys)
if len(m) != len(b) {
return false
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad, I missed something here. I should be iterating over akeys to see if bkeys exist in the reference map and its value is equivalent. I'll fix this up.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, there's no need to sort the keys for that either. Just ranging on m will test that b indeed has the same keys and value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, I wonder what I was thinking here 🙃 I'll try remind myself when I come back to this.

meta.go Outdated
Comment on lines 48 to 54
if !ok {
return false
}

if av != bv {
return false
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about this:

Suggested change
if !ok {
return false
}
if av != bv {
return false
}
if !ok || av != bv {
return false
}

Comment on lines +66 to +97
func (m Meta) CreatedForPV() string {
return m.coalesce("kubernetes.io/created-for/pv/name", "kubernetes.io-created-for-pv-name")
}

func (m Meta) CreatedForPVC() string {
return m.coalesce("kubernetes.io/created-for/pvc/name", "kubernetes.io-created-for-pvc-name")
}

func (m Meta) CreatedForNamespace() string {
return m.coalesce("kubernetes.io/created-for/pvc/namespace", "kubernetes.io-created-for-pvc-namespace")
}

func (m Meta) CreatedBy() string {
return m.coalesce("storage.gke.io/created-by", "created-by")
}

func (m Meta) Zone() string {
return m.coalesce("zone", "location")
}

func (m Meta) coalesce(keys ...string) string {
for _, k := range keys {
v, ok := m[k]
if !ok {
continue
}

return v
}

return ""
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, please.

Comment on lines 153 to 157
ts := 0.0
lastUsed := d.LastUsedAt()
if !lastUsed.IsZero() {
ts = float64(lastUsed.UnixMilli())
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dannykopping looks like the suggestion wasn't formatted properly 😭

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I has spaces at the end! Fire up your Emacs, M-x delete-trailing-whitespace et voilà! Or just add a before-save-hook that runs it automatically 😬

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My guess is that Danny used my suggestion, which wasn't formatted properly.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, my comment still stands 😉

Also changed test package so unexported functions could be tested

Signed-off-by: Danny Kopping <[email protected]>
@dannykopping
Copy link
Contributor Author

@inkel @Pokom please have another look; I've addressed your comments

Copy link
Collaborator

@inkel inkel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Left a small question but I don't think it's blocking this.

cmd/unused-exporter/exporter.go Show resolved Hide resolved
@inkel inkel merged commit 54bcedb into main Jan 22, 2024
2 checks passed
@inkel inkel deleted the dannykopping/last-used branch January 22, 2024 14:41
@inkel
Copy link
Collaborator

inkel commented Jan 22, 2024

Thank you for your contribution, @dannykopping!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants