From 66057d02deaa53d334c920bce2d8936943167031 Mon Sep 17 00:00:00 2001 From: Peter Brachwitz Date: Fri, 26 Jul 2024 12:45:59 +0200 Subject: [PATCH 1/7] Report memory usage by application --- docs/operating-eck/licensing.asciidoc | 46 +++++++++++--- pkg/license/aggregator.go | 52 ++++++++-------- pkg/license/aggregator_test.go | 11 +++- pkg/license/license.go | 79 ++++++++++++++++++++---- pkg/license/license_test.go | 38 +++++++++--- pkg/license/reporter_test.go | 87 ++++++++++++++++++++++----- pkg/utils/metrics/operator.go | 40 ++++++++++++ 7 files changed, 279 insertions(+), 74 deletions(-) diff --git a/docs/operating-eck/licensing.asciidoc b/docs/operating-eck/licensing.asciidoc index c8e4fc8e61..91d8a881bf 100644 --- a/docs/operating-eck/licensing.asciidoc +++ b/docs/operating-eck/licensing.asciidoc @@ -105,13 +105,23 @@ The operator periodically writes the total amount of Elastic resources under man ---- > kubectl -n elastic-system get configmap elastic-licensing -o json | jq .data { + "apm_memory": "0.50GiB", + "apm_memory_bytes": "536870912", + "eck_license_expiry_date": "2025-01-01T00:59:59+01:00", "eck_license_level": "enterprise", - "eck_license_expiry_date": "2022-01-01T00:59:59+01:00", + "elasticsearch_memory": "18.00GiB", + "elasticsearch_memory_bytes": "19327352832", "enterprise_resource_units": "1", - "max_enterprise_resource_units": "10", - "timestamp": "2020-01-03T23:38:20Z", - "total_managed_memory": "64GiB", - "total_managed_memory_bytes": "68719476736" + "enterprise_search_memory": "4.00GiB", + "enterprise_search_memory_bytes": "4294967296", + "kibana_memory": "1.00GiB", + "kibana_memory_bytes": "1073741824", + "logstash_memory": "2.00GiB", + "logstash_memory_bytes": "2147483648", + "max_enterprise_resource_units": "250", + "timestamp": "2024-07-26T12:40:42+02:00", + "total_managed_memory": "25.50GiB", + "total_managed_memory_bytes": "27380416512" } ---- @@ -120,12 +130,30 @@ If the operator metrics endpoint is enabled with the `--metrics-port` flag (chec [source,shell] ---- > curl "$ECK_METRICS_ENDPOINT" | grep elastic_licensing +# HELP elastic_licensing_enterprise_resource_units_max Maximum number of enterprise resource units available +# TYPE elastic_licensing_enterprise_resource_units_max gauge +elastic_licensing_enterprise_resource_units_max{license_level="enterprise"} 250 # HELP elastic_licensing_enterprise_resource_units_total Total enterprise resource units used # TYPE elastic_licensing_enterprise_resource_units_total gauge -elastic_licensing_enterprise_resource_units_total{license_level="basic"} 6 -# HELP elastic_licensing_memory_gigabytes_total Total memory used in GB -# TYPE elastic_licensing_memory_gigabytes_total gauge -elastic_licensing_memory_gigabytes_total{license_level="basic"} 357.01915648 +elastic_licensing_enterprise_resource_units_total{license_level="enterprise"} 1 +# HELP elastic_licensing_memory_gibibytes_apm Memory used by APM server in GiB +# TYPE elastic_licensing_memory_gibibytes_apm gauge +elastic_licensing_memory_gibibytes_apm{license_level="enterprise"} 0.5 +# HELP elastic_licensing_memory_gibibytes_elasticsearch Memory used by Elasticsearch in GiB +# TYPE elastic_licensing_memory_gibibytes_elasticsearch gauge +elastic_licensing_memory_gibibytes_elasticsearch{license_level="enterprise"} 18 +# HELP elastic_licensing_memory_gibibytes_enterprise_search Memory used by Enterprise Search in GiB +# TYPE elastic_licensing_memory_gibibytes_enterprise_search gauge +elastic_licensing_memory_gibibytes_enterprise_search{license_level="enterprise"} 4 +# HELP elastic_licensing_memory_gibibytes_kibana Memory used by Kibana in GiB +# TYPE elastic_licensing_memory_gibibytes_kibana gauge +elastic_licensing_memory_gibibytes_kibana{license_level="enterprise"} 1 +# HELP elastic_licensing_memory_gibibytes_logstash Memory used by Logstash in GiB +# TYPE elastic_licensing_memory_gibibytes_logstash gauge +elastic_licensing_memory_gibibytes_logstash{license_level="enterprise"} 2 +# HELP elastic_licensing_memory_gibibytes_total Total memory used in GiB +# TYPE elastic_licensing_memory_gibibytes_total gauge +elastic_licensing_memory_gibibytes_total{license_level="enterprise"} 25.5 ---- NOTE: Logstash resources managed by ECK will be counted towards ERU usage for informational purposes. Billable consumption depends on license terms on a per customer basis (See link:https://www.elastic.co/agreements/global/self-managed[Self Managed Subscription Agreement]) diff --git a/pkg/license/aggregator.go b/pkg/license/aggregator.go index 412c9adff4..6d04b13328 100644 --- a/pkg/license/aggregator.go +++ b/pkg/license/aggregator.go @@ -35,11 +35,11 @@ type Aggregator struct { client k8s.Client } -type aggregate func(ctx context.Context) (resource.Quantity, error) +type aggregate func(ctx context.Context) (managedMemory, error) // AggregateMemory aggregates the total memory of all Elastic managed components -func (a Aggregator) AggregateMemory(ctx context.Context) (resource.Quantity, error) { - var totalMemory resource.Quantity +func (a Aggregator) AggregateMemory(ctx context.Context) (memoryUsage, error) { + usage := newMemoryUsage() for _, f := range []aggregate{ a.aggregateElasticsearchMemory, @@ -50,19 +50,19 @@ func (a Aggregator) AggregateMemory(ctx context.Context) (resource.Quantity, err } { memory, err := f(ctx) if err != nil { - return resource.Quantity{}, err + return memoryUsage{}, err } - totalMemory.Add(memory) + usage.Add(memory) } - return totalMemory, nil + return usage, nil } -func (a Aggregator) aggregateElasticsearchMemory(ctx context.Context) (resource.Quantity, error) { +func (a Aggregator) aggregateElasticsearchMemory(ctx context.Context) (managedMemory, error) { var esList esv1.ElasticsearchList err := a.client.List(context.Background(), &esList) if err != nil { - return resource.Quantity{}, errors.Wrap(err, "failed to aggregate Elasticsearch memory") + return managedMemory{}, errors.Wrap(err, "failed to aggregate Elasticsearch memory") } var total resource.Quantity @@ -75,7 +75,7 @@ func (a Aggregator) aggregateElasticsearchMemory(ctx context.Context) (resource. nodespec.DefaultMemoryLimits, ) if err != nil { - return resource.Quantity{}, errors.Wrap(err, "failed to aggregate Elasticsearch memory") + return managedMemory{}, errors.Wrap(err, "failed to aggregate Elasticsearch memory") } total.Add(multiply(mem, nodeSet.Count)) @@ -84,14 +84,14 @@ func (a Aggregator) aggregateElasticsearchMemory(ctx context.Context) (resource. } } - return total, nil + return managedMemory{total, elasticsearchKey}, nil } -func (a Aggregator) aggregateEnterpriseSearchMemory(ctx context.Context) (resource.Quantity, error) { +func (a Aggregator) aggregateEnterpriseSearchMemory(ctx context.Context) (managedMemory, error) { var entList entv1.EnterpriseSearchList err := a.client.List(context.Background(), &entList) if err != nil { - return resource.Quantity{}, errors.Wrap(err, "failed to aggregate Enterprise Search memory") + return managedMemory{}, errors.Wrap(err, "failed to aggregate Enterprise Search memory") } var total resource.Quantity @@ -103,7 +103,7 @@ func (a Aggregator) aggregateEnterpriseSearchMemory(ctx context.Context) (resour enterprisesearch.DefaultMemoryLimits, ) if err != nil { - return resource.Quantity{}, errors.Wrap(err, "failed to aggregate Enterprise Search memory") + return managedMemory{}, errors.Wrap(err, "failed to aggregate Enterprise Search memory") } total.Add(multiply(mem, ent.Spec.Count)) @@ -111,14 +111,14 @@ func (a Aggregator) aggregateEnterpriseSearchMemory(ctx context.Context) (resour "memory", mem.String(), "count", ent.Spec.Count) } - return total, nil + return managedMemory{total, entSearchKey}, nil } -func (a Aggregator) aggregateKibanaMemory(ctx context.Context) (resource.Quantity, error) { +func (a Aggregator) aggregateKibanaMemory(ctx context.Context) (managedMemory, error) { var kbList kbv1.KibanaList err := a.client.List(context.Background(), &kbList) if err != nil { - return resource.Quantity{}, errors.Wrap(err, "failed to aggregate Kibana memory") + return managedMemory{}, errors.Wrap(err, "failed to aggregate Kibana memory") } var total resource.Quantity @@ -130,7 +130,7 @@ func (a Aggregator) aggregateKibanaMemory(ctx context.Context) (resource.Quantit kibana.DefaultMemoryLimits, ) if err != nil { - return resource.Quantity{}, errors.Wrap(err, "failed to aggregate Kibana memory") + return managedMemory{}, errors.Wrap(err, "failed to aggregate Kibana memory") } total.Add(multiply(mem, kb.Spec.Count)) @@ -138,14 +138,14 @@ func (a Aggregator) aggregateKibanaMemory(ctx context.Context) (resource.Quantit "memory", mem.String(), "count", kb.Spec.Count) } - return total, nil + return managedMemory{total, kibanaKey}, nil } -func (a Aggregator) aggregateLogstashMemory(ctx context.Context) (resource.Quantity, error) { +func (a Aggregator) aggregateLogstashMemory(ctx context.Context) (managedMemory, error) { var lsList lsv1alpha1.LogstashList err := a.client.List(context.Background(), &lsList) if err != nil { - return resource.Quantity{}, errors.Wrap(err, "failed to aggregate Logstash memory") + return managedMemory{}, errors.Wrap(err, "failed to aggregate Logstash memory") } var total resource.Quantity @@ -157,7 +157,7 @@ func (a Aggregator) aggregateLogstashMemory(ctx context.Context) (resource.Quant logstash.DefaultMemoryLimit, ) if err != nil { - return resource.Quantity{}, errors.Wrap(err, "failed to aggregate Logstash memory") + return managedMemory{}, errors.Wrap(err, "failed to aggregate Logstash memory") } total.Add(multiply(mem, ls.Spec.Count)) @@ -165,14 +165,14 @@ func (a Aggregator) aggregateLogstashMemory(ctx context.Context) (resource.Quant "memory", mem.String(), "count", ls.Spec.Count) } - return total, nil + return managedMemory{total, logstashKey}, nil } -func (a Aggregator) aggregateApmServerMemory(ctx context.Context) (resource.Quantity, error) { +func (a Aggregator) aggregateApmServerMemory(ctx context.Context) (managedMemory, error) { var asList apmv1.ApmServerList err := a.client.List(context.Background(), &asList) if err != nil { - return resource.Quantity{}, errors.Wrap(err, "failed to aggregate APM Server memory") + return managedMemory{}, errors.Wrap(err, "failed to aggregate APM Server memory") } var total resource.Quantity @@ -184,7 +184,7 @@ func (a Aggregator) aggregateApmServerMemory(ctx context.Context) (resource.Quan apmserver.DefaultMemoryLimits, ) if err != nil { - return resource.Quantity{}, errors.Wrap(err, "failed to aggregate APM Server memory") + return managedMemory{}, errors.Wrap(err, "failed to aggregate APM Server memory") } total.Add(multiply(mem, as.Spec.Count)) @@ -192,7 +192,7 @@ func (a Aggregator) aggregateApmServerMemory(ctx context.Context) (resource.Quan "memory", mem.String(), "count", as.Spec.Count) } - return total, nil + return managedMemory{total, apmKey}, nil } // containerMemLimits reads the container memory limits from the resource specification with fallback diff --git a/pkg/license/aggregator_test.go b/pkg/license/aggregator_test.go index c2356af13c..5a74a7fbd1 100644 --- a/pkg/license/aggregator_test.go +++ b/pkg/license/aggregator_test.go @@ -142,7 +142,16 @@ func TestAggregator(t *testing.T) { val, err := aggregator.AggregateMemory(context.Background()) require.NoError(t, err) - require.Equal(t, 329.9073486328125, inGiB(val)) + for k, v := range map[string]float64{ + elasticsearchKey: 294.0, + kibanaKey: 5.9073486328125, + apmKey: 2.0, + entSearchKey: 24.0, + logstashKey: 4.0, + } { + require.Equal(t, v, val.appUsage[k].InGiB(), k) + } + require.Equal(t, 329.9073486328125, val.totalMemory.InGiB(), "total") } func readObjects(t *testing.T, filePath string) []client.Object { diff --git a/pkg/license/license.go b/pkg/license/license.go index 9596f2df86..80205743e7 100644 --- a/pkg/license/license.go +++ b/pkg/license/license.go @@ -37,16 +37,65 @@ const ( Type = "elastic-usage" // GiB represents the number of bytes for 1 GiB GiB = 1024 * 1024 * 1024 + + elasticsearchKey = "elasticsearch" + kibanaKey = "kibana" + apmKey = "apm" + entSearchKey = "enterprise_search" + logstashKey = "logstash" + totalKey = "total_managed" ) +type managedMemory struct { + resource.Quantity + source string +} + +func newManagedMemory(binarySI int64, source string) managedMemory { + return managedMemory{ + Quantity: *resource.NewQuantity(binarySI, resource.BinarySI), + source: source, + } +} + +func (mm managedMemory) InGiB() float64 { + return inGiB(resource.Quantity(mm.Quantity)) +} + +func (mm managedMemory) toMap(m map[string]string) { + m[mm.source+"_memory"] = fmt.Sprintf("%0.2fGiB", inGiB(mm.Quantity)) + m[mm.source+"_memory_bytes"] = fmt.Sprintf("%d", mm.Quantity.Value()) +} + +type memoryUsage struct { + appUsage map[string]managedMemory + totalMemory managedMemory +} + +func newMemoryUsage(values ...managedMemory) memoryUsage { + usage := memoryUsage{ + appUsage: map[string]managedMemory{}, + totalMemory: managedMemory{source: totalKey}, + } + for _, v := range values { + usage.appUsage[v.source] = v + usage.totalMemory.Add(v.Quantity) + } + return usage +} + +func (mu *memoryUsage) Add(memory managedMemory) { + mu.appUsage[memory.source] = memory + mu.totalMemory.Add(memory.Quantity) +} + // LicensingInfo represents information about the operator license including the total memory of all Elastic managed // components type LicensingInfo struct { + memoryUsage Timestamp string EckLicenseLevel string EckLicenseExpiryDate *time.Time - TotalManagedMemoryGiB float64 - TotalManagedMemoryBytes int64 MaxEnterpriseResourceUnits int64 EnterpriseResourceUnits int64 } @@ -54,12 +103,14 @@ type LicensingInfo struct { // toMap transforms a LicensingInfo to a map of string, in order to fill in the data of a config map func (li LicensingInfo) toMap() map[string]string { m := map[string]string{ - "timestamp": li.Timestamp, - "eck_license_level": li.EckLicenseLevel, - "total_managed_memory": fmt.Sprintf("%0.2fGiB", li.TotalManagedMemoryGiB), - "total_managed_memory_bytes": fmt.Sprintf("%d", li.TotalManagedMemoryBytes), - "enterprise_resource_units": strconv.FormatInt(li.EnterpriseResourceUnits, 10), + "timestamp": li.Timestamp, + "eck_license_level": li.EckLicenseLevel, + "enterprise_resource_units": strconv.FormatInt(li.EnterpriseResourceUnits, 10), + } + for _, v := range li.appUsage { + v.toMap(m) } + li.totalMemory.toMap(m) if li.MaxEnterpriseResourceUnits > 0 { m["max_enterprise_resource_units"] = strconv.FormatInt(li.MaxEnterpriseResourceUnits, 10) @@ -74,7 +125,12 @@ func (li LicensingInfo) toMap() map[string]string { func (li LicensingInfo) ReportAsMetrics() { labels := prometheus.Labels{metrics.LicenseLevelLabel: li.EckLicenseLevel} - metrics.LicensingTotalMemoryGauge.With(labels).Set(li.TotalManagedMemoryGiB) + metrics.LicensingTotalMemoryGauge.With(labels).Set(li.totalMemory.InGiB()) + metrics.LicensingESMemoryGauge.With(labels).Set(li.appUsage[elasticsearchKey].InGiB()) + metrics.LicensingKBMemoryGauge.With(labels).Set(li.appUsage[kibanaKey].InGiB()) + metrics.LicensingAPMMemoryGauge.With(labels).Set(li.appUsage[apmKey].InGiB()) + metrics.LicensingEntSearchMemoryGauge.With(labels).Set((li.appUsage[entSearchKey].InGiB())) + metrics.LicensingLogstashMemoryGauge.With(labels).Set(li.appUsage[logstashKey].InGiB()) metrics.LicensingTotalERUGauge.With(labels).Set(float64(li.EnterpriseResourceUnits)) if li.MaxEnterpriseResourceUnits > 0 { @@ -89,19 +145,18 @@ type LicensingResolver struct { } // ToInfo returns licensing information given the total memory of all Elastic managed components -func (r LicensingResolver) ToInfo(ctx context.Context, totalMemory resource.Quantity) (LicensingInfo, error) { +func (r LicensingResolver) ToInfo(ctx context.Context, memoryUsage memoryUsage) (LicensingInfo, error) { operatorLicense, err := r.getOperatorLicense(ctx) if err != nil { return LicensingInfo{}, err } licensingInfo := LicensingInfo{ + memoryUsage: memoryUsage, Timestamp: time.Now().Format(time.RFC3339), EckLicenseLevel: r.getOperatorLicenseLevel(operatorLicense), EckLicenseExpiryDate: r.getOperatorLicenseExpiry(operatorLicense), - TotalManagedMemoryGiB: inGiB(totalMemory), - TotalManagedMemoryBytes: totalMemory.Value(), - EnterpriseResourceUnits: inEnterpriseResourceUnits(totalMemory), + EnterpriseResourceUnits: inEnterpriseResourceUnits(memoryUsage.totalMemory.Quantity), } // include the max ERUs only for a non trial/basic license diff --git a/pkg/license/license_test.go b/pkg/license/license_test.go index 6a6860fab3..ac94c8af9e 100644 --- a/pkg/license/license_test.go +++ b/pkg/license/license_test.go @@ -17,7 +17,7 @@ func TestToMap(t *testing.T) { dateFixture := time.Date(2021, 11, 03, 0, 0, 0, 0, time.UTC) t.Run("empty_object", func(t *testing.T) { - i := LicensingInfo{} + i := LicensingInfo{memoryUsage: newMemoryUsage()} have := i.toMap() want := map[string]string{ "timestamp": "", @@ -31,24 +31,42 @@ func TestToMap(t *testing.T) { t.Run("complete_object", func(t *testing.T) { i := LicensingInfo{ + memoryUsage: memoryUsage{ + appUsage: map[string]managedMemory{ + elasticsearchKey: newManagedMemory(21474836480, elasticsearchKey), + kibanaKey: newManagedMemory(8589934592, kibanaKey), + apmKey: newManagedMemory(4294967296, apmKey), + entSearchKey: newManagedMemory(17179869184, entSearchKey), + logstashKey: newManagedMemory(17179869184, logstashKey), + }, + totalMemory: newManagedMemory(68719476736, totalKey), + }, Timestamp: "2020-05-28T11:15:31Z", EckLicenseLevel: "enterprise", EckLicenseExpiryDate: &dateFixture, - TotalManagedMemoryGiB: 64, - TotalManagedMemoryBytes: 68719476736, EnterpriseResourceUnits: 1, MaxEnterpriseResourceUnits: 10, } have := i.toMap() want := map[string]string{ - "timestamp": "2020-05-28T11:15:31Z", - "eck_license_level": "enterprise", - "eck_license_expiry_date": "2021-11-03T00:00:00Z", - "total_managed_memory": "64.00GiB", - "total_managed_memory_bytes": "68719476736", - "enterprise_resource_units": "1", - "max_enterprise_resource_units": "10", + "timestamp": "2020-05-28T11:15:31Z", + "eck_license_level": "enterprise", + "eck_license_expiry_date": "2021-11-03T00:00:00Z", + "elasticsearch_memory": "20.00GiB", + "elasticsearch_memory_bytes": "21474836480", + "kibana_memory": "8.00GiB", + "kibana_memory_bytes": "8589934592", + "apm_memory": "4.00GiB", + "apm_memory_bytes": "4294967296", + "enterprise_search_memory": "16.00GiB", + "enterprise_search_memory_bytes": "17179869184", + "logstash_memory": "16.00GiB", + "logstash_memory_bytes": "17179869184", + "total_managed_memory": "64.00GiB", + "total_managed_memory_bytes": "68719476736", + "enterprise_resource_units": "1", + "max_enterprise_resource_units": "10", } assert.Equal(t, want, have) }) diff --git a/pkg/license/reporter_test.go b/pkg/license/reporter_test.go index 1918369e7e..f5c0cabb32 100644 --- a/pkg/license/reporter_test.go +++ b/pkg/license/reporter_test.go @@ -41,8 +41,16 @@ func TestGet(t *testing.T) { require.NoError(t, err) want := LicensingInfo{ - TotalManagedMemoryGiB: 20.00, - TotalManagedMemoryBytes: 21474836480, + memoryUsage: memoryUsage{ + appUsage: map[string]managedMemory{ + elasticsearchKey: newManagedMemory(21474836480, elasticsearchKey), + kibanaKey: newManagedMemory(0, kibanaKey), + apmKey: newManagedMemory(0, apmKey), + entSearchKey: newManagedMemory(0, entSearchKey), + logstashKey: newManagedMemory(0, logstashKey), + }, + totalMemory: managedMemory{Quantity: resource.MustParse("20Gi"), source: totalKey}, + }, EnterpriseResourceUnits: 1, EckLicenseLevel: "basic", } @@ -76,8 +84,16 @@ func TestGet(t *testing.T) { require.NoError(t, err) want := LicensingInfo{ - TotalManagedMemoryGiB: 320.00, - TotalManagedMemoryBytes: 343597383680, + memoryUsage: memoryUsage{ + appUsage: map[string]managedMemory{ + elasticsearchKey: newManagedMemory(343597383680, elasticsearchKey), + kibanaKey: newManagedMemory(0, kibanaKey), + apmKey: newManagedMemory(0, apmKey), + entSearchKey: newManagedMemory(0, entSearchKey), + logstashKey: newManagedMemory(0, logstashKey), + }, + totalMemory: newManagedMemory(343597383680, totalKey), + }, EnterpriseResourceUnits: 5, EckLicenseLevel: "basic", } @@ -110,8 +126,16 @@ func TestGet(t *testing.T) { require.NoError(t, err) want := LicensingInfo{ - TotalManagedMemoryGiB: 208.00, - TotalManagedMemoryBytes: 223338299392, + memoryUsage: memoryUsage{ + appUsage: map[string]managedMemory{ + elasticsearchKey: newManagedMemory(223338299392, elasticsearchKey), + kibanaKey: newManagedMemory(0, kibanaKey), + apmKey: newManagedMemory(0, apmKey), + entSearchKey: newManagedMemory(0, entSearchKey), + logstashKey: newManagedMemory(0, logstashKey), + }, + totalMemory: newManagedMemory(223338299392, totalKey), + }, EnterpriseResourceUnits: 4, EckLicenseLevel: "basic", } @@ -130,8 +154,16 @@ func TestGet(t *testing.T) { require.NoError(t, err) want := LicensingInfo{ - TotalManagedMemoryGiB: 100.00, - TotalManagedMemoryBytes: 107374182400, + memoryUsage: memoryUsage{ + appUsage: map[string]managedMemory{ + elasticsearchKey: newManagedMemory(0, elasticsearchKey), + kibanaKey: newManagedMemory(107374182400, kibanaKey), + apmKey: newManagedMemory(0, apmKey), + entSearchKey: newManagedMemory(0, entSearchKey), + logstashKey: newManagedMemory(0, logstashKey), + }, + totalMemory: newManagedMemory(107374182400, totalKey), + }, EnterpriseResourceUnits: 2, EckLicenseLevel: "basic", } @@ -163,8 +195,16 @@ func TestGet(t *testing.T) { have, err := NewResourceReporter(k8s.NewFakeClient(&kb), operatorNs, nil).Get(context.Background()) require.NoError(t, err) want := LicensingInfo{ - TotalManagedMemoryGiB: 200.00, - TotalManagedMemoryBytes: 214748364800, + memoryUsage: memoryUsage{ + appUsage: map[string]managedMemory{ + elasticsearchKey: newManagedMemory(0, elasticsearchKey), + kibanaKey: newManagedMemory(214748364800, kibanaKey), + apmKey: newManagedMemory(0, apmKey), + entSearchKey: newManagedMemory(0, entSearchKey), + logstashKey: newManagedMemory(0, logstashKey), + }, + totalMemory: newManagedMemory(214748364800, totalKey), + }, EnterpriseResourceUnits: 4, EckLicenseLevel: "basic", } @@ -193,8 +233,16 @@ func TestGet(t *testing.T) { have, err := NewResourceReporter(k8s.NewFakeClient(&kb), operatorNs, nil).Get(context.Background()) require.NoError(t, err) want := LicensingInfo{ - TotalManagedMemoryGiB: 190.73, - TotalManagedMemoryBytes: 204800000000, + memoryUsage: memoryUsage{ + appUsage: map[string]managedMemory{ + elasticsearchKey: newManagedMemory(0, elasticsearchKey), + kibanaKey: newManagedMemory(204800000000, kibanaKey), + apmKey: newManagedMemory(0, apmKey), + entSearchKey: newManagedMemory(0, entSearchKey), + logstashKey: newManagedMemory(0, logstashKey), + }, + totalMemory: newManagedMemory(204800000000, totalKey), + }, EnterpriseResourceUnits: 3, EckLicenseLevel: "basic", } @@ -245,8 +293,15 @@ func Test_Start(t *testing.T) { cm.Data["eck_license_level"] == defaultOperatorLicenseLevel && cm.Data["enterprise_resource_units"] == "2" && cm.Data["total_managed_memory"] == "83.00GiB" && - cm.Data["total_managed_memory_bytes"] == "89120571392" - }, waitFor, tick) + cm.Data["total_managed_memory_bytes"] == "89120571392" && + cm.Data["elasticsearch_memory"] == "80.00GiB" && // 40 * 2Gi + cm.Data["elasticsearch_memory_bytes"] == "85899345920" && + cm.Data["kibana_memory"] == "2.00GiB" && // 2 * 1Gi + cm.Data["kibana_memory_bytes"] == "2147483648" && + cm.Data["apm_memory"] == "1.00GiB" && // 2 * 512Mi + cm.Data["apm_memory_bytes"] == "1073741824" + + }, waitFor, tick, "40*ES, 2*KB, 2 *APM") // increase the Elasticsearch nodes count es.Spec.NodeSets[0].Count = 80 @@ -268,7 +323,7 @@ func Test_Start(t *testing.T) { cm.Data["enterprise_resource_units"] == "3" && cm.Data["total_managed_memory"] == "163.00GiB" && cm.Data["total_managed_memory_bytes"] == "175019917312" - }, waitFor, tick) + }, waitFor, tick, "80*ES, 2*KB, 2*APM") startTrial(t, k8sClient) // check that the license level has been updated @@ -287,7 +342,7 @@ func Test_Start(t *testing.T) { cm.Data["enterprise_resource_units"] == "3" && cm.Data["total_managed_memory"] == "163.00GiB" && cm.Data["total_managed_memory_bytes"] == "175019917312" - }, waitFor, tick) + }, waitFor, tick, "trial license") } func startTrial(t *testing.T, k8sClient client.Client) { diff --git a/pkg/utils/metrics/operator.go b/pkg/utils/metrics/operator.go index 1b73b0f4cf..9b65dcd884 100644 --- a/pkg/utils/metrics/operator.go +++ b/pkg/utils/metrics/operator.go @@ -52,6 +52,46 @@ var ( Name: "memory_gibibytes_total", Help: "Total memory used in GiB", }, []string{LicenseLevelLabel})) + + // LicensingESMemoryGauge reports the Elasticsearch memory usage for licensing purposes. + LicensingESMemoryGauge = registerGauge(prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Namespace: namespace, + Subsystem: licensingSubsystem, + Name: "memory_gibibytes_elasticsearch", + Help: "Memory used by Elasticsearch in GiB", + }, []string{LicenseLevelLabel})) + + // LicensingKBMemoryGauge reports the Kibana memory usage for licensing purposes. + LicensingKBMemoryGauge = registerGauge(prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Namespace: namespace, + Subsystem: licensingSubsystem, + Name: "memory_gibibytes_kibana", + Help: "Memory used by Kibana in GiB", + }, []string{LicenseLevelLabel})) + + // LicensingAPMMemoryGauge reports the APM server memory usage for licensing purposes. + LicensingAPMMemoryGauge = registerGauge(prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Namespace: namespace, + Subsystem: licensingSubsystem, + Name: "memory_gibibytes_apm", + Help: "Memory used by APM server in GiB", + }, []string{LicenseLevelLabel})) + + // LicensingEntSearchMemoryGauge reports the Enterprise search memory usage for licensing purposes. + LicensingEntSearchMemoryGauge = registerGauge(prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Namespace: namespace, + Subsystem: licensingSubsystem, + Name: "memory_gibibytes_enterprise_search", + Help: "Memory used by Enterprise Search in GiB", + }, []string{LicenseLevelLabel})) + + // LicensingLogstashMemoryGauge reports the Logstash memory usage for licensing purposes. + LicensingLogstashMemoryGauge = registerGauge(prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Namespace: namespace, + Subsystem: licensingSubsystem, + Name: "memory_gibibytes_logstash", + Help: "Memory used by Logstash in GiB", + }, []string{LicenseLevelLabel})) ) func registerGauge(gauge *prometheus.GaugeVec) *prometheus.GaugeVec { From d3292151c05475fc9b6345e4159e9a4ed6f5b442 Mon Sep 17 00:00:00 2001 From: Peter Brachwitz Date: Fri, 26 Jul 2024 12:56:04 +0200 Subject: [PATCH 2/7] Label is a better name than source --- pkg/license/license.go | 14 +++++++------- pkg/license/reporter_test.go | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pkg/license/license.go b/pkg/license/license.go index 80205743e7..e4e051030f 100644 --- a/pkg/license/license.go +++ b/pkg/license/license.go @@ -48,13 +48,13 @@ const ( type managedMemory struct { resource.Quantity - source string + label string } func newManagedMemory(binarySI int64, source string) managedMemory { return managedMemory{ Quantity: *resource.NewQuantity(binarySI, resource.BinarySI), - source: source, + label: source, } } @@ -63,8 +63,8 @@ func (mm managedMemory) InGiB() float64 { } func (mm managedMemory) toMap(m map[string]string) { - m[mm.source+"_memory"] = fmt.Sprintf("%0.2fGiB", inGiB(mm.Quantity)) - m[mm.source+"_memory_bytes"] = fmt.Sprintf("%d", mm.Quantity.Value()) + m[mm.label+"_memory"] = fmt.Sprintf("%0.2fGiB", inGiB(mm.Quantity)) + m[mm.label+"_memory_bytes"] = fmt.Sprintf("%d", mm.Quantity.Value()) } type memoryUsage struct { @@ -75,17 +75,17 @@ type memoryUsage struct { func newMemoryUsage(values ...managedMemory) memoryUsage { usage := memoryUsage{ appUsage: map[string]managedMemory{}, - totalMemory: managedMemory{source: totalKey}, + totalMemory: managedMemory{label: totalKey}, } for _, v := range values { - usage.appUsage[v.source] = v + usage.appUsage[v.label] = v usage.totalMemory.Add(v.Quantity) } return usage } func (mu *memoryUsage) Add(memory managedMemory) { - mu.appUsage[memory.source] = memory + mu.appUsage[memory.label] = memory mu.totalMemory.Add(memory.Quantity) } diff --git a/pkg/license/reporter_test.go b/pkg/license/reporter_test.go index f5c0cabb32..17ab539b1f 100644 --- a/pkg/license/reporter_test.go +++ b/pkg/license/reporter_test.go @@ -49,7 +49,7 @@ func TestGet(t *testing.T) { entSearchKey: newManagedMemory(0, entSearchKey), logstashKey: newManagedMemory(0, logstashKey), }, - totalMemory: managedMemory{Quantity: resource.MustParse("20Gi"), source: totalKey}, + totalMemory: managedMemory{Quantity: resource.MustParse("20Gi"), label: totalKey}, }, EnterpriseResourceUnits: 1, EckLicenseLevel: "basic", From 212037317d7cf245d1b6688ee2c5d1689c994582 Mon Sep 17 00:00:00 2001 From: Peter Brachwitz Date: Fri, 26 Jul 2024 13:00:35 +0200 Subject: [PATCH 3/7] consistent visibility + missed file save --- pkg/license/aggregator_test.go | 4 ++-- pkg/license/license.go | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/pkg/license/aggregator_test.go b/pkg/license/aggregator_test.go index 5a74a7fbd1..f0966ca16a 100644 --- a/pkg/license/aggregator_test.go +++ b/pkg/license/aggregator_test.go @@ -149,9 +149,9 @@ func TestAggregator(t *testing.T) { entSearchKey: 24.0, logstashKey: 4.0, } { - require.Equal(t, v, val.appUsage[k].InGiB(), k) + require.Equal(t, v, val.appUsage[k].inGiB(), k) } - require.Equal(t, 329.9073486328125, val.totalMemory.InGiB(), "total") + require.Equal(t, 329.9073486328125, val.totalMemory.inGiB(), "total") } func readObjects(t *testing.T, filePath string) []client.Object { diff --git a/pkg/license/license.go b/pkg/license/license.go index e4e051030f..050b32c9bc 100644 --- a/pkg/license/license.go +++ b/pkg/license/license.go @@ -51,14 +51,14 @@ type managedMemory struct { label string } -func newManagedMemory(binarySI int64, source string) managedMemory { +func newManagedMemory(binarySI int64, label string) managedMemory { return managedMemory{ Quantity: *resource.NewQuantity(binarySI, resource.BinarySI), - label: source, + label: label, } } -func (mm managedMemory) InGiB() float64 { +func (mm managedMemory) inGiB() float64 { return inGiB(resource.Quantity(mm.Quantity)) } @@ -125,12 +125,12 @@ func (li LicensingInfo) toMap() map[string]string { func (li LicensingInfo) ReportAsMetrics() { labels := prometheus.Labels{metrics.LicenseLevelLabel: li.EckLicenseLevel} - metrics.LicensingTotalMemoryGauge.With(labels).Set(li.totalMemory.InGiB()) - metrics.LicensingESMemoryGauge.With(labels).Set(li.appUsage[elasticsearchKey].InGiB()) - metrics.LicensingKBMemoryGauge.With(labels).Set(li.appUsage[kibanaKey].InGiB()) - metrics.LicensingAPMMemoryGauge.With(labels).Set(li.appUsage[apmKey].InGiB()) - metrics.LicensingEntSearchMemoryGauge.With(labels).Set((li.appUsage[entSearchKey].InGiB())) - metrics.LicensingLogstashMemoryGauge.With(labels).Set(li.appUsage[logstashKey].InGiB()) + metrics.LicensingTotalMemoryGauge.With(labels).Set(li.totalMemory.inGiB()) + metrics.LicensingESMemoryGauge.With(labels).Set(li.appUsage[elasticsearchKey].inGiB()) + metrics.LicensingKBMemoryGauge.With(labels).Set(li.appUsage[kibanaKey].inGiB()) + metrics.LicensingAPMMemoryGauge.With(labels).Set(li.appUsage[apmKey].inGiB()) + metrics.LicensingEntSearchMemoryGauge.With(labels).Set((li.appUsage[entSearchKey].inGiB())) + metrics.LicensingLogstashMemoryGauge.With(labels).Set(li.appUsage[logstashKey].inGiB()) metrics.LicensingTotalERUGauge.With(labels).Set(float64(li.EnterpriseResourceUnits)) if li.MaxEnterpriseResourceUnits > 0 { From e28f72ee891f73e8a9fd46572ab8a7a4373c86b1 Mon Sep 17 00:00:00 2001 From: Peter Brachwitz Date: Fri, 26 Jul 2024 13:05:18 +0200 Subject: [PATCH 4/7] remove lint --- pkg/license/aggregator.go | 18 +++++++++--------- pkg/license/aggregator_test.go | 4 ++-- pkg/license/license.go | 8 ++------ pkg/license/reporter.go | 6 +++--- 4 files changed, 16 insertions(+), 20 deletions(-) diff --git a/pkg/license/aggregator.go b/pkg/license/aggregator.go index 6d04b13328..4a27d204e0 100644 --- a/pkg/license/aggregator.go +++ b/pkg/license/aggregator.go @@ -30,15 +30,15 @@ import ( ulog "github.com/elastic/cloud-on-k8s/v2/pkg/utils/log" ) -// Aggregator aggregates the total of resources of all Elastic managed components -type Aggregator struct { +// aggregator aggregates the total of resources of all Elastic managed components +type aggregator struct { client k8s.Client } type aggregate func(ctx context.Context) (managedMemory, error) -// AggregateMemory aggregates the total memory of all Elastic managed components -func (a Aggregator) AggregateMemory(ctx context.Context) (memoryUsage, error) { +// aggregateMemory aggregates the total memory of all Elastic managed components +func (a aggregator) aggregateMemory(ctx context.Context) (memoryUsage, error) { usage := newMemoryUsage() for _, f := range []aggregate{ @@ -58,7 +58,7 @@ func (a Aggregator) AggregateMemory(ctx context.Context) (memoryUsage, error) { return usage, nil } -func (a Aggregator) aggregateElasticsearchMemory(ctx context.Context) (managedMemory, error) { +func (a aggregator) aggregateElasticsearchMemory(ctx context.Context) (managedMemory, error) { var esList esv1.ElasticsearchList err := a.client.List(context.Background(), &esList) if err != nil { @@ -87,7 +87,7 @@ func (a Aggregator) aggregateElasticsearchMemory(ctx context.Context) (managedMe return managedMemory{total, elasticsearchKey}, nil } -func (a Aggregator) aggregateEnterpriseSearchMemory(ctx context.Context) (managedMemory, error) { +func (a aggregator) aggregateEnterpriseSearchMemory(ctx context.Context) (managedMemory, error) { var entList entv1.EnterpriseSearchList err := a.client.List(context.Background(), &entList) if err != nil { @@ -114,7 +114,7 @@ func (a Aggregator) aggregateEnterpriseSearchMemory(ctx context.Context) (manage return managedMemory{total, entSearchKey}, nil } -func (a Aggregator) aggregateKibanaMemory(ctx context.Context) (managedMemory, error) { +func (a aggregator) aggregateKibanaMemory(ctx context.Context) (managedMemory, error) { var kbList kbv1.KibanaList err := a.client.List(context.Background(), &kbList) if err != nil { @@ -141,7 +141,7 @@ func (a Aggregator) aggregateKibanaMemory(ctx context.Context) (managedMemory, e return managedMemory{total, kibanaKey}, nil } -func (a Aggregator) aggregateLogstashMemory(ctx context.Context) (managedMemory, error) { +func (a aggregator) aggregateLogstashMemory(ctx context.Context) (managedMemory, error) { var lsList lsv1alpha1.LogstashList err := a.client.List(context.Background(), &lsList) if err != nil { @@ -168,7 +168,7 @@ func (a Aggregator) aggregateLogstashMemory(ctx context.Context) (managedMemory, return managedMemory{total, logstashKey}, nil } -func (a Aggregator) aggregateApmServerMemory(ctx context.Context) (managedMemory, error) { +func (a aggregator) aggregateApmServerMemory(ctx context.Context) (managedMemory, error) { var asList apmv1.ApmServerList err := a.client.List(context.Background(), &asList) if err != nil { diff --git a/pkg/license/aggregator_test.go b/pkg/license/aggregator_test.go index f0966ca16a..e4b7927d0a 100644 --- a/pkg/license/aggregator_test.go +++ b/pkg/license/aggregator_test.go @@ -138,9 +138,9 @@ func TestMemFromNodeOpts(t *testing.T) { func TestAggregator(t *testing.T) { objects := readObjects(t, "testdata/stack.yaml") client := k8s.NewFakeClient(objects...) - aggregator := Aggregator{client: client} + aggregator := aggregator{client: client} - val, err := aggregator.AggregateMemory(context.Background()) + val, err := aggregator.aggregateMemory(context.Background()) require.NoError(t, err) for k, v := range map[string]float64{ elasticsearchKey: 294.0, diff --git a/pkg/license/license.go b/pkg/license/license.go index 050b32c9bc..f3720e8a9f 100644 --- a/pkg/license/license.go +++ b/pkg/license/license.go @@ -59,7 +59,7 @@ func newManagedMemory(binarySI int64, label string) managedMemory { } func (mm managedMemory) inGiB() float64 { - return inGiB(resource.Quantity(mm.Quantity)) + return inGiB(mm.Quantity) } func (mm managedMemory) toMap(m map[string]string) { @@ -72,15 +72,11 @@ type memoryUsage struct { totalMemory managedMemory } -func newMemoryUsage(values ...managedMemory) memoryUsage { +func newMemoryUsage() memoryUsage { usage := memoryUsage{ appUsage: map[string]managedMemory{}, totalMemory: managedMemory{label: totalKey}, } - for _, v := range values { - usage.appUsage[v.label] = v - usage.totalMemory.Add(v.Quantity) - } return usage } diff --git a/pkg/license/reporter.go b/pkg/license/reporter.go index f3dffa8af6..4cb8616825 100644 --- a/pkg/license/reporter.go +++ b/pkg/license/reporter.go @@ -21,7 +21,7 @@ const ResourceReporterFrequency = 2 * time.Minute // ResourceReporter aggregates resources of all Elastic components managed by the operator // and reports them in a config map in the form of licensing information type ResourceReporter struct { - aggregator Aggregator + aggregator aggregator licensingResolver LicensingResolver tracer *apm.Tracer } @@ -29,7 +29,7 @@ type ResourceReporter struct { // NewResourceReporter returns a new ResourceReporter func NewResourceReporter(c client.Client, operatorNs string, tracer *apm.Tracer) ResourceReporter { return ResourceReporter{ - aggregator: Aggregator{ + aggregator: aggregator{ client: c, }, licensingResolver: LicensingResolver{ @@ -77,7 +77,7 @@ func (r ResourceReporter) Report(ctx context.Context) error { func (r ResourceReporter) Get(ctx context.Context) (LicensingInfo, error) { span, _ := apm.StartSpan(ctx, "get_license_info", tracing.SpanTypeApp) defer span.End() - totalMemory, err := r.aggregator.AggregateMemory(ctx) + totalMemory, err := r.aggregator.aggregateMemory(ctx) if err != nil { return LicensingInfo{}, err } From 70745dcbc3f5bca84921e43a56227ad10454a897 Mon Sep 17 00:00:00 2001 From: Peter Brachwitz Date: Fri, 26 Jul 2024 13:08:26 +0200 Subject: [PATCH 5/7] more naming nits --- pkg/license/aggregator.go | 2 +- pkg/license/license.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/license/aggregator.go b/pkg/license/aggregator.go index 4a27d204e0..1cda063edd 100644 --- a/pkg/license/aggregator.go +++ b/pkg/license/aggregator.go @@ -52,7 +52,7 @@ func (a aggregator) aggregateMemory(ctx context.Context) (memoryUsage, error) { if err != nil { return memoryUsage{}, err } - usage.Add(memory) + usage.add(memory) } return usage, nil diff --git a/pkg/license/license.go b/pkg/license/license.go index f3720e8a9f..90c7b49c13 100644 --- a/pkg/license/license.go +++ b/pkg/license/license.go @@ -62,7 +62,7 @@ func (mm managedMemory) inGiB() float64 { return inGiB(mm.Quantity) } -func (mm managedMemory) toMap(m map[string]string) { +func (mm managedMemory) intoMap(m map[string]string) { m[mm.label+"_memory"] = fmt.Sprintf("%0.2fGiB", inGiB(mm.Quantity)) m[mm.label+"_memory_bytes"] = fmt.Sprintf("%d", mm.Quantity.Value()) } @@ -80,7 +80,7 @@ func newMemoryUsage() memoryUsage { return usage } -func (mu *memoryUsage) Add(memory managedMemory) { +func (mu *memoryUsage) add(memory managedMemory) { mu.appUsage[memory.label] = memory mu.totalMemory.Add(memory.Quantity) } @@ -104,9 +104,9 @@ func (li LicensingInfo) toMap() map[string]string { "enterprise_resource_units": strconv.FormatInt(li.EnterpriseResourceUnits, 10), } for _, v := range li.appUsage { - v.toMap(m) + v.intoMap(m) } - li.totalMemory.toMap(m) + li.totalMemory.intoMap(m) if li.MaxEnterpriseResourceUnits > 0 { m["max_enterprise_resource_units"] = strconv.FormatInt(li.MaxEnterpriseResourceUnits, 10) From c9671d7284ee985603be0143f2093780520bc72a Mon Sep 17 00:00:00 2001 From: Peter Brachwitz Date: Fri, 26 Jul 2024 13:15:09 +0200 Subject: [PATCH 6/7] remove accidental newline --- pkg/license/reporter_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/license/reporter_test.go b/pkg/license/reporter_test.go index 17ab539b1f..6d78545001 100644 --- a/pkg/license/reporter_test.go +++ b/pkg/license/reporter_test.go @@ -300,7 +300,6 @@ func Test_Start(t *testing.T) { cm.Data["kibana_memory_bytes"] == "2147483648" && cm.Data["apm_memory"] == "1.00GiB" && // 2 * 512Mi cm.Data["apm_memory_bytes"] == "1073741824" - }, waitFor, tick, "40*ES, 2*KB, 2 *APM") // increase the Elasticsearch nodes count From 86279abb9f08f853ec949856c0a7303140cb0483 Mon Sep 17 00:00:00 2001 From: Peter Brachwitz Date: Fri, 26 Jul 2024 15:33:09 +0200 Subject: [PATCH 7/7] review feedback --- pkg/license/license.go | 5 ++--- pkg/license/reporter.go | 4 ++-- pkg/utils/metrics/operator.go | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/pkg/license/license.go b/pkg/license/license.go index 90c7b49c13..4cd30e6e2f 100644 --- a/pkg/license/license.go +++ b/pkg/license/license.go @@ -73,11 +73,10 @@ type memoryUsage struct { } func newMemoryUsage() memoryUsage { - usage := memoryUsage{ + return memoryUsage{ appUsage: map[string]managedMemory{}, totalMemory: managedMemory{label: totalKey}, } - return usage } func (mu *memoryUsage) add(memory managedMemory) { @@ -125,7 +124,7 @@ func (li LicensingInfo) ReportAsMetrics() { metrics.LicensingESMemoryGauge.With(labels).Set(li.appUsage[elasticsearchKey].inGiB()) metrics.LicensingKBMemoryGauge.With(labels).Set(li.appUsage[kibanaKey].inGiB()) metrics.LicensingAPMMemoryGauge.With(labels).Set(li.appUsage[apmKey].inGiB()) - metrics.LicensingEntSearchMemoryGauge.With(labels).Set((li.appUsage[entSearchKey].inGiB())) + metrics.LicensingEntSearchMemoryGauge.With(labels).Set(li.appUsage[entSearchKey].inGiB()) metrics.LicensingLogstashMemoryGauge.With(labels).Set(li.appUsage[logstashKey].inGiB()) metrics.LicensingTotalERUGauge.With(labels).Set(float64(li.EnterpriseResourceUnits)) diff --git a/pkg/license/reporter.go b/pkg/license/reporter.go index 4cb8616825..1af11c3c1f 100644 --- a/pkg/license/reporter.go +++ b/pkg/license/reporter.go @@ -77,10 +77,10 @@ func (r ResourceReporter) Report(ctx context.Context) error { func (r ResourceReporter) Get(ctx context.Context) (LicensingInfo, error) { span, _ := apm.StartSpan(ctx, "get_license_info", tracing.SpanTypeApp) defer span.End() - totalMemory, err := r.aggregator.aggregateMemory(ctx) + usage, err := r.aggregator.aggregateMemory(ctx) if err != nil { return LicensingInfo{}, err } - return r.licensingResolver.ToInfo(ctx, totalMemory) + return r.licensingResolver.ToInfo(ctx, usage) } diff --git a/pkg/utils/metrics/operator.go b/pkg/utils/metrics/operator.go index 9b65dcd884..4b940dff10 100644 --- a/pkg/utils/metrics/operator.go +++ b/pkg/utils/metrics/operator.go @@ -77,7 +77,7 @@ var ( Help: "Memory used by APM server in GiB", }, []string{LicenseLevelLabel})) - // LicensingEntSearchMemoryGauge reports the Enterprise search memory usage for licensing purposes. + // LicensingEntSearchMemoryGauge reports the Enterprise Search memory usage for licensing purposes. LicensingEntSearchMemoryGauge = registerGauge(prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: namespace, Subsystem: licensingSubsystem,