leader.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // Copyright 2015 The etcd Authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package stats
  15. import (
  16. "encoding/json"
  17. "math"
  18. "sync"
  19. "time"
  20. )
  21. // LeaderStats is used by the leader in an etcd cluster, and encapsulates
  22. // statistics about communication with its followers
  23. type LeaderStats struct {
  24. leaderStats
  25. sync.Mutex
  26. }
  27. type leaderStats struct {
  28. // Leader is the ID of the leader in the etcd cluster.
  29. // TODO(jonboulle): clarify that these are IDs, not names
  30. Leader string `json:"leader"`
  31. Followers map[string]*FollowerStats `json:"followers"`
  32. }
  33. // NewLeaderStats generates a new LeaderStats with the given id as leader
  34. func NewLeaderStats(id string) *LeaderStats {
  35. return &LeaderStats{
  36. leaderStats: leaderStats{
  37. Leader: id,
  38. Followers: make(map[string]*FollowerStats),
  39. },
  40. }
  41. }
  42. func (ls *LeaderStats) JSON() []byte {
  43. ls.Lock()
  44. stats := ls.leaderStats
  45. ls.Unlock()
  46. b, err := json.Marshal(stats)
  47. // TODO(jonboulle): appropriate error handling?
  48. if err != nil {
  49. plog.Errorf("error marshalling leader stats (%v)", err)
  50. }
  51. return b
  52. }
  53. func (ls *LeaderStats) Follower(name string) *FollowerStats {
  54. ls.Lock()
  55. defer ls.Unlock()
  56. fs, ok := ls.Followers[name]
  57. if !ok {
  58. fs = &FollowerStats{}
  59. fs.Latency.Minimum = 1 << 63
  60. ls.Followers[name] = fs
  61. }
  62. return fs
  63. }
  64. // FollowerStats encapsulates various statistics about a follower in an etcd cluster
  65. type FollowerStats struct {
  66. Latency LatencyStats `json:"latency"`
  67. Counts CountsStats `json:"counts"`
  68. sync.Mutex
  69. }
  70. // LatencyStats encapsulates latency statistics.
  71. type LatencyStats struct {
  72. Current float64 `json:"current"`
  73. Average float64 `json:"average"`
  74. averageSquare float64
  75. StandardDeviation float64 `json:"standardDeviation"`
  76. Minimum float64 `json:"minimum"`
  77. Maximum float64 `json:"maximum"`
  78. }
  79. // CountsStats encapsulates raft statistics.
  80. type CountsStats struct {
  81. Fail uint64 `json:"fail"`
  82. Success uint64 `json:"success"`
  83. }
  84. // Succ updates the FollowerStats with a successful send
  85. func (fs *FollowerStats) Succ(d time.Duration) {
  86. fs.Lock()
  87. defer fs.Unlock()
  88. total := float64(fs.Counts.Success) * fs.Latency.Average
  89. totalSquare := float64(fs.Counts.Success) * fs.Latency.averageSquare
  90. fs.Counts.Success++
  91. fs.Latency.Current = float64(d) / (1000000.0)
  92. if fs.Latency.Current > fs.Latency.Maximum {
  93. fs.Latency.Maximum = fs.Latency.Current
  94. }
  95. if fs.Latency.Current < fs.Latency.Minimum {
  96. fs.Latency.Minimum = fs.Latency.Current
  97. }
  98. fs.Latency.Average = (total + fs.Latency.Current) / float64(fs.Counts.Success)
  99. fs.Latency.averageSquare = (totalSquare + fs.Latency.Current*fs.Latency.Current) / float64(fs.Counts.Success)
  100. // sdv = sqrt(avg(x^2) - avg(x)^2)
  101. fs.Latency.StandardDeviation = math.Sqrt(fs.Latency.averageSquare - fs.Latency.Average*fs.Latency.Average)
  102. }
  103. // Fail updates the FollowerStats with an unsuccessful send
  104. func (fs *FollowerStats) Fail() {
  105. fs.Lock()
  106. defer fs.Unlock()
  107. fs.Counts.Fail++
  108. }