From 51a36c047d0c93ba133ea487c7d6eaf82c122c6b Mon Sep 17 00:00:00 2001 From: Niladri Halder Date: Mon, 17 Jun 2024 08:00:08 +0000 Subject: [PATCH 1/3] feat(event): add NodeCount, ReplicaCount, VolumeCapacity event fields Signed-off-by: Niladri Halder --- README.md | 4 +--- example/main.go | 6 +++--- pkg/event/build.go | 24 ++++++++++++------------ usage/usage.go | 44 ++++++++++---------------------------------- 4 files changed, 26 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index 67e9cdb..7b3f260 100644 --- a/README.md +++ b/README.md @@ -53,9 +53,7 @@ Create a new `client` and `Send()` an 'event'. VolumeName("pvc-b3968e30-9020-4011-943a-7ab338d5f19f"). VolumeClaimName("openebs-lvmpv"). Category("volume-deprovision"). - Action("replica:2"). - Label("Capacity"). - Value("2Gi"). + NodeCount("3"). Build() err = client.Send(event) diff --git a/example/main.go b/example/main.go index 18afed5..991da13 100644 --- a/example/main.go +++ b/example/main.go @@ -30,9 +30,9 @@ func main() { VolumeName("pvc-b3968e30-9020-4011-943a-7ab338d5f19f"). VolumeClaimName("openebs-lvmpv"). Category("volume_deprovision"). - Action("replica"). - Label("Capacity"). - Value("2"). + NodeCount("2"). + VolumeCapacity("19238457924875977657"). + ReplicaCount("1000"). Build() err = client.Send(event) diff --git a/pkg/event/build.go b/pkg/event/build.go index 369e743..6d86ebb 100644 --- a/pkg/event/build.go +++ b/pkg/event/build.go @@ -44,12 +44,12 @@ type OpenebsEvent struct { VolumeClaimName string `json:"vol_claim_name"` // Category of event, i.e install, volume-provision Category string `json:"event_category"` - // Action of the event, i.e running, replica:1 - Action string `json:"event_action"` - // Label for the event, i.e nodes, capacity - Label string `json:"event_label"` - // Value for the label, i.e 4, 2 - Value string `json:"event_value"` + // NodeCount is the number of kubernetes nodes in the cluster. + NodeCount string `json:"node_count"` + // VolumeCapacity is the size of a volume. + VolumeCapacity string `json:"vol_capacity,omitempty"` + // ReplicaCount is the number of replicas attached to a volume. + ReplicaCount string `json:"vol_replica_count,omitempty"` } // OpenebsEventBuilder is builder for OpenebsEvent @@ -123,18 +123,18 @@ func (b *OpenebsEventBuilder) Category(category string) *OpenebsEventBuilder { return b } -func (b *OpenebsEventBuilder) Action(action string) *OpenebsEventBuilder { - b.openebsEvent.Action = action +func (b *OpenebsEventBuilder) NodeCount(nodeCount string) *OpenebsEventBuilder { + b.openebsEvent.NodeCount = nodeCount return b } -func (b *OpenebsEventBuilder) Label(label string) *OpenebsEventBuilder { - b.openebsEvent.Label = label +func (b *OpenebsEventBuilder) ReplicaCount(replicaCount string) *OpenebsEventBuilder { + b.openebsEvent.ReplicaCount = replicaCount return b } -func (b *OpenebsEventBuilder) Value(value string) *OpenebsEventBuilder { - b.openebsEvent.Value = value +func (b *OpenebsEventBuilder) VolumeCapacity(capacity string) *OpenebsEventBuilder { + b.openebsEvent.VolumeCapacity = capacity return b } diff --git a/usage/usage.go b/usage/usage.go index 16befb7..430fc91 100644 --- a/usage/usage.go +++ b/usage/usage.go @@ -19,11 +19,11 @@ package usage import ( "strconv" - k8sapi "github.com/openebs/lib-csi/pkg/client/k8s" "k8s.io/klog/v2" ga4Client "github.com/openebs/google-analytics-4/pkg/client" ga4Event "github.com/openebs/google-analytics-4/pkg/event" + k8sapi "github.com/openebs/lib-csi/pkg/client/k8s" ) // Usage struct represents all information about a usage metric sent to @@ -67,44 +67,22 @@ func (u *Usage) SetCategory(c string) *Usage { return u } -// SetAction sets the action of an event -func (u *Usage) SetAction(a string) *Usage { - u.OpenebsEventBuilder.Action(a) - return u -} - -// SetLabel sets the label for an event -func (u *Usage) SetLabel(l string) *Usage { - u.OpenebsEventBuilder.Label(l) +// SetNodeCount sets the node count for a k8s cluster. +func (u *Usage) SetNodeCount(n string) *Usage { + u.OpenebsEventBuilder.NodeCount(n) return u } -// SetValue sets the value for an event's label -func (u *Usage) SetValue(v string) *Usage { - u.OpenebsEventBuilder.Value(v) - return u -} - -// SetVolumeCapacity sets the storage capacity of the volume for a volume event +// SetVolumeCapacity sets the size of a volume. func (u *Usage) SetVolumeCapacity(volCapG string) *Usage { s, _ := toGigaUnits(volCapG) - u.SetValue(strconv.FormatInt(s, 10)) + u.OpenebsEventBuilder.VolumeCapacity(strconv.FormatInt(s, 10)) return u } -// SetReplicaCount Wrapper for setting replica count for volume events -// NOTE: This doesn't get the replica count in a volume de-provision event. -// TODO: Pick the current value of replica-count from the CAS-engine -func (u *Usage) SetReplicaCount(count, method string) *Usage { - if method == VolumeProvision && count == "" { - // Case: When volume-provision the replica count isn't specified - // it is set to three by default by the m-apiserver - u.OpenebsEventBuilder.Action(DefaultReplicaCount) - } else { - // Catch all case for volume-deprovision event and - // volume-provision event with an overridden replica-count - u.OpenebsEventBuilder.Action(Replica + count) - } +// SetReplicaCount sets the number of replicas for a volume. +func (u *Usage) SetReplicaCount(replicaCount string) *Usage { + u.OpenebsEventBuilder.ReplicaCount(replicaCount) return u } @@ -149,9 +127,7 @@ func (u *Usage) InstallBuilder(override bool) *Usage { u.OpenebsEventBuilder. K8sDefaultNsUid(v.id). Category(InstallEvent). - Action(RunningStatus). - Label(EventLabelNode). - Value(strconv.Itoa(clusterSize)) + NodeCount(strconv.Itoa(clusterSize)) return u } From cb1379608beca8a8b54bc21fa6dd9f01c59863e2 Mon Sep 17 00:00:00 2001 From: Niladri Halder Date: Mon, 17 Jun 2024 18:07:08 +0000 Subject: [PATCH 2/3] fix(usage): report volume capacities in human readable formats using IEC units Signed-off-by: Niladri Halder --- go.mod | 2 +- go.sum | 4 ++-- usage/usage.go | 4 ++-- usage/utils.go | 14 +++++++------- usage/utils_test.go | 30 ++++++++++++------------------ 5 files changed, 24 insertions(+), 30 deletions(-) diff --git a/go.mod b/go.mod index fc0d82c..b19ee24 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/openebs/google-analytics-4 go 1.19 require ( - github.com/docker/go-units v0.5.0 + github.com/dustin/go-humanize v1.0.1 github.com/openebs/lib-csi v0.8.2 k8s.io/apimachinery v0.27.2 k8s.io/klog/v2 v2.100.1 diff --git a/go.sum b/go.sum index 6df80d5..db85e3c 100644 --- a/go.sum +++ b/go.sum @@ -14,9 +14,9 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= -github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/emicklei/go-restful/v3 v3.10.2 h1:hIovbnmBTLjHXkqEBUz3HGpXZdM7ZrE9fJIZIqlJLqE= github.com/emicklei/go-restful/v3 v3.10.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= diff --git a/usage/usage.go b/usage/usage.go index 430fc91..139ae10 100644 --- a/usage/usage.go +++ b/usage/usage.go @@ -75,8 +75,8 @@ func (u *Usage) SetNodeCount(n string) *Usage { // SetVolumeCapacity sets the size of a volume. func (u *Usage) SetVolumeCapacity(volCapG string) *Usage { - s, _ := toGigaUnits(volCapG) - u.OpenebsEventBuilder.VolumeCapacity(strconv.FormatInt(s, 10)) + s, _ := toHumanSize(volCapG) + u.OpenebsEventBuilder.VolumeCapacity(s) return u } diff --git a/usage/utils.go b/usage/utils.go index 68ac531..23a0132 100644 --- a/usage/utils.go +++ b/usage/utils.go @@ -16,12 +16,12 @@ limitations under the License. package usage -import "github.com/docker/go-units" +import ( + "github.com/dustin/go-humanize" +) -// toGigaUnits converts a size from xB to bytes where x={k,m,g,t,p...} -// and return the number of Gigabytes as an integer -// 1 gigabyte=1000 megabyte -func toGigaUnits(size string) (int64, error) { - sizeInBytes, err := units.FromHumanSize(size) - return sizeInBytes / units.GB, err +// toHumanSize converts sizes to legible human sizes in IEC units. +func toHumanSize(size string) (string, error) { + sizeInBytes, err := humanize.ParseBigBytes(size) + return humanize.BigIBytes(sizeInBytes), err } diff --git a/usage/utils_test.go b/usage/utils_test.go index 8407d09..fee0b5d 100644 --- a/usage/utils_test.go +++ b/usage/utils_test.go @@ -18,44 +18,38 @@ package usage import "testing" -func TestToGigaUnits(t *testing.T) { +func TestToHumanSize(t *testing.T) { tests := map[string]struct { - stringSize string - expectedGsize int64 - positiveTest bool + stringSize string + expectedSize string + positiveTest bool }{ - "One Hundred Twenty Three thousand Four Hundred Fifty Six Teribytes": { + "One Hundred Twenty Three thousand Four Hundred Fifty Six Tebibytes": { "123456 TiB", - 123456000, + "121 PiB", true, }, "One Gibibyte": { "1 GiB", - 1, + "1.0 GiB", true, }, "One Megabyte": { "1 MB", - 0, // One cannot express <1GB in integer + "977 KiB", true, }, - "One Megabyte negative-case": { - "1 MB", - 1, - false, - // 1 MB isn't 1 GB - }, "One hundred four point five gigabyte": { "104.5 GB", - 104, + "97 GiB", true, }, } for testKey, testSuite := range tests { - gotValue, err := toGigaUnits(testSuite.stringSize) - if (gotValue != testSuite.expectedGsize || err != nil) && testSuite.positiveTest { - t.Fatalf("Tests failed for %s, expected=%d, got=%d", testKey, testSuite.expectedGsize, gotValue) + gotValue, err := toHumanSize(testSuite.stringSize) + if (gotValue != testSuite.expectedSize || err != nil) && testSuite.positiveTest { + t.Fatalf("Tests failed for %s, expected=%s, got=%s", testKey, testSuite.expectedSize, gotValue) } } } From 5554773fd1e8d18b8c282a004f651851bdf89cce Mon Sep 17 00:00:00 2001 From: Niladri Halder Date: Wed, 19 Jun 2024 05:13:32 +0000 Subject: [PATCH 3/3] feat(usage): add feature to ping immediately after PingCheck starts Signed-off-by: Niladri Halder --- usage/ping.go | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/usage/ping.go b/usage/ping.go index 1e4ca6a..1d776a9 100644 --- a/usage/ping.go +++ b/usage/ping.go @@ -36,16 +36,23 @@ const ( ) // PingCheck sends ping events to Google Analytics -func PingCheck(engineName, category string) { +func PingCheck(engineName, category string, pingImmediately bool) { // Create a new usage field u := New() + pingSender := u.CommonBuild(engineName). + InstallBuilder(true). + SetCategory(category) + + if pingImmediately { + // Ping immediately. + pingSender.Send() + } + duration := getPingPeriod() ticker := time.NewTicker(duration) for range ticker.C { - u.CommonBuild(engineName). - InstallBuilder(true). - SetCategory(category). - Send() + // Ping periodically, starting at 'duration'. + pingSender.Send() } }