From c07dcd653becfcafd4ef373cc080d10ed0a8b7ff Mon Sep 17 00:00:00 2001 From: Kosuke Morimoto Date: Tue, 29 Aug 2023 11:45:40 +0900 Subject: [PATCH] add malloc_info metrics Signed-off-by: Kosuke Morimoto --- internal/core/malloc/malloc.go | 24 +- internal/core/malloc/malloc_test.go | 2 - internal/errors/malloc.go | 22 ++ .../metrics/mem/malloc/malloc.go | 242 ++++++++++++++++++ pkg/agent/core/ngt/usecase/agentd.go | 2 + 5 files changed, 283 insertions(+), 9 deletions(-) create mode 100644 internal/errors/malloc.go create mode 100644 internal/observability/metrics/mem/malloc/malloc.go diff --git a/internal/core/malloc/malloc.go b/internal/core/malloc/malloc.go index cae6c5b0b03..dad36612eb4 100644 --- a/internal/core/malloc/malloc.go +++ b/internal/core/malloc/malloc.go @@ -49,26 +49,36 @@ type Sizes struct { Unsorted Size `xml:"unsorted"` } -type Memory struct { +type Total struct { Type string `xml:"fast,attr"` Count int `xml:"count,attr"` Size int `xml:"size,attr"` } +type System struct { + Type string `xml:"fast,attr"` + Size int `xml:"size,attr"` +} + +type Aspace struct { + Type string `xml:"fast,attr"` + Size int `xml:"size,attr"` +} + type Heap struct { Nr string `xml:"nr,attr"` Sizes Sizes `xml:"sizes"` - Total []*Memory `xml:"total"` - System []*Memory `xml:"system"` - Aspace []*Memory `xml:"aspace"` + Total []*Total `xml:"total"` + System []*System `xml:"system"` + Aspace []*Aspace `xml:"aspace"` } type MallocInfo struct { Version string `xml:"version,attr"` Heap []*Heap `xml:"heap"` - Total []*Memory `xml:"total"` - System []*Memory `xml:"system"` - Aspace []*Memory `xml:"aspace"` + Total []*Total `xml:"total"` + System []*System `xml:"system"` + Aspace []*Aspace `xml:"aspace"` } func convert(body string) (*MallocInfo, error) { diff --git a/internal/core/malloc/malloc_test.go b/internal/core/malloc/malloc_test.go index 3cf74540615..e20d0443a0f 100644 --- a/internal/core/malloc/malloc_test.go +++ b/internal/core/malloc/malloc_test.go @@ -71,7 +71,6 @@ func Test_convert(t *testing.T) { if err := checkFunc(test.want, gotM, err); err != nil { tt.Errorf("error = %v", err) } - }) } } @@ -136,7 +135,6 @@ func TestGetMallocInfo(t *testing.T) { if err := checkFunc(test.want, got, err); err != nil { tt.Errorf("error = %v", err) } - }) } } diff --git a/internal/errors/malloc.go b/internal/errors/malloc.go new file mode 100644 index 00000000000..c47669d8200 --- /dev/null +++ b/internal/errors/malloc.go @@ -0,0 +1,22 @@ +// +// Copyright (C) 2019-2023 vdaas.org vald team +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Package errors provides error types and function +package errors + +var ErrUnexpectedReturnCode = func(ret int) error { + return Errorf("unexpected return code: %d", ret) +} diff --git a/internal/observability/metrics/mem/malloc/malloc.go b/internal/observability/metrics/mem/malloc/malloc.go new file mode 100644 index 00000000000..b0051b67e22 --- /dev/null +++ b/internal/observability/metrics/mem/malloc/malloc.go @@ -0,0 +1,242 @@ +// Copyright (C) 2019-2023 vdaas.org vald team +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package malloc + +import ( + "context" + + "github.com/vdaas/vald/internal/core/malloc" + "github.com/vdaas/vald/internal/observability/metrics" + "go.opentelemetry.io/otel/sdk/metric/aggregation" + "go.opentelemetry.io/otel/sdk/metric/view" +) + +const ( + totalFastCountMetricsName = "total_fast_count" + totalFastCountMetricsDescription = "Total fast count" + + totalFastSizeMetricsName = "total_fast_size" + totalFastSizeMetricsDescription = "Total fast size" + + totalRestCountMetricsName = "total_rest_count" + totalRestCountMetricsDescription = "Total rest count" + + totalRestSizeMetricsName = "total_rest_size" + totalRestSizeMetricsDescription = "Total rest size" + + systemCurrentSizeMetricsName = "system_current_size" + systemCurrentSizeMetricsDescription = "System current size" + + systemMaxSizeMetricsName = "system_max_size" + systemMaxSizeMetricsDescription = "System max size" + + aspaceTotalSizeMetricsName = "aspace_total_size" + aspaceTotalSizeMetricsDescription = "Aspace total size" + + aspaceMprotectSizeMetricsName = "aspace_mprotect_size" + aspaceMprotectSizeMetricsDescription = "Aspace mprotect size" +) + +type mallocMetrics struct{} + +func New() metrics.Metric { + return &mallocMetrics{} +} + +func (m *mallocMetrics) View() ([]*metrics.View, error) { + totalFastCount, err := view.New( + view.MatchInstrumentName(totalFastCountMetricsName), + view.WithSetDescription(totalFastCountMetricsDescription), + view.WithSetAggregation(aggregation.LastValue{}), + ) + if err != nil { + return nil, err + } + + totalFastSize, err := view.New( + view.MatchInstrumentName(totalFastSizeMetricsName), + view.WithSetDescription(totalFastSizeMetricsDescription), + view.WithSetAggregation(aggregation.LastValue{}), + ) + if err != nil { + return nil, err + } + + totalRestCount, err := view.New( + view.MatchInstrumentName(totalRestCountMetricsName), + view.WithSetDescription(totalRestCountMetricsDescription), + view.WithSetAggregation(aggregation.LastValue{}), + ) + if err != nil { + return nil, err + } + + totalRestSize, err := view.New( + view.MatchInstrumentName(totalRestSizeMetricsName), + view.WithSetDescription(totalRestSizeMetricsDescription), + view.WithSetAggregation(aggregation.LastValue{}), + ) + if err != nil { + return nil, err + } + + systemCurrentSize, err := view.New( + view.MatchInstrumentName(systemCurrentSizeMetricsName), + view.WithSetDescription(systemCurrentSizeMetricsDescription), + view.WithSetAggregation(aggregation.LastValue{}), + ) + if err != nil { + return nil, err + } + + systemMaxSize, err := view.New( + view.MatchInstrumentName(systemMaxSizeMetricsName), + view.WithSetDescription(systemMaxSizeMetricsDescription), + view.WithSetAggregation(aggregation.LastValue{}), + ) + if err != nil { + return nil, err + } + + aspaceTotalSize, err := view.New( + view.MatchInstrumentName(aspaceTotalSizeMetricsName), + view.WithSetDescription(aspaceTotalSizeMetricsDescription), + view.WithSetAggregation(aggregation.LastValue{}), + ) + if err != nil { + return nil, err + } + + aspaceMprotectSize, err := view.New( + view.MatchInstrumentName(aspaceMprotectSizeMetricsName), + view.WithSetDescription(aspaceMprotectSizeMetricsDescription), + view.WithSetAggregation(aggregation.LastValue{}), + ) + if err != nil { + return nil, err + } + + return []*metrics.View{ + &totalFastCount, + &totalFastSize, + &totalRestCount, + &totalRestSize, + &systemCurrentSize, + &systemMaxSize, + &aspaceTotalSize, + &aspaceMprotectSize, + }, nil +} + +func (mm *mallocMetrics) Register(m metrics.Meter) error { + totalFastCount, err := m.AsyncInt64().Gauge( + totalFastCountMetricsName, + metrics.WithDescription(totalFastCountMetricsDescription), + metrics.WithUnit(metrics.Dimensionless), + ) + if err != nil { + return err + } + + totalFastSize, err := m.AsyncInt64().Gauge( + totalFastSizeMetricsName, + metrics.WithDescription(totalFastSizeMetricsDescription), + metrics.WithUnit(metrics.Dimensionless), + ) + if err != nil { + return err + } + + totalRestCount, err := m.AsyncInt64().Gauge( + totalRestCountMetricsName, + metrics.WithDescription(totalRestCountMetricsDescription), + metrics.WithUnit(metrics.Dimensionless), + ) + if err != nil { + return err + } + + totalRestSize, err := m.AsyncInt64().Gauge( + totalRestSizeMetricsName, + metrics.WithDescription(totalRestSizeMetricsDescription), + metrics.WithUnit(metrics.Dimensionless), + ) + if err != nil { + return err + } + + systemCurrentSize, err := m.AsyncInt64().Gauge( + systemCurrentSizeMetricsName, + metrics.WithDescription(systemCurrentSizeMetricsDescription), + metrics.WithUnit(metrics.Dimensionless), + ) + if err != nil { + return err + } + + systemMaxSize, err := m.AsyncInt64().Gauge( + systemMaxSizeMetricsName, + metrics.WithDescription(systemMaxSizeMetricsDescription), + metrics.WithUnit(metrics.Dimensionless), + ) + if err != nil { + return err + } + + aspaceTotalSize, err := m.AsyncInt64().Gauge( + aspaceTotalSizeMetricsName, + metrics.WithDescription(aspaceTotalSizeMetricsDescription), + metrics.WithUnit(metrics.Dimensionless), + ) + if err != nil { + return err + } + + aspaceMprotectSize, err := m.AsyncInt64().Gauge( + aspaceMprotectSizeMetricsName, + metrics.WithDescription(aspaceMprotectSizeMetricsDescription), + metrics.WithUnit(metrics.Dimensionless), + ) + if err != nil { + return err + } + + return m.RegisterCallback( + []metrics.AsynchronousInstrument{ + totalFastCount, + totalFastSize, + totalRestCount, + totalRestSize, + systemCurrentSize, + systemMaxSize, + aspaceTotalSize, + aspaceMprotectSize, + }, + func(ctx context.Context) { + mallocInfo, err := malloc.GetMallocInfo() + if err != nil { + return + } + + totalFastCount.Observe(ctx, int64(mallocInfo.Total[0].Count)) + totalFastSize.Observe(ctx, int64(mallocInfo.Total[0].Size)) + totalRestCount.Observe(ctx, int64(mallocInfo.Total[1].Count)) + totalRestSize.Observe(ctx, int64(mallocInfo.Total[1].Size)) + systemCurrentSize.Observe(ctx, int64(mallocInfo.System[0].Size)) + systemMaxSize.Observe(ctx, int64(mallocInfo.System[1].Size)) + aspaceTotalSize.Observe(ctx, int64(mallocInfo.Aspace[0].Size)) + aspaceMprotectSize.Observe(ctx, int64(mallocInfo.Aspace[1].Size)) + }, + ) +} diff --git a/pkg/agent/core/ngt/usecase/agentd.go b/pkg/agent/core/ngt/usecase/agentd.go index 2e198edea48..6b50bab53d2 100644 --- a/pkg/agent/core/ngt/usecase/agentd.go +++ b/pkg/agent/core/ngt/usecase/agentd.go @@ -27,6 +27,7 @@ import ( "github.com/vdaas/vald/internal/observability" ngtmetrics "github.com/vdaas/vald/internal/observability/metrics/agent/core/ngt" infometrics "github.com/vdaas/vald/internal/observability/metrics/info" + mallocmetrics "github.com/vdaas/vald/internal/observability/metrics/mem/malloc" "github.com/vdaas/vald/internal/runner" "github.com/vdaas/vald/internal/safety" "github.com/vdaas/vald/internal/servers/server" @@ -97,6 +98,7 @@ func New(cfg *config.Data) (r runner.Runner, err error) { cfg.Observability, ngtmetrics.New(ngt), infometrics.New("agent_core_ngt_info", "Agent NGT info", *cfg.NGT), + mallocmetrics.New(), ) if err != nil { return nil, err