Skip to content

Commit

Permalink
feat(logic): introduce telemetry to track predicate call counts
Browse files Browse the repository at this point in the history
  • Loading branch information
ccamel committed Nov 10, 2024
1 parent d0722b2 commit d0fd0c7
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 14 deletions.
28 changes: 14 additions & 14 deletions x/logic/keeper/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ func (k Keeper) newInterpreter(ctx context.Context, params types.Params) (*prolo
interpreter.WithHooks(
whitelistBlacklistHookFn(whitelistPredicates, blacklistPredicates),
gasMeterHookFn(sdkctx, params.GetGasPolicy()),
telemetryPredicateCallCounterHookFn(),
),
interpreter.WithPredicates(ctx, interpreter.RegistryNames),
interpreter.WithBootstrap(ctx, util.NonZeroOrDefault(interpreterParams.GetBootstrap(), bootstrap.Bootstrap())),
Expand Down Expand Up @@ -135,23 +136,24 @@ func whitelistBlacklistHookFn(whitelist, blacklist []string) engine.HookFunc {
return nil
}

predicateStringer, ok := operand.(fmt.Stringer)
predicate, ok := stringifyOperand(operand)
if !ok {
return engine.SyntaxError(operand, env)
}

predicate := predicateStringer.String()
if !interpreter.IsRegistered(predicate) {
return nil
}

if interpreter.IsRegistered(predicate) {
if _, found := allowed.Get(predicate); !found {
return engine.PermissionError(
prolog2.AtomOperationExecute,
prolog2.AtomPermissionForbiddenPredicate,
engine.NewAtom(predicate),
env,
)
}
if _, found := allowed.Get(predicate); !found {
return engine.PermissionError(
prolog2.AtomOperationExecute,
prolog2.AtomPermissionForbiddenPredicate,
engine.NewAtom(predicate),
env,
)
}

return nil
}
}
Expand All @@ -166,13 +168,11 @@ func gasMeterHookFn(ctx context.Context, gasPolicy types.GasPolicy) engine.HookF
return nil
}

operandStringer, ok := operand.(fmt.Stringer)
predicate, ok := stringifyOperand(operand)
if !ok {
return engine.SyntaxError(operand, env)
}

predicate := operandStringer.String()

cost := lookupCost(predicate,
lo.CoalesceOrEmpty(gasPolicy.DefaultPredicateCost, defaultPredicateCost),
gasPolicy.PredicateCosts)
Expand Down
55 changes: 55 additions & 0 deletions x/logic/keeper/metrics.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package keeper

import (
"fmt"

"github.com/axone-protocol/prolog/engine"
"github.com/hashicorp/go-metrics"

"github.com/cosmos/cosmos-sdk/telemetry"

"github.com/axone-protocol/axoned/v10/x/logic/interpreter"
"github.com/axone-protocol/axoned/v10/x/logic/types"
)

var metricsKeys = []string{types.ModuleName, "vm", "predicate"}

const (
labelPredicate = "predicate"
)

func telemetryPredicateCallCounterHookFn() engine.HookFunc {
return func(opcode engine.Opcode, operand engine.Term, _ *engine.Env) error {
if opcode != engine.OpCall {
return nil
}

predicate, ok := stringifyOperand(operand)
if !ok {
return nil
}

if !interpreter.IsRegistered(predicate) {
return nil
}

telemetry.IncrCounterWithLabels(
metricsKeys,
1,
[]metrics.Label{
telemetry.NewLabel(labelPredicate, predicate),
},
)

return nil
}
}

// stringifyOperand returns the string representation of the operand if it implements fmt.Stringer.
// It returns an empty string and false if the operand does not have a string representation.
func stringifyOperand(operand engine.Term) (string, bool) {
if stringer, ok := operand.(fmt.Stringer); ok {
return stringer.String(), true
}
return "", false
}

0 comments on commit d0fd0c7

Please sign in to comment.