Procházet zdrojové kódy

Add support of EventDomainFronting event

tags/v2.0.0-rc1
9seconds před 5 roky
rodič
revize
bef14bd009

+ 7
- 5
events/event_stream.go Zobrazit soubor

@@ -60,7 +60,7 @@ func NewEventStream(observerFactories []ObserverFactory) mtglib.EventStream {
60 60
 	return rv
61 61
 }
62 62
 
63
-func eventStreamProcessor(ctx context.Context, eventChan <-chan mtglib.Event, observer Observer) {
63
+func eventStreamProcessor(ctx context.Context, eventChan <-chan mtglib.Event, observer Observer) { // nolint: cyclop
64 64
 	defer observer.Shutdown()
65 65
 
66 66
 	for {
@@ -69,14 +69,16 @@ func eventStreamProcessor(ctx context.Context, eventChan <-chan mtglib.Event, ob
69 69
 			return
70 70
 		case evt := <-eventChan:
71 71
 			switch typedEvt := evt.(type) {
72
-			case mtglib.EventStart:
73
-				observer.EventStart(typedEvt)
74
-			case mtglib.EventConnectedToDC:
75
-				observer.EventConnectedToDC(typedEvt)
76 72
 			case mtglib.EventTraffic:
77 73
 				observer.EventTraffic(typedEvt)
74
+			case mtglib.EventStart:
75
+				observer.EventStart(typedEvt)
78 76
 			case mtglib.EventFinish:
79 77
 				observer.EventFinish(typedEvt)
78
+			case mtglib.EventConnectedToDC:
79
+				observer.EventConnectedToDC(typedEvt)
80
+			case mtglib.EventDomainFronting:
81
+				observer.EventDomainFronting(typedEvt)
80 82
 			case mtglib.EventIPBlocklisted:
81 83
 				observer.EventIPBlocklisted(typedEvt)
82 84
 			case mtglib.EventConcurrencyLimited:

+ 23
- 0
events/event_stream_test.go Zobrazit soubor

@@ -90,6 +90,29 @@ func (suite *EventStreamTestSuite) TestEventConnectedToDC() {
90 90
 	time.Sleep(100 * time.Millisecond)
91 91
 }
92 92
 
93
+func (suite *EventStreamTestSuite) TestEventDomainFronting() {
94
+	evt := mtglib.EventDomainFronting{
95
+		CreatedAt: time.Now(),
96
+		ConnID:    "connID",
97
+	}
98
+
99
+	for _, v := range []*ObserverMock{suite.observerMock1, suite.observerMock2} {
100
+		v.
101
+			On("EventDomainFronting", mock.Anything).
102
+			Once().
103
+			Run(func(args mock.Arguments) {
104
+				caught := args.Get(0).(mtglib.EventDomainFronting)
105
+
106
+				suite.Equal(evt.CreatedAt, caught.CreatedAt)
107
+				suite.Equal(evt.ConnID, caught.ConnID)
108
+				suite.Equal(evt.StreamID(), caught.StreamID())
109
+			})
110
+	}
111
+
112
+	suite.stream.Send(suite.ctx, evt)
113
+	time.Sleep(100 * time.Millisecond)
114
+}
115
+
93 116
 func (suite *EventStreamTestSuite) TestEventTraffic() {
94 117
 	evt := mtglib.EventTraffic{
95 118
 		CreatedAt: time.Now(),

+ 1
- 0
events/init.go Zobrazit soubor

@@ -6,6 +6,7 @@ type Observer interface {
6 6
 	EventStart(mtglib.EventStart)
7 7
 	EventFinish(mtglib.EventFinish)
8 8
 	EventConnectedToDC(mtglib.EventConnectedToDC)
9
+	EventDomainFronting(mtglib.EventDomainFronting)
9 10
 	EventTraffic(mtglib.EventTraffic)
10 11
 	EventConcurrencyLimited(mtglib.EventConcurrencyLimited)
11 12
 	EventIPBlocklisted(mtglib.EventIPBlocklisted)

+ 4
- 0
events/init_test.go Zobrazit soubor

@@ -17,6 +17,10 @@ func (o *ObserverMock) EventConnectedToDC(evt mtglib.EventConnectedToDC) {
17 17
 	o.Called(evt)
18 18
 }
19 19
 
20
+func (o *ObserverMock) EventDomainFronting(evt mtglib.EventDomainFronting) {
21
+	o.Called(evt)
22
+}
23
+
20 24
 func (o *ObserverMock) EventTraffic(evt mtglib.EventTraffic) {
21 25
 	o.Called(evt)
22 26
 }

+ 15
- 0
events/multi_observer.go Zobrazit soubor

@@ -40,6 +40,21 @@ func (m multiObserver) EventConnectedToDC(evt mtglib.EventConnectedToDC) {
40 40
 	wg.Wait()
41 41
 }
42 42
 
43
+func (m multiObserver) EventDomainFronting(evt mtglib.EventDomainFronting) {
44
+	wg := &sync.WaitGroup{}
45
+	wg.Add(len(m.observers))
46
+
47
+	for _, v := range m.observers {
48
+		go func(obs Observer) {
49
+			defer wg.Done()
50
+
51
+			obs.EventDomainFronting(evt)
52
+		}(v)
53
+	}
54
+
55
+	wg.Wait()
56
+}
57
+
43 58
 func (m multiObserver) EventTraffic(evt mtglib.EventTraffic) {
44 59
 	wg := &sync.WaitGroup{}
45 60
 	wg.Add(len(m.observers))

+ 1
- 0
events/noop.go Zobrazit soubor

@@ -19,6 +19,7 @@ type noopObserver struct{}
19 19
 
20 20
 func (n noopObserver) EventStart(_ mtglib.EventStart)                           {}
21 21
 func (n noopObserver) EventConnectedToDC(_ mtglib.EventConnectedToDC)           {}
22
+func (n noopObserver) EventDomainFronting(_ mtglib.EventDomainFronting)         {}
22 23
 func (n noopObserver) EventTraffic(_ mtglib.EventTraffic)                       {}
23 24
 func (n noopObserver) EventFinish(_ mtglib.EventFinish)                         {}
24 25
 func (n noopObserver) EventConcurrencyLimited(_ mtglib.EventConcurrencyLimited) {}

+ 6
- 0
events/noop_test.go Zobrazit soubor

@@ -31,6 +31,10 @@ func (suite *NoopTestSuite) SetupSuite() {
31 31
 			RemoteIP:  net.ParseIP("127.1.0.1"),
32 32
 			DC:        2,
33 33
 		},
34
+		"domain-fronting": mtglib.EventDomainFronting{
35
+			CreatedAt: time.Now(),
36
+			ConnID:    "connID",
37
+		},
34 38
 		"traffic": mtglib.EventTraffic{
35 39
 			CreatedAt: time.Now(),
36 40
 			ConnID:    "connID",
@@ -76,6 +80,8 @@ func (suite *NoopTestSuite) TestObserver() {
76 80
 				observer.EventStart(typedEvt)
77 81
 			case mtglib.EventConnectedToDC:
78 82
 				observer.EventConnectedToDC(typedEvt)
83
+			case mtglib.EventDomainFronting:
84
+				observer.EventDomainFronting(typedEvt)
79 85
 			case mtglib.EventFinish:
80 86
 				observer.EventFinish(typedEvt)
81 87
 			case mtglib.EventConcurrencyLimited:

+ 3
- 3
mtglib/conns.go Zobrazit soubor

@@ -9,7 +9,7 @@ import (
9 9
 	"time"
10 10
 )
11 11
 
12
-type connTelegramTraffic struct {
12
+type connTraffic struct {
13 13
 	net.Conn
14 14
 
15 15
 	connID string
@@ -17,7 +17,7 @@ type connTelegramTraffic struct {
17 17
 	ctx    context.Context
18 18
 }
19 19
 
20
-func (c connTelegramTraffic) Read(b []byte) (int, error) {
20
+func (c connTraffic) Read(b []byte) (int, error) {
21 21
 	n, err := c.Conn.Read(b)
22 22
 
23 23
 	if n > 0 {
@@ -32,7 +32,7 @@ func (c connTelegramTraffic) Read(b []byte) (int, error) {
32 32
 	return n, err // nolint: wrapcheck
33 33
 }
34 34
 
35
-func (c connTelegramTraffic) Write(b []byte) (int, error) {
35
+func (c connTraffic) Write(b []byte) (int, error) {
36 36
 	n, err := c.Conn.Write(b)
37 37
 
38 38
 	if n > 0 {

+ 13
- 0
mtglib/events.go Zobrazit soubor

@@ -62,6 +62,19 @@ func (e EventFinish) Timestamp() time.Time {
62 62
 	return e.CreatedAt
63 63
 }
64 64
 
65
+type EventDomainFronting struct {
66
+	CreatedAt time.Time
67
+	ConnID    string
68
+}
69
+
70
+func (e EventDomainFronting) StreamID() string {
71
+	return e.ConnID
72
+}
73
+
74
+func (e EventDomainFronting) Timestamp() time.Time {
75
+	return e.CreatedAt
76
+}
77
+
65 78
 type EventConcurrencyLimited struct {
66 79
 	CreatedAt time.Time
67 80
 }

+ 10
- 0
mtglib/events_test.go Zobrazit soubor

@@ -58,6 +58,16 @@ func (suite *EventsTestSuite) TestEventTraffic() {
58 58
 	suite.WithinDuration(time.Now(), evt.Timestamp(), 10*time.Millisecond)
59 59
 }
60 60
 
61
+func (suite *EventsTestSuite) TestEventDomainFronting() {
62
+	evt := mtglib.EventDomainFronting{
63
+		CreatedAt: time.Now(),
64
+		ConnID:    "CONNID",
65
+	}
66
+
67
+	suite.Equal("CONNID", evt.StreamID())
68
+	suite.WithinDuration(time.Now(), evt.Timestamp(), 10*time.Millisecond)
69
+}
70
+
61 71
 func (suite *EventsTestSuite) TestEventConcurrencyLimited() {
62 72
 	evt := mtglib.EventConcurrencyLimited{
63 73
 		CreatedAt: time.Now(),

+ 14
- 2
mtglib/proxy.go Zobrazit soubor

@@ -215,7 +215,7 @@ func (p *Proxy) doTelegramCall(ctx *streamContext) error {
215 215
 	}
216 216
 
217 217
 	ctx.telegramConn = obfuscated2.Conn{
218
-		Conn: connTelegramTraffic{
218
+		Conn: connTraffic{
219 219
 			Conn:   conn,
220 220
 			connID: ctx.connID,
221 221
 			stream: p.eventStream,
@@ -235,7 +235,12 @@ func (p *Proxy) doTelegramCall(ctx *streamContext) error {
235 235
 	return nil
236 236
 }
237 237
 
238
-func (p *Proxy) doDomainFronting(ctx context.Context, conn *connRewind) {
238
+func (p *Proxy) doDomainFronting(ctx *streamContext, conn *connRewind) {
239
+	p.eventStream.Send(p.ctx, EventDomainFronting{
240
+		CreatedAt: time.Now(),
241
+		ConnID:    ctx.connID,
242
+	})
243
+
239 244
 	conn.Rewind()
240 245
 
241 246
 	frontConn, err := p.network.DialContext(ctx, "tcp", p.domainFrontAddress)
@@ -245,6 +250,13 @@ func (p *Proxy) doDomainFronting(ctx context.Context, conn *connRewind) {
245 250
 		return
246 251
 	}
247 252
 
253
+	frontConn = connTraffic{
254
+		Conn:   frontConn,
255
+		ctx:    ctx,
256
+		connID: ctx.connID,
257
+		stream: p.eventStream,
258
+	}
259
+
248 260
 	rel := relay.AcquireRelay(ctx,
249 261
 		p.logger.Named("domain-fronting"), p.bufferSize, p.idleTimeout)
250 262
 	defer relay.ReleaseRelay(rel)

+ 6
- 4
stats/pools.go Zobrazit soubor

@@ -4,15 +4,17 @@ import "sync"
4 4
 
5 5
 var streamInfoPool = sync.Pool{
6 6
 	New: func() interface{} {
7
-		return streamInfo{}
7
+		return &streamInfo{
8
+			tags: make(map[string]string),
9
+		}
8 10
 	},
9 11
 }
10 12
 
11
-func acquireStreamInfo() streamInfo {
12
-	return streamInfoPool.Get().(streamInfo)
13
+func acquireStreamInfo() *streamInfo {
14
+	return streamInfoPool.Get().(*streamInfo)
13 15
 }
14 16
 
15
-func releaseStreamInfo(info streamInfo) {
17
+func releaseStreamInfo(info *streamInfo) {
16 18
 	info.Reset()
17 19
 	streamInfoPool.Put(info)
18 20
 }

+ 47
- 17
stats/prometheus.go Zobrazit soubor

@@ -13,7 +13,7 @@ import (
13 13
 )
14 14
 
15 15
 type prometheusProcessor struct {
16
-	streams map[string]streamInfo
16
+	streams map[string]*streamInfo
17 17
 	factory *PrometheusFactory
18 18
 }
19 19
 
@@ -21,15 +21,15 @@ func (p prometheusProcessor) EventStart(evt mtglib.EventStart) {
21 21
 	info := acquireStreamInfo()
22 22
 
23 23
 	if evt.RemoteIP.To4() != nil {
24
-		info[TagIPFamily] = TagIPFamilyIPv4
24
+		info.tags[TagIPFamily] = TagIPFamilyIPv4
25 25
 	} else {
26
-		info[TagIPFamily] = TagIPFamilyIPv6
26
+		info.tags[TagIPFamily] = TagIPFamilyIPv6
27 27
 	}
28 28
 
29 29
 	p.streams[evt.StreamID()] = info
30 30
 
31 31
 	p.factory.metricClientConnections.
32
-		WithLabelValues(info[TagIPFamily]).
32
+		WithLabelValues(info.tags[TagIPFamily]).
33 33
 		Inc()
34 34
 }
35 35
 
@@ -39,11 +39,25 @@ func (p prometheusProcessor) EventConnectedToDC(evt mtglib.EventConnectedToDC) {
39 39
 		return
40 40
 	}
41 41
 
42
-	info[TagTelegramIP] = evt.RemoteIP.String()
43
-	info[TagDC] = strconv.Itoa(evt.DC)
42
+	info.tags[TagTelegramIP] = evt.RemoteIP.String()
43
+	info.tags[TagDC] = strconv.Itoa(evt.DC)
44 44
 
45 45
 	p.factory.metricTelegramConnections.
46
-		WithLabelValues(info[TagTelegramIP], info[TagDC]).
46
+		WithLabelValues(info.tags[TagTelegramIP], info.tags[TagDC]).
47
+		Inc()
48
+}
49
+
50
+func (p prometheusProcessor) EventDomainFronting(evt mtglib.EventDomainFronting) {
51
+	info, ok := p.streams[evt.StreamID()]
52
+	if !ok {
53
+		return
54
+	}
55
+
56
+	info.isDomainFronted = true
57
+
58
+	p.factory.metricDomainFronting.Inc()
59
+	p.factory.metricDomainFrontingConnections.
60
+		WithLabelValues(info.tags[TagIPFamily]).
47 61
 		Inc()
48 62
 }
49 63
 
@@ -53,9 +67,17 @@ func (p prometheusProcessor) EventTraffic(evt mtglib.EventTraffic) {
53 67
 		return
54 68
 	}
55 69
 
56
-	p.factory.metricTelegramTraffic.
57
-		WithLabelValues(info[TagTelegramIP], info[TagDC], getDirection(evt.IsRead)).
58
-		Add(float64(evt.Traffic))
70
+	direction := getDirection(evt.IsRead)
71
+
72
+	if info.isDomainFronted {
73
+		p.factory.metricDomainFrontingTraffic.
74
+			WithLabelValues(direction).
75
+			Add(float64(evt.Traffic))
76
+	} else {
77
+		p.factory.metricTelegramTraffic.
78
+			WithLabelValues(info.tags[TagTelegramIP], info.tags[TagDC], direction).
79
+			Add(float64(evt.Traffic))
80
+	}
59 81
 }
60 82
 
61 83
 func (p prometheusProcessor) EventFinish(evt mtglib.EventFinish) {
@@ -70,12 +92,16 @@ func (p prometheusProcessor) EventFinish(evt mtglib.EventFinish) {
70 92
 	}()
71 93
 
72 94
 	p.factory.metricClientConnections.
73
-		WithLabelValues(info[TagIPFamily]).
95
+		WithLabelValues(info.tags[TagIPFamily]).
74 96
 		Dec()
75 97
 
76
-	if telegramIP, ok := info[TagTelegramIP]; ok {
98
+	if info.isDomainFronted {
99
+		p.factory.metricDomainFrontingConnections.
100
+			WithLabelValues(info.tags[TagIPFamily]).
101
+			Dec()
102
+	} else if telegramIP, ok := info.tags[TagTelegramIP]; ok {
77 103
 		p.factory.metricTelegramConnections.
78
-			WithLabelValues(telegramIP, info[TagDC]).
104
+			WithLabelValues(telegramIP, info.tags[TagDC]).
79 105
 			Dec()
80 106
 	}
81 107
 }
@@ -89,7 +115,11 @@ func (p prometheusProcessor) EventIPBlocklisted(evt mtglib.EventIPBlocklisted) {
89 115
 }
90 116
 
91 117
 func (p prometheusProcessor) Shutdown() {
92
-	p.streams = make(map[string]streamInfo)
118
+	for _, v := range p.streams {
119
+		releaseStreamInfo(v)
120
+	}
121
+
122
+	p.streams = make(map[string]*streamInfo)
93 123
 }
94 124
 
95 125
 type PrometheusFactory struct {
@@ -110,7 +140,7 @@ type PrometheusFactory struct {
110 140
 
111 141
 func (p *PrometheusFactory) Make() events.Observer {
112 142
 	return prometheusProcessor{
113
-		streams: make(map[string]streamInfo),
143
+		streams: make(map[string]*streamInfo),
114 144
 		factory: p,
115 145
 	}
116 146
 }
@@ -149,8 +179,8 @@ func NewPrometheus(metricPrefix, httpPath string) *PrometheusFactory { // nolint
149 179
 		}, []string{TagTelegramIP, TagDC}),
150 180
 		metricDomainFrontingConnections: prometheus.NewGaugeVec(prometheus.GaugeOpts{
151 181
 			Namespace: metricPrefix,
152
-			Name:      MetricDomainFronting,
153
-			Help:      "A number of connections which talk with front domain.",
182
+			Name:      MetricDomainFrontingConnections,
183
+			Help:      "A number of connections which talk to front domain.",
154 184
 		}, []string{TagIPFamily}),
155 185
 
156 186
 		metricTelegramTraffic: prometheus.NewCounterVec(prometheus.CounterOpts{

+ 60
- 1
stats/prometheus_test.go Zobrazit soubor

@@ -54,7 +54,7 @@ func (suite *PrometheusTestSuite) TearDownTest() {
54 54
 	suite.httpListener.Close()
55 55
 }
56 56
 
57
-func (suite *PrometheusTestSuite) TestEventStartFinish() {
57
+func (suite *PrometheusTestSuite) TestTelegramPath() {
58 58
 	suite.prometheus.EventStart(mtglib.EventStart{
59 59
 		CreatedAt: time.Now(),
60 60
 		ConnID:    "connID",
@@ -114,6 +114,65 @@ func (suite *PrometheusTestSuite) TestEventStartFinish() {
114 114
 	suite.Contains(data, `mtg_telegram_connections{dc="4",telegram_ip="10.0.0.1"} 0`)
115 115
 }
116 116
 
117
+func (suite *PrometheusTestSuite) TestDomainFrontingPath() {
118
+	suite.prometheus.EventStart(mtglib.EventStart{
119
+		CreatedAt: time.Now(),
120
+		ConnID:    "connID",
121
+		RemoteIP:  net.ParseIP("10.0.0.10"),
122
+	})
123
+	time.Sleep(100 * time.Millisecond)
124
+
125
+	data, err := suite.Get()
126
+	suite.NoError(err)
127
+	suite.Contains(data, `mtg_client_connections{ip_family="ipv4"} 1`)
128
+
129
+	suite.prometheus.EventDomainFronting(mtglib.EventDomainFronting{
130
+		CreatedAt: time.Now(),
131
+		ConnID:    "connID",
132
+	})
133
+	time.Sleep(100 * time.Millisecond)
134
+
135
+	data, err = suite.Get()
136
+	suite.NoError(err)
137
+	suite.Contains(data, `mtg_domain_fronting 1`)
138
+	suite.Contains(data, `mtg_domain_fronting_connections{ip_family="ipv4"} 1`)
139
+
140
+	suite.prometheus.EventTraffic(mtglib.EventTraffic{
141
+		CreatedAt: time.Now(),
142
+		ConnID:    "connID",
143
+		Traffic:   200,
144
+		IsRead:    true,
145
+	})
146
+	time.Sleep(100 * time.Millisecond)
147
+
148
+	data, err = suite.Get()
149
+	suite.NoError(err)
150
+	suite.Contains(data, `mtg_domain_fronting_traffic{direction="to_client"} 200`)
151
+
152
+	suite.prometheus.EventTraffic(mtglib.EventTraffic{
153
+		CreatedAt: time.Now(),
154
+		ConnID:    "connID",
155
+		Traffic:   100,
156
+		IsRead:    false,
157
+	})
158
+	time.Sleep(100 * time.Millisecond)
159
+
160
+	data, err = suite.Get()
161
+	suite.NoError(err)
162
+	suite.Contains(data, `mtg_domain_fronting_traffic{direction="from_client"} 100`)
163
+
164
+	suite.prometheus.EventFinish(mtglib.EventFinish{
165
+		CreatedAt: time.Now(),
166
+		ConnID:    "connID",
167
+	})
168
+	time.Sleep(100 * time.Millisecond)
169
+
170
+	data, err = suite.Get()
171
+	suite.NoError(err)
172
+	suite.Contains(data, `mtg_client_connections{ip_family="ipv4"} 0`)
173
+	suite.Contains(data, `mtg_domain_fronting_connections{ip_family="ipv4"} 0`)
174
+}
175
+
117 176
 func (suite *PrometheusTestSuite) TestEventConcurrencyLimited() {
118 177
 	suite.prometheus.EventConcurrencyLimited(mtglib.EventConcurrencyLimited{
119 178
 		CreatedAt: time.Now(),

+ 38
- 12
stats/statsd.go Zobrazit soubor

@@ -13,7 +13,7 @@ import (
13 13
 )
14 14
 
15 15
 type statsdProcessor struct {
16
-	streams map[string]streamInfo
16
+	streams map[string]*streamInfo
17 17
 	client  *statsd.Client
18 18
 }
19 19
 
@@ -21,9 +21,9 @@ func (s statsdProcessor) EventStart(evt mtglib.EventStart) {
21 21
 	info := acquireStreamInfo()
22 22
 
23 23
 	if evt.RemoteIP.To4() != nil {
24
-		info[TagIPFamily] = TagIPFamilyIPv4
24
+		info.tags[TagIPFamily] = TagIPFamilyIPv4
25 25
 	} else {
26
-		info[TagIPFamily] = TagIPFamilyIPv6
26
+		info.tags[TagIPFamily] = TagIPFamilyIPv6
27 27
 	}
28 28
 
29 29
 	s.streams[evt.StreamID()] = info
@@ -39,8 +39,8 @@ func (s statsdProcessor) EventConnectedToDC(evt mtglib.EventConnectedToDC) {
39 39
 		return
40 40
 	}
41 41
 
42
-	info[TagTelegramIP] = evt.RemoteIP.String()
43
-	info[TagDC] = strconv.Itoa(evt.DC)
42
+	info.tags[TagTelegramIP] = evt.RemoteIP.String()
43
+	info.tags[TagDC] = strconv.Itoa(evt.DC)
44 44
 
45 45
 	s.client.GaugeDelta(MetricTelegramConnections,
46 46
 		1,
@@ -48,17 +48,39 @@ func (s statsdProcessor) EventConnectedToDC(evt mtglib.EventConnectedToDC) {
48 48
 		info.T(TagDC))
49 49
 }
50 50
 
51
+func (s statsdProcessor) EventDomainFronting(evt mtglib.EventDomainFronting) {
52
+	info, ok := s.streams[evt.StreamID()]
53
+	if !ok {
54
+		return
55
+	}
56
+
57
+	info.isDomainFronted = true
58
+
59
+	s.client.Incr(MetricDomainFronting, 1)
60
+	s.client.GaugeDelta(MetricDomainFrontingConnections,
61
+		1,
62
+		info.T(TagIPFamily))
63
+}
64
+
51 65
 func (s statsdProcessor) EventTraffic(evt mtglib.EventTraffic) {
52 66
 	info, ok := s.streams[evt.StreamID()]
53 67
 	if !ok {
54 68
 		return
55 69
 	}
56 70
 
57
-	s.client.Incr(MetricTelegramTraffic,
58
-		int64(evt.Traffic),
59
-		info.T(TagTelegramIP),
60
-		info.T(TagDC),
61
-		statsd.StringTag(TagDirection, getDirection(evt.IsRead)))
71
+	directionTag := statsd.StringTag(TagDirection, getDirection(evt.IsRead))
72
+
73
+	if info.isDomainFronted {
74
+		s.client.Incr(MetricDomainFrontingTraffic,
75
+			int64(evt.Traffic),
76
+			directionTag)
77
+	} else {
78
+		s.client.Incr(MetricTelegramTraffic,
79
+			int64(evt.Traffic),
80
+			info.T(TagTelegramIP),
81
+			info.T(TagDC),
82
+			directionTag)
83
+	}
62 84
 }
63 85
 
64 86
 func (s statsdProcessor) EventFinish(evt mtglib.EventFinish) {
@@ -76,7 +98,11 @@ func (s statsdProcessor) EventFinish(evt mtglib.EventFinish) {
76 98
 		-1,
77 99
 		info.T(TagIPFamily))
78 100
 
79
-	if _, ok := info[TagTelegramIP]; ok {
101
+	if info.isDomainFronted {
102
+		s.client.GaugeDelta(MetricDomainFrontingConnections,
103
+			-1,
104
+			info.T(TagIPFamily))
105
+	} else if _, ok := info.tags[TagTelegramIP]; ok {
80 106
 		s.client.GaugeDelta(MetricTelegramConnections,
81 107
 			-1,
82 108
 			info.T(TagTelegramIP),
@@ -119,7 +145,7 @@ func (s StatsdFactory) Close() error {
119 145
 func (s StatsdFactory) Make() events.Observer {
120 146
 	return statsdProcessor{
121 147
 		client:  s.client,
122
-		streams: make(map[string]streamInfo),
148
+		streams: make(map[string]*streamInfo),
123 149
 	}
124 150
 }
125 151
 

+ 57
- 2
stats/statsd_test.go Zobrazit soubor

@@ -16,7 +16,7 @@ import (
16 16
 	"github.com/stretchr/testify/suite"
17 17
 )
18 18
 
19
-const statsdSleepTime = 3 * statsd.DefaultFlushInterval
19
+const statsdSleepTime = 4 * statsd.DefaultFlushInterval
20 20
 
21 21
 type statsdFakeServer struct {
22 22
 	conn  *net.UDPConn
@@ -104,7 +104,7 @@ func (suite *StatsdTestSuite) TearDownTest() {
104 104
 	suite.statsdServer.Close()
105 105
 }
106 106
 
107
-func (suite *StatsdTestSuite) TestEventStartFinish() {
107
+func (suite *StatsdTestSuite) TestTelegramPath() {
108 108
 	suite.statsd.EventStart(mtglib.EventStart{
109 109
 		CreatedAt: time.Now(),
110 110
 		ConnID:    "connID",
@@ -152,6 +152,61 @@ func (suite *StatsdTestSuite) TestEventStartFinish() {
152 152
 		"mtg.telegram_connections:-1|g|#telegram_ip:10.1.0.10,dc:2")
153 153
 	suite.Contains(suite.statsdServer.String(),
154 154
 		"mtg.client_connections:-1|g|#ip_family:ipv4")
155
+
156
+	suite.NotContains(suite.statsdServer.String(), "domain_fronting_traffic")
157
+	suite.NotContains(suite.statsdServer.String(), "domain_fronting_connections")
158
+}
159
+
160
+func (suite *StatsdTestSuite) TestDomainFrontingPath() {
161
+	suite.statsd.EventStart(mtglib.EventStart{
162
+		CreatedAt: time.Now(),
163
+		ConnID:    "connID",
164
+		RemoteIP:  net.ParseIP("10.0.0.10"),
165
+	})
166
+	time.Sleep(statsdSleepTime)
167
+	suite.Equal("mtg.client_connections:+1|g|#ip_family:ipv4", suite.statsdServer.String())
168
+
169
+	suite.statsd.EventDomainFronting(mtglib.EventDomainFronting{
170
+		CreatedAt: time.Now(),
171
+		ConnID:    "connID",
172
+	})
173
+	time.Sleep(statsdSleepTime)
174
+	suite.Contains(suite.statsdServer.String(), "mtg.domain_fronting:1|c")
175
+	suite.Contains(suite.statsdServer.String(),
176
+		`mtg.domain_fronting_connections:+1|g|#ip_family:ipv4`)
177
+
178
+	suite.statsd.EventTraffic(mtglib.EventTraffic{
179
+		CreatedAt: time.Now(),
180
+		ConnID:    "connID",
181
+		Traffic:   30,
182
+		IsRead:    true,
183
+	})
184
+	time.Sleep(statsdSleepTime)
185
+	suite.Contains(suite.statsdServer.String(),
186
+		`mtg.domain_fronting_traffic:30|c|#direction:to_client`)
187
+
188
+	suite.statsd.EventTraffic(mtglib.EventTraffic{
189
+		CreatedAt: time.Now(),
190
+		ConnID:    "connID",
191
+		Traffic:   90,
192
+		IsRead:    false,
193
+	})
194
+	time.Sleep(statsdSleepTime)
195
+	suite.Contains(suite.statsdServer.String(),
196
+		`mtg.domain_fronting_traffic:90|c|#direction:from_client`)
197
+
198
+	suite.statsd.EventFinish(mtglib.EventFinish{
199
+		CreatedAt: time.Now(),
200
+		ConnID:    "connID",
201
+	})
202
+	time.Sleep(statsdSleepTime)
203
+	suite.Contains(suite.statsdServer.String(),
204
+		"mtg.domain_fronting_connections:-1|g|#ip_family:ipv4")
205
+	suite.Contains(suite.statsdServer.String(),
206
+		"mtg.client_connections:-1|g|#ip_family:ipv4")
207
+
208
+	suite.NotContains(suite.statsdServer.String(), "telegram_traffic")
209
+	suite.NotContains(suite.statsdServer.String(), "telegram_connections")
155 210
 }
156 211
 
157 212
 func (suite *StatsdTestSuite) TestEventConcurrencyLimited() {

+ 10
- 5
stats/stream_info.go Zobrazit soubor

@@ -2,15 +2,20 @@ package stats
2 2
 
3 3
 import statsd "github.com/smira/go-statsd"
4 4
 
5
-type streamInfo map[string]string
5
+type streamInfo struct {
6
+	isDomainFronted bool
7
+	tags            map[string]string
8
+}
6 9
 
7 10
 func (s streamInfo) T(key string) statsd.Tag {
8
-	return statsd.StringTag(key, s[key])
11
+	return statsd.StringTag(key, s.tags[key])
9 12
 }
10 13
 
11
-func (s streamInfo) Reset() {
12
-	for k := range s {
13
-		delete(s, k)
14
+func (s *streamInfo) Reset() {
15
+	s.isDomainFronted = false
16
+
17
+	for k := range s.tags {
18
+		delete(s.tags, k)
14 19
 	}
15 20
 }
16 21
 

Načítá se…
Zrušit
Uložit