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
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

stats_prometheus.go 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. package stats
  2. import (
  3. "fmt"
  4. "net"
  5. "net/http"
  6. "strconv"
  7. "github.com/prometheus/client_golang/prometheus"
  8. "github.com/prometheus/client_golang/prometheus/promhttp"
  9. "github.com/9seconds/mtg/config"
  10. "github.com/9seconds/mtg/conntypes"
  11. )
  12. type statsPrometheus struct {
  13. connections *prometheus.GaugeVec
  14. telegramConnections *prometheus.GaugeVec
  15. traffic *prometheus.GaugeVec
  16. crashes prometheus.Gauge
  17. antiReplays prometheus.Counter
  18. }
  19. func (s *statsPrometheus) IngressTraffic(traffic int) {
  20. s.traffic.WithLabelValues("ingress").Add(float64(traffic))
  21. }
  22. func (s *statsPrometheus) EgressTraffic(traffic int) {
  23. s.traffic.WithLabelValues("egress").Add(float64(traffic))
  24. }
  25. func (s *statsPrometheus) ClientConnected(connectionType conntypes.ConnectionType, addr *net.TCPAddr) {
  26. s.changeConnections(connectionType, addr, 1.0)
  27. }
  28. func (s *statsPrometheus) ClientDisconnected(connectionType conntypes.ConnectionType, addr *net.TCPAddr) {
  29. s.changeConnections(connectionType, addr, -1.0)
  30. }
  31. func (s *statsPrometheus) changeConnections(connectionType conntypes.ConnectionType,
  32. addr *net.TCPAddr,
  33. increment float64) {
  34. labels := [...]string{
  35. "intermediate",
  36. "ipv4",
  37. }
  38. switch connectionType {
  39. case conntypes.ConnectionTypeAbridged:
  40. labels[0] = "abridged"
  41. case conntypes.ConnectionTypeSecure:
  42. labels[0] = "secured"
  43. }
  44. if addr.IP.To4() == nil {
  45. labels[1] = "ipv6" // nolint: goconst
  46. }
  47. s.connections.WithLabelValues(labels[:]...).Add(increment)
  48. }
  49. func (s *statsPrometheus) TelegramConnected(dc conntypes.DC, addr *net.TCPAddr) {
  50. s.changeTelegramConnections(dc, addr, 1.0)
  51. }
  52. func (s *statsPrometheus) TelegramDisconnected(dc conntypes.DC, addr *net.TCPAddr) {
  53. s.changeTelegramConnections(dc, addr, -1.0)
  54. }
  55. func (s *statsPrometheus) changeTelegramConnections(dc conntypes.DC, addr *net.TCPAddr, increment float64) {
  56. labels := [...]string{
  57. strconv.Itoa(int(dc)),
  58. "ipv4",
  59. }
  60. if addr.IP.To4() == nil {
  61. labels[1] = "ipv6"
  62. }
  63. s.telegramConnections.WithLabelValues(labels[:]...).Add(increment)
  64. }
  65. func (s *statsPrometheus) Crash() {
  66. s.crashes.Inc()
  67. }
  68. func (s *statsPrometheus) AntiReplayDetected() {
  69. s.antiReplays.Inc()
  70. }
  71. func newStatsPrometheus(mux *http.ServeMux) (Interface, error) {
  72. registry := prometheus.NewPedanticRegistry()
  73. instance := &statsPrometheus{
  74. connections: prometheus.NewGaugeVec(prometheus.GaugeOpts{
  75. Namespace: config.C.StatsNamespace,
  76. Name: "connections",
  77. Help: "Current number of client connections to the proxy.",
  78. }, []string{"type", "protocol"}),
  79. telegramConnections: prometheus.NewGaugeVec(prometheus.GaugeOpts{
  80. Namespace: config.C.StatsNamespace,
  81. Name: "telegram_connections",
  82. Help: "Current number of telegram connections established by this proxy.",
  83. }, []string{"dc", "protocol"}),
  84. traffic: prometheus.NewGaugeVec(prometheus.GaugeOpts{
  85. Namespace: config.C.StatsNamespace,
  86. Name: "traffic",
  87. Help: "Traffic passed through the proxy in bytes.",
  88. }, []string{"direction"}),
  89. crashes: prometheus.NewGauge(prometheus.GaugeOpts{
  90. Namespace: config.C.StatsNamespace,
  91. Name: "crashes",
  92. Help: "How many crashes happened.",
  93. }),
  94. antiReplays: prometheus.NewCounter(prometheus.CounterOpts{
  95. Namespace: config.C.StatsNamespace,
  96. Name: "anti_replays",
  97. Help: "How many anti replay attacks were prevented.",
  98. }),
  99. }
  100. if err := registry.Register(instance.connections); err != nil {
  101. return nil, fmt.Errorf("cannot register metrics for connections: %w", err)
  102. }
  103. if err := registry.Register(instance.telegramConnections); err != nil {
  104. return nil, fmt.Errorf("cannot register metrics for telegram connections: %w", err)
  105. }
  106. if err := registry.Register(instance.traffic); err != nil {
  107. return nil, fmt.Errorf("cannot register metrics for traffic: %w", err)
  108. }
  109. if err := registry.Register(instance.crashes); err != nil {
  110. return nil, fmt.Errorf("cannot register metrics for crashes: %w", err)
  111. }
  112. if err := registry.Register(instance.antiReplays); err != nil {
  113. return nil, fmt.Errorf("cannot register metrics for anti replays: %w", err)
  114. }
  115. handler := promhttp.HandlerFor(registry, promhttp.HandlerOpts{})
  116. mux.Handle("/", handler)
  117. return instance, nil
  118. }