diff --git a/core/base/context.go b/core/base/context.go index e78b98a4..b97f4729 100644 --- a/core/base/context.go +++ b/core/base/context.go @@ -30,6 +30,9 @@ type EntryContext struct { StatNode StatNode Input *SentinelInput + + // checker name of the hit rule + RuleChecker string // the result of rule slots check RuleCheckResult *TokenResult // reserve for storing some intermediate data from the Entry execution process diff --git a/core/circuitbreaker/slot.go b/core/circuitbreaker/slot.go index 1b577897..70bd6ae5 100644 --- a/core/circuitbreaker/slot.go +++ b/core/circuitbreaker/slot.go @@ -20,6 +20,8 @@ import ( const ( RuleCheckSlotOrder = 5000 + + name = "circuitbreaker" ) var ( @@ -52,6 +54,11 @@ func (b *Slot) Check(ctx *base.EntryContext) *base.TokenResult { func checkPass(ctx *base.EntryContext) (bool, *Rule) { breakers := getBreakersOfResource(ctx.Resource.Name()) + if len(breakers) == 0 { + return true, nil + } + + ctx.RuleChecker = name for _, breaker := range breakers { passed := breaker.TryPass(ctx) if !passed { diff --git a/core/flow/slot.go b/core/flow/slot.go index 13ad17b5..e5f7c9c9 100644 --- a/core/flow/slot.go +++ b/core/flow/slot.go @@ -15,16 +15,19 @@ package flow import ( + "github.com/pkg/errors" + "github.com/alibaba/sentinel-golang/core/base" "github.com/alibaba/sentinel-golang/core/stat" metric_exporter "github.com/alibaba/sentinel-golang/exporter/metric" "github.com/alibaba/sentinel-golang/logging" "github.com/alibaba/sentinel-golang/util" - "github.com/pkg/errors" ) const ( RuleCheckSlotOrder = 2000 + + name = "flow" ) var ( @@ -57,6 +60,8 @@ func (s *Slot) Check(ctx *base.EntryContext) *base.TokenResult { logging.Warn("[FlowSlot Check]Nil traffic controller found", "resourceName", res) continue } + + ctx.RuleChecker = name r := canPassCheck(tc, ctx.StatNode, ctx.Input.BatchCount) if r == nil { // nil means pass diff --git a/core/hotspot/slot.go b/core/hotspot/slot.go index d7edf1e7..81afe953 100644 --- a/core/hotspot/slot.go +++ b/core/hotspot/slot.go @@ -21,6 +21,8 @@ import ( const ( RuleCheckSlotOrder = 4000 + + name = "hotspot" ) var ( @@ -45,6 +47,8 @@ func (s *Slot) Check(ctx *base.EntryContext) *base.TokenResult { if arg == nil { continue } + + ctx.RuleChecker = name r := canPassCheck(tc, arg, batch) if r == nil { continue diff --git a/core/isolation/slot.go b/core/isolation/slot.go index 037991e4..6e2b4b84 100644 --- a/core/isolation/slot.go +++ b/core/isolation/slot.go @@ -15,13 +15,16 @@ package isolation import ( + "github.com/pkg/errors" + "github.com/alibaba/sentinel-golang/core/base" "github.com/alibaba/sentinel-golang/logging" - "github.com/pkg/errors" ) const ( RuleCheckSlotOrder = 3000 + + name = "isolation" ) var ( @@ -59,6 +62,8 @@ func checkPass(ctx *base.EntryContext) (bool, *Rule, uint32) { for _, rule := range getRulesOfResource(ctx.Resource.Name()) { threshold := rule.Threshold if rule.MetricType == Concurrency { + ctx.RuleChecker = name + if cur := statNode.CurrentConcurrency(); cur >= 0 { curCount = uint32(cur) } else { diff --git a/core/stat/stat_slot.go b/core/stat/stat_slot.go index 2845dead..bab9a773 100644 --- a/core/stat/stat_slot.go +++ b/core/stat/stat_slot.go @@ -32,7 +32,7 @@ var ( handledCounter = metric_exporter.NewCounter( "handled_total", "Total handled count", - []string{"resource", "result", "block_type"}) + []string{"resource", "result", "block_type", "rule_name"}) ) func init() { @@ -52,7 +52,7 @@ func (s *Slot) OnEntryPassed(ctx *base.EntryContext) { s.recordPassFor(InboundNode(), ctx.Input.BatchCount) } - handledCounter.Add(float64(ctx.Input.BatchCount), ctx.Resource.Name(), ResultPass, "") + handledCounter.Add(float64(ctx.Input.BatchCount), ctx.Resource.Name(), ResultPass, "", ctx.RuleChecker) } func (s *Slot) OnEntryBlocked(ctx *base.EntryContext, blockError *base.BlockError) { @@ -61,7 +61,8 @@ func (s *Slot) OnEntryBlocked(ctx *base.EntryContext, blockError *base.BlockErro s.recordBlockFor(InboundNode(), ctx.Input.BatchCount) } - handledCounter.Add(float64(ctx.Input.BatchCount), ctx.Resource.Name(), ResultBlock, blockError.BlockType().String()) + handledCounter.Add(float64(ctx.Input.BatchCount), ctx.Resource.Name(), ResultBlock, + blockError.BlockType().String(), ctx.RuleChecker) } func (s *Slot) OnCompleted(ctx *base.EntryContext) { diff --git a/core/system/slot.go b/core/system/slot.go index 5871ddcc..1be02b53 100644 --- a/core/system/slot.go +++ b/core/system/slot.go @@ -22,6 +22,8 @@ import ( const ( RuleCheckSlotOrder = 1000 + + name = "system" ) var ( @@ -42,7 +44,7 @@ func (s *AdaptiveSlot) Check(ctx *base.EntryContext) *base.TokenResult { rules := getRules() result := ctx.RuleCheckResult for _, rule := range rules { - passed, msg, snapshotValue := s.doCheckRule(rule) + passed, msg, snapshotValue := s.doCheckRule(ctx, rule) if passed { continue } @@ -56,9 +58,12 @@ func (s *AdaptiveSlot) Check(ctx *base.EntryContext) *base.TokenResult { return result } -func (s *AdaptiveSlot) doCheckRule(rule *Rule) (bool, string, float64) { +func (s *AdaptiveSlot) doCheckRule(ctx *base.EntryContext, rule *Rule) (bool, string, float64) { var msg string + prevChecker := ctx.RuleChecker + ctx.RuleChecker = name + threshold := rule.TriggerCount switch rule.MetricType { case InboundQPS: @@ -101,6 +106,7 @@ func (s *AdaptiveSlot) doCheckRule(rule *Rule) (bool, string, float64) { } return true, "", c default: + ctx.RuleChecker = prevChecker msg = "system undefined metric type, pass by default" return true, msg, 0.0 } diff --git a/core/system/slot_test.go b/core/system/slot_test.go index aa918aa2..5af72824 100644 --- a/core/system/slot_test.go +++ b/core/system/slot_test.go @@ -17,11 +17,12 @@ package system import ( "testing" + "github.com/stretchr/testify/assert" + "github.com/alibaba/sentinel-golang/core/base" "github.com/alibaba/sentinel-golang/core/stat" "github.com/alibaba/sentinel-golang/core/system_metric" "github.com/alibaba/sentinel-golang/util" - "github.com/stretchr/testify/assert" ) func TestCheckNilInput(t *testing.T) { @@ -60,14 +61,14 @@ func TestDoCheckRuleConcurrency(t *testing.T) { TriggerCount: 0.5} t.Run("TrueConcurrency", func(t *testing.T) { - isOK, _, v := sas.doCheckRule(rule) + isOK, _, v := sas.doCheckRule(&base.EntryContext{}, rule) assert.True(t, util.Float64Equals(float64(0.0), v)) assert.Equal(t, true, isOK) }) t.Run("FalseConcurrency", func(t *testing.T) { stat.InboundNode().IncreaseConcurrency() - isOK, _, v := sas.doCheckRule(rule) + isOK, _, v := sas.doCheckRule(&base.EntryContext{}, rule) assert.True(t, util.Float64Equals(float64(1.0), v)) assert.Equal(t, false, isOK) stat.InboundNode().DecreaseConcurrency() @@ -80,7 +81,7 @@ func TestDoCheckRuleLoad(t *testing.T) { TriggerCount: 0.5} t.Run("TrueLoad", func(t *testing.T) { - isOK, _, v := sas.doCheckRule(rule) + isOK, _, v := sas.doCheckRule(&base.EntryContext{}, rule) assert.True(t, util.Float64Equals(system_metric.NotRetrievedLoadValue, v)) assert.Equal(t, true, isOK) }) @@ -88,7 +89,7 @@ func TestDoCheckRuleLoad(t *testing.T) { t.Run("BBRTrueLoad", func(t *testing.T) { rule.Strategy = BBR system_metric.SetSystemLoad(1.0) - isOK, _, v := sas.doCheckRule(rule) + isOK, _, v := sas.doCheckRule(&base.EntryContext{}, rule) assert.Equal(t, true, isOK) assert.True(t, util.Float64Equals(float64(1.0), v)) system_metric.SetSystemLoad(system_metric.NotRetrievedLoadValue) @@ -103,7 +104,7 @@ func TestDoCheckRuleCpuUsage(t *testing.T) { } t.Run("TrueCpuUsage", func(t *testing.T) { - isOK, _, v := sas.doCheckRule(rule) + isOK, _, v := sas.doCheckRule(&base.EntryContext{}, rule) assert.True(t, util.Float64Equals(system_metric.NotRetrievedCpuUsageValue, v)) assert.Equal(t, true, isOK) }) @@ -111,7 +112,7 @@ func TestDoCheckRuleCpuUsage(t *testing.T) { t.Run("BBRTrueCpuUsage", func(t *testing.T) { rule.Strategy = BBR system_metric.SetSystemCpuUsage(0.8) - isOK, _, v := sas.doCheckRule(rule) + isOK, _, v := sas.doCheckRule(&base.EntryContext{}, rule) assert.Equal(t, true, isOK) assert.True(t, util.Float64Equals(0.8, v)) system_metric.SetSystemCpuUsage(system_metric.NotRetrievedCpuUsageValue) @@ -123,7 +124,7 @@ func TestDoCheckRuleDefault(t *testing.T) { rule := &Rule{MetricType: MetricTypeSize, TriggerCount: 0.5} - isOK, _, v := sas.doCheckRule(rule) + isOK, _, v := sas.doCheckRule(&base.EntryContext{}, rule) assert.Equal(t, true, isOK) assert.True(t, util.Float64Equals(float64(0.0), v)) }