Highly-opinionated (ex-bullshit-free) MTPROTO proxy for Telegram. If you use v1.0 or upgrade broke you proxy, please read the chapter Version 2
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

prometheus.go 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. package stats
  2. import (
  3. "context"
  4. "net"
  5. "net/http"
  6. "time"
  7. "github.com/9seconds/mtg/v2/events"
  8. "github.com/9seconds/mtg/v2/mtglib"
  9. "github.com/prometheus/client_golang/prometheus"
  10. "github.com/prometheus/client_golang/prometheus/promhttp"
  11. )
  12. type prometheusProcessor struct {
  13. streams map[string]*streamInfo
  14. factory *PrometheusFactory
  15. }
  16. func (p prometheusProcessor) EventStart(evt mtglib.EventStart) {
  17. sInfo := &streamInfo{
  18. createdAt: evt.CreatedAt,
  19. clientIP: evt.RemoteIP,
  20. }
  21. p.streams[evt.StreamID()] = sInfo
  22. p.factory.metricActiveConnections.WithLabelValues(sInfo.IPType()).Inc()
  23. }
  24. func (p prometheusProcessor) EventFinish(evt mtglib.EventFinish) {
  25. sInfo, ok := p.streams[evt.StreamID()]
  26. if !ok {
  27. return
  28. }
  29. defer delete(p.streams, evt.StreamID())
  30. duration := evt.CreatedAt.Sub(sInfo.createdAt)
  31. p.factory.metricActiveConnections.WithLabelValues(sInfo.IPType()).Dec()
  32. p.factory.metricSessionDuration.Observe(float64(duration) / float64(time.Second))
  33. }
  34. func (p prometheusProcessor) EventConcurrencyLimited(_ mtglib.EventConcurrencyLimited) {
  35. p.factory.metricConcurrencyLimited.Inc()
  36. }
  37. func (p prometheusProcessor) EventIPBlocklisted(evt mtglib.EventIPBlocklisted) {
  38. if evt.RemoteIP.To4() == nil {
  39. p.factory.metricIPBlocklisted.WithLabelValues(TagIPTypeIPv6).Inc()
  40. } else {
  41. p.factory.metricIPBlocklisted.WithLabelValues(TagIPTypeIPv4).Inc()
  42. }
  43. }
  44. func (p prometheusProcessor) Shutdown() {
  45. p.streams = make(map[string]*streamInfo)
  46. }
  47. type PrometheusFactory struct {
  48. httpServer *http.Server
  49. metricActiveConnections *prometheus.GaugeVec
  50. metricIPBlocklisted *prometheus.CounterVec
  51. metricConcurrencyLimited prometheus.Counter
  52. metricSessionDuration prometheus.Histogram
  53. }
  54. func (p *PrometheusFactory) Make() events.Observer {
  55. return prometheusProcessor{
  56. streams: make(map[string]*streamInfo),
  57. factory: p,
  58. }
  59. }
  60. func (p *PrometheusFactory) Serve(listener net.Listener) error {
  61. return p.httpServer.Serve(listener)
  62. }
  63. func (p *PrometheusFactory) Close() error {
  64. return p.httpServer.Shutdown(context.Background())
  65. }
  66. func NewPrometheus(metricPrefix, httpPath string) *PrometheusFactory {
  67. registry := prometheus.NewPedanticRegistry()
  68. httpHandler := promhttp.HandlerFor(registry, promhttp.HandlerOpts{
  69. EnableOpenMetrics: true,
  70. })
  71. mux := http.NewServeMux()
  72. mux.Handle(httpPath, httpHandler)
  73. factory := &PrometheusFactory{
  74. httpServer: &http.Server{
  75. Handler: mux,
  76. },
  77. metricActiveConnections: prometheus.NewGaugeVec(prometheus.GaugeOpts{
  78. Namespace: metricPrefix,
  79. Name: MetricActiveConnection,
  80. Help: "A number of connections under active processing.",
  81. }, []string{TagIPType}),
  82. metricSessionDuration: prometheus.NewHistogram(prometheus.HistogramOpts{
  83. Namespace: metricPrefix,
  84. Name: MetricSessionDuration,
  85. Help: "Session duration.",
  86. Buckets: []float64{ // per 30 seconds
  87. 30,
  88. 60,
  89. 90,
  90. 120,
  91. 150,
  92. 180,
  93. 210,
  94. 240,
  95. 270,
  96. 300,
  97. },
  98. }),
  99. metricConcurrencyLimited: prometheus.NewCounter(prometheus.CounterOpts{
  100. Namespace: metricPrefix,
  101. Name: MetricConcurrencyLimited,
  102. Help: "A number of sessions that were rejected by concurrency limiter.",
  103. }),
  104. metricIPBlocklisted: prometheus.NewCounterVec(prometheus.CounterOpts{
  105. Namespace: metricPrefix,
  106. Name: MetricIPBlocklisted,
  107. Help: "A number of rejected sessions due to ip blocklisting",
  108. }, []string{TagIPType}),
  109. }
  110. registry.MustRegister(factory.metricActiveConnections)
  111. registry.MustRegister(factory.metricSessionDuration)
  112. registry.MustRegister(factory.metricConcurrencyLimited)
  113. registry.MustRegister(factory.metricIPBlocklisted)
  114. return factory
  115. }