Add support of EventDomainFronting event

This commit is contained in:
9seconds
2021-03-29 11:56:05 +03:00
parent 36d695118e
commit bef14bd009
17 changed files with 317 additions and 53 deletions
+7 -5
View File
@@ -60,7 +60,7 @@ func NewEventStream(observerFactories []ObserverFactory) mtglib.EventStream {
return rv return rv
} }
func eventStreamProcessor(ctx context.Context, eventChan <-chan mtglib.Event, observer Observer) { func eventStreamProcessor(ctx context.Context, eventChan <-chan mtglib.Event, observer Observer) { // nolint: cyclop
defer observer.Shutdown() defer observer.Shutdown()
for { for {
@@ -69,14 +69,16 @@ func eventStreamProcessor(ctx context.Context, eventChan <-chan mtglib.Event, ob
return return
case evt := <-eventChan: case evt := <-eventChan:
switch typedEvt := evt.(type) { switch typedEvt := evt.(type) {
case mtglib.EventStart:
observer.EventStart(typedEvt)
case mtglib.EventConnectedToDC:
observer.EventConnectedToDC(typedEvt)
case mtglib.EventTraffic: case mtglib.EventTraffic:
observer.EventTraffic(typedEvt) observer.EventTraffic(typedEvt)
case mtglib.EventStart:
observer.EventStart(typedEvt)
case mtglib.EventFinish: case mtglib.EventFinish:
observer.EventFinish(typedEvt) observer.EventFinish(typedEvt)
case mtglib.EventConnectedToDC:
observer.EventConnectedToDC(typedEvt)
case mtglib.EventDomainFronting:
observer.EventDomainFronting(typedEvt)
case mtglib.EventIPBlocklisted: case mtglib.EventIPBlocklisted:
observer.EventIPBlocklisted(typedEvt) observer.EventIPBlocklisted(typedEvt)
case mtglib.EventConcurrencyLimited: case mtglib.EventConcurrencyLimited:
+23
View File
@@ -90,6 +90,29 @@ func (suite *EventStreamTestSuite) TestEventConnectedToDC() {
time.Sleep(100 * time.Millisecond) time.Sleep(100 * time.Millisecond)
} }
func (suite *EventStreamTestSuite) TestEventDomainFronting() {
evt := mtglib.EventDomainFronting{
CreatedAt: time.Now(),
ConnID: "connID",
}
for _, v := range []*ObserverMock{suite.observerMock1, suite.observerMock2} {
v.
On("EventDomainFronting", mock.Anything).
Once().
Run(func(args mock.Arguments) {
caught := args.Get(0).(mtglib.EventDomainFronting)
suite.Equal(evt.CreatedAt, caught.CreatedAt)
suite.Equal(evt.ConnID, caught.ConnID)
suite.Equal(evt.StreamID(), caught.StreamID())
})
}
suite.stream.Send(suite.ctx, evt)
time.Sleep(100 * time.Millisecond)
}
func (suite *EventStreamTestSuite) TestEventTraffic() { func (suite *EventStreamTestSuite) TestEventTraffic() {
evt := mtglib.EventTraffic{ evt := mtglib.EventTraffic{
CreatedAt: time.Now(), CreatedAt: time.Now(),
+1
View File
@@ -6,6 +6,7 @@ type Observer interface {
EventStart(mtglib.EventStart) EventStart(mtglib.EventStart)
EventFinish(mtglib.EventFinish) EventFinish(mtglib.EventFinish)
EventConnectedToDC(mtglib.EventConnectedToDC) EventConnectedToDC(mtglib.EventConnectedToDC)
EventDomainFronting(mtglib.EventDomainFronting)
EventTraffic(mtglib.EventTraffic) EventTraffic(mtglib.EventTraffic)
EventConcurrencyLimited(mtglib.EventConcurrencyLimited) EventConcurrencyLimited(mtglib.EventConcurrencyLimited)
EventIPBlocklisted(mtglib.EventIPBlocklisted) EventIPBlocklisted(mtglib.EventIPBlocklisted)
+4
View File
@@ -17,6 +17,10 @@ func (o *ObserverMock) EventConnectedToDC(evt mtglib.EventConnectedToDC) {
o.Called(evt) o.Called(evt)
} }
func (o *ObserverMock) EventDomainFronting(evt mtglib.EventDomainFronting) {
o.Called(evt)
}
func (o *ObserverMock) EventTraffic(evt mtglib.EventTraffic) { func (o *ObserverMock) EventTraffic(evt mtglib.EventTraffic) {
o.Called(evt) o.Called(evt)
} }
+15
View File
@@ -40,6 +40,21 @@ func (m multiObserver) EventConnectedToDC(evt mtglib.EventConnectedToDC) {
wg.Wait() wg.Wait()
} }
func (m multiObserver) EventDomainFronting(evt mtglib.EventDomainFronting) {
wg := &sync.WaitGroup{}
wg.Add(len(m.observers))
for _, v := range m.observers {
go func(obs Observer) {
defer wg.Done()
obs.EventDomainFronting(evt)
}(v)
}
wg.Wait()
}
func (m multiObserver) EventTraffic(evt mtglib.EventTraffic) { func (m multiObserver) EventTraffic(evt mtglib.EventTraffic) {
wg := &sync.WaitGroup{} wg := &sync.WaitGroup{}
wg.Add(len(m.observers)) wg.Add(len(m.observers))
+1
View File
@@ -19,6 +19,7 @@ type noopObserver struct{}
func (n noopObserver) EventStart(_ mtglib.EventStart) {} func (n noopObserver) EventStart(_ mtglib.EventStart) {}
func (n noopObserver) EventConnectedToDC(_ mtglib.EventConnectedToDC) {} func (n noopObserver) EventConnectedToDC(_ mtglib.EventConnectedToDC) {}
func (n noopObserver) EventDomainFronting(_ mtglib.EventDomainFronting) {}
func (n noopObserver) EventTraffic(_ mtglib.EventTraffic) {} func (n noopObserver) EventTraffic(_ mtglib.EventTraffic) {}
func (n noopObserver) EventFinish(_ mtglib.EventFinish) {} func (n noopObserver) EventFinish(_ mtglib.EventFinish) {}
func (n noopObserver) EventConcurrencyLimited(_ mtglib.EventConcurrencyLimited) {} func (n noopObserver) EventConcurrencyLimited(_ mtglib.EventConcurrencyLimited) {}
+6
View File
@@ -31,6 +31,10 @@ func (suite *NoopTestSuite) SetupSuite() {
RemoteIP: net.ParseIP("127.1.0.1"), RemoteIP: net.ParseIP("127.1.0.1"),
DC: 2, DC: 2,
}, },
"domain-fronting": mtglib.EventDomainFronting{
CreatedAt: time.Now(),
ConnID: "connID",
},
"traffic": mtglib.EventTraffic{ "traffic": mtglib.EventTraffic{
CreatedAt: time.Now(), CreatedAt: time.Now(),
ConnID: "connID", ConnID: "connID",
@@ -76,6 +80,8 @@ func (suite *NoopTestSuite) TestObserver() {
observer.EventStart(typedEvt) observer.EventStart(typedEvt)
case mtglib.EventConnectedToDC: case mtglib.EventConnectedToDC:
observer.EventConnectedToDC(typedEvt) observer.EventConnectedToDC(typedEvt)
case mtglib.EventDomainFronting:
observer.EventDomainFronting(typedEvt)
case mtglib.EventFinish: case mtglib.EventFinish:
observer.EventFinish(typedEvt) observer.EventFinish(typedEvt)
case mtglib.EventConcurrencyLimited: case mtglib.EventConcurrencyLimited:
+3 -3
View File
@@ -9,7 +9,7 @@ import (
"time" "time"
) )
type connTelegramTraffic struct { type connTraffic struct {
net.Conn net.Conn
connID string connID string
@@ -17,7 +17,7 @@ type connTelegramTraffic struct {
ctx context.Context ctx context.Context
} }
func (c connTelegramTraffic) Read(b []byte) (int, error) { func (c connTraffic) Read(b []byte) (int, error) {
n, err := c.Conn.Read(b) n, err := c.Conn.Read(b)
if n > 0 { if n > 0 {
@@ -32,7 +32,7 @@ func (c connTelegramTraffic) Read(b []byte) (int, error) {
return n, err // nolint: wrapcheck return n, err // nolint: wrapcheck
} }
func (c connTelegramTraffic) Write(b []byte) (int, error) { func (c connTraffic) Write(b []byte) (int, error) {
n, err := c.Conn.Write(b) n, err := c.Conn.Write(b)
if n > 0 { if n > 0 {
+13
View File
@@ -62,6 +62,19 @@ func (e EventFinish) Timestamp() time.Time {
return e.CreatedAt return e.CreatedAt
} }
type EventDomainFronting struct {
CreatedAt time.Time
ConnID string
}
func (e EventDomainFronting) StreamID() string {
return e.ConnID
}
func (e EventDomainFronting) Timestamp() time.Time {
return e.CreatedAt
}
type EventConcurrencyLimited struct { type EventConcurrencyLimited struct {
CreatedAt time.Time CreatedAt time.Time
} }
+10
View File
@@ -58,6 +58,16 @@ func (suite *EventsTestSuite) TestEventTraffic() {
suite.WithinDuration(time.Now(), evt.Timestamp(), 10*time.Millisecond) suite.WithinDuration(time.Now(), evt.Timestamp(), 10*time.Millisecond)
} }
func (suite *EventsTestSuite) TestEventDomainFronting() {
evt := mtglib.EventDomainFronting{
CreatedAt: time.Now(),
ConnID: "CONNID",
}
suite.Equal("CONNID", evt.StreamID())
suite.WithinDuration(time.Now(), evt.Timestamp(), 10*time.Millisecond)
}
func (suite *EventsTestSuite) TestEventConcurrencyLimited() { func (suite *EventsTestSuite) TestEventConcurrencyLimited() {
evt := mtglib.EventConcurrencyLimited{ evt := mtglib.EventConcurrencyLimited{
CreatedAt: time.Now(), CreatedAt: time.Now(),
+14 -2
View File
@@ -215,7 +215,7 @@ func (p *Proxy) doTelegramCall(ctx *streamContext) error {
} }
ctx.telegramConn = obfuscated2.Conn{ ctx.telegramConn = obfuscated2.Conn{
Conn: connTelegramTraffic{ Conn: connTraffic{
Conn: conn, Conn: conn,
connID: ctx.connID, connID: ctx.connID,
stream: p.eventStream, stream: p.eventStream,
@@ -235,7 +235,12 @@ func (p *Proxy) doTelegramCall(ctx *streamContext) error {
return nil return nil
} }
func (p *Proxy) doDomainFronting(ctx context.Context, conn *connRewind) { func (p *Proxy) doDomainFronting(ctx *streamContext, conn *connRewind) {
p.eventStream.Send(p.ctx, EventDomainFronting{
CreatedAt: time.Now(),
ConnID: ctx.connID,
})
conn.Rewind() conn.Rewind()
frontConn, err := p.network.DialContext(ctx, "tcp", p.domainFrontAddress) frontConn, err := p.network.DialContext(ctx, "tcp", p.domainFrontAddress)
@@ -245,6 +250,13 @@ func (p *Proxy) doDomainFronting(ctx context.Context, conn *connRewind) {
return return
} }
frontConn = connTraffic{
Conn: frontConn,
ctx: ctx,
connID: ctx.connID,
stream: p.eventStream,
}
rel := relay.AcquireRelay(ctx, rel := relay.AcquireRelay(ctx,
p.logger.Named("domain-fronting"), p.bufferSize, p.idleTimeout) p.logger.Named("domain-fronting"), p.bufferSize, p.idleTimeout)
defer relay.ReleaseRelay(rel) defer relay.ReleaseRelay(rel)
+6 -4
View File
@@ -4,15 +4,17 @@ import "sync"
var streamInfoPool = sync.Pool{ var streamInfoPool = sync.Pool{
New: func() interface{} { New: func() interface{} {
return streamInfo{} return &streamInfo{
tags: make(map[string]string),
}
}, },
} }
func acquireStreamInfo() streamInfo { func acquireStreamInfo() *streamInfo {
return streamInfoPool.Get().(streamInfo) return streamInfoPool.Get().(*streamInfo)
} }
func releaseStreamInfo(info streamInfo) { func releaseStreamInfo(info *streamInfo) {
info.Reset() info.Reset()
streamInfoPool.Put(info) streamInfoPool.Put(info)
} }
+47 -17
View File
@@ -13,7 +13,7 @@ import (
) )
type prometheusProcessor struct { type prometheusProcessor struct {
streams map[string]streamInfo streams map[string]*streamInfo
factory *PrometheusFactory factory *PrometheusFactory
} }
@@ -21,15 +21,15 @@ func (p prometheusProcessor) EventStart(evt mtglib.EventStart) {
info := acquireStreamInfo() info := acquireStreamInfo()
if evt.RemoteIP.To4() != nil { if evt.RemoteIP.To4() != nil {
info[TagIPFamily] = TagIPFamilyIPv4 info.tags[TagIPFamily] = TagIPFamilyIPv4
} else { } else {
info[TagIPFamily] = TagIPFamilyIPv6 info.tags[TagIPFamily] = TagIPFamilyIPv6
} }
p.streams[evt.StreamID()] = info p.streams[evt.StreamID()] = info
p.factory.metricClientConnections. p.factory.metricClientConnections.
WithLabelValues(info[TagIPFamily]). WithLabelValues(info.tags[TagIPFamily]).
Inc() Inc()
} }
@@ -39,11 +39,25 @@ func (p prometheusProcessor) EventConnectedToDC(evt mtglib.EventConnectedToDC) {
return return
} }
info[TagTelegramIP] = evt.RemoteIP.String() info.tags[TagTelegramIP] = evt.RemoteIP.String()
info[TagDC] = strconv.Itoa(evt.DC) info.tags[TagDC] = strconv.Itoa(evt.DC)
p.factory.metricTelegramConnections. p.factory.metricTelegramConnections.
WithLabelValues(info[TagTelegramIP], info[TagDC]). WithLabelValues(info.tags[TagTelegramIP], info.tags[TagDC]).
Inc()
}
func (p prometheusProcessor) EventDomainFronting(evt mtglib.EventDomainFronting) {
info, ok := p.streams[evt.StreamID()]
if !ok {
return
}
info.isDomainFronted = true
p.factory.metricDomainFronting.Inc()
p.factory.metricDomainFrontingConnections.
WithLabelValues(info.tags[TagIPFamily]).
Inc() Inc()
} }
@@ -53,9 +67,17 @@ func (p prometheusProcessor) EventTraffic(evt mtglib.EventTraffic) {
return return
} }
p.factory.metricTelegramTraffic. direction := getDirection(evt.IsRead)
WithLabelValues(info[TagTelegramIP], info[TagDC], getDirection(evt.IsRead)).
Add(float64(evt.Traffic)) if info.isDomainFronted {
p.factory.metricDomainFrontingTraffic.
WithLabelValues(direction).
Add(float64(evt.Traffic))
} else {
p.factory.metricTelegramTraffic.
WithLabelValues(info.tags[TagTelegramIP], info.tags[TagDC], direction).
Add(float64(evt.Traffic))
}
} }
func (p prometheusProcessor) EventFinish(evt mtglib.EventFinish) { func (p prometheusProcessor) EventFinish(evt mtglib.EventFinish) {
@@ -70,12 +92,16 @@ func (p prometheusProcessor) EventFinish(evt mtglib.EventFinish) {
}() }()
p.factory.metricClientConnections. p.factory.metricClientConnections.
WithLabelValues(info[TagIPFamily]). WithLabelValues(info.tags[TagIPFamily]).
Dec() Dec()
if telegramIP, ok := info[TagTelegramIP]; ok { if info.isDomainFronted {
p.factory.metricDomainFrontingConnections.
WithLabelValues(info.tags[TagIPFamily]).
Dec()
} else if telegramIP, ok := info.tags[TagTelegramIP]; ok {
p.factory.metricTelegramConnections. p.factory.metricTelegramConnections.
WithLabelValues(telegramIP, info[TagDC]). WithLabelValues(telegramIP, info.tags[TagDC]).
Dec() Dec()
} }
} }
@@ -89,7 +115,11 @@ func (p prometheusProcessor) EventIPBlocklisted(evt mtglib.EventIPBlocklisted) {
} }
func (p prometheusProcessor) Shutdown() { func (p prometheusProcessor) Shutdown() {
p.streams = make(map[string]streamInfo) for _, v := range p.streams {
releaseStreamInfo(v)
}
p.streams = make(map[string]*streamInfo)
} }
type PrometheusFactory struct { type PrometheusFactory struct {
@@ -110,7 +140,7 @@ type PrometheusFactory struct {
func (p *PrometheusFactory) Make() events.Observer { func (p *PrometheusFactory) Make() events.Observer {
return prometheusProcessor{ return prometheusProcessor{
streams: make(map[string]streamInfo), streams: make(map[string]*streamInfo),
factory: p, factory: p,
} }
} }
@@ -149,8 +179,8 @@ func NewPrometheus(metricPrefix, httpPath string) *PrometheusFactory { // nolint
}, []string{TagTelegramIP, TagDC}), }, []string{TagTelegramIP, TagDC}),
metricDomainFrontingConnections: prometheus.NewGaugeVec(prometheus.GaugeOpts{ metricDomainFrontingConnections: prometheus.NewGaugeVec(prometheus.GaugeOpts{
Namespace: metricPrefix, Namespace: metricPrefix,
Name: MetricDomainFronting, Name: MetricDomainFrontingConnections,
Help: "A number of connections which talk with front domain.", Help: "A number of connections which talk to front domain.",
}, []string{TagIPFamily}), }, []string{TagIPFamily}),
metricTelegramTraffic: prometheus.NewCounterVec(prometheus.CounterOpts{ metricTelegramTraffic: prometheus.NewCounterVec(prometheus.CounterOpts{
+60 -1
View File
@@ -54,7 +54,7 @@ func (suite *PrometheusTestSuite) TearDownTest() {
suite.httpListener.Close() suite.httpListener.Close()
} }
func (suite *PrometheusTestSuite) TestEventStartFinish() { func (suite *PrometheusTestSuite) TestTelegramPath() {
suite.prometheus.EventStart(mtglib.EventStart{ suite.prometheus.EventStart(mtglib.EventStart{
CreatedAt: time.Now(), CreatedAt: time.Now(),
ConnID: "connID", ConnID: "connID",
@@ -114,6 +114,65 @@ func (suite *PrometheusTestSuite) TestEventStartFinish() {
suite.Contains(data, `mtg_telegram_connections{dc="4",telegram_ip="10.0.0.1"} 0`) suite.Contains(data, `mtg_telegram_connections{dc="4",telegram_ip="10.0.0.1"} 0`)
} }
func (suite *PrometheusTestSuite) TestDomainFrontingPath() {
suite.prometheus.EventStart(mtglib.EventStart{
CreatedAt: time.Now(),
ConnID: "connID",
RemoteIP: net.ParseIP("10.0.0.10"),
})
time.Sleep(100 * time.Millisecond)
data, err := suite.Get()
suite.NoError(err)
suite.Contains(data, `mtg_client_connections{ip_family="ipv4"} 1`)
suite.prometheus.EventDomainFronting(mtglib.EventDomainFronting{
CreatedAt: time.Now(),
ConnID: "connID",
})
time.Sleep(100 * time.Millisecond)
data, err = suite.Get()
suite.NoError(err)
suite.Contains(data, `mtg_domain_fronting 1`)
suite.Contains(data, `mtg_domain_fronting_connections{ip_family="ipv4"} 1`)
suite.prometheus.EventTraffic(mtglib.EventTraffic{
CreatedAt: time.Now(),
ConnID: "connID",
Traffic: 200,
IsRead: true,
})
time.Sleep(100 * time.Millisecond)
data, err = suite.Get()
suite.NoError(err)
suite.Contains(data, `mtg_domain_fronting_traffic{direction="to_client"} 200`)
suite.prometheus.EventTraffic(mtglib.EventTraffic{
CreatedAt: time.Now(),
ConnID: "connID",
Traffic: 100,
IsRead: false,
})
time.Sleep(100 * time.Millisecond)
data, err = suite.Get()
suite.NoError(err)
suite.Contains(data, `mtg_domain_fronting_traffic{direction="from_client"} 100`)
suite.prometheus.EventFinish(mtglib.EventFinish{
CreatedAt: time.Now(),
ConnID: "connID",
})
time.Sleep(100 * time.Millisecond)
data, err = suite.Get()
suite.NoError(err)
suite.Contains(data, `mtg_client_connections{ip_family="ipv4"} 0`)
suite.Contains(data, `mtg_domain_fronting_connections{ip_family="ipv4"} 0`)
}
func (suite *PrometheusTestSuite) TestEventConcurrencyLimited() { func (suite *PrometheusTestSuite) TestEventConcurrencyLimited() {
suite.prometheus.EventConcurrencyLimited(mtglib.EventConcurrencyLimited{ suite.prometheus.EventConcurrencyLimited(mtglib.EventConcurrencyLimited{
CreatedAt: time.Now(), CreatedAt: time.Now(),
+38 -12
View File
@@ -13,7 +13,7 @@ import (
) )
type statsdProcessor struct { type statsdProcessor struct {
streams map[string]streamInfo streams map[string]*streamInfo
client *statsd.Client client *statsd.Client
} }
@@ -21,9 +21,9 @@ func (s statsdProcessor) EventStart(evt mtglib.EventStart) {
info := acquireStreamInfo() info := acquireStreamInfo()
if evt.RemoteIP.To4() != nil { if evt.RemoteIP.To4() != nil {
info[TagIPFamily] = TagIPFamilyIPv4 info.tags[TagIPFamily] = TagIPFamilyIPv4
} else { } else {
info[TagIPFamily] = TagIPFamilyIPv6 info.tags[TagIPFamily] = TagIPFamilyIPv6
} }
s.streams[evt.StreamID()] = info s.streams[evt.StreamID()] = info
@@ -39,8 +39,8 @@ func (s statsdProcessor) EventConnectedToDC(evt mtglib.EventConnectedToDC) {
return return
} }
info[TagTelegramIP] = evt.RemoteIP.String() info.tags[TagTelegramIP] = evt.RemoteIP.String()
info[TagDC] = strconv.Itoa(evt.DC) info.tags[TagDC] = strconv.Itoa(evt.DC)
s.client.GaugeDelta(MetricTelegramConnections, s.client.GaugeDelta(MetricTelegramConnections,
1, 1,
@@ -48,17 +48,39 @@ func (s statsdProcessor) EventConnectedToDC(evt mtglib.EventConnectedToDC) {
info.T(TagDC)) info.T(TagDC))
} }
func (s statsdProcessor) EventDomainFronting(evt mtglib.EventDomainFronting) {
info, ok := s.streams[evt.StreamID()]
if !ok {
return
}
info.isDomainFronted = true
s.client.Incr(MetricDomainFronting, 1)
s.client.GaugeDelta(MetricDomainFrontingConnections,
1,
info.T(TagIPFamily))
}
func (s statsdProcessor) EventTraffic(evt mtglib.EventTraffic) { func (s statsdProcessor) EventTraffic(evt mtglib.EventTraffic) {
info, ok := s.streams[evt.StreamID()] info, ok := s.streams[evt.StreamID()]
if !ok { if !ok {
return return
} }
s.client.Incr(MetricTelegramTraffic, directionTag := statsd.StringTag(TagDirection, getDirection(evt.IsRead))
int64(evt.Traffic),
info.T(TagTelegramIP), if info.isDomainFronted {
info.T(TagDC), s.client.Incr(MetricDomainFrontingTraffic,
statsd.StringTag(TagDirection, getDirection(evt.IsRead))) int64(evt.Traffic),
directionTag)
} else {
s.client.Incr(MetricTelegramTraffic,
int64(evt.Traffic),
info.T(TagTelegramIP),
info.T(TagDC),
directionTag)
}
} }
func (s statsdProcessor) EventFinish(evt mtglib.EventFinish) { func (s statsdProcessor) EventFinish(evt mtglib.EventFinish) {
@@ -76,7 +98,11 @@ func (s statsdProcessor) EventFinish(evt mtglib.EventFinish) {
-1, -1,
info.T(TagIPFamily)) info.T(TagIPFamily))
if _, ok := info[TagTelegramIP]; ok { if info.isDomainFronted {
s.client.GaugeDelta(MetricDomainFrontingConnections,
-1,
info.T(TagIPFamily))
} else if _, ok := info.tags[TagTelegramIP]; ok {
s.client.GaugeDelta(MetricTelegramConnections, s.client.GaugeDelta(MetricTelegramConnections,
-1, -1,
info.T(TagTelegramIP), info.T(TagTelegramIP),
@@ -119,7 +145,7 @@ func (s StatsdFactory) Close() error {
func (s StatsdFactory) Make() events.Observer { func (s StatsdFactory) Make() events.Observer {
return statsdProcessor{ return statsdProcessor{
client: s.client, client: s.client,
streams: make(map[string]streamInfo), streams: make(map[string]*streamInfo),
} }
} }
+57 -2
View File
@@ -16,7 +16,7 @@ import (
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
) )
const statsdSleepTime = 3 * statsd.DefaultFlushInterval const statsdSleepTime = 4 * statsd.DefaultFlushInterval
type statsdFakeServer struct { type statsdFakeServer struct {
conn *net.UDPConn conn *net.UDPConn
@@ -104,7 +104,7 @@ func (suite *StatsdTestSuite) TearDownTest() {
suite.statsdServer.Close() suite.statsdServer.Close()
} }
func (suite *StatsdTestSuite) TestEventStartFinish() { func (suite *StatsdTestSuite) TestTelegramPath() {
suite.statsd.EventStart(mtglib.EventStart{ suite.statsd.EventStart(mtglib.EventStart{
CreatedAt: time.Now(), CreatedAt: time.Now(),
ConnID: "connID", ConnID: "connID",
@@ -152,6 +152,61 @@ func (suite *StatsdTestSuite) TestEventStartFinish() {
"mtg.telegram_connections:-1|g|#telegram_ip:10.1.0.10,dc:2") "mtg.telegram_connections:-1|g|#telegram_ip:10.1.0.10,dc:2")
suite.Contains(suite.statsdServer.String(), suite.Contains(suite.statsdServer.String(),
"mtg.client_connections:-1|g|#ip_family:ipv4") "mtg.client_connections:-1|g|#ip_family:ipv4")
suite.NotContains(suite.statsdServer.String(), "domain_fronting_traffic")
suite.NotContains(suite.statsdServer.String(), "domain_fronting_connections")
}
func (suite *StatsdTestSuite) TestDomainFrontingPath() {
suite.statsd.EventStart(mtglib.EventStart{
CreatedAt: time.Now(),
ConnID: "connID",
RemoteIP: net.ParseIP("10.0.0.10"),
})
time.Sleep(statsdSleepTime)
suite.Equal("mtg.client_connections:+1|g|#ip_family:ipv4", suite.statsdServer.String())
suite.statsd.EventDomainFronting(mtglib.EventDomainFronting{
CreatedAt: time.Now(),
ConnID: "connID",
})
time.Sleep(statsdSleepTime)
suite.Contains(suite.statsdServer.String(), "mtg.domain_fronting:1|c")
suite.Contains(suite.statsdServer.String(),
`mtg.domain_fronting_connections:+1|g|#ip_family:ipv4`)
suite.statsd.EventTraffic(mtglib.EventTraffic{
CreatedAt: time.Now(),
ConnID: "connID",
Traffic: 30,
IsRead: true,
})
time.Sleep(statsdSleepTime)
suite.Contains(suite.statsdServer.String(),
`mtg.domain_fronting_traffic:30|c|#direction:to_client`)
suite.statsd.EventTraffic(mtglib.EventTraffic{
CreatedAt: time.Now(),
ConnID: "connID",
Traffic: 90,
IsRead: false,
})
time.Sleep(statsdSleepTime)
suite.Contains(suite.statsdServer.String(),
`mtg.domain_fronting_traffic:90|c|#direction:from_client`)
suite.statsd.EventFinish(mtglib.EventFinish{
CreatedAt: time.Now(),
ConnID: "connID",
})
time.Sleep(statsdSleepTime)
suite.Contains(suite.statsdServer.String(),
"mtg.domain_fronting_connections:-1|g|#ip_family:ipv4")
suite.Contains(suite.statsdServer.String(),
"mtg.client_connections:-1|g|#ip_family:ipv4")
suite.NotContains(suite.statsdServer.String(), "telegram_traffic")
suite.NotContains(suite.statsdServer.String(), "telegram_connections")
} }
func (suite *StatsdTestSuite) TestEventConcurrencyLimited() { func (suite *StatsdTestSuite) TestEventConcurrencyLimited() {
+12 -7
View File
@@ -2,15 +2,20 @@ package stats
import statsd "github.com/smira/go-statsd" import statsd "github.com/smira/go-statsd"
type streamInfo map[string]string type streamInfo struct {
isDomainFronted bool
func (s streamInfo) T(key string) statsd.Tag { tags map[string]string
return statsd.StringTag(key, s[key])
} }
func (s streamInfo) Reset() { func (s streamInfo) T(key string) statsd.Tag {
for k := range s { return statsd.StringTag(key, s.tags[key])
delete(s, k) }
func (s *streamInfo) Reset() {
s.isDomainFronted = false
for k := range s.tags {
delete(s.tags, k)
} }
} }