Skip to content

Commit

Permalink
http.send: Add metric for counting inter-query cache hits (#4087)
Browse files Browse the repository at this point in the history
An inter-query cache is used to cache responses for http.send. This change allows users to gain insight into how the cache is performing by tracking the number of cache hits.
Fixes: #4023

Signed-off-by: Mira Yadav <mira.yadav620@gmail.com>
  • Loading branch information
mirayadav committed Dec 3, 2021
1 parent af4ad84 commit 1c51402
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 14 deletions.
9 changes: 5 additions & 4 deletions topdown/http.go
Expand Up @@ -68,9 +68,10 @@ var allowedKeyNames = [...]string{
}

var (
allowedKeys = ast.NewSet()
requiredKeys = ast.NewSet(ast.StringTerm("method"), ast.StringTerm("url"))
httpSendLatencyMetricKey = "rego_builtin_" + strings.ReplaceAll(ast.HTTPSend.Name, ".", "_")
allowedKeys = ast.NewSet()
requiredKeys = ast.NewSet(ast.StringTerm("method"), ast.StringTerm("url"))
httpSendLatencyMetricKey = "rego_builtin_" + strings.ReplaceAll(ast.HTTPSend.Name, ".", "_")
httpSendInterQueryCacheHits = httpSendLatencyMetricKey + "_interquery_cache_hits"
)

type httpSendKey string
Expand Down Expand Up @@ -627,7 +628,7 @@ func (c *interQueryCache) checkHTTPSendInterQueryCache() (ast.Value, error) {
if !found {
return nil, nil
}

c.bctx.Metrics.Counter(httpSendInterQueryCacheHits).Incr()
var cachedRespData *interQueryCacheData

switch v := value.(type) {
Expand Down
49 changes: 39 additions & 10 deletions topdown/http_test.go
Expand Up @@ -30,6 +30,8 @@ import (
"github.com/open-policy-agent/opa/metrics"
"github.com/open-policy-agent/opa/topdown/builtins"

iCache "github.com/open-policy-agent/opa/topdown/cache"

"github.com/open-policy-agent/opa/ast"
)

Expand Down Expand Up @@ -2483,17 +2485,44 @@ func TestHTTPSendMetrics(t *testing.T) {

defer ts.Close()

// Execute query and verify http.send latency shows up in metrics registry.
m := metrics.New()
q := NewQuery(ast.MustParseBody(fmt.Sprintf(`http.send({"method": "get", "url": %q})`, ts.URL))).WithMetrics(m)
_, err := q.Run(context.Background())
if err != nil {
t.Fatal(err)
}
t.Run("latency", func(t *testing.T) {
// Execute query and verify http.send latency shows up in metrics registry.
m := metrics.New()
q := NewQuery(ast.MustParseBody(fmt.Sprintf(`http.send({"method": "get", "url": %q})`, ts.URL))).WithMetrics(m)
_, err := q.Run(context.Background())
if err != nil {
t.Fatal(err)
}

if m.Timer(httpSendLatencyMetricKey).Int64() == 0 {
t.Fatal("expected non-zero value for http.send latency metric")
}
if m.Timer(httpSendLatencyMetricKey).Int64() == 0 {
t.Fatal("expected non-zero value for http.send latency metric")
}
})

t.Run("cache hits", func(t *testing.T) {
// add an inter-query cache
config, _ := iCache.ParseCachingConfig(nil)
interQueryCache := iCache.NewInterQueryCache(config)

// Execute query twice and verify http.send inter-query cache hit metric is incremented.
m := metrics.New()
q := NewQuery(ast.MustParseBody(fmt.Sprintf(`http.send({"method": "get", "url": %q, "cache": true})`, ts.URL))).
WithInterQueryBuiltinCache(interQueryCache).
WithMetrics(m)
_, err := q.Run(context.Background())
if err != nil {
t.Fatal(err)
}
// cache hit
_, err = q.Run(context.Background())
if err != nil {
t.Fatal(err)
}

if exp, act := uint64(1), m.Counter(httpSendInterQueryCacheHits).Value(); exp != act {
t.Fatalf("expected %d cache hits, got %d", exp, act)
}
})
}

func TestInitDefaults(t *testing.T) {
Expand Down

0 comments on commit 1c51402

Please sign in to comment.