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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. package stats
  2. import (
  3. "fmt"
  4. "strings"
  5. "time"
  6. "github.com/9seconds/mtg/v2/events"
  7. "github.com/9seconds/mtg/v2/mtglib"
  8. statsd "github.com/smira/go-statsd"
  9. )
  10. type statsdFakeLogger struct{}
  11. func (s statsdFakeLogger) Printf(msg string, args ...interface{}) {}
  12. type statsdProcessor struct {
  13. streams map[string]*streamInfo
  14. client *statsd.Client
  15. }
  16. func (s statsdProcessor) EventStart(evt mtglib.EventStart) {
  17. sInfo := &streamInfo{
  18. createdAt: evt.CreatedAt,
  19. clientIP: evt.RemoteIP,
  20. }
  21. s.streams[evt.StreamID()] = sInfo
  22. ipTypeTag := statsd.StringTag(TagIPType, sInfo.IPType())
  23. s.client.GaugeDelta(MetricActiveConnection, 1, ipTypeTag)
  24. }
  25. func (s statsdProcessor) EventFinish(evt mtglib.EventFinish) {
  26. sInfo, ok := s.streams[evt.StreamID()]
  27. if !ok {
  28. return
  29. }
  30. defer delete(s.streams, evt.StreamID())
  31. duration := evt.CreatedAt.Sub(sInfo.createdAt)
  32. ipTypeTag := statsd.StringTag(TagIPType, sInfo.IPType())
  33. s.client.GaugeDelta(MetricActiveConnection, -1, ipTypeTag)
  34. s.client.PrecisionTiming(MetricSessionDuration, duration)
  35. }
  36. func (s statsdProcessor) EventConcurrencyLimited(_ mtglib.EventConcurrencyLimited) {
  37. s.client.Incr(MetricConcurrencyLimited, 1)
  38. }
  39. func (s statsdProcessor) EventIPBlocklisted(evt mtglib.EventIPBlocklisted) {
  40. var tag statsd.Tag
  41. if evt.RemoteIP.To4() == nil {
  42. tag = statsd.StringTag(TagIPType, TagIPTypeIPv6)
  43. } else {
  44. tag = statsd.StringTag(TagIPType, TagIPTypeIPv4)
  45. }
  46. s.client.Incr(MetricIPBlocklisted, 1, tag)
  47. }
  48. func (s statsdProcessor) Shutdown() {
  49. now := time.Now()
  50. events := make([]mtglib.EventFinish, 0, len(s.streams))
  51. for k := range s.streams {
  52. events = append(events, mtglib.EventFinish{
  53. CreatedAt: now,
  54. ConnID: k,
  55. })
  56. }
  57. for i := range events {
  58. s.EventFinish(events[i])
  59. }
  60. }
  61. type StatsdFactory struct {
  62. client *statsd.Client
  63. }
  64. func (s StatsdFactory) Close() error {
  65. return s.client.Close()
  66. }
  67. func (s StatsdFactory) Make() events.Observer {
  68. return statsdProcessor{
  69. client: s.client,
  70. streams: make(map[string]*streamInfo),
  71. }
  72. }
  73. func NewStatsd(address, metricPrefix, tagFormat string) (StatsdFactory, error) {
  74. options := []statsd.Option{
  75. statsd.MetricPrefix(metricPrefix),
  76. statsd.Logger(statsdFakeLogger{}),
  77. }
  78. switch strings.ToLower(tagFormat) {
  79. case "datadog":
  80. options = append(options, statsd.TagStyle(statsd.TagFormatDatadog))
  81. case "influxdb":
  82. options = append(options, statsd.TagStyle(statsd.TagFormatInfluxDB))
  83. case "graphite":
  84. options = append(options, statsd.TagStyle(statsd.TagFormatGraphite))
  85. default:
  86. return StatsdFactory{}, fmt.Errorf("unknown tag format %s", tagFormat)
  87. }
  88. return StatsdFactory{
  89. client: statsd.NewClient(address, options...),
  90. }, nil
  91. }