cachestat.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. package cache
  2. import (
  3. "sync/atomic"
  4. "time"
  5. "github.com/wuntsong-org/go-zero-plus/core/logx"
  6. "github.com/wuntsong-org/go-zero-plus/core/timex"
  7. )
  8. const statInterval = time.Minute
  9. // A Stat is used to stat the cache.
  10. type Stat struct {
  11. name string
  12. // export the fields to let the unit tests working,
  13. // reside in internal package, doesn't matter.
  14. Total uint64
  15. Hit uint64
  16. Miss uint64
  17. DbFails uint64
  18. }
  19. // NewStat returns a Stat.
  20. func NewStat(name string) *Stat {
  21. ret := &Stat{
  22. name: name,
  23. }
  24. go func() {
  25. ticker := timex.NewTicker(statInterval)
  26. defer ticker.Stop()
  27. ret.statLoop(ticker)
  28. }()
  29. return ret
  30. }
  31. // IncrementTotal increments the total count.
  32. func (s *Stat) IncrementTotal() {
  33. atomic.AddUint64(&s.Total, 1)
  34. }
  35. // IncrementHit increments the hit count.
  36. func (s *Stat) IncrementHit() {
  37. atomic.AddUint64(&s.Hit, 1)
  38. }
  39. // IncrementMiss increments the miss count.
  40. func (s *Stat) IncrementMiss() {
  41. atomic.AddUint64(&s.Miss, 1)
  42. }
  43. // IncrementDbFails increments the db fail count.
  44. func (s *Stat) IncrementDbFails() {
  45. atomic.AddUint64(&s.DbFails, 1)
  46. }
  47. func (s *Stat) statLoop(ticker timex.Ticker) {
  48. for range ticker.Chan() {
  49. total := atomic.SwapUint64(&s.Total, 0)
  50. if total == 0 {
  51. continue
  52. }
  53. hit := atomic.SwapUint64(&s.Hit, 0)
  54. percent := 100 * float32(hit) / float32(total)
  55. miss := atomic.SwapUint64(&s.Miss, 0)
  56. dbf := atomic.SwapUint64(&s.DbFails, 0)
  57. logx.Statf("dbcache(%s) - qpm: %d, hit_ratio: %.1f%%, hit: %d, miss: %d, db_fails: %d",
  58. s.name, total, percent, hit, miss, dbf)
  59. }
  60. }