You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

366 lines
12 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
4 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. package stats
  2. import (
  3. "log"
  4. "net"
  5. "net/http"
  6. "os"
  7. "strconv"
  8. "strings"
  9. "time"
  10. "github.com/prometheus/client_golang/prometheus"
  11. "github.com/prometheus/client_golang/prometheus/collectors"
  12. "github.com/prometheus/client_golang/prometheus/promhttp"
  13. "github.com/prometheus/client_golang/prometheus/push"
  14. "github.com/seaweedfs/seaweedfs/weed/glog"
  15. )
  16. // Readonly volume types
  17. const (
  18. Namespace = "SeaweedFS"
  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: Namespace,
  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: Namespace,
  37. Subsystem: "master",
  38. Name: "is_leader",
  39. Help: "is leader",
  40. })
  41. MasterAdminLock = prometheus.NewGaugeVec(
  42. prometheus.GaugeOpts{
  43. Namespace: Namespace,
  44. Subsystem: "master",
  45. Name: "admin_lock",
  46. Help: "admin lock",
  47. }, []string{"client"})
  48. MasterReceivedHeartbeatCounter = prometheus.NewCounterVec(
  49. prometheus.CounterOpts{
  50. Namespace: Namespace,
  51. Subsystem: "master",
  52. Name: "received_heartbeats",
  53. Help: "Counter of master received heartbeat.",
  54. }, []string{"type"})
  55. MasterReplicaPlacementMismatch = prometheus.NewGaugeVec(
  56. prometheus.GaugeOpts{
  57. Namespace: Namespace,
  58. Subsystem: "master",
  59. Name: "replica_placement_mismatch",
  60. Help: "replica placement mismatch",
  61. }, []string{"collection", "id"})
  62. MasterVolumeLayout = prometheus.NewGaugeVec(
  63. prometheus.GaugeOpts{
  64. Namespace: Namespace,
  65. Subsystem: "master",
  66. Name: "volume_layout_total",
  67. Help: "Number of volumes in volume layouts",
  68. }, []string{"collection", "dataCenter", "type"})
  69. MasterPickForWriteErrorCounter = prometheus.NewCounter(
  70. prometheus.CounterOpts{
  71. Namespace: Namespace,
  72. Subsystem: "master",
  73. Name: "pick_for_write_error",
  74. Help: "Counter of master pick for write error",
  75. })
  76. MasterLeaderChangeCounter = prometheus.NewCounterVec(
  77. prometheus.CounterOpts{
  78. Namespace: Namespace,
  79. Subsystem: "master",
  80. Name: "leader_changes",
  81. Help: "Counter of master leader changes.",
  82. }, []string{"type"})
  83. FilerRequestCounter = prometheus.NewCounterVec(
  84. prometheus.CounterOpts{
  85. Namespace: Namespace,
  86. Subsystem: "filer",
  87. Name: "request_total",
  88. Help: "Counter of filer requests.",
  89. }, []string{"type", "code"})
  90. FilerHandlerCounter = prometheus.NewCounterVec(
  91. prometheus.CounterOpts{
  92. Namespace: Namespace,
  93. Subsystem: "filer",
  94. Name: "handler_total",
  95. Help: "Counter of filer handlers.",
  96. }, []string{"type"})
  97. FilerRequestHistogram = prometheus.NewHistogramVec(
  98. prometheus.HistogramOpts{
  99. Namespace: Namespace,
  100. Subsystem: "filer",
  101. Name: "request_seconds",
  102. Help: "Bucketed histogram of filer request processing time.",
  103. Buckets: prometheus.ExponentialBuckets(0.0001, 2, 24),
  104. }, []string{"type"})
  105. FilerServerLastSendTsOfSubscribeGauge = prometheus.NewGaugeVec(
  106. prometheus.GaugeOpts{
  107. Namespace: Namespace,
  108. Subsystem: "filer",
  109. Name: "last_send_timestamp_of_subscribe",
  110. Help: "The last send timestamp of the filer subscription.",
  111. }, []string{"sourceFiler", "clientName", "path"})
  112. FilerStoreCounter = prometheus.NewCounterVec(
  113. prometheus.CounterOpts{
  114. Namespace: Namespace,
  115. Subsystem: "filerStore",
  116. Name: "request_total",
  117. Help: "Counter of filer store requests.",
  118. }, []string{"store", "type"})
  119. FilerStoreHistogram = prometheus.NewHistogramVec(
  120. prometheus.HistogramOpts{
  121. Namespace: Namespace,
  122. Subsystem: "filerStore",
  123. Name: "request_seconds",
  124. Help: "Bucketed histogram of filer store request processing time.",
  125. Buckets: prometheus.ExponentialBuckets(0.0001, 2, 24),
  126. }, []string{"store", "type"})
  127. FilerSyncOffsetGauge = prometheus.NewGaugeVec(
  128. prometheus.GaugeOpts{
  129. Namespace: Namespace,
  130. Subsystem: "filerSync",
  131. Name: "sync_offset",
  132. Help: "The offset of the filer synchronization service.",
  133. }, []string{"sourceFiler", "targetFiler", "clientName", "path"})
  134. VolumeServerRequestCounter = prometheus.NewCounterVec(
  135. prometheus.CounterOpts{
  136. Namespace: Namespace,
  137. Subsystem: "volumeServer",
  138. Name: "request_total",
  139. Help: "Counter of volume server requests.",
  140. }, []string{"type", "code"})
  141. VolumeServerHandlerCounter = prometheus.NewCounterVec(
  142. prometheus.CounterOpts{
  143. Namespace: Namespace,
  144. Subsystem: "volumeServer",
  145. Name: "handler_total",
  146. Help: "Counter of volume server handlers.",
  147. }, []string{"type"})
  148. VolumeServerVacuumingCompactCounter = prometheus.NewCounterVec(
  149. prometheus.CounterOpts{
  150. Namespace: Namespace,
  151. Subsystem: "volumeServer",
  152. Name: "vacuuming_compact_count",
  153. Help: "Counter of volume vacuuming Compact counter",
  154. }, []string{"success"})
  155. VolumeServerVacuumingCommitCounter = prometheus.NewCounterVec(
  156. prometheus.CounterOpts{
  157. Namespace: Namespace,
  158. Subsystem: "volumeServer",
  159. Name: "vacuuming_commit_count",
  160. Help: "Counter of volume vacuuming commit counter",
  161. }, []string{"success"})
  162. VolumeServerVacuumingHistogram = prometheus.NewHistogramVec(
  163. prometheus.HistogramOpts{
  164. Namespace: Namespace,
  165. Subsystem: "volumeServer",
  166. Name: "vacuuming_seconds",
  167. Help: "Bucketed histogram of volume server vacuuming processing time.",
  168. Buckets: prometheus.ExponentialBuckets(0.0001, 2, 24),
  169. }, []string{"type"})
  170. VolumeServerRequestHistogram = prometheus.NewHistogramVec(
  171. prometheus.HistogramOpts{
  172. Namespace: Namespace,
  173. Subsystem: "volumeServer",
  174. Name: "request_seconds",
  175. Help: "Bucketed histogram of volume server request processing time.",
  176. Buckets: prometheus.ExponentialBuckets(0.0001, 2, 24),
  177. }, []string{"type"})
  178. VolumeServerVolumeGauge = prometheus.NewGaugeVec(
  179. prometheus.GaugeOpts{
  180. Namespace: Namespace,
  181. Subsystem: "volumeServer",
  182. Name: "volumes",
  183. Help: "Number of volumes or shards.",
  184. }, []string{"collection", "type"})
  185. VolumeServerReadOnlyVolumeGauge = prometheus.NewGaugeVec(
  186. prometheus.GaugeOpts{
  187. Namespace: Namespace,
  188. Subsystem: "volumeServer",
  189. Name: "read_only_volumes",
  190. Help: "Number of read only volumes.",
  191. }, []string{"collection", "type"})
  192. VolumeServerMaxVolumeCounter = prometheus.NewGauge(
  193. prometheus.GaugeOpts{
  194. Namespace: Namespace,
  195. Subsystem: "volumeServer",
  196. Name: "max_volumes",
  197. Help: "Maximum number of volumes.",
  198. })
  199. VolumeServerDiskSizeGauge = prometheus.NewGaugeVec(
  200. prometheus.GaugeOpts{
  201. Namespace: Namespace,
  202. Subsystem: "volumeServer",
  203. Name: "total_disk_size",
  204. Help: "Actual disk size used by volumes.",
  205. }, []string{"collection", "type"})
  206. VolumeServerResourceGauge = prometheus.NewGaugeVec(
  207. prometheus.GaugeOpts{
  208. Namespace: Namespace,
  209. Subsystem: "volumeServer",
  210. Name: "resource",
  211. Help: "Resource usage",
  212. }, []string{"name", "type"})
  213. S3RequestCounter = prometheus.NewCounterVec(
  214. prometheus.CounterOpts{
  215. Namespace: Namespace,
  216. Subsystem: "s3",
  217. Name: "request_total",
  218. Help: "Counter of s3 requests.",
  219. }, []string{"type", "code", "bucket"})
  220. S3HandlerCounter = prometheus.NewCounterVec(
  221. prometheus.CounterOpts{
  222. Namespace: Namespace,
  223. Subsystem: "s3",
  224. Name: "handler_total",
  225. Help: "Counter of s3 server handlers.",
  226. }, []string{"type"})
  227. S3RequestHistogram = prometheus.NewHistogramVec(
  228. prometheus.HistogramOpts{
  229. Namespace: Namespace,
  230. Subsystem: "s3",
  231. Name: "request_seconds",
  232. Help: "Bucketed histogram of s3 request processing time.",
  233. Buckets: prometheus.ExponentialBuckets(0.0001, 2, 24),
  234. }, []string{"type", "bucket"})
  235. S3TimeToFirstByteHistogram = prometheus.NewHistogramVec(
  236. prometheus.HistogramOpts{
  237. Namespace: Namespace,
  238. Subsystem: "s3",
  239. Name: "time_to_first_byte_millisecond",
  240. Help: "Bucketed histogram of s3 time to first byte request processing time.",
  241. Buckets: prometheus.ExponentialBuckets(0.001, 2, 27),
  242. }, []string{"type", "bucket"})
  243. )
  244. func init() {
  245. Gather.MustRegister(MasterClientConnectCounter)
  246. Gather.MustRegister(MasterRaftIsleader)
  247. Gather.MustRegister(MasterAdminLock)
  248. Gather.MustRegister(MasterReceivedHeartbeatCounter)
  249. Gather.MustRegister(MasterLeaderChangeCounter)
  250. Gather.MustRegister(MasterReplicaPlacementMismatch)
  251. Gather.MustRegister(MasterVolumeLayout)
  252. Gather.MustRegister(FilerRequestCounter)
  253. Gather.MustRegister(FilerHandlerCounter)
  254. Gather.MustRegister(FilerRequestHistogram)
  255. Gather.MustRegister(FilerStoreCounter)
  256. Gather.MustRegister(FilerStoreHistogram)
  257. Gather.MustRegister(FilerSyncOffsetGauge)
  258. Gather.MustRegister(FilerServerLastSendTsOfSubscribeGauge)
  259. Gather.MustRegister(collectors.NewGoCollector())
  260. Gather.MustRegister(collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}))
  261. Gather.MustRegister(VolumeServerRequestCounter)
  262. Gather.MustRegister(VolumeServerHandlerCounter)
  263. Gather.MustRegister(VolumeServerRequestHistogram)
  264. Gather.MustRegister(VolumeServerVacuumingCompactCounter)
  265. Gather.MustRegister(VolumeServerVacuumingCommitCounter)
  266. Gather.MustRegister(VolumeServerVacuumingHistogram)
  267. Gather.MustRegister(VolumeServerVolumeGauge)
  268. Gather.MustRegister(VolumeServerMaxVolumeCounter)
  269. Gather.MustRegister(VolumeServerReadOnlyVolumeGauge)
  270. Gather.MustRegister(VolumeServerDiskSizeGauge)
  271. Gather.MustRegister(VolumeServerResourceGauge)
  272. Gather.MustRegister(S3RequestCounter)
  273. Gather.MustRegister(S3HandlerCounter)
  274. Gather.MustRegister(S3RequestHistogram)
  275. Gather.MustRegister(S3TimeToFirstByteHistogram)
  276. }
  277. func LoopPushingMetric(name, instance, addr string, intervalSeconds int) {
  278. if addr == "" || intervalSeconds == 0 {
  279. return
  280. }
  281. glog.V(0).Infof("%s server sends metrics to %s every %d seconds", name, addr, intervalSeconds)
  282. pusher := push.New(addr, name).Gatherer(Gather).Grouping("instance", instance)
  283. for {
  284. err := pusher.Push()
  285. if err != nil && !strings.HasPrefix(err.Error(), "unexpected status code 200") {
  286. glog.V(0).Infof("could not push metrics to prometheus push gateway %s: %v", addr, err)
  287. }
  288. if intervalSeconds <= 0 {
  289. intervalSeconds = 15
  290. }
  291. time.Sleep(time.Duration(intervalSeconds) * time.Second)
  292. }
  293. }
  294. func JoinHostPort(host string, port int) string {
  295. portStr := strconv.Itoa(port)
  296. if strings.HasPrefix(host, "[") && strings.HasSuffix(host, "]") {
  297. return host + ":" + portStr
  298. }
  299. return net.JoinHostPort(host, portStr)
  300. }
  301. func StartMetricsServer(ip string, port int) {
  302. if port == 0 {
  303. return
  304. }
  305. http.Handle("/metrics", promhttp.HandlerFor(Gather, promhttp.HandlerOpts{}))
  306. log.Fatal(http.ListenAndServe(JoinHostPort(ip, port), nil))
  307. }
  308. func SourceName(port uint32) string {
  309. hostname, err := os.Hostname()
  310. if err != nil {
  311. return "unknown"
  312. }
  313. return net.JoinHostPort(hostname, strconv.Itoa(int(port)))
  314. }
  315. // todo - can be changed to DeletePartialMatch when https://github.com/prometheus/client_golang/pull/1013 gets released
  316. func DeleteCollectionMetrics(collection string) {
  317. VolumeServerDiskSizeGauge.DeleteLabelValues(collection, "normal")
  318. for _, volume_type := range readOnlyVolumeTypes {
  319. VolumeServerReadOnlyVolumeGauge.DeleteLabelValues(collection, volume_type)
  320. }
  321. VolumeServerVolumeGauge.DeleteLabelValues(collection, "volume")
  322. }