mirror of
https://github.com/ScuroNeko/mtg.git
synced 2026-08-31 18:44:02 +03:00
Add support of EventDomainFronting event
This commit is contained in:
@@ -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:
|
||||||
|
|||||||
@@ -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(),
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
@@ -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) {}
|
||||||
|
|||||||
@@ -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
@@ -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 {
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
+46
-16
@@ -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)).
|
|
||||||
|
if info.isDomainFronted {
|
||||||
|
p.factory.metricDomainFrontingTraffic.
|
||||||
|
WithLabelValues(direction).
|
||||||
Add(float64(evt.Traffic))
|
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{
|
||||||
|
|||||||
@@ -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(),
|
||||||
|
|||||||
+34
-8
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
directionTag := statsd.StringTag(TagDirection, getDirection(evt.IsRead))
|
||||||
|
|
||||||
|
if info.isDomainFronted {
|
||||||
|
s.client.Incr(MetricDomainFrontingTraffic,
|
||||||
|
int64(evt.Traffic),
|
||||||
|
directionTag)
|
||||||
|
} else {
|
||||||
s.client.Incr(MetricTelegramTraffic,
|
s.client.Incr(MetricTelegramTraffic,
|
||||||
int64(evt.Traffic),
|
int64(evt.Traffic),
|
||||||
info.T(TagTelegramIP),
|
info.T(TagTelegramIP),
|
||||||
info.T(TagDC),
|
info.T(TagDC),
|
||||||
statsd.StringTag(TagDirection, getDirection(evt.IsRead)))
|
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
@@ -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
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user