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
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

stats_prometheus.go 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. package stats
  2. import (
  3. "net"
  4. "net/http"
  5. "strconv"
  6. "github.com/9seconds/mtg/config"
  7. "github.com/9seconds/mtg/conntypes"
  8. "github.com/prometheus/client_golang/prometheus"
  9. "github.com/prometheus/client_golang/prometheus/promhttp"
  10. )
  11. type statsPrometheus struct {
  12. connections *prometheus.GaugeVec
  13. telegramConnections *prometheus.GaugeVec
  14. traffic *prometheus.GaugeVec
  15. crashes prometheus.Counter
  16. replayAttacks prometheus.Counter
  17. authenticationFailed prometheus.Counter
  18. cloakedRequests prometheus.Counter
  19. }
  20. func (s *statsPrometheus) IngressTraffic(traffic int) {
  21. s.traffic.WithLabelValues("ingress").Add(float64(traffic))
  22. }
  23. func (s *statsPrometheus) EgressTraffic(traffic int) {
  24. s.traffic.WithLabelValues("egress").Add(float64(traffic))
  25. }
  26. func (s *statsPrometheus) ClientConnected(connectionType conntypes.ConnectionType, addr *net.TCPAddr) {
  27. s.changeConnections(connectionType, addr, 1.0)
  28. }
  29. func (s *statsPrometheus) ClientDisconnected(connectionType conntypes.ConnectionType, addr *net.TCPAddr) {
  30. s.changeConnections(connectionType, addr, -1.0)
  31. }
  32. func (s *statsPrometheus) changeConnections(connectionType conntypes.ConnectionType,
  33. addr *net.TCPAddr,
  34. increment float64) {
  35. labels := [...]string{
  36. "intermediate",
  37. "ipv4",
  38. }
  39. switch connectionType {
  40. case conntypes.ConnectionTypeAbridged:
  41. labels[0] = "abridged"
  42. case conntypes.ConnectionTypeSecure:
  43. labels[0] = "secured"
  44. case conntypes.ConnectionTypeIntermediate:
  45. labels[0] = "intermediate"
  46. case conntypes.ConnectionTypeUnknown:
  47. panic("unknown connection type")
  48. }
  49. if addr.IP.To4() == nil {
  50. labels[1] = "ipv6"
  51. }
  52. s.connections.WithLabelValues(labels[:]...).Add(increment)
  53. }
  54. func (s *statsPrometheus) TelegramConnected(dc conntypes.DC, addr *net.TCPAddr) {
  55. s.changeTelegramConnections(dc, addr, 1.0)
  56. }
  57. func (s *statsPrometheus) TelegramDisconnected(dc conntypes.DC, addr *net.TCPAddr) {
  58. s.changeTelegramConnections(dc, addr, -1.0)
  59. }
  60. func (s *statsPrometheus) changeTelegramConnections(dc conntypes.DC, addr *net.TCPAddr, increment float64) {
  61. labels := [...]string{
  62. strconv.Itoa(int(dc)),
  63. "ipv4",
  64. }
  65. if addr.IP.To4() == nil {
  66. labels[1] = "ipv6"
  67. }
  68. s.telegramConnections.WithLabelValues(labels[:]...).Add(increment)
  69. }
  70. func (s *statsPrometheus) Crash() {
  71. s.crashes.Inc()
  72. }
  73. func (s *statsPrometheus) ReplayDetected() {
  74. s.replayAttacks.Inc()
  75. }
  76. func (s *statsPrometheus) AuthenticationFailed() {
  77. s.authenticationFailed.Inc()
  78. }
  79. func (s *statsPrometheus) CloakedRequest() {
  80. s.cloakedRequests.Inc()
  81. }
  82. func newStatsPrometheus(mux *http.ServeMux) Interface {
  83. registry := prometheus.NewPedanticRegistry()
  84. instance := &statsPrometheus{
  85. connections: prometheus.NewGaugeVec(prometheus.GaugeOpts{
  86. Namespace: config.C.StatsNamespace,
  87. Name: "connections",
  88. Help: "Current number of client connections to the proxy.",
  89. }, []string{"type", "protocol"}),
  90. telegramConnections: prometheus.NewGaugeVec(prometheus.GaugeOpts{
  91. Namespace: config.C.StatsNamespace,
  92. Name: "telegram_connections",
  93. Help: "Current number of telegram connections established by this proxy.",
  94. }, []string{"dc", "protocol"}),
  95. traffic: prometheus.NewGaugeVec(prometheus.GaugeOpts{
  96. Namespace: config.C.StatsNamespace,
  97. Name: "traffic",
  98. Help: "Traffic passed through the proxy in bytes.",
  99. }, []string{"direction"}),
  100. crashes: prometheus.NewCounter(prometheus.CounterOpts{
  101. Namespace: config.C.StatsNamespace,
  102. Name: "crashes",
  103. Help: "How many crashes happened.",
  104. }),
  105. replayAttacks: prometheus.NewCounter(prometheus.CounterOpts{
  106. Namespace: config.C.StatsNamespace,
  107. Name: "replay_attacks",
  108. Help: "How many replay attacks were prevented.",
  109. }),
  110. authenticationFailed: prometheus.NewCounter(prometheus.CounterOpts{
  111. Namespace: config.C.StatsNamespace,
  112. Name: "authentication_failed",
  113. Help: "How many authentication failed events we've seen.",
  114. }),
  115. cloakedRequests: prometheus.NewCounter(prometheus.CounterOpts{
  116. Namespace: config.C.StatsNamespace,
  117. Name: "cloaked_requests",
  118. Help: "How many requests were proxified during cloaking.",
  119. }),
  120. }
  121. registry.MustRegister(instance.connections)
  122. registry.MustRegister(instance.telegramConnections)
  123. registry.MustRegister(instance.traffic)
  124. registry.MustRegister(instance.crashes)
  125. registry.MustRegister(instance.replayAttacks)
  126. registry.MustRegister(instance.authenticationFailed)
  127. registry.MustRegister(instance.cloakedRequests)
  128. handler := promhttp.HandlerFor(registry, promhttp.HandlerOpts{})
  129. mux.Handle("/", handler)
  130. return instance
  131. }