Repository: alibaba/sentinel-golang
Pull request #302 (2020-10-23 15:04:07)

Fix no limit of batch count in flow throttling checker
<!--  Thanks for submitting a pull request! Here are some tips for you:
1. Please make sure you have read and understood the contributing guidelines: https://github.com/alibaba/blob/master/CONTRIBUTING.md
2. Please make sure the PR has a corresponding issue.
-->

### Describe what this PR does / why we need it
Fix no limit of batch count in flow throttling checker.

### Does this pull request fix one issue?

<!--If that, add "Fixes #xxxx" below in the next line. For example, Fixes #15. Otherwise, add "NONE" -->

### Describe how you did it


### Describe how to verify it


### Special notes for reviews


Patch:
diff --git a/api/tracer.go b/api/tracer.go
index 1a1171f..aea81dc 100644
--- a/api/tracer.go
+++ b/api/tracer.go
@@ -10,7 +10,7 @@ import (
 func TraceError(entry *base.SentinelEntry, err error) {
 	defer func() {
 		if e := recover(); e != nil {
-			logging.Error(errors.Errorf("%+v", e), "failed to TraceError")
+			logging.Error(errors.Errorf("%+v", e), "Failed to api.TraceError()")
 			return
 		}
 	}()
diff --git a/core/base/entry.go b/core/base/entry.go
index 9967c51..b082149 100644
--- a/core/base/entry.go
+++ b/core/base/entry.go
@@ -77,7 +77,7 @@ func (e *SentinelEntry) Exit(exitOps ...ExitOption) {
 	e.exitCtl.Do(func() {
 		defer func() {
 			if err := recover(); err != nil {
-				logging.Error(errors.Errorf("%+v", err), "Sentinel internal panic in entry exit func")
+				logging.Error(errors.Errorf("%+v", err), "Sentinel internal panic in SentinelEntry.Exit()")
 			}
 			if e.sc != nil {
 				e.sc.RefurbishContext(ctx)
@@ -85,7 +85,7 @@ func (e *SentinelEntry) Exit(exitOps ...ExitOption) {
 		}()
 		for _, handler := range e.exitHandlers {
 			if err := handler(e, ctx); err != nil {
-				logging.Error(err, "Fail to execute exitHandler", "resource", e.Resource().Name())
+				logging.Error(err, "Fail to execute exitHandler in SentinelEntry.Exit()", "resource", e.Resource().Name())
 			}
 		}
 		if e.sc != nil {
diff --git a/core/base/slot_chain.go b/core/base/slot_chain.go
index d50d26b..84395fe 100644
--- a/core/base/slot_chain.go
+++ b/core/base/slot_chain.go
@@ -205,7 +205,7 @@ func (sc *SlotChain) Entry(ctx *EntryContext) *TokenResult {
 	// If happened, need to add TokenResult in EntryContext
 	defer func() {
 		if err := recover(); err != nil {
-			logging.Error(errors.Errorf("%+v", err), "Sentinel internal panic in SlotChain")
+			logging.Error(errors.Errorf("%+v", err), "Sentinel internal panic in SlotChain.Entry()")
 			ctx.SetError(errors.Errorf("%+v", err))
 			return
 		}
@@ -261,7 +261,8 @@ func (sc *SlotChain) Entry(ctx *EntryContext) *TokenResult {
 
 func (sc *SlotChain) exit(ctx *EntryContext) {
 	if ctx == nil || ctx.Entry() == nil {
-		logging.Error(errors.New("nil EntryContext or SentinelEntry"), "")
+		logging.Error(errors.New("entryContext or SentinelEntry is nil"),
+			"EntryContext or SentinelEntry is nil in SlotChain.exit()", "ctx", ctx)
 		return
 	}
 	// The OnCompleted is called only when entry passed
diff --git a/core/base/stat.go b/core/base/stat.go
index 79e0601..28a2c69 100644
--- a/core/base/stat.go
+++ b/core/base/stat.go
@@ -1,7 +1,7 @@
 package base
 
 import (
-	"github.com/pkg/errors"
+	"errors"
 )
 
 type TimePredicate func(uint64) bool
diff --git a/core/circuitbreaker/circuit_breaker.go b/core/circuitbreaker/circuit_breaker.go
index 531b968..feced37 100644
--- a/core/circuitbreaker/circuit_breaker.go
+++ b/core/circuitbreaker/circuit_breaker.go
@@ -1,6 +1,7 @@
 package circuitbreaker
 
 import (
+	"reflect"
 	"sync/atomic"
 
 	"github.com/alibaba/sentinel-golang/core/base"
@@ -152,7 +153,7 @@ func (b *circuitBreakerBase) fromOpenToHalfOpen(ctx *base.EntryContext) bool {
 
 		entry := ctx.Entry()
 		if entry == nil {
-			logging.Error(errors.New("nil entry"), "nil entry when probing", "rule", b.rule)
+			logging.Error(errors.New("nil entry"), "Nil entry in circuitBreakerBase.fromOpenToHalfOpen()", "rule", b.rule)
 		} else {
 			// add hook for entry exit
 			// if the current circuit breaker performs the probe through this entry, but the entry was blocked,
@@ -341,21 +342,21 @@ func (s *slowRequestLeapArray) ResetBucketTo(bw *sbase.BucketWrap, startTime uin
 func (s *slowRequestLeapArray) currentCounter() *slowRequestCounter {
 	curBucket, err := s.data.CurrentBucket(s)
 	if err != nil {
-		logging.Error(err, "failed to get current bucket")
+		logging.Error(err, "Failed to get current bucket in slowRequestLeapArray.currentCounter()")
 		return nil
 	}
 	if curBucket == nil {
-		logging.Error(errors.New("nil current BucketWrap"), "Current bucket is nil")
+		logging.Error(errors.New("nil current BucketWrap"), "Current bucket is nil in slowRequestLeapArray.currentCounter()")
 		return nil
 	}
 	mb := curBucket.Value.Load()
 	if mb == nil {
-		logging.Error(errors.New("Current bucket atomic Value is nil"), "")
+		logging.Error(errors.New("current bucket atomic Value is nil"), "Current bucket atomic Value is nil in slowRequestLeapArray.currentCounter()")
 		return nil
 	}
 	counter, ok := mb.(*slowRequestCounter)
 	if !ok {
-		logging.Error(errors.New("Bucket data type error"), "")
+		logging.Error(errors.New("bucket data type error"), "Bucket data type error in slowRequestLeapArray.currentCounter()", "expect type", "*slowRequestCounter", "actual type", reflect.TypeOf(mb).Name())
 		return nil
 	}
 	return counter
@@ -367,12 +368,12 @@ func (s *slowRequestLeapArray) allCounter() []*slowRequestCounter {
 	for _, b := range buckets {
 		mb := b.Value.Load()
 		if mb == nil {
-			logging.Error(errors.New("Current bucket atomic Value is nil"), "")
+			logging.Error(errors.New("current bucket atomic Value is nil"), "Current bucket atomic Value is nil in slowRequestLeapArray.allCounter()")
 			continue
 		}
 		counter, ok := mb.(*slowRequestCounter)
 		if !ok {
-			logging.Error(errors.New("Bucket data type error"), "")
+			logging.Error(errors.New("bucket data type error"), "Bucket data type error in slowRequestLeapArray.allCounter()", "expect type", "*slowRequestCounter", "actual type", reflect.TypeOf(mb).Name())
 			continue
 		}
 		ret = append(ret, counter)
@@ -518,21 +519,21 @@ func (s *errorCounterLeapArray) ResetBucketTo(bw *sbase.BucketWrap, startTime ui
 func (s *errorCounterLeapArray) currentCounter() *errorCounter {
 	curBucket, err := s.data.CurrentBucket(s)
 	if err != nil {
-		logging.Error(err, "Failed to get current bucket")
+		logging.Error(err, "Failed to get current bucket in errorCounterLeapArray.currentCounter()")
 		return nil
 	}
 	if curBucket == nil {
-		logging.Error(errors.New("Current bucket is nil"), "")
+		logging.Error(errors.New("current bucket is nil"), "Current bucket is nil in errorCounterLeapArray.currentCounter()")
 		return nil
 	}
 	mb := curBucket.Value.Load()
 	if mb == nil {
-		logging.Error(errors.New("Current bucket atomic Value is nil"), "")
+		logging.Error(errors.New("current bucket atomic Value is nil"), "Current bucket atomic Value is nil in errorCounterLeapArray.currentCounter()")
 		return nil
 	}
 	counter, ok := mb.(*errorCounter)
 	if !ok {
-		logging.Error(errors.New("Bucket data type error"), "")
+		logging.Error(errors.New("bucket data type error"), "Bucket data type error in errorCounterLeapArray.currentCounter()", "expect type", "*errorCounter", "actual type", reflect.TypeOf(mb).Name())
 		return nil
 	}
 	return counter
@@ -544,12 +545,12 @@ func (s *errorCounterLeapArray) allCounter() []*errorCounter {
 	for _, b := range buckets {
 		mb := b.Value.Load()
 		if mb == nil {
-			logging.Error(errors.New("Current bucket atomic Value is nil"), "")
+			logging.Error(errors.New("current bucket atomic Value is nil"), "Current bucket atomic Value is nil in errorCounterLeapArray.allCounter()")
 			continue
 		}
 		counter, ok := mb.(*errorCounter)
 		if !ok {
-			logging.Error(errors.New("Bucket data type error"), "")
+			logging.Error(errors.New("bucket data type error"), "Bucket data type error in errorCounterLeapArray.allCounter()", "expect type", "*errorCounter", "actual type", reflect.TypeOf(mb).Name())
 			continue
 		}
 		ret = append(ret, counter)
diff --git a/core/circuitbreaker/rule_manager.go b/core/circuitbreaker/rule_manager.go
index 1615da6..ed36d9c 100644
--- a/core/circuitbreaker/rule_manager.go
+++ b/core/circuitbreaker/rule_manager.go
@@ -33,7 +33,7 @@ func init() {
 		}
 		stat, ok := reuseStat.(*slowRequestLeapArray)
 		if !ok || stat == nil {
-			logging.Warn("Expect to generate circuit breaker with reuse statistic, but fail to do type assertion, expect:*slowRequestLeapArray", "statType", reflect.TypeOf(stat).Name())
+			logging.Warn("[CircuitBreaker RuleManager] Expect to generate circuit breaker with reuse statistic, but fail to do type assertion, expect:*slowRequestLeapArray", "statType", reflect.TypeOf(stat).Name())
 			return newSlowRtCircuitBreaker(r)
 		}
 		return newSlowRtCircuitBreakerWithStat(r, stat), nil
@@ -48,7 +48,7 @@ func init() {
 		}
 		stat, ok := reuseStat.(*errorCounterLeapArray)
 		if !ok || stat == nil {
-			logging.Warn("Expect to generate circuit breaker with reuse statistic, but fail to do type assertion, expect:*errorCounterLeapArray", "statType", reflect.TypeOf(stat).Name())
+			logging.Warn("[CircuitBreaker RuleManager] Expect to generate circuit breaker with reuse statistic, but fail to do type assertion, expect:*errorCounterLeapArray", "statType", reflect.TypeOf(stat).Name())
 			return newErrorRatioCircuitBreaker(r)
 		}
 		return newErrorRatioCircuitBreakerWithStat(r, stat), nil
@@ -63,7 +63,7 @@ func init() {
 		}
 		stat, ok := reuseStat.(*errorCounterLeapArray)
 		if !ok || stat == nil {
-			logging.Warn("Expect to generate circuit breaker with reuse statistic, but fail to do type assertion, expect:*errorCounterLeapArray", "statType", reflect.TypeOf(stat).Name())
+			logging.Warn("[CircuitBreaker RuleManager] Expect to generate circuit breaker with reuse statistic, but fail to do type assertion, expect:*errorCounterLeapArray", "statType", reflect.TypeOf(stat).Name())
 			return newErrorCountCircuitBreaker(r)
 		}
 		return newErrorCountCircuitBreakerWithStat(r, stat), nil
@@ -187,7 +187,7 @@ func onRuleUpdate(rules []*Rule) (err error) {
 			continue
 		}
 		if err := IsValid(rule); err != nil {
-			logging.Warn("Ignoring invalid circuit breaking rule when loading new rules", "rule", rule, "err", err)
+			logging.Warn("[CircuitBreaker onRuleUpdate] Ignoring invalid circuit breaking rule when loading new rules", "rule", rule, "err", err)
 			continue
 		}
 
@@ -213,7 +213,7 @@ func onRuleUpdate(rules []*Rule) (err error) {
 		if r := recover(); r != nil {
 			return
 		}
-		logging.Debug("Time statistics(ns) for updating circuit breaker rule", "timeCost", util.CurrentTimeNano()-start)
+		logging.Debug("[CircuitBreaker onRuleUpdate] Time statistics(ns) for updating circuit breaker rule", "timeCost", util.CurrentTimeNano()-start)
 		logRuleUpdate(newBreakerRules)
 	}()
 
@@ -238,7 +238,7 @@ func onRuleUpdate(rules []*Rule) (err error) {
 
 			generator := cbGenFuncMap[r.Strategy]
 			if generator == nil {
-				logging.Warn("Ignoring the rule due to unsupported circuit breaking strategy", "rule", r)
+				logging.Warn("[CircuitBreaker onRuleUpdate] Ignoring the rule due to unsupported circuit breaking strategy", "rule", r)
 				continue
 			}
 
@@ -250,7 +250,7 @@ func onRuleUpdate(rules []*Rule) (err error) {
 				cb, e = generator(r, nil)
 			}
 			if cb == nil || e != nil {
-				logging.Warn("Ignoring the rule due to bad generated circuit breaker", "rule", r, "err", e)
+				logging.Warn("[CircuitBreaker onRuleUpdate] Ignoring the rule due to bad generated circuit breaker", "rule", r, "err", e)
 				continue
 			}
 
diff --git a/core/config/config.go b/core/config/config.go
index dc66b79..8fc6aaa 100644
--- a/core/config/config.go
+++ b/core/config/config.go
@@ -53,7 +53,7 @@ func OverrideConfigFromEnvAndInitLog() error {
 		return err
 	}
 
-	defer logging.Info("print effective global config", "globalConfig", *globalCfg)
+	defer logging.Info("[Config] Print effective global config", "globalConfig", *globalCfg)
 	// Configured Logger is the highest priority
 	if configLogger := Logger(); configLogger != nil {
 		err = logging.ResetGlobalLogger(configLogger)
@@ -70,7 +70,7 @@ func OverrideConfigFromEnvAndInitLog() error {
 	if err := initializeLogConfig(logDir, LogUsePid()); err != nil {
 		return err
 	}
-	logging.Info("App name resolved", "appName", AppName())
+	logging.Info("[Config] App name resolved", "appName", AppName())
 	return nil
 }
 
@@ -93,7 +93,7 @@ func loadGlobalConfigFromYamlFile(filePath string) error {
 	if err != nil {
 		return err
 	}
-	logging.Info("Resolving Sentinel config from file", "file", filePath)
+	logging.Info("[Config] Resolving Sentinel config from file", "file", filePath)
 	return checkConfValid(&(globalCfg.Sentinel))
 }
 
@@ -128,7 +128,7 @@ func overrideItemsFromSystemEnv() error {
 
 func initializeLogConfig(logDir string, usePid bool) (err error) {
 	if logDir == "" {
-		return errors.New("Invalid empty log path")
+		return errors.New("invalid empty log path")
 	}
 
 	initLogOnce.Do(func() {
@@ -155,7 +155,7 @@ func reconfigureRecordLogger(logBaseDir string, withPid bool) error {
 		return err
 	}
 
-	logging.Info("INFO: log base directory is: " + logBaseDir)
+	logging.Info("[Config] Log base directory", "baseDir", logBaseDir)
 
 	return nil
 }
diff --git a/core/flow/rule.go b/core/flow/rule.go
index b739642..4ddfc1f 100644
--- a/core/flow/rule.go
+++ b/core/flow/rule.go
@@ -74,12 +74,15 @@ type Rule struct {
 	ControlBehavior        ControlBehavior        `json:"controlBehavior"`
 	// Threshold means the threshold during StatIntervalInMs
 	// If StatIntervalInMs is 1000(1 second), Threshold means QPS
-	Threshold         float64          `json:"threshold"`
-	RelationStrategy  RelationStrategy `json:"relationStrategy"`
-	RefResource       string           `json:"refResource"`
-	MaxQueueingTimeMs uint32           `json:"maxQueueingTimeMs"`
-	WarmUpPeriodSec   uint32           `json:"warmUpPeriodSec"`
-	WarmUpColdFactor  uint32           `json:"warmUpColdFactor"`
+	Threshold        float64          `json:"threshold"`
+	RelationStrategy RelationStrategy `json:"relationStrategy"`
+	RefResource      string           `json:"refResource"`
+	// MaxQueueingTimeMs only takes effect when ControlBehavior is Throttling.
+	// When MaxQueueingTimeMs is 0, it means Throttling only controls interval of requests,
+	// and requests exceeding the threshold will be rejected directly.
+	MaxQueueingTimeMs uint32 `json:"maxQueueingTimeMs"`
+	WarmUpPeriodSec   uint32 `json:"warmUpPeriodSec"`
+	WarmUpColdFactor  uint32 `json:"warmUpColdFactor"`
 	// StatIntervalInMs indicates the statistic interval and it's the optional setting for flow Rule.
 	// If user doesn't set StatIntervalInMs, that means using default metric statistic of resource.
 	// If the StatIntervalInMs user specifies can not reuse the global statistic of resource,
diff --git a/core/flow/rule_manager.go b/core/flow/rule_manager.go
index e7266e0..04199a9 100644
--- a/core/flow/rule_manager.go
+++ b/core/flow/rule_manager.go
@@ -133,7 +133,7 @@ func onRuleUpdate(rules []*Rule) (err error) {
 	resRulesMap := make(map[string][]*Rule)
 	for _, rule := range rules {
 		if err := IsValidRule(rule); err != nil {
-			logging.Warn("ignoring invalid flow rule", "rule", rule, "reason", err)
+			logging.Warn("[Flow onRuleUpdate] Ignoring invalid flow rule", "rule", rule, "reason", err)
 			continue
 		}
 		resRules, exist := resRulesMap[rule.Resource]
@@ -150,7 +150,7 @@ func onRuleUpdate(rules []*Rule) (err error) {
 		if r := recover(); r != nil {
 			return
 		}
-		logging.Debug("time statistic(ns) for updating flow rule", "timeCost", util.CurrentTimeNano()-start)
+		logging.Debug("[Flow onRuleUpdate] Time statistic(ns) for updating flow rule", "timeCost", util.CurrentTimeNano()-start)
 		logRuleUpdate(m)
 	}()
 	for res, rulesOfRes := range resRulesMap {
@@ -297,7 +297,7 @@ func generateStatFor(rule *Rule) (*standaloneStatistic, error) {
 		retStat.writeOnlyMetric = nil
 		return &retStat, nil
 	} else if err == base.GlobalStatisticNonReusableError {
-		logging.Info("flow rule couldn't reuse global statistic and will generate independent statistic", "rule", rule)
+		logging.Info("[FlowRuleManager] Flow rule couldn't reuse global statistic and will generate independent statistic", "rule", rule)
 		retStat.reuseResourceStat = false
 		realLeapArray := sbase.NewBucketLeapArray(sampleCount, intervalInMs)
 		metricStat, e := sbase.NewSlidingWindowMetric(sampleCount, intervalInMs, realLeapArray)
@@ -390,7 +390,7 @@ func buildRulesOfRes(res string, rulesOfRes []*Rule) []*TrafficShapingController
 	emptyTcs := make([]*TrafficShapingController, 0, 0)
 	for _, rule := range rulesOfRes {
 		if res != rule.Resource {
-			logging.Error(errors.Errorf("unmatched resource name, expect: %s, actual: %s", res, rule.Resource), "FlowManager: unmatched resource name ", "rule", rule)
+			logging.Error(errors.Errorf("unmatched resource name expect: %s, actual: %s", res, rule.Resource), "Unmatched resource name in flow.buildRulesOfRes()", "rule", rule)
 			continue
 		}
 		oldResTcs, exist := tcMap[res]
@@ -415,7 +415,7 @@ func buildRulesOfRes(res string, rulesOfRes []*Rule) []*TrafficShapingController
 			controlBehavior:        rule.ControlBehavior,
 		}]
 		if !supported || generator == nil {
-			logging.Error(errors.New("unsupported flow control strategy"), "ignoring the rule due to unsupported control behavior", "rule", rule)
+			logging.Error(errors.New("unsupported flow control strategy"), "Ignoring the rule due to unsupported control behavior in flow.buildRulesOfRes()", "rule", rule)
 			continue
 		}
 		var tc *TrafficShapingController
@@ -427,7 +427,7 @@ func buildRulesOfRes(res string, rulesOfRes []*Rule) []*TrafficShapingController
 		}
 
 		if tc == nil || e != nil {
-			logging.Error(errors.New("bad generated traffic controller"), "ignoring the rule due to bad generated traffic controller.", "rule", rule)
+			logging.Error(errors.New("bad generated traffic controller"), "Ignoring the rule due to bad generated traffic controller in flow.buildRulesOfRes()", "rule", rule)
 			continue
 		}
 		if reuseStatIdx >= 0 {
@@ -470,9 +470,6 @@ func IsValidRule(rule *Rule) error {
 			return errors.New("WarmUpColdFactor must be great than 1")
 		}
 	}
-	if rule.ControlBehavior == Throttling && rule.MaxQueueingTimeMs == 0 {
-		return errors.New("MaxQueueingTimeMs can't be 0 when control behavior is Throttling")
-	}
 	if rule.StatIntervalInMs > 10*60*1000 {
 		logging.Info("StatIntervalInMs is great than 10 minutes, less than 10 minutes is recommended.")
 	}
diff --git a/core/flow/slot.go b/core/flow/slot.go
index d6a4cb7..e2af8ce 100644
--- a/core/flow/slot.go
+++ b/core/flow/slot.go
@@ -32,7 +32,7 @@ func (s *Slot) Check(ctx *base.EntryContext) *base.TokenResult {
 	// Check rules in order
 	for _, tc := range tcs {
 		if tc == nil {
-			logging.Warn("nil traffic controller found", "resourceName", res)
+			logging.Warn("[FlowSlot Check]Nil traffic controller found", "resourceName", res)
 			continue
 		}
 		r := canPassCheck(tc, ctx.StatNode, ctx.Input.BatchCount)
@@ -73,7 +73,7 @@ func checkInLocal(tc *TrafficShapingController, resStat base.StatNode, batchCoun
 	actual := selectNodeByRelStrategy(tc.rule, resStat)
 	if actual == nil {
 		logging.FrequentErrorOnce.Do(func() {
-			logging.Error(errors.Errorf("nil resource node"), "no resource node for flow rule", "rule", tc.rule)
+			logging.Error(errors.Errorf("nil resource node"), "No resource node for flow rule in FlowSlot.checkInLocal()", "rule", tc.rule)
 		})
 		return base.NewTokenResultPass()
 	}
diff --git a/core/flow/standalone_stat_slot.go b/core/flow/standalone_stat_slot.go
index 0e40fe7..d8fa51a 100644
--- a/core/flow/standalone_stat_slot.go
+++ b/core/flow/standalone_stat_slot.go
@@ -28,7 +28,7 @@ func (s StandaloneStatSlot) OnEntryPassed(ctx *base.EntryContext) {
 			if tc.boundStat.writeOnlyMetric != nil {
 				tc.boundStat.writeOnlyMetric.AddCount(base.MetricEventPass, int64(ctx.Input.BatchCount))
 			} else {
-				logging.Error(errors.New("nil independent write statistic"), "flow module: nil statistic for traffic control", "rule", tc.rule)
+				logging.Error(errors.New("nil independent write statistic"), "Nil statistic for traffic control in StandaloneStatSlot.OnEntryPassed()", "rule", tc.rule)
 			}
 		}
 	}
diff --git a/core/flow/tc_throttling.go b/core/flow/tc_throttling.go
index 43c6ce3..504256a 100644
--- a/core/flow/tc_throttling.go
+++ b/core/flow/tc_throttling.go
@@ -47,6 +47,9 @@ func (c *ThrottlingChecker) DoCheck(_ base.StatNode, batchCount uint32, threshol
 	if threshold <= 0.0 {
 		return base.NewTokenResultBlocked(base.BlockTypeFlow)
 	}
+	if float64(batchCount) > threshold {
+		return base.NewTokenResultBlocked(base.BlockTypeFlow)
+	}
 	// Here we use nanosecond so that we could control the queueing time more accurately.
 	curNano := util.CurrentTimeNano()
 
diff --git a/core/hotspot/cache/lru.go b/core/hotspot/cache/lru.go
index c369f0d..c9bf7c9 100644
--- a/core/hotspot/cache/lru.go
+++ b/core/hotspot/cache/lru.go
@@ -26,7 +26,7 @@ type entry struct {
 // NewLRU constructs an LRU of the given size
 func NewLRU(size int, onEvict EvictCallback) (*LRU, error) {
 	if size <= 0 {
-		return nil, errors.New("Must provide a positive size")
+		return nil, errors.New("must provide a positive size")
 	}
 	c := &LRU{
 		size:      size,
diff --git a/core/hotspot/concurrency_stat_slot.go b/core/hotspot/concurrency_stat_slot.go
index d919373..4c7b967 100644
--- a/core/hotspot/concurrency_stat_slot.go
+++ b/core/hotspot/concurrency_stat_slot.go
@@ -36,7 +36,7 @@ func (c *ConcurrencyStatSlot) OnEntryPassed(ctx *base.EntryContext) {
 		concurrencyPtr, existed := metric.ConcurrencyCounter.Get(arg)
 		if !existed || concurrencyPtr == nil {
 			if logging.DebugEnabled() {
-				logging.Debug("Parameter does not exist in ConcurrencyCounter.", "argument", arg)
+				logging.Debug("[ConcurrencyStatSlot OnEntryPassed] Parameter does not exist in ConcurrencyCounter.", "argument", arg)
 			}
 			continue
 		}
@@ -61,7 +61,7 @@ func (c *ConcurrencyStatSlot) OnCompleted(ctx *base.EntryContext) {
 		concurrencyPtr, existed := metric.ConcurrencyCounter.Get(arg)
 		if !existed || concurrencyPtr == nil {
 			if logging.DebugEnabled() {
-				logging.Debug("Parameter does not exist in ConcurrencyCounter.", "argument", arg)
+				logging.Debug("[ConcurrencyStatSlot OnCompleted] Parameter does not exist in ConcurrencyCounter.", "argument", arg)
 			}
 			continue
 		}
diff --git a/core/hotspot/rule_manager.go b/core/hotspot/rule_manager.go
index 7d74429..49ecfaa 100644
--- a/core/hotspot/rule_manager.go
+++ b/core/hotspot/rule_manager.go
@@ -120,7 +120,7 @@ func onRuleUpdate(rules []*Rule) (err error) {
 	newRuleMap := make(map[string][]*Rule)
 	for _, r := range rules {
 		if err := IsValidRule(r); err != nil {
-			logging.Warn("Ignoring invalid hotspot rule when loading new rules", "rule", r, "err", err)
+			logging.Warn("[HotSpot onRuleUpdate] Ignoring invalid hotspot rule when loading new rules", "rule", r, "err", err)
 			continue
 		}
 		res := r.ResourceName()
@@ -144,7 +144,7 @@ func onRuleUpdate(rules []*Rule) (err error) {
 		if r := recover(); r != nil {
 			return
 		}
-		logging.Debug("time statistic(ns) for updating hotspot rule", "timeCost", util.CurrentTimeNano()-start)
+		logging.Debug("[HotSpot onRuleUpdate] Time statistic(ns) for updating hotSpot rule", "timeCost", util.CurrentTimeNano()-start)
 		logRuleUpdate(m)
 	}()
 
@@ -169,7 +169,7 @@ func onRuleUpdate(rules []*Rule) (err error) {
 			// generate new traffic shaping controller
 			generator, supported := tcGenFuncMap[r.ControlBehavior]
 			if !supported {
-				logging.Warn("Ignoring the frequent param flow rule due to unsupported control behavior", "rule", r)
+				logging.Warn("[HotSpot onRuleUpdate] Ignoring the frequent param flow rule due to unsupported control behavior", "rule", r)
 				continue
 			}
 			var tc TrafficShapingController
@@ -180,7 +180,7 @@ func onRuleUpdate(rules []*Rule) (err error) {
 				tc = generator(r, nil)
 			}
 			if tc == nil {
-				logging.Debug("Ignoring the frequent param flow rule due to bad generated traffic controller", "rule", r)
+				logging.Debug("[HotSpot onRuleUpdate] Ignoring the frequent param flow rule due to bad generated traffic controller", "rule", r)
 				continue
 			}
 
diff --git a/core/hotspot/slot.go b/core/hotspot/slot.go
index e06aed7..9b0dc2f 100644
--- a/core/hotspot/slot.go
+++ b/core/hotspot/slot.go
@@ -34,13 +34,13 @@ func matchArg(tc TrafficShapingController, args []interface{}) interface{} {
 	}
 	if idx < 0 {
 		if logging.DebugEnabled() {
-			logging.Debug("The param index of hotspot traffic shaping controller is invalid", "args", args, "paramIndex", tc.BoundParamIndex())
+			logging.Debug("[Slot matchArg] The param index of hotspot traffic shaping controller is invalid", "args", args, "paramIndex", tc.BoundParamIndex())
 		}
 		return nil
 	}
 	if idx >= len(args) {
 		if logging.DebugEnabled() {
-			logging.Debug("The argument in index doesn't exist", "args", args, "paramIndex", tc.BoundParamIndex())
+			logging.Debug("[Slot matchArg] The argument in index doesn't exist", "args", args, "paramIndex", tc.BoundParamIndex())
 		}
 		return nil
 	}
diff --git a/core/hotspot/traffic_shaping.go b/core/hotspot/traffic_shaping.go
index b0e756e..cfed71a 100644
--- a/core/hotspot/traffic_shaping.go
+++ b/core/hotspot/traffic_shaping.go
@@ -61,7 +61,7 @@ func newBaseTrafficShapingController(r *Rule) *baseTrafficShapingController {
 		size = int(math.Min(float64(ParamsMaxCapacity), float64(ParamsCapacityBase*r.DurationInSec)))
 	}
 	if size <= 0 {
-		logging.Warn("invalid size of cache, so use default value for ParamsMaxCapacity and ParamsCapacityBase",
+		logging.Warn("[HotSpot newBaseTrafficShapingController] Invalid size of cache, so use default value for ParamsMaxCapacity and ParamsCapacityBase",
 			"ParamsMaxCapacity", ParamsMaxCapacity, "ParamsCapacityBase", ParamsCapacityBase)
 		size = ParamsMaxCapacity
 	}
diff --git a/core/isolation/rule_manager.go b/core/isolation/rule_manager.go
index 3afa147..21df3e6 100644
--- a/core/isolation/rule_manager.go
+++ b/core/isolation/rule_manager.go
@@ -22,7 +22,7 @@ func LoadRules(rules []*Rule) (updated bool, err error) {
 	m := make(map[string][]*Rule)
 	for _, r := range rules {
 		if e := IsValid(r); e != nil {
-			logging.Error(e, "invalid isolation rule.", "rule", r)
+			logging.Error(e, "Invalid isolation rule in isolation.LoadRules()", "rule", r)
 			continue
 		}
 		resRules, ok := m[r.Resource]
@@ -36,7 +36,7 @@ func LoadRules(rules []*Rule) (updated bool, err error) {
 	rwMux.Lock()
 	defer func() {
 		rwMux.Unlock()
-		logging.Debug("time statistic(ns) for updating isolation rule", "timeCost", util.CurrentTimeNano()-start)
+		logging.Debug("[Isolation LoadRules] Time statistic(ns) for updating isolation rule", "timeCost", util.CurrentTimeNano()-start)
 		logRuleUpdate(m)
 	}()
 
diff --git a/core/isolation/slot.go b/core/isolation/slot.go
index bdd066f..d33c99d 100644
--- a/core/isolation/slot.go
+++ b/core/isolation/slot.go
@@ -48,7 +48,7 @@ func checkPass(ctx *base.EntryContext) (bool, *Rule, uint32) {
 				curCount = uint32(cur)
 			} else {
 				curCount = 0
-				logging.Error(errors.New("negative concurrency"), "", "rule", rule)
+				logging.Error(errors.New("negative concurrency"), "Negative concurrency in isolation.checkPass()", "rule", rule)
 			}
 			if curCount+batchCount > threshold {
 				return false, rule, curCount
diff --git a/core/log/metric/aggregator.go b/core/log/metric/aggregator.go
index 1ea7ebc..d3483bd 100644
--- a/core/log/metric/aggregator.go
+++ b/core/log/metric/aggregator.go
@@ -37,7 +37,7 @@ func InitTask() (err error) {
 
 		metricWriter, err = NewDefaultMetricLogWriter(config.MetricLogSingleFileMaxSize(), config.MetricLogMaxFileAmount())
 		if err != nil {
-			logging.Error(err, "Failed to initialize the MetricLogWriter")
+			logging.Error(err, "Failed to initialize the MetricLogWriter in aggregator.InitTask()")
 			return
 		}
 
@@ -76,7 +76,7 @@ func writeTaskLoop() {
 			for _, t := range keys {
 				err := metricWriter.Write(t, m[t])
 				if err != nil {
-					logging.Error(err, "[MetricAggregatorTask] fail tp write metric")
+					logging.Error(err, "[MetricAggregatorTask] fail tp write metric in aggregator.writeTaskLoop()")
 				}
 			}
 		}
diff --git a/core/log/metric/reader.go b/core/log/metric/reader.go
index 4f72164..efda221 100644
--- a/core/log/metric/reader.go
+++ b/core/log/metric/reader.go
@@ -106,7 +106,7 @@ func (r *defaultMetricLogReader) readMetricsInOneFile(filename string, offset ui
 		}
 		item, err := base.MetricItemFromFatString(line)
 		if err != nil {
-			logging.Error(err, "Failed to convert MetricItem to string")
+			logging.Error(err, "Failed to convert MetricItem to string in defaultMetricLogReader.readMetricsInOneFile()")
 			continue
 		}
 		tsSec := item.Timestamp / 1000
@@ -140,7 +140,7 @@ func (r *defaultMetricLogReader) readMetricsInOneFileByEndTime(filename string,
 		}
 		item, err := base.MetricItemFromFatString(line)
 		if err != nil {
-			logging.Error(err, "Invalid line of metric file", "fileLine", line)
+			logging.Error(err, "Invalid line of metric file in defaultMetricLogReader.readMetricsInOneFileByEndTime()", "fileLine", line)
 			continue
 		}
 		tsSec := item.Timestamp / 1000
diff --git a/core/log/metric/searcher.go b/core/log/metric/searcher.go
index 5c849fc..8ccdf31 100644
--- a/core/log/metric/searcher.go
+++ b/core/log/metric/searcher.go
@@ -56,7 +56,7 @@ func (s *DefaultMetricSearcher) searchOffsetAndRead(beginTimeMs uint64, doRead f
 	// If cache is not up-to-date, we'll read from the initial position (offset 0 of the first file).
 	offsetStart, fileNo, err := s.getOffsetStartAndFileIdx(filenames, beginTimeMs)
 	if err != nil {
-		logging.Warn("Failed to getOffsetStartAndFileIdx", "beginTimeMs", beginTimeMs, "err", err)
+		logging.Warn("[searchOffsetAndRead] Failed to getOffsetStartAndFileIdx", "beginTimeMs", beginTimeMs, "err", err)
 	}
 	fileAmount := uint32(len(filenames))
 	for i := fileNo; i < fileAmount; i++ {
@@ -65,7 +65,7 @@ func (s *DefaultMetricSearcher) searchOffsetAndRead(beginTimeMs uint64, doRead f
 		// If offset = -1, it indicates that current file (i) does not satisfy the condition.
 		offset, err := s.findOffsetToStart(filename, beginTimeMs, offsetStart)
 		if err != nil {
-			logging.Warn("Failed to findOffsetToStart, will try next file", "beginTimeMs", beginTimeMs,
+			logging.Warn("[searchOffsetAndRead] Failed to findOffsetToStart, will try next file", "beginTimeMs", beginTimeMs,
 				"filename", filename, "offsetStart", offsetStart, "err", err)
 			continue
 		}
diff --git a/core/log/metric/writer.go b/core/log/metric/writer.go
index f598248..b584fe3 100644
--- a/core/log/metric/writer.go
+++ b/core/log/metric/writer.go
@@ -106,7 +106,7 @@ func (d *DefaultMetricLogWriter) writeItemsAndFlush(items []*base.MetricItem) er
 	for _, item := range items {
 		s, err := item.ToFatString()
 		if err != nil {
-			logging.Warn("Failed to convert MetricItem to string", "resourceName", item.Resource, "err", err)
+			logging.Warn("[writeItemsAndFlush] Failed to convert MetricItem to string", "resourceName", item.Resource, "err", err)
 			continue
 		}
 
@@ -171,14 +171,14 @@ func (d *DefaultMetricLogWriter) removeDeprecatedFiles() error {
 		idxFilename := formMetricIdxFileName(filename)
 		err = os.Remove(filename)
 		if err != nil {
-			logging.Error(err, "[MetricWriter] Failed to remove metric log file", "filename", filename)
+			logging.Error(err, "Failed to remove metric log file in DefaultMetricLogWriter.removeDeprecatedFiles()", "filename", filename)
 		} else {
-			logging.Info("[MetricWriter] Metric log file removed", "filename", filename)
+			logging.Info("[MetricWriter] Metric log file removed in DefaultMetricLogWriter.removeDeprecatedFiles()", "filename", filename)
 		}
 
 		err = os.Remove(idxFilename)
 		if err != nil {
-			logging.Error(err, "[MetricWriter] Failed to remove metric log file", "idxFilename", idxFilename)
+			logging.Error(err, "Failed to remove metric log file in DefaultMetricLogWriter.removeDeprecatedFiles()", "idxFilename", idxFilename)
 		} else {
 			logging.Info("[MetricWriter] Metric index file removed", "idxFilename", idxFilename)
 		}
@@ -218,12 +218,12 @@ func (d *DefaultMetricLogWriter) closeCurAndNewFile(filename string) error {
 
 	if d.curMetricFile != nil {
 		if err = d.curMetricFile.Close(); err != nil {
-			logging.Error(err, "[MetricWriter] Failed to close metric log file", "curMetricFile", d.curMetricFile.Name())
+			logging.Error(err, "Failed to close metric log file in DefaultMetricLogWriter.closeCurAndNewFile()", "curMetricFile", d.curMetricFile.Name())
 		}
 	}
 	if d.curMetricIdxFile != nil {
 		if err = d.curMetricIdxFile.Close(); err != nil {
-			logging.Error(err, "[MetricWriter] Failed to close metric index file", "curMetricIdxFile", d.curMetricIdxFile.Name())
+			logging.Error(err, "Failed to close metric index file in DefaultMetricLogWriter.closeCurAndNewFile()", "curMetricIdxFile", d.curMetricIdxFile.Name())
 		}
 	}
 	// Create new metric log file, whether it exists or not.
diff --git a/core/stat/base/bucket_leap_array.go b/core/stat/base/bucket_leap_array.go
index e51b816..915e856 100644
--- a/core/stat/base/bucket_leap_array.go
+++ b/core/stat/base/bucket_leap_array.go
@@ -1,6 +1,7 @@
 package base
 
 import (
+	"reflect"
 	"sync/atomic"
 
 	"github.com/alibaba/sentinel-golang/core/base"
@@ -76,21 +77,21 @@ func (bla *BucketLeapArray) AddCount(event base.MetricEvent, count int64) {
 func (bla *BucketLeapArray) addCountWithTime(now uint64, event base.MetricEvent, count int64) {
 	curBucket, err := bla.data.currentBucketOfTime(now, bla)
 	if err != nil {
-		logging.Error(err, "Failed to get current bucket", "now", now)
+		logging.Error(err, "Failed to get current bucket in BucketLeapArray.addCountWithTime()", "now", now)
 		return
 	}
 	if curBucket == nil {
-		logging.Error(errors.New("current bucket is nil"), "Failed to add count")
+		logging.Error(errors.New("current bucket is nil"), "Nil curBucket in BucketLeapArray.addCountWithTime()")
 		return
 	}
 	mb := curBucket.Value.Load()
 	if mb == nil {
-		logging.Error(errors.New("nil bucket"), "Failed to add count: current bucket atomic Value is nil")
+		logging.Error(errors.New("nil bucket"), "Current bucket atomic Value is nil in BucketLeapArray.addCountWithTime()")
 		return
 	}
 	b, ok := mb.(*MetricBucket)
 	if !ok {
-		logging.Error(errors.New("fail to type assert, expect MetricBucket"), "Failed to add count: bucket data type error")
+		logging.Error(errors.New("fail to type assert"), "Bucket data type error in BucketLeapArray.addCountWithTime()", "expectType", "*MetricBucket", "actualType", reflect.TypeOf(mb).Name())
 		return
 	}
 	b.Add(event, count)
@@ -105,18 +106,18 @@ func (bla *BucketLeapArray) Count(event base.MetricEvent) int64 {
 func (bla *BucketLeapArray) CountWithTime(now uint64, event base.MetricEvent) int64 {
 	_, err := bla.data.currentBucketOfTime(now, bla)
 	if err != nil {
-		logging.Error(err, "Failed to get current bucket", "now", now)
+		logging.Error(err, "Failed to get current bucket in BucketLeapArray.CountWithTime()", "now", now)
 	}
 	count := int64(0)
 	for _, ww := range bla.data.valuesWithTime(now) {
 		mb := ww.Value.Load()
 		if mb == nil {
-			logging.Error(errors.New("current bucket is nil"), "Failed to load current bucket")
+			logging.Error(errors.New("current bucket is nil"), "Failed to load current bucket in BucketLeapArray.CountWithTime()")
 			continue
 		}
 		b, ok := mb.(*MetricBucket)
 		if !ok {
-			logging.Error(errors.New("fail to type assert, expect MetricBucket"), "fail to get current MetricBucket")
+			logging.Error(errors.New("fail to type assert"), "Bucket data type error in BucketLeapArray.CountWithTime()", "expectType", "*MetricBucket", "actualType", reflect.TypeOf(mb).Name())
 			continue
 		}
 		count += b.Get(event)
@@ -128,7 +129,7 @@ func (bla *BucketLeapArray) CountWithTime(now uint64, event base.MetricEvent) in
 func (bla *BucketLeapArray) Values(now uint64) []*BucketWrap {
 	_, err := bla.data.currentBucketOfTime(now, bla)
 	if err != nil {
-		logging.Error(err, "Failed to get current bucket", "now", now)
+		logging.Error(err, "Failed to get current bucket in BucketLeapArray.Values()", "now", now)
 	}
 	return bla.data.valuesWithTime(now)
 }
@@ -140,7 +141,7 @@ func (bla *BucketLeapArray) ValuesConditional(now uint64, predicate base.TimePre
 func (bla *BucketLeapArray) MinRt() int64 {
 	_, err := bla.data.CurrentBucket(bla)
 	if err != nil {
-		logging.Error(err, "Failed to get current bucket")
+		logging.Error(err, "Failed to get current bucket in BucketLeapArray.MinRt()")
 	}
 
 	ret := base.DefaultStatisticMaxRt
@@ -148,12 +149,12 @@ func (bla *BucketLeapArray) MinRt() int64 {
 	for _, v := range bla.data.Values() {
 		mb := v.Value.Load()
 		if mb == nil {
-			logging.Error(errors.New("current bucket is nil"), "Failed to load current bucket")
+			logging.Error(errors.New("current bucket is nil"), "Failed to load current bucket in BucketLeapArray.MinRt()")
 			continue
 		}
 		b, ok := mb.(*MetricBucket)
 		if !ok {
-			logging.Error(errors.New("fail to type assert, expect MetricBucket"), "fail to get current MetricBucket")
+			logging.Error(errors.New("fail to type assert"), "Bucket data type error in BucketLeapArray.MinRt()", "expectType", "*MetricBucket", "actualType", reflect.TypeOf(mb).Name())
 			continue
 		}
 		mr := b.MinRt()
diff --git a/core/stat/base/sliding_window_metric.go b/core/stat/base/sliding_window_metric.go
index 1a8f40c..68a1d59 100644
--- a/core/stat/base/sliding_window_metric.go
+++ b/core/stat/base/sliding_window_metric.go
@@ -24,7 +24,7 @@ type SlidingWindowMetric struct {
 // It must pass the parameter point to the real storage entity
 func NewSlidingWindowMetric(sampleCount, intervalInMs uint32, real *BucketLeapArray) (*SlidingWindowMetric, error) {
 	if real == nil {
-		return nil, errors.New("Nil BucketLeapArray")
+		return nil, errors.New("nil BucketLeapArray")
 	}
 	if err := base.CheckValidityForReuseStatistic(sampleCount, intervalInMs, real.SampleCount(), real.IntervalInMs()); err != nil {
 		return nil, err
@@ -57,12 +57,12 @@ func (m *SlidingWindowMetric) count(event base.MetricEvent, values []*BucketWrap
 	for _, ww := range values {
 		mb := ww.Value.Load()
 		if mb == nil {
-			logging.Error(errors.New("nil BucketWrap"), "Illegal state: current bucket Value is nil when summing count")
+			logging.Error(errors.New("nil BucketWrap"), "Current bucket value is nil in SlidingWindowMetric.count()")
 			continue
 		}
 		counter, ok := mb.(*MetricBucket)
 		if !ok {
-			logging.Error(errors.New("type assert failed"), "Fail to do type assert, expect: MetricBucket", "type", reflect.TypeOf(mb).Name())
+			logging.Error(errors.New("type assert failed"), "Fail to do type assert in SlidingWindowMetric.count()", "expectType", "*MetricBucket", "actualType", reflect.TypeOf(mb).Name())
 			continue
 		}
 		ret += counter.Get(event)
@@ -106,12 +106,12 @@ func (m *SlidingWindowMetric) GetMaxOfSingleBucket(event base.MetricEvent) int64
 	for _, w := range satisfiedBuckets {
 		mb := w.Value.Load()
 		if mb == nil {
-			logging.Error(errors.New("nil BucketWrap"), "Illegal state: current bucket Value is nil when GetMaxOfSingleBucket")
+			logging.Error(errors.New("nil BucketWrap"), "Current bucket value is nil in SlidingWindowMetric.GetMaxOfSingleBucket()")
 			continue
 		}
 		counter, ok := mb.(*MetricBucket)
 		if !ok {
-			logging.Error(errors.New("type assert failed"), "Fail to do type assert, expect: MetricBucket", "type", reflect.TypeOf(mb).Name())
+			logging.Error(errors.New("type assert failed"), "Fail to do type assert in SlidingWindowMetric.GetMaxOfSingleBucket()", "expectType", "*MetricBucket", "actualType", reflect.TypeOf(mb).Name())
 			continue
 		}
 		v := counter.Get(event)
@@ -129,12 +129,12 @@ func (m *SlidingWindowMetric) MinRT() float64 {
 	for _, w := range satisfiedBuckets {
 		mb := w.Value.Load()
 		if mb == nil {
-			logging.Error(errors.New("nil BucketWrap"), "Illegal state: current bucket Value is nil when calculating minRT")
+			logging.Error(errors.New("nil BucketWrap"), "Current bucket value is nil in SlidingWindowMetric.MinRT()")
 			continue
 		}
 		counter, ok := mb.(*MetricBucket)
 		if !ok {
-			logging.Error(errors.New("type assert failed"), "Fail to do type assert, expect: MetricBucket", "type", reflect.TypeOf(mb).Name())
+			logging.Error(errors.New("type assert failed"), "Fail to do type assert in SlidingWindowMetric.MinRT()", "expectType", "*MetricBucket", "actualType", reflect.TypeOf(mb).Name())
 			continue
 		}
 		v := counter.MinRt()
@@ -188,12 +188,12 @@ func (m *SlidingWindowMetric) metricItemFromBuckets(ts uint64, ws []*BucketWrap)
 	for _, w := range ws {
 		mi := w.Value.Load()
 		if mi == nil {
-			logging.Error(errors.New("nil BucketWrap"), "Get nil bucket when generating MetricItem from buckets")
+			logging.Error(errors.New("nil BucketWrap"), "Current bucket value is nil in SlidingWindowMetric.metricItemFromBuckets()")
 			return nil
 		}
 		mb, ok := mi.(*MetricBucket)
 		if !ok {
-			logging.Error(errors.New("type assert failed"), "Fail to do type assert, expect: MetricBucket", "bucketStartTime", w.BucketStart, "type", reflect.TypeOf(mb).Name())
+			logging.Error(errors.New("type assert failed"), "Fail to do type assert in SlidingWindowMetric.metricItemFromBuckets()", "bucketStartTime", w.BucketStart, "expectType", "*MetricBucket", "actualType", reflect.TypeOf(mb).Name())
 			return nil
 		}
 		item.PassQps += uint64(mb.Get(base.MetricEventPass))
@@ -213,12 +213,12 @@ func (m *SlidingWindowMetric) metricItemFromBuckets(ts uint64, ws []*BucketWrap)
 func (m *SlidingWindowMetric) metricItemFromBucket(w *BucketWrap) *base.MetricItem {
 	mi := w.Value.Load()
 	if mi == nil {
-		logging.Error(errors.New("nil BucketWrap"), "Get nil bucket when generating MetricItem from buckets")
+		logging.Error(errors.New("nil BucketWrap"), "Current bucket value is nil in SlidingWindowMetric.metricItemFromBucket()")
 		return nil
 	}
 	mb, ok := mi.(*MetricBucket)
 	if !ok {
-		logging.Error(errors.New("type assert failed"), "Fail to do type assert, expect: MetricBucket", "type", reflect.TypeOf(mb).Name())
+		logging.Error(errors.New("type assert failed"), "Fail to do type assert in SlidingWindowMetric.metricItemFromBucket()", "expectType", "*MetricBucket", "actualType", reflect.TypeOf(mb).Name())
 		return nil
 	}
 	completeQps := mb.Get(base.MetricEventComplete)
diff --git a/core/stat/node_storage.go b/core/stat/node_storage.go
index f473aff..1119196 100644
--- a/core/stat/node_storage.go
+++ b/core/stat/node_storage.go
@@ -54,7 +54,7 @@ func GetOrCreateResourceNode(resource string, resourceType base.ResourceType) *R
 	}
 
 	if len(resNodeMap) >= int(base.DefaultMaxResourceAmount) {
-		logging.Warn("Resource amount exceeds the threshold", "maxResourceAmount", base.DefaultMaxResourceAmount)
+		logging.Warn("[GetOrCreateResourceNode] Resource amount exceeds the threshold", "maxResourceAmount", base.DefaultMaxResourceAmount)
 	}
 	node = NewResourceNode(resource, resourceType)
 	resNodeMap[resource] = node
diff --git a/core/system/rule_manager.go b/core/system/rule_manager.go
index 8dcd2f0..08e51e9 100644
--- a/core/system/rule_manager.go
+++ b/core/system/rule_manager.go
@@ -54,7 +54,7 @@ func LoadRules(rules []*Rule) (bool, error) {
 	m := buildRuleMap(rules)
 
 	if err := onRuleUpdate(m); err != nil {
-		logging.Error(err, "Fail to load rules", "rules", rules)
+		logging.Error(err, "Fail to load rules in system.LoadRules()", "rules", rules)
 		return false, err
 	}
 
@@ -72,7 +72,7 @@ func onRuleUpdate(r RuleMap) error {
 	ruleMapMux.Lock()
 	defer func() {
 		ruleMapMux.Unlock()
-		logging.Debug("time statistic(ns) for updating system rule", "timeCost", util.CurrentTimeNano()-start)
+		logging.Debug("[System onRuleUpdate] Time statistic(ns) for updating system rule", "timeCost", util.CurrentTimeNano()-start)
 		if len(r) > 0 {
 			logging.Info("[SystemRuleManager] System rules loaded", "rules", r)
 		} else {
@@ -92,7 +92,7 @@ func buildRuleMap(rules []*Rule) RuleMap {
 
 	for _, rule := range rules {
 		if err := IsValidSystemRule(rule); err != nil {
-			logging.Warn("Ignoring invalid system rule", "rule", rule, "err", err)
+			logging.Warn("[System buildRuleMap] Ignoring invalid system rule", "rule", rule, "err", err)
 			continue
 		}
 		rulesOfRes, exists := m[rule.MetricType]
diff --git a/core/system/sys_stat.go b/core/system/sys_stat.go
index 552f1c2..0355b1d 100644
--- a/core/system/sys_stat.go
+++ b/core/system/sys_stat.go
@@ -57,11 +57,11 @@ func InitCollector(intervalMs uint32) {
 func retrieveAndUpdateSystemStat() {
 	cpuStats, err := cpu.Times(false)
 	if err != nil {
-		logging.Warn("Failed to retrieve current CPU usage", "err", err)
+		logging.Warn("[retrieveAndUpdateSystemStat] Failed to retrieve current CPU usage", "err", err)
 	}
 	loadStat, err := load.Avg()
 	if err != nil {
-		logging.Warn("Failed to retrieve current system load", "err", err)
+		logging.Warn("[retrieveAndUpdateSystemStat] Failed to retrieve current system load", "err", err)
 	}
 	if len(cpuStats) > 0 {
 		curCpuStat := &cpuStats[0]
diff --git a/example/circuitbreaker/error_count/circuit_breaker_error_count_example.go b/example/circuitbreaker/error_count/circuit_breaker_error_count_example.go
index e2e0f62..b97ea86 100644
--- a/example/circuitbreaker/error_count/circuit_breaker_error_count_example.go
+++ b/example/circuitbreaker/error_count/circuit_breaker_error_count_example.go
@@ -56,7 +56,7 @@ func main() {
 		log.Fatal(err)
 	}
 
-	logging.Info("Sentinel Go circuit breaking demo is running. You may see the pass/block metric in the metric log.")
+	logging.Info("[CircuitBreaker ErrorCount] Sentinel Go circuit breaking demo is running. You may see the pass/block metric in the metric log.")
 	go func() {
 		for {
 			e, b := sentinel.Entry("abc")
diff --git a/example/circuitbreaker/error_ratio/circuit_breaker_error_ratio_example.go b/example/circuitbreaker/error_ratio/circuit_breaker_error_ratio_example.go
index d5b7d01..517fb0b 100644
--- a/example/circuitbreaker/error_ratio/circuit_breaker_error_ratio_example.go
+++ b/example/circuitbreaker/error_ratio/circuit_breaker_error_ratio_example.go
@@ -56,7 +56,7 @@ func main() {
 		log.Fatal(err)
 	}
 
-	logging.Info("Sentinel Go circuit breaking demo is running. You may see the pass/block metric in the metric log.")
+	logging.Info("[CircuitBreaker ErrorRatio] Sentinel Go circuit breaking demo is running. You may see the pass/block metric in the metric log.")
 	go func() {
 		for {
 			e, b := sentinel.Entry("abc")
diff --git a/example/circuitbreaker/slow_rt_ratio/circuit_breaker_slow_rt_ratio_example.go b/example/circuitbreaker/slow_rt_ratio/circuit_breaker_slow_rt_ratio_example.go
index a7aeb4a..7172b9c 100644
--- a/example/circuitbreaker/slow_rt_ratio/circuit_breaker_slow_rt_ratio_example.go
+++ b/example/circuitbreaker/slow_rt_ratio/circuit_breaker_slow_rt_ratio_example.go
@@ -57,7 +57,7 @@ func main() {
 		log.Fatal(err)
 	}
 
-	logging.Info("Sentinel Go circuit breaking demo is running. You may see the pass/block metric in the metric log.")
+	logging.Info("[CircuitBreaker SlowRtRatio] Sentinel Go circuit breaking demo is running. You may see the pass/block metric in the metric log.")
 	go func() {
 		for {
 			e, b := sentinel.Entry("abc")
diff --git a/example/hotspot_param_flow/concurrency/hotspot_params_concurrency_example.go b/example/hotspot_param_flow/concurrency/hotspot_params_concurrency_example.go
index 91698f0..ad4a50b 100644
--- a/example/hotspot_param_flow/concurrency/hotspot_params_concurrency_example.go
+++ b/example/hotspot_param_flow/concurrency/hotspot_params_concurrency_example.go
@@ -1,7 +1,6 @@
 package main
 
 import (
-	"fmt"
 	"log"
 	"math/rand"
 	"time"
@@ -41,12 +40,12 @@ func main() {
 	go func() {
 		node := stat.GetOrCreateResourceNode("abc", base.ResTypeCommon)
 		for {
-			logging.Info(fmt.Sprintf("current concurrency:%d", node.CurrentConcurrency()))
+			logging.Info("[HotSpot Concurrency] currentConcurrency", "currentConcurrency", node.CurrentConcurrency())
 			time.Sleep(time.Duration(100) * time.Millisecond)
 		}
 	}()
 
-	logging.Info("Sentinel Go hot-spot param flow control demo is running. You may see the pass/block metric in the metric log.")
+	logging.Info("[HotSpot Concurrency] Sentinel Go hot-spot param flow control demo is running. You may see the pass/block metric in the metric log.")
 	for i := 0; i < 10; i++ {
 		go func() {
 			for {
diff --git a/example/hotspot_param_flow/qps_reject/hotspot_params_qps_reject_example.go b/example/hotspot_param_flow/qps_reject/hotspot_params_qps_reject_example.go
index 956bb59..16ad126 100644
--- a/example/hotspot_param_flow/qps_reject/hotspot_params_qps_reject_example.go
+++ b/example/hotspot_param_flow/qps_reject/hotspot_params_qps_reject_example.go
@@ -1,7 +1,6 @@
 package main
 
 import (
-	"fmt"
 	"log"
 	"math/rand"
 	"time"
@@ -50,7 +49,7 @@ func main() {
 		return
 	}
 
-	fmt.Println("Sentinel Go hot-spot param flow control demo is running. You may see the pass/block metric in the metric log.")
+	logging.Info("[HotSpot Reject] Sentinel Go hot-spot param flow control demo is running. You may see the pass/block metric in the metric log.")
 	for i := 0; i < 10; i++ {
 		go func() {
 			for {
diff --git a/example/hotspot_param_flow/qps_throttling/hotspot_params_qps_throttling_example.go b/example/hotspot_param_flow/qps_throttling/hotspot_params_qps_throttling_example.go
index 5ac5f71..136c0ae 100644
--- a/example/hotspot_param_flow/qps_throttling/hotspot_params_qps_throttling_example.go
+++ b/example/hotspot_param_flow/qps_throttling/hotspot_params_qps_throttling_example.go
@@ -1,7 +1,6 @@
 package main
 
 import (
-	"fmt"
 	"log"
 	"math/rand"
 
@@ -49,7 +48,7 @@ func main() {
 		return
 	}
 
-	fmt.Println("Sentinel Go hot-spot param flow control demo is running. You may see the pass/block metric in the metric log.")
+	logging.Info("[HotSpot Throttling] Sentinel Go hot-spot param flow control demo is running. You may see the pass/block metric in the metric log.")
 	for i := 0; i < 10; i++ {
 		go func() {
 			for {
diff --git a/example/isolation/concurrency_limitation_example.go b/example/isolation/concurrency_limitation_example.go
index 0e87645..9a42552 100644
--- a/example/isolation/concurrency_limitation_example.go
+++ b/example/isolation/concurrency_limitation_example.go
@@ -39,10 +39,10 @@ func main() {
 			for {
 				e, b := sentinel.Entry("abc", sentinel.WithBatchCount(1))
 				if b != nil {
-					logging.Info("blocked", "reason", b.BlockType().String(), "rule", b.TriggeredRule(), "snapshot", b.TriggeredValue())
+					logging.Info("[Isolation] Blocked", "reason", b.BlockType().String(), "rule", b.TriggeredRule(), "snapshot", b.TriggeredValue())
 					time.Sleep(time.Duration(rand.Uint64()%20) * time.Millisecond)
 				} else {
-					logging.Info("passed")
+					logging.Info("[Isolation] Passed")
 					time.Sleep(time.Duration(rand.Uint64()%20) * time.Millisecond)
 					e.Exit()
 				}
diff --git a/ext/datasource/consul/consul.go b/ext/datasource/consul/consul.go
index 11c5b72..ee19f17 100644
--- a/ext/datasource/consul/consul.go
+++ b/ext/datasource/consul/consul.go
@@ -83,7 +83,7 @@ func (c *consulDataSource) Initialize() error {
 	}
 	if err := c.doReadAndUpdate(); err != nil {
 		// Failed to read default should't block initialization
-		logging.Error(err, "[Consul] Failed to read initial data for key", "propertyKey", c.propertyKey)
+		logging.Error(err, "Failed to read initial data for key in consulDataSource.Initialize()", "propertyKey", c.propertyKey)
 	}
 
 	go util.RunWithRecover(c.watch)
@@ -103,12 +103,12 @@ func (c *consulDataSource) watch() {
 			}
 
 			if api.IsRetryableError(err) {
-				logging.Warn("[Consul] Update failed with retryable error", "err", err)
+				logging.Warn("[Consul] Update failed with retryable error in consulDataSource.watch()", "err", err)
 				time.Sleep(time.Second)
 				continue
 			}
 			logging.FrequentErrorOnce.Do(func() {
-				logging.Error(err, "[Consul] Failed to update data", "propertyKey", c.propertyKey)
+				logging.Error(err, "Failed to update data in consulDataSource.watch()", "propertyKey", c.propertyKey)
 			})
 		}
 	}
diff --git a/ext/datasource/etcdv3/etcdv3.go b/ext/datasource/etcdv3/etcdv3.go
index df90d3d..5f06309 100644
--- a/ext/datasource/etcdv3/etcdv3.go
+++ b/ext/datasource/etcdv3/etcdv3.go
@@ -42,7 +42,7 @@ func NewDataSource(client *clientv3.Client, key string, handlers ...datasource.P
 func (s *Etcdv3DataSource) Initialize() error {
 	err := s.doReadAndUpdate()
 	if err != nil {
-		logging.Error(err, "Fail to update data for key when execute Initialize function", "propertyKey", s.propertyKey)
+		logging.Error(err, "Fail to update data for key when execute Etcdv3DataSource.Initialize()", "propertyKey", s.propertyKey)
 	}
 	go util.RunWithRecover(s.watch)
 	return nil
@@ -59,7 +59,7 @@ func (s *Etcdv3DataSource) ReadSource() ([]byte, error) {
 		return nil, errors.Errorf("The key[%s] is not existed in etcd server.", s.propertyKey)
 	}
 	s.lastUpdatedRevision = resp.Header.GetRevision()
-	logging.Info("Get the newest data for key", "propertyKey", s.propertyKey,
+	logging.Info("[Etcdv3] Get the newest data for key", "propertyKey", s.propertyKey,
 		"revision", resp.Header.GetRevision(), "value", resp.Kvs[0].Value)
 	return resp.Kvs[0].Value, nil
 }
diff --git a/ext/datasource/file/refreshable_file.go b/ext/datasource/file/refreshable_file.go
index d716e2e..af57139 100644
--- a/ext/datasource/file/refreshable_file.go
+++ b/ext/datasource/file/refreshable_file.go
@@ -53,7 +53,7 @@ func (s *RefreshableFileDataSource) Initialize() error {
 
 	err := s.doReadAndUpdate()
 	if err != nil {
-		logging.Error(err, "Fail to execute doReadAndUpdate")
+		logging.Error(err, "Fail to execute RefreshableFileDataSource.doReadAndUpdate")
 	}
 
 	w, err := fsnotify.NewWatcher()
@@ -72,7 +72,7 @@ func (s *RefreshableFileDataSource) Initialize() error {
 			select {
 			case ev := <-s.watcher.Events:
 				if ev.Op&fsnotify.Rename == fsnotify.Rename {
-					logging.Warn("The file source was renamed.", "sourceFilePath", s.sourceFilePath)
+					logging.Warn("[RefreshableFileDataSource] The file source was renamed.", "sourceFilePath", s.sourceFilePath)
 					updateErr := s.Handle(nil)
 					if updateErr != nil {
 						logging.Error(updateErr, "Fail to update nil property")
@@ -97,7 +97,7 @@ func (s *RefreshableFileDataSource) Initialize() error {
 					}
 				}
 				if ev.Op&fsnotify.Remove == fsnotify.Remove {
-					logging.Warn("The file source was removed.", "sourceFilePath", s.sourceFilePath)
+					logging.Warn("[RefreshableFileDataSource] The file source was removed.", "sourceFilePath", s.sourceFilePath)
 					updateErr := s.Handle(nil)
 					if updateErr != nil {
 						logging.Error(updateErr, "Fail to update nil property")
@@ -108,7 +108,7 @@ func (s *RefreshableFileDataSource) Initialize() error {
 
 				err := s.doReadAndUpdate()
 				if err != nil {
-					logging.Error(err, "Fail to execute doReadAndUpdate")
+					logging.Error(err, "Fail to execute RefreshableFileDataSource.doReadAndUpdate")
 				}
 			case err := <-s.watcher.Errors:
 				logging.Error(err, "Watch err on file", "sourceFilePath", s.sourceFilePath)
@@ -134,6 +134,6 @@ func (s *RefreshableFileDataSource) Close() error {
 		return nil
 	}
 	s.closeChan <- struct{}{}
-	logging.Info("The RefreshableFileDataSource for file had been closed.", "sourceFilePath", s.sourceFilePath)
+	logging.Info("[File] The RefreshableFileDataSource for file had been closed.", "sourceFilePath", s.sourceFilePath)
 	return nil
 }
diff --git a/ext/datasource/nacos/nacos.go b/ext/datasource/nacos/nacos.go
index 9d06354..e6cd515 100644
--- a/ext/datasource/nacos/nacos.go
+++ b/ext/datasource/nacos/nacos.go
@@ -21,10 +21,10 @@ type NacosDataSource struct {
 
 func NewNacosDataSource(client config_client.IConfigClient, group, dataId string, handlers ...datasource.PropertyHandler) (*NacosDataSource, error) {
 	if client == nil {
-		return nil, errors.New("Nil nacos config client")
+		return nil, errors.New("nil nacos config client")
 	}
 	if len(group) == 0 || len(dataId) == 0 {
-		return nil, errors.New(fmt.Sprintf("Invalid parameters, group: %s, dataId: %s", group, dataId))
+		return nil, errors.New(fmt.Sprintf("invalid parameters, group: %s, dataId: %s", group, dataId))
 	}
 	var ds = &NacosDataSource{
 		Base:   datasource.Base{},
@@ -51,7 +51,7 @@ func (s *NacosDataSource) Initialize() error {
 	}
 	err = s.listen(s.client)
 	if err == nil {
-		logging.Info("nacos data source is successfully initialized", "group", s.group, "dataId", s.dataId)
+		logging.Info("[Nacos] Nacos data source is successfully initialized", "group", s.group, "dataId", s.dataId)
 	}
 	return err
 }
@@ -65,7 +65,7 @@ func (s *NacosDataSource) ReadSource() ([]byte, error) {
 		return nil, errors.Errorf("Failed to read the nacos data source when initialization, err: %+v", err)
 	}
 
-	logging.Info("succeed to read source", "group", s.group, "dataId", s.dataId, "content", content)
+	logging.Info("[Nacos] Succeed to read source", "group", s.group, "dataId", s.dataId, "content", content)
 	return []byte(content), err
 }
 
@@ -78,10 +78,10 @@ func (s *NacosDataSource) listen(client config_client.IConfigClient) (err error)
 		DataId: s.dataId,
 		Group:  s.group,
 		OnChange: func(namespace, group, dataId, data string) {
-			logging.Info("receive listened property", "namespace", namespace, "group", group, "dataId", dataId, "data", data)
+			logging.Info("[Nacos] Receive listened property", "namespace", namespace, "group", group, "dataId", dataId, "data", data)
 			err := s.doUpdate([]byte(data))
 			if err != nil {
-				logging.Error(err, "fail to update data source")
+				logging.Error(err, "Fail to update data source in NacosDataSource.listen()")
 			}
 		},
 	}
@@ -100,6 +100,6 @@ func (s *NacosDataSource) Close() error {
 	if err != nil {
 		return errors.Errorf("Failed to cancel listen to the nacos data source, err: %+v", err)
 	}
-	logging.Info("the nacos datasource had been closed", "group", s.group, "dataId", s.dataId)
+	logging.Info("[Nacos] The nacos datasource had been closed", "group", s.group, "dataId", s.dataId)
 	return nil
 }
diff --git a/ext/datasource/property.go b/ext/datasource/property.go
index 5c7ad90..7bfad65 100644
--- a/ext/datasource/property.go
+++ b/ext/datasource/property.go
@@ -49,7 +49,7 @@ func (h *DefaultPropertyHandler) isPropertyConsistent(src interface{}) bool {
 func (h *DefaultPropertyHandler) Handle(src []byte) error {
 	defer func() {
 		if err := recover(); err != nil {
-			logging.Error(errors.Errorf("%+v", err), "Unexpected panic", "err")
+			logging.Error(errors.Errorf("%+v", err), "Unexpected panic in DefaultPropertyHandler.Handle()")
 		}
 	}()
 	// convert to target property
diff --git a/util/auto_recover.go b/util/auto_recover.go
index 417150d..f9425af 100644
--- a/util/auto_recover.go
+++ b/util/auto_recover.go
@@ -8,7 +8,7 @@ import (
 func RunWithRecover(f func()) {
 	defer func() {
 		if err := recover(); err != nil {
-			logging.Error(errors.Errorf("%+v", err), "unexpected panic")
+			logging.Error(errors.Errorf("%+v", err), "Unexpected panic in util.RunWithRecover()")
 		}
 	}()
 	f()


Test patch:
diff --git a/core/flow/rule_manager_test.go b/core/flow/rule_manager_test.go
index b6090b4..d1d23a1 100644
--- a/core/flow/rule_manager_test.go
+++ b/core/flow/rule_manager_test.go
@@ -54,14 +54,18 @@ func TestIsValidFlowRule(t *testing.T) {
 	badRule1 := &Rule{Threshold: 1, Resource: ""}
 	badRule2 := &Rule{Threshold: -1.9, Resource: "test"}
 	badRule3 := &Rule{Threshold: 5, Resource: "test", TokenCalculateStrategy: WarmUp, ControlBehavior: Reject}
-	goodRule1 := &Rule{Threshold: 10, Resource: "test", TokenCalculateStrategy: WarmUp, ControlBehavior: Throttling, WarmUpPeriodSec: 10, MaxQueueingTimeMs: 10, StatIntervalInMs: 1000}
 	badRule4 := &Rule{Threshold: 5, Resource: "test", TokenCalculateStrategy: WarmUp, ControlBehavior: Reject, StatIntervalInMs: 6000000}
 
+	goodRule1 := &Rule{Threshold: 10, Resource: "test", TokenCalculateStrategy: WarmUp, ControlBehavior: Throttling, WarmUpPeriodSec: 10, MaxQueueingTimeMs: 10, StatIntervalInMs: 1000}
+	goodRule2 := &Rule{Threshold: 10, Resource: "test", TokenCalculateStrategy: WarmUp, ControlBehavior: Throttling, WarmUpPeriodSec: 10, MaxQueueingTimeMs: 0, StatIntervalInMs: 1000}
+
 	assert.Error(t, IsValidRule(badRule1))
 	assert.Error(t, IsValidRule(badRule2))
 	assert.Error(t, IsValidRule(badRule3))
-	assert.NoError(t, IsValidRule(goodRule1))
 	assert.Error(t, IsValidRule(badRule4))
+
+	assert.NoError(t, IsValidRule(goodRule1))
+	assert.NoError(t, IsValidRule(goodRule2))
 }
 
 func TestGetRules(t *testing.T) {
diff --git a/core/flow/tc_throttling_test.go b/core/flow/tc_throttling_test.go
index 0fb1e46..8867d54 100644
--- a/core/flow/tc_throttling_test.go
+++ b/core/flow/tc_throttling_test.go
@@ -17,9 +17,13 @@ func TestThrottlingChecker_DoCheckNoQueueingSingleThread(t *testing.T) {
 
 	tc := NewThrottlingChecker(nil, uint32(timeoutMs), uint32(intervalMs))
 
+	// Should block when batchCount > threshold.
+	res := tc.DoCheck(nil, uint32(threshold+1.0), threshold)
+	assert.True(t, res != nil && res.IsBlocked())
+
 	// The first request will pass.
-	ret := tc.DoCheck(nil, 1, threshold)
-	assert.True(t, ret == nil || ret.IsPass())
+	res = tc.DoCheck(nil, uint32(threshold), threshold)
+	assert.True(t, res == nil || res.IsPass())
 
 	reqCount := 10
 	for i := 0; i < reqCount; i++ {
@@ -38,22 +42,29 @@ func TestThrottlingChecker_DoCheckSingleThread(t *testing.T) {
 
 	tc := NewThrottlingChecker(nil, uint32(timeoutMs), uint32(intervalMs))
 
+	// Should block when batchCount > threshold.
+	res := tc.DoCheck(nil, uint32(threshold+1.0), threshold)
+	assert.True(t, res != nil && res.IsBlocked())
+
+	// The first request will pass.
+	res = tc.DoCheck(nil, uint32(threshold), threshold)
+	assert.True(t, res == nil || res.IsPass())
+
 	resultList := make([]*base.TokenResult, 0)
 	reqCount := 20
 	for i := 0; i < reqCount; i++ {
 		res := tc.DoCheck(nil, 1, threshold)
 		resultList = append(resultList, res)
 	}
-	assert.True(t, resultList[0] == nil)
 
 	// waitCount is count of request that will wait and not be blocked
 	waitCount := int(float64(timeoutMs) / (float64(intervalMs) / threshold))
-	for i := 1; i <= waitCount; i++ {
+	for i := 0; i < waitCount; i++ {
 		assert.True(t, resultList[i].Status() == base.ResultStatusShouldWait)
 		wt := resultList[i].WaitMs()
-		assert.InEpsilon(t, i*1000/int(waitCount), wt, 10)
+		assert.InEpsilon(t, (i+1)*1000/int(waitCount), wt, 10)
 	}
-	for i := waitCount + 1; i < reqCount; i++ {
+	for i := waitCount; i < reqCount; i++ {
 		assert.True(t, resultList[i].IsBlocked())
 	}
 }
diff --git a/ext/datasource/file/refreshable_file_test.go b/ext/datasource/file/refreshable_file_test.go
index f3977eb..bc917b6 100644
--- a/ext/datasource/file/refreshable_file_test.go
+++ b/ext/datasource/file/refreshable_file_test.go
@@ -125,7 +125,7 @@ func TestRefreshableFileDataSource_doReadAndUpdate(t *testing.T) {
 			closeChan:      make(chan struct{}),
 		}
 		mh1 := &datasource.MockPropertyHandler{}
-		hErr := errors.New("Handle error")
+		hErr := errors.New("handle error")
 		mh1.On("Handle", tmock.Anything).Return(hErr)
 		mh1.On("isPropertyConsistent", tmock.Anything).Return(false)
 		s.AddPropertyHandler(mh1)
@@ -150,7 +150,7 @@ func TestRefreshableFileDataSource_doReadAndUpdate(t *testing.T) {
 			closeChan:      make(chan struct{}),
 		}
 		mh1 := &datasource.MockPropertyHandler{}
-		hErr := errors.New("Handle error")
+		hErr := errors.New("handle error")
 		mh1.On("Handle", tmock.Anything).Return(hErr)
 		mh1.On("isPropertyConsistent", tmock.Anything).Return(false)
 		mh2 := &datasource.MockPropertyHandler{}