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 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. package stats
  2. import (
  3. "fmt"
  4. "strings"
  5. "time"
  6. "github.com/9seconds/mtg/v2/events"
  7. "github.com/9seconds/mtg/v2/logger"
  8. "github.com/9seconds/mtg/v2/mtglib"
  9. statsd "github.com/smira/go-statsd"
  10. )
  11. type statsdProcessor struct {
  12. streams map[string]*streamInfo
  13. client *statsd.Client
  14. }
  15. func (s statsdProcessor) EventStart(evt mtglib.EventStart) {
  16. info := acquireStreamInfo()
  17. info.SetStartTime(evt.CreatedAt)
  18. info.SetClientIP(evt.RemoteIP)
  19. s.streams[evt.StreamID()] = info
  20. s.client.GaugeDelta(MetricClientConnections,
  21. 1,
  22. info.TV(TagIPFamily))
  23. }
  24. func (s statsdProcessor) EventConnectedToDC(evt mtglib.EventConnectedToDC) {
  25. info, ok := s.streams[evt.StreamID()]
  26. if !ok {
  27. return
  28. }
  29. info.SetTelegramIP(evt.RemoteIP)
  30. info.SetDC(evt.DC)
  31. s.client.GaugeDelta(MetricTelegramConnections,
  32. 1,
  33. info.TV(TagTelegramIP),
  34. info.TV(TagDC))
  35. }
  36. func (s statsdProcessor) EventTelegramTraffic(evt mtglib.EventTelegramTraffic) {
  37. info, ok := s.streams[evt.StreamID()]
  38. if !ok {
  39. return
  40. }
  41. s.client.Incr(MetricTelegramTraffic,
  42. int64(evt.Traffic),
  43. info.TV(TagTelegramIP),
  44. info.TV(TagDC),
  45. statsd.StringTag(TagDirection, getDirection(evt.IsRead)))
  46. }
  47. func (s statsdProcessor) EventFinish(evt mtglib.EventFinish) {
  48. info, ok := s.streams[evt.StreamID()]
  49. if !ok {
  50. return
  51. }
  52. defer func() {
  53. delete(s.streams, evt.StreamID())
  54. releaseStreamInfo(info)
  55. }()
  56. s.client.GaugeDelta(MetricClientConnections,
  57. -1,
  58. info.TV(TagIPFamily))
  59. if info.V(TagTelegramIP) != "" {
  60. s.client.GaugeDelta(MetricTelegramConnections,
  61. -1,
  62. info.TV(TagTelegramIP),
  63. info.TV(TagDC))
  64. }
  65. }
  66. func (s statsdProcessor) EventConcurrencyLimited(_ mtglib.EventConcurrencyLimited) {
  67. s.client.Incr(MetricConcurrencyLimited, 1)
  68. }
  69. func (s statsdProcessor) EventIPBlocklisted(evt mtglib.EventIPBlocklisted) {
  70. s.client.Incr(MetricIPBlocklisted, 1)
  71. }
  72. func (s statsdProcessor) Shutdown() {
  73. now := time.Now()
  74. events := make([]mtglib.EventFinish, 0, len(s.streams))
  75. for k := range s.streams {
  76. events = append(events, mtglib.EventFinish{
  77. CreatedAt: now,
  78. ConnID: k,
  79. })
  80. }
  81. for i := range events {
  82. s.EventFinish(events[i])
  83. }
  84. }
  85. type StatsdFactory struct {
  86. client *statsd.Client
  87. }
  88. func (s StatsdFactory) Close() error {
  89. return s.client.Close()
  90. }
  91. func (s StatsdFactory) Make() events.Observer {
  92. return statsdProcessor{
  93. client: s.client,
  94. streams: make(map[string]*streamInfo),
  95. }
  96. }
  97. func NewStatsd(address string, log logger.StdLikeLogger,
  98. metricPrefix, tagFormat string) (StatsdFactory, error) {
  99. options := []statsd.Option{
  100. statsd.MetricPrefix(metricPrefix),
  101. statsd.Logger(log),
  102. }
  103. switch strings.ToLower(tagFormat) {
  104. case "datadog":
  105. options = append(options, statsd.TagStyle(statsd.TagFormatDatadog))
  106. case "influxdb":
  107. options = append(options, statsd.TagStyle(statsd.TagFormatInfluxDB))
  108. case "graphite":
  109. options = append(options, statsd.TagStyle(statsd.TagFormatGraphite))
  110. default:
  111. return StatsdFactory{}, fmt.Errorf("unknown tag format %s", tagFormat)
  112. }
  113. return StatsdFactory{
  114. client: statsd.NewClient(address, options...),
  115. }, nil
  116. }