metrics.go 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. package stats
  2. import (
  3. "fmt"
  4. "log"
  5. "net"
  6. "net/http"
  7. "os"
  8. "strconv"
  9. "strings"
  10. "time"
  11. "github.com/prometheus/client_golang/prometheus"
  12. "github.com/prometheus/client_golang/prometheus/collectors"
  13. "github.com/prometheus/client_golang/prometheus/promhttp"
  14. "github.com/prometheus/client_golang/prometheus/push"
  15. "github.com/seaweedfs/seaweedfs/weed/glog"
  16. )
  17. // Readonly volume types
  18. const (
  19. IsReadOnly = "IsReadOnly"
  20. NoWriteOrDelete = "noWriteOrDelete"
  21. NoWriteCanDelete = "noWriteCanDelete"
  22. IsDiskSpaceLow = "isDiskSpaceLow"
  23. )
  24. var readOnlyVolumeTypes = [4]string{IsReadOnly, NoWriteOrDelete, NoWriteCanDelete, IsDiskSpaceLow}
  25. var (
  26. Gather = prometheus.NewRegistry()
  27. MasterClientConnectCounter = prometheus.NewCounterVec(
  28. prometheus.CounterOpts{
  29. Namespace: "SeaweedFS",
  30. Subsystem: "wdclient",
  31. Name: "connect_updates",
  32. Help: "Counter of master client leader updates.",
  33. }, []string{"type"})
  34. MasterRaftIsleader = prometheus.NewGauge(
  35. prometheus.GaugeOpts{
  36. Namespace: "SeaweedFS",
  37. Subsystem: "master",
  38. Name: "is_leader",
  39. Help: "is leader",
  40. })
  41. MasterReceivedHeartbeatCounter = prometheus.NewCounterVec(
  42. prometheus.CounterOpts{
  43. Namespace: "SeaweedFS",
  44. Subsystem: "master",
  45. Name: "received_heartbeats",
  46. Help: "Counter of master received heartbeat.",
  47. }, []string{"type"})
  48. MasterReplicaPlacementMismatch = prometheus.NewGaugeVec(
  49. prometheus.GaugeOpts{
  50. Namespace: "SeaweedFS",
  51. Subsystem: "master",
  52. Name: "replica_placement_mismatch",
  53. Help: "replica placement mismatch",
  54. }, []string{"collection", "id"})
  55. MasterLeaderChangeCounter = prometheus.NewCounterVec(
  56. prometheus.CounterOpts{
  57. Namespace: "SeaweedFS",
  58. Subsystem: "master",
  59. Name: "leader_changes",
  60. Help: "Counter of master leader changes.",
  61. }, []string{"type"})
  62. FilerRequestCounter = prometheus.NewCounterVec(
  63. prometheus.CounterOpts{
  64. Namespace: "SeaweedFS",
  65. Subsystem: "filer",
  66. Name: "request_total",
  67. Help: "Counter of filer requests.",
  68. }, []string{"type"})
  69. FilerRequestHistogram = prometheus.NewHistogramVec(
  70. prometheus.HistogramOpts{
  71. Namespace: "SeaweedFS",
  72. Subsystem: "filer",
  73. Name: "request_seconds",
  74. Help: "Bucketed histogram of filer request processing time.",
  75. Buckets: prometheus.ExponentialBuckets(0.0001, 2, 24),
  76. }, []string{"type"})
  77. FilerServerLastSendTsOfSubscribeGauge = prometheus.NewGaugeVec(
  78. prometheus.GaugeOpts{
  79. Namespace: "SeaweedFS",
  80. Subsystem: "filer",
  81. Name: "last_send_timestamp_of_subscribe",
  82. Help: "The last send timestamp of the filer subscription.",
  83. }, []string{"sourceFiler", "clientName", "path"})
  84. FilerStoreCounter = prometheus.NewCounterVec(
  85. prometheus.CounterOpts{
  86. Namespace: "SeaweedFS",
  87. Subsystem: "filerStore",
  88. Name: "request_total",
  89. Help: "Counter of filer store requests.",
  90. }, []string{"store", "type"})
  91. FilerStoreHistogram = prometheus.NewHistogramVec(
  92. prometheus.HistogramOpts{
  93. Namespace: "SeaweedFS",
  94. Subsystem: "filerStore",
  95. Name: "request_seconds",
  96. Help: "Bucketed histogram of filer store request processing time.",
  97. Buckets: prometheus.ExponentialBuckets(0.0001, 2, 24),
  98. }, []string{"store", "type"})
  99. FilerSyncOffsetGauge = prometheus.NewGaugeVec(
  100. prometheus.GaugeOpts{
  101. Namespace: "SeaweedFS",
  102. Subsystem: "filerSync",
  103. Name: "sync_offset",
  104. Help: "The offset of the filer synchronization service.",
  105. }, []string{"sourceFiler", "targetFiler", "clientName", "path"})
  106. VolumeServerRequestCounter = prometheus.NewCounterVec(
  107. prometheus.CounterOpts{
  108. Namespace: "SeaweedFS",
  109. Subsystem: "volumeServer",
  110. Name: "request_total",
  111. Help: "Counter of volume server requests.",
  112. }, []string{"type"})
  113. VolumeServerRequestHistogram = prometheus.NewHistogramVec(
  114. prometheus.HistogramOpts{
  115. Namespace: "SeaweedFS",
  116. Subsystem: "volumeServer",
  117. Name: "request_seconds",
  118. Help: "Bucketed histogram of volume server request processing time.",
  119. Buckets: prometheus.ExponentialBuckets(0.0001, 2, 24),
  120. }, []string{"type"})
  121. VolumeServerVolumeCounter = prometheus.NewGaugeVec(
  122. prometheus.GaugeOpts{
  123. Namespace: "SeaweedFS",
  124. Subsystem: "volumeServer",
  125. Name: "volumes",
  126. Help: "Number of volumes or shards.",
  127. }, []string{"collection", "type"})
  128. VolumeServerReadOnlyVolumeGauge = prometheus.NewGaugeVec(
  129. prometheus.GaugeOpts{
  130. Namespace: "SeaweedFS",
  131. Subsystem: "volumeServer",
  132. Name: "read_only_volumes",
  133. Help: "Number of read only volumes.",
  134. }, []string{"collection", "type"})
  135. VolumeServerMaxVolumeCounter = prometheus.NewGauge(
  136. prometheus.GaugeOpts{
  137. Namespace: "SeaweedFS",
  138. Subsystem: "volumeServer",
  139. Name: "max_volumes",
  140. Help: "Maximum number of volumes.",
  141. })
  142. VolumeServerDiskSizeGauge = prometheus.NewGaugeVec(
  143. prometheus.GaugeOpts{
  144. Namespace: "SeaweedFS",
  145. Subsystem: "volumeServer",
  146. Name: "total_disk_size",
  147. Help: "Actual disk size used by volumes.",
  148. }, []string{"collection", "type"})
  149. VolumeServerResourceGauge = prometheus.NewGaugeVec(
  150. prometheus.GaugeOpts{
  151. Namespace: "SeaweedFS",
  152. Subsystem: "volumeServer",
  153. Name: "resource",
  154. Help: "Resource usage",
  155. }, []string{"name", "type"})
  156. S3RequestCounter = prometheus.NewCounterVec(
  157. prometheus.CounterOpts{
  158. Namespace: "SeaweedFS",
  159. Subsystem: "s3",
  160. Name: "request_total",
  161. Help: "Counter of s3 requests.",
  162. }, []string{"type", "code", "bucket"})
  163. S3RequestHistogram = prometheus.NewHistogramVec(
  164. prometheus.HistogramOpts{
  165. Namespace: "SeaweedFS",
  166. Subsystem: "s3",
  167. Name: "request_seconds",
  168. Help: "Bucketed histogram of s3 request processing time.",
  169. Buckets: prometheus.ExponentialBuckets(0.0001, 2, 24),
  170. }, []string{"type", "bucket"})
  171. )
  172. func init() {
  173. Gather.MustRegister(MasterClientConnectCounter)
  174. Gather.MustRegister(MasterRaftIsleader)
  175. Gather.MustRegister(MasterReceivedHeartbeatCounter)
  176. Gather.MustRegister(MasterLeaderChangeCounter)
  177. Gather.MustRegister(MasterReplicaPlacementMismatch)
  178. Gather.MustRegister(FilerRequestCounter)
  179. Gather.MustRegister(FilerRequestHistogram)
  180. Gather.MustRegister(FilerStoreCounter)
  181. Gather.MustRegister(FilerStoreHistogram)
  182. Gather.MustRegister(FilerSyncOffsetGauge)
  183. Gather.MustRegister(FilerServerLastSendTsOfSubscribeGauge)
  184. Gather.MustRegister(collectors.NewGoCollector())
  185. Gather.MustRegister(collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}))
  186. Gather.MustRegister(VolumeServerRequestCounter)
  187. Gather.MustRegister(VolumeServerRequestHistogram)
  188. Gather.MustRegister(VolumeServerVolumeCounter)
  189. Gather.MustRegister(VolumeServerMaxVolumeCounter)
  190. Gather.MustRegister(VolumeServerReadOnlyVolumeGauge)
  191. Gather.MustRegister(VolumeServerDiskSizeGauge)
  192. Gather.MustRegister(VolumeServerResourceGauge)
  193. Gather.MustRegister(S3RequestCounter)
  194. Gather.MustRegister(S3RequestHistogram)
  195. }
  196. func LoopPushingMetric(name, instance, addr string, intervalSeconds int) {
  197. if addr == "" || intervalSeconds == 0 {
  198. return
  199. }
  200. glog.V(0).Infof("%s server sends metrics to %s every %d seconds", name, addr, intervalSeconds)
  201. pusher := push.New(addr, name).Gatherer(Gather).Grouping("instance", instance)
  202. for {
  203. err := pusher.Push()
  204. if err != nil && !strings.HasPrefix(err.Error(), "unexpected status code 200") {
  205. glog.V(0).Infof("could not push metrics to prometheus push gateway %s: %v", addr, err)
  206. }
  207. if intervalSeconds <= 0 {
  208. intervalSeconds = 15
  209. }
  210. time.Sleep(time.Duration(intervalSeconds) * time.Second)
  211. }
  212. }
  213. func StartMetricsServer(port int) {
  214. if port == 0 {
  215. return
  216. }
  217. http.Handle("/metrics", promhttp.HandlerFor(Gather, promhttp.HandlerOpts{}))
  218. log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), nil))
  219. }
  220. func SourceName(port uint32) string {
  221. hostname, err := os.Hostname()
  222. if err != nil {
  223. return "unknown"
  224. }
  225. return net.JoinHostPort(hostname, strconv.Itoa(int(port)))
  226. }
  227. // todo - can be changed to DeletePartialMatch when https://github.com/prometheus/client_golang/pull/1013 gets released
  228. func DeleteCollectionMetrics(collection string) {
  229. VolumeServerDiskSizeGauge.DeleteLabelValues(collection, "normal")
  230. for _, volume_type := range readOnlyVolumeTypes {
  231. VolumeServerReadOnlyVolumeGauge.DeleteLabelValues(collection, volume_type)
  232. }
  233. VolumeServerVolumeCounter.DeleteLabelValues(collection, "volume")
  234. }