Skip to content

Commit

Permalink
Merge pull request #355 from hello-wn/feat-cachext-monitor
Browse files Browse the repository at this point in the history
monitor cache hit rate by prometheus
  • Loading branch information
fenngwd authored Oct 25, 2021
2 parents 014d8a2 + b240aea commit c05c379
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 2 deletions.
10 changes: 10 additions & 0 deletions extensions/cachext/cached.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"time"

"github.com/RichardKnop/machinery/v1/log"
"github.com/prometheus/client_golang/prometheus"
)

const Nil = cacheNil("cache result is nil")
Expand Down Expand Up @@ -61,7 +62,16 @@ func (c *CachedConfig) GetResult(ctx context.Context, out interface{}, strArgs [
if err != nil {
return err
}
labels := prometheus.Labels{prefixName: c.cache.prefix, funcName: c.funcName}
if c.cache.requestCounter != nil {
// Increment request counter.
c.cache.requestCounter.With(labels).Inc()
}
if data != nil {
if c.cache.hitCounter != nil {
// Increment hit counter.
c.cache.hitCounter.With(labels).Inc()
}
if c.cacheNil && decodeIsNil(data) {
// 无法直接把out设置为nil,这里通过返回特殊的错误来表示nil。调用方需要判断
return Nil
Expand Down
37 changes: 37 additions & 0 deletions extensions/cachext/ext.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import (
"github.com/shanbay/gobay"
"github.com/spf13/viper"
"github.com/vmihailenco/msgpack"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)

type void struct{}
Expand All @@ -24,6 +26,8 @@ type CacheExt struct {
prefix string
initialized bool
cachedFuncName map[string]void
requestCounter *prometheus.CounterVec
hitCounter *prometheus.CounterVec
}

var (
Expand All @@ -32,6 +36,13 @@ var (
mu sync.Mutex
)

const (
prefixName = "prefix_name"
funcName = "func_name"
)

var cacheLabels = []string{prefixName, funcName}

// CacheBackend
type CacheBackend interface {
Init(*viper.Viper) error
Expand Down Expand Up @@ -73,6 +84,10 @@ func (c *CacheExt) Init(app *gobay.Application) error {
} else {
return errors.New("No backend found for cache_backend:" + backendConfig)
}
if config.GetBool("monitor_enable") {
c.requestCounter = newCacheRequestCounter()
c.hitCounter = newCacheHitCounter()
}

c.initialized = true
return nil
Expand Down Expand Up @@ -240,3 +255,25 @@ func decodeIsNil(data interface{}) bool {
}
return false
}

// Create a collector for total cache request counter
func newCacheRequestCounter() *prometheus.CounterVec {
return promauto.NewCounterVec(
prometheus.CounterOpts{
Name: "cache_request_counter",
Help: "Number of cache requests",
},
cacheLabels,
)
}

// Create a collector for cache hit counter
func newCacheHitCounter() *prometheus.CounterVec {
return promauto.NewCounterVec(
prometheus.CounterOpts{
Name: "cache_hit_counter",
Help: "Number of cache hits",
},
cacheLabels,
)
}
55 changes: 55 additions & 0 deletions extensions/cachext/ext_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,19 @@ package cachext_test
import (
"context"
"fmt"
"io/ioutil"
"log"
"strings"
"testing"
"time"

"net/http"

"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/shanbay/gobay"
"github.com/shanbay/gobay/extensions/cachext"
_ "github.com/shanbay/gobay/extensions/cachext/backend/memory"
"github.com/stretchr/testify/assert"
)

func ExampleCacheExt_Set() {
Expand Down Expand Up @@ -577,3 +583,52 @@ func Benchmark_Cached(b *testing.B) {
}
}
}

func TestCacheExt_Cached_Monitor(t *testing.T) {
// 准备数据
cache := &cachext.CacheExt{NS: "cache_"}
exts := map[gobay.Key]gobay.Extension{
"cache": cache,
}
_, err := gobay.CreateApp("../../testdata/", "cachemonitored", exts)
assert.Nil(t, err)

fetchMetricData := func() string {
resp, err := http.Get("http://localhost:2112/metrics")
if err != nil {
t.Error(err)
}
defer resp.Body.Close()
rawData, err := ioutil.ReadAll(resp.Body)
if err != nil {
t.Error(err)
}
return string(rawData)
}

go func() {
http.Handle("/metrics", promhttp.Handler())
if err := http.ListenAndServe(":2112", nil); err != nil {
log.Fatalf("error when start prometheus server: %v\n", err)
}
}()

// Cache method
f_str := func(_ context.Context, keys []string, args []int64) (interface{}, error) {
return keys[0], nil
}
c_f_str := cache.Cached("f_str", f_str, cachext.WithTTL(10*time.Second))
str := ""

// Get result from function
c_f_str.GetResult(context.Background(), &str, []string{"hello"}, []int64{})
data := fetchMetricData()
assert.Contains(t, data, `cache_request_counter{func_name="f_str",prefix_name="github"} 1`)
assert.NotContains(t, data, `cache_hit_counter`)

// Get result from cache
c_f_str.GetResult(context.Background(), &str, []string{"hello"}, []int64{})
data = fetchMetricData()
assert.Contains(t, data, `cache_request_counter{func_name="f_str",prefix_name="github"} 2`)
assert.Contains(t, data, `cache_hit_counter{func_name="f_str",prefix_name="github"} 1`)
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ require (
github.com/mattn/go-sqlite3 v1.14.6
github.com/mitchellh/mapstructure v1.4.1
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.11.0
github.com/prometheus/procfs v0.7.1 // indirect
github.com/satori/go.uuid v1.2.0
github.com/spf13/cobra v1.1.1
Expand Down
Loading

0 comments on commit c05c379

Please sign in to comment.