Skip to content

Commit

Permalink
enhance local cache logs and metrics (#146)
Browse files Browse the repository at this point in the history
* enhance local cache logs and metrics

* Linting issues

* update dependencies

* fix go sum

* fix tests

* Add do func

* Enhance logs
  • Loading branch information
lucaslopezf authored Oct 11, 2024
1 parent bd235fe commit f58f9e8
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 120 deletions.
5 changes: 3 additions & 2 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@ linters:
- gosec
- goconst
- gocritic
- megacheck
- staticcheck
- unused
- gosimple
- goconst
- bodyclose
- unconvert
- unparam
- unused
- durationcheck
- exportloopref
- copyloopvar
- makezero
- nilerr
- reassign
Expand Down
38 changes: 19 additions & 19 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
module github.com/zondax/golem

go 1.22
go 1.22.0

toolchain go1.23.0

require (
github.com/ClickHouse/clickhouse-go/v2 v2.28.2
github.com/ClickHouse/clickhouse-go/v2 v2.29.0
github.com/alicebob/miniredis/v2 v2.33.0
github.com/allegro/bigcache/v3 v3.1.0
github.com/go-chi/chi/v5 v5.1.0
github.com/go-chi/cors v1.2.1
github.com/go-redis/redis/v8 v8.11.5
github.com/go-redsync/redsync/v4 v4.13.0
github.com/go-resty/resty/v2 v2.14.0
github.com/go-resty/resty/v2 v2.15.3
github.com/google/uuid v1.6.0
github.com/prometheus/client_golang v1.20.2
github.com/prometheus/client_golang v1.20.4
github.com/shirou/gopsutil v3.21.11+incompatible
github.com/spf13/cobra v1.8.1
github.com/spf13/viper v1.19.0
github.com/stretchr/testify v1.9.0
go.uber.org/zap v1.27.0
golang.org/x/sync v0.8.0
golang.org/x/time v0.6.0
golang.org/x/time v0.7.0
gorm.io/driver/clickhouse v0.6.1
gorm.io/driver/postgres v1.5.9
gorm.io/gorm v1.25.11
gorm.io/gorm v1.25.12
)

require (
Expand Down Expand Up @@ -52,11 +52,11 @@ require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/pgx/v5 v5.6.0 // indirect
github.com/jackc/puddle/v2 v2.2.1 // indirect
github.com/jackc/pgx/v5 v5.7.1 // indirect
github.com/jackc/puddle/v2 v2.2.2 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/klauspost/compress v1.17.9 // indirect
github.com/klauspost/compress v1.17.10 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/paulmach/orb v0.11.1 // indirect
Expand All @@ -65,7 +65,7 @@ require (
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.57.0 // indirect
github.com/prometheus/common v0.60.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/sagikazarmark/locafero v0.6.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
Expand All @@ -78,18 +78,18 @@ require (
github.com/stretchr/objx v0.5.2 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/tklauser/go-sysconf v0.3.14 // indirect
github.com/tklauser/numcpus v0.8.0 // indirect
github.com/tklauser/numcpus v0.9.0 // indirect
github.com/yuin/gopher-lua v1.1.1 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.opentelemetry.io/otel v1.29.0 // indirect
go.opentelemetry.io/otel/trace v1.29.0 // indirect
go.opentelemetry.io/otel v1.30.0 // indirect
go.opentelemetry.io/otel/trace v1.30.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.26.0 // indirect
golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 // indirect
golang.org/x/net v0.28.0 // indirect
golang.org/x/sys v0.24.0 // indirect
golang.org/x/text v0.17.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
golang.org/x/crypto v0.28.0 // indirect
golang.org/x/exp v0.0.0-20241004190924-225e2abe05e6 // indirect
golang.org/x/net v0.30.0 // indirect
golang.org/x/sys v0.26.0 // indirect
golang.org/x/text v0.19.0 // indirect
google.golang.org/protobuf v1.35.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
122 changes: 36 additions & 86 deletions go.sum

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions pkg/utils/converters.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package utils

import "errors"

// IntToUInt64 safely converts an int to uint64.
// Returns an error if the number is negative.
func IntToUInt64(i int) (uint64, error) {
if i < 0 {
return 0, errors.New("cannot convert negative int to uint64")
}
return uint64(i), nil
}

// IntToUInt safely converts an int to uint.
// Returns an error if the number is negative.
func IntToUInt(i int) (uint, error) {
if i < 0 {
return 0, errors.New("cannot convert negative int to uint")
}
return uint(i), nil
}
31 changes: 22 additions & 9 deletions pkg/zcache/local_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import (
"context"
"encoding/json"
"errors"
"github.com/zondax/golem/pkg/logger"
"time"

"github.com/zondax/golem/pkg/logger"

"github.com/allegro/bigcache/v3"
"github.com/zondax/golem/pkg/metrics"
"github.com/zondax/golem/pkg/metrics/collectors"
Expand All @@ -26,6 +27,7 @@ const (
cleanupItemCountMetricKey = "local_cache_cleanup_item_count"
cleanupDeletedItemCountMetricKey = "local_cache_cleanup_deleted_item_count"
cleanupErrorMetricKey = "local_cache_cleanup_errors"
cleanupLastRunMetricKey = "local_cache_cleanup_last_run"
)

type CacheItem struct {
Expand Down Expand Up @@ -160,16 +162,18 @@ func (c *localCache) cleanupExpiredKeys() {
for iterator.SetNext() {
entry, err := iterator.Value()
if err != nil {
c.logger.Errorf("[cleanup] - Error iterating over cache entries: %v", err)
if err = c.metricsServer.UpdateMetric(cleanupErrorMetricKey, 1, iterationErrorLabel); err != nil {
c.logger.Errorf("error updating %s metric with label %s: [%s]", cleanupErrorMetricKey, iterationErrorLabel, err)
c.logger.Errorf("[cleanup] - error updating %s metric with label %s: [%s]", cleanupErrorMetricKey, iterationErrorLabel, err)
}
continue
}

var cachedItem CacheItem
if err = json.Unmarshal(entry.Value(), &cachedItem); err != nil {
c.logger.Errorf("[cleanup] - Error unmarshalling cache item: %v", err)
if err = c.metricsServer.UpdateMetric(cleanupErrorMetricKey, 1, unmarshalErrorLabel); err != nil {
c.logger.Errorf("error updating %s metric with label %s: [%s]", cleanupErrorMetricKey, unmarshalErrorLabel, err)
c.logger.Errorf("[cleanup] - error updating %s metric with label %s: [%s]", cleanupErrorMetricKey, unmarshalErrorLabel, err)
}
continue
}
Expand All @@ -193,18 +197,23 @@ func (c *localCache) cleanupExpiredKeys() {

// update metrics
if err := c.metricsServer.UpdateMetric(cleanupItemCountMetricKey, float64(totalResident-totalDeleted), residentItemCountLabel); err != nil {
c.logger.Errorf("Failed to update cleanup item count metric, err: %s", err)
c.logger.Errorf("[cleanup] - Failed to update cleanup item count metric, err: %s", err)
}
if err := c.metricsServer.UpdateMetric(cleanupDeletedItemCountMetricKey, float64(totalDeleted), deletedItemCountLabel); err != nil {
c.logger.Errorf("Failed to update deletion cleanup deleted item count metric, err: %s", err)
c.logger.Errorf("[cleanup] - Failed to update deletion cleanup deleted item count metric, err: %s", err)
}

if err := c.metricsServer.UpdateMetric(cleanupLastRunMetricKey, float64(time.Now().Unix())); err != nil {
c.logger.Errorf("[cleanup] - Failed to update cleanup last run metric, err: %s", err)
}
}

func (c *localCache) deleteKeysInBatch(keys []string) (deleted int) {
for _, key := range keys {
if err := c.client.Delete(key); err != nil {
c.logger.Errorf("[cleanup] - Error deleting key %s: %v", key, err)
if err = c.metricsServer.UpdateMetric(cleanupErrorMetricKey, 1, deletionErrorLabel); err != nil {
c.logger.Errorf("error updating %s metric with label %s: [%s]", cleanupErrorMetricKey, deletionErrorLabel, err)
c.logger.Errorf("[cleanup] - error updating %s metric with label %s: [%s]", cleanupErrorMetricKey, deletionErrorLabel, err)
}
continue
}
Expand All @@ -215,14 +224,18 @@ func (c *localCache) deleteKeysInBatch(keys []string) (deleted int) {

func (c *localCache) registerCleanupMetrics() {
if err := c.metricsServer.RegisterMetric(cleanupErrorMetricKey, "Counts different types of errors occurred during cache cleanup process", []string{errorTypeLabel}, &collectors.Counter{}); err != nil {
c.logger.Errorf("Failed to register cleanup metrics, err: %s", err)
c.logger.Errorf("[cleanup] - Failed to register cleanup metrics, err: %s", err)
}

if err := c.metricsServer.RegisterMetric(cleanupItemCountMetricKey, "Counts the valid items in the cache during cache cleanup process", []string{itemCountLabel}, &collectors.Gauge{}); err != nil {
c.logger.Errorf("Failed to register cleanup metrics, err: %s", err)
c.logger.Errorf("[cleanup] - Failed to register cleanup metrics, err: %s", err)
}

if err := c.metricsServer.RegisterMetric(cleanupDeletedItemCountMetricKey, "Counts the expired (deleted) items in the cache during cache cleanup process", []string{itemCountLabel}, &collectors.Gauge{}); err != nil {
c.logger.Errorf("Failed to register cleanup metrics, err: %s", err)
c.logger.Errorf("[cleanup] - Failed to register cleanup metrics, err: %s", err)
}

if err := c.metricsServer.RegisterMetric(cleanupLastRunMetricKey, "Timestamp of the last cleanup process execution", []string{}, &collectors.Gauge{}); err != nil {
c.logger.Errorf("[cleanup] - Failed to register cleanup last run metric, err: %s", err)
}
}
3 changes: 3 additions & 0 deletions pkg/zcache/local_cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,13 +207,16 @@ func (suite *LocalCacheTestSuite) TestCleanupProcessMetrics() {
got := sync.Map{}

tm := &metrics.MockTaskMetrics{}
tm.On("RegisterMetric", "local_cache_cleanup_last_run", mock.Anything, []string{}, mock.Anything).Once().
Return(nil)
tm.On("RegisterMetric", "local_cache_cleanup_errors", mock.Anything, []string{"error_type"}, mock.Anything).Once().
Return(nil)
tm.On("RegisterMetric", "local_cache_cleanup_item_count", mock.Anything, []string{"item_count"}, mock.Anything).Once().
Return(nil)
tm.On("RegisterMetric", "local_cache_cleanup_deleted_item_count", mock.Anything, []string{"item_count"}, mock.Anything).Once().
Return(nil)

tm.On("UpdateMetric", "local_cache_cleanup_last_run", mock.Anything, mock.Anything).Return(nil)
tm.On("UpdateMetric", "local_cache_cleanup_errors", mock.Anything, mock.Anything).Return(nil)
tm.On("UpdateMetric", "local_cache_cleanup_item_count", mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
total := args.Get(1).(float64)
Expand Down
7 changes: 5 additions & 2 deletions pkg/zhttpclient/backoff/backoff.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package backoff

import (
"github.com/zondax/golem/pkg/utils"
"time"

"github.com/cenkalti/backoff/v4"
Expand Down Expand Up @@ -35,11 +36,13 @@ func (b *BackOff) WithInitialDuration(initial time.Duration) *BackOff {

func (b *BackOff) Exponential() backoff.BackOff {
tmp := backoff.NewExponentialBackOff(backoff.WithInitialInterval(b.initialDuration), backoff.WithMaxElapsedTime(b.maxDuration), backoff.WithMultiplier(exponentialMultiplier))
return backoff.WithMaxRetries(tmp, uint64(b.maxAttempts))
maxAttempts, _ := utils.IntToUInt64(b.maxAttempts)
return backoff.WithMaxRetries(tmp, maxAttempts)
}

func (b *BackOff) Linear() backoff.BackOff {
return backoff.WithMaxRetries(backoff.NewConstantBackOff(b.initialDuration), uint64(b.maxAttempts))
maxAttempts, _ := utils.IntToUInt64(b.maxAttempts)
return backoff.WithMaxRetries(backoff.NewConstantBackOff(b.initialDuration), maxAttempts)
}

// Do retries op if it returns an error according to the provided backoff
Expand Down
4 changes: 3 additions & 1 deletion pkg/zhttpclient/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package zhttpclient
import (
"context"
"crypto/tls"
"github.com/zondax/golem/pkg/utils"
"io"
"net"
"net/http"
Expand Down Expand Up @@ -76,7 +77,8 @@ func (z *zHTTPClient) SetRetryPolicy(retryPolicy *RetryPolicy) ZHTTPClient {
// default backoff function is provided by resty
if retryPolicy.backoffFn != nil {
z.client.SetRetryAfter(func(c *resty.Client, r *resty.Response) (time.Duration, error) {
return retryPolicy.backoffFn(uint(r.Request.Attempt), r.RawResponse, nil), nil
attempt, _ := utils.IntToUInt(r.Request.Attempt)
return retryPolicy.backoffFn(attempt, r.RawResponse, nil), nil
})
}
return z
Expand Down
4 changes: 3 additions & 1 deletion pkg/zhttpclient/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"context"
"errors"
"fmt"
"github.com/zondax/golem/pkg/utils"
"io"
"net"
"net/http"
Expand Down Expand Up @@ -369,7 +370,8 @@ func TestHTTPClient_Retry(t *testing.T) {
backoff.WithMultiplier(2),
)
tmp.RandomizationFactor = 0
b := backoff.WithMaxRetries(tmp, uint64(r.MaxAttempts))
maxAttempts, _ := utils.IntToUInt64(r.MaxAttempts)
b := backoff.WithMaxRetries(tmp, maxAttempts)

r.SetBackoff(func(_ uint, _ *http.Response, _ error) time.Duration {
return b.NextBackOff()
Expand Down

0 comments on commit f58f9e8

Please sign in to comment.