mirror of
https://github.com/ScuroNeko/mtg.git
synced 2026-08-31 20:14:01 +03:00
Reset a project
This commit is contained in:
@@ -1,60 +0,0 @@
|
||||
package stats
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/9seconds/mtg/conntypes"
|
||||
)
|
||||
|
||||
type IngressTrafficInterface interface {
|
||||
IngressTraffic(int)
|
||||
}
|
||||
|
||||
type EgressTrafficInterface interface {
|
||||
EgressTraffic(int)
|
||||
}
|
||||
|
||||
type ClientConnectedInterface interface {
|
||||
ClientConnected(conntypes.ConnectionType, *net.TCPAddr)
|
||||
}
|
||||
|
||||
type ClientDisconnectedInterface interface {
|
||||
ClientDisconnected(conntypes.ConnectionType, *net.TCPAddr)
|
||||
}
|
||||
|
||||
type TelegramConnectedInterface interface {
|
||||
TelegramConnected(conntypes.DC, *net.TCPAddr)
|
||||
}
|
||||
|
||||
type TelegramDisconnectedInterface interface {
|
||||
TelegramDisconnected(conntypes.DC, *net.TCPAddr)
|
||||
}
|
||||
|
||||
type CrashInterface interface {
|
||||
Crash()
|
||||
}
|
||||
|
||||
type ReplayDetectedInterface interface {
|
||||
ReplayDetected()
|
||||
}
|
||||
|
||||
type AuthenticationFailedInterface interface {
|
||||
AuthenticationFailed()
|
||||
}
|
||||
|
||||
type CloakedRequestInterface interface {
|
||||
CloakedRequest()
|
||||
}
|
||||
|
||||
type Interface interface {
|
||||
IngressTrafficInterface
|
||||
EgressTrafficInterface
|
||||
ClientConnectedInterface
|
||||
ClientDisconnectedInterface
|
||||
TelegramConnectedInterface
|
||||
TelegramDisconnectedInterface
|
||||
CrashInterface
|
||||
ReplayDetectedInterface
|
||||
AuthenticationFailedInterface
|
||||
CloakedRequestInterface
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
package stats
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/9seconds/mtg/conntypes"
|
||||
)
|
||||
|
||||
type multiStats []Interface
|
||||
|
||||
func (m multiStats) IngressTraffic(traffic int) {
|
||||
for i := range m {
|
||||
go m[i].IngressTraffic(traffic)
|
||||
}
|
||||
}
|
||||
|
||||
func (m multiStats) EgressTraffic(traffic int) {
|
||||
for i := range m {
|
||||
go m[i].EgressTraffic(traffic)
|
||||
}
|
||||
}
|
||||
|
||||
func (m multiStats) ClientConnected(connectionType conntypes.ConnectionType, addr *net.TCPAddr) {
|
||||
for i := range m {
|
||||
go m[i].ClientConnected(connectionType, addr)
|
||||
}
|
||||
}
|
||||
|
||||
func (m multiStats) ClientDisconnected(connectionType conntypes.ConnectionType, addr *net.TCPAddr) {
|
||||
for i := range m {
|
||||
go m[i].ClientDisconnected(connectionType, addr)
|
||||
}
|
||||
}
|
||||
|
||||
func (m multiStats) TelegramConnected(dc conntypes.DC, addr *net.TCPAddr) {
|
||||
for i := range m {
|
||||
go m[i].TelegramConnected(dc, addr)
|
||||
}
|
||||
}
|
||||
|
||||
func (m multiStats) TelegramDisconnected(dc conntypes.DC, addr *net.TCPAddr) {
|
||||
for i := range m {
|
||||
go m[i].TelegramDisconnected(dc, addr)
|
||||
}
|
||||
}
|
||||
|
||||
func (m multiStats) Crash() {
|
||||
for i := range m {
|
||||
go m[i].Crash()
|
||||
}
|
||||
}
|
||||
|
||||
func (m multiStats) ReplayDetected() {
|
||||
for i := range m {
|
||||
go m[i].ReplayDetected()
|
||||
}
|
||||
}
|
||||
|
||||
func (m multiStats) AuthenticationFailed() {
|
||||
for i := range m {
|
||||
go m[i].AuthenticationFailed()
|
||||
}
|
||||
}
|
||||
|
||||
func (m multiStats) CloakedRequest() {
|
||||
for i := range m {
|
||||
go m[i].CloakedRequest()
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
package stats
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
"github.com/9seconds/mtg/config"
|
||||
)
|
||||
|
||||
var Stats Interface
|
||||
|
||||
func Init(ctx context.Context) error {
|
||||
mux := http.NewServeMux()
|
||||
|
||||
stats := []Interface{newStatsPrometheus(mux)}
|
||||
if config.C.StatsdAddr != nil {
|
||||
stats = append(stats, newStatsStatsd())
|
||||
}
|
||||
|
||||
listener, err := net.Listen("tcp", config.C.StatsBind.String())
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot initialize stats server: %w", err)
|
||||
}
|
||||
|
||||
srv := http.Server{
|
||||
Handler: mux,
|
||||
}
|
||||
|
||||
go srv.Serve(listener) // nolint: errcheck
|
||||
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
srv.Shutdown(context.Background()) // nolint: errcheck
|
||||
}()
|
||||
|
||||
Stats = multiStats(stats)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,156 +0,0 @@
|
||||
package stats
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/9seconds/mtg/config"
|
||||
"github.com/9seconds/mtg/conntypes"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
)
|
||||
|
||||
type statsPrometheus struct {
|
||||
connections *prometheus.GaugeVec
|
||||
telegramConnections *prometheus.GaugeVec
|
||||
traffic *prometheus.GaugeVec
|
||||
crashes prometheus.Counter
|
||||
replayAttacks prometheus.Counter
|
||||
authenticationFailed prometheus.Counter
|
||||
cloakedRequests prometheus.Counter
|
||||
}
|
||||
|
||||
func (s *statsPrometheus) IngressTraffic(traffic int) {
|
||||
s.traffic.WithLabelValues("ingress").Add(float64(traffic))
|
||||
}
|
||||
|
||||
func (s *statsPrometheus) EgressTraffic(traffic int) {
|
||||
s.traffic.WithLabelValues("egress").Add(float64(traffic))
|
||||
}
|
||||
|
||||
func (s *statsPrometheus) ClientConnected(connectionType conntypes.ConnectionType, addr *net.TCPAddr) {
|
||||
s.changeConnections(connectionType, addr, 1.0)
|
||||
}
|
||||
|
||||
func (s *statsPrometheus) ClientDisconnected(connectionType conntypes.ConnectionType, addr *net.TCPAddr) {
|
||||
s.changeConnections(connectionType, addr, -1.0)
|
||||
}
|
||||
|
||||
func (s *statsPrometheus) changeConnections(connectionType conntypes.ConnectionType,
|
||||
addr *net.TCPAddr,
|
||||
increment float64) {
|
||||
labels := [...]string{
|
||||
"intermediate",
|
||||
"ipv4",
|
||||
}
|
||||
|
||||
switch connectionType {
|
||||
case conntypes.ConnectionTypeAbridged:
|
||||
labels[0] = "abridged"
|
||||
case conntypes.ConnectionTypeSecure:
|
||||
labels[0] = "secured"
|
||||
case conntypes.ConnectionTypeIntermediate:
|
||||
labels[0] = "intermediate"
|
||||
case conntypes.ConnectionTypeUnknown:
|
||||
panic("unknown connection type")
|
||||
}
|
||||
|
||||
if addr.IP.To4() == nil {
|
||||
labels[1] = "ipv6"
|
||||
}
|
||||
|
||||
s.connections.WithLabelValues(labels[:]...).Add(increment)
|
||||
}
|
||||
|
||||
func (s *statsPrometheus) TelegramConnected(dc conntypes.DC, addr *net.TCPAddr) {
|
||||
s.changeTelegramConnections(dc, addr, 1.0)
|
||||
}
|
||||
|
||||
func (s *statsPrometheus) TelegramDisconnected(dc conntypes.DC, addr *net.TCPAddr) {
|
||||
s.changeTelegramConnections(dc, addr, -1.0)
|
||||
}
|
||||
|
||||
func (s *statsPrometheus) changeTelegramConnections(dc conntypes.DC, addr *net.TCPAddr, increment float64) {
|
||||
labels := [...]string{
|
||||
strconv.Itoa(int(dc)),
|
||||
"ipv4",
|
||||
}
|
||||
|
||||
if addr.IP.To4() == nil {
|
||||
labels[1] = "ipv6"
|
||||
}
|
||||
|
||||
s.telegramConnections.WithLabelValues(labels[:]...).Add(increment)
|
||||
}
|
||||
|
||||
func (s *statsPrometheus) Crash() {
|
||||
s.crashes.Inc()
|
||||
}
|
||||
|
||||
func (s *statsPrometheus) ReplayDetected() {
|
||||
s.replayAttacks.Inc()
|
||||
}
|
||||
|
||||
func (s *statsPrometheus) AuthenticationFailed() {
|
||||
s.authenticationFailed.Inc()
|
||||
}
|
||||
|
||||
func (s *statsPrometheus) CloakedRequest() {
|
||||
s.cloakedRequests.Inc()
|
||||
}
|
||||
|
||||
func newStatsPrometheus(mux *http.ServeMux) Interface {
|
||||
registry := prometheus.NewPedanticRegistry()
|
||||
|
||||
instance := &statsPrometheus{
|
||||
connections: prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
||||
Namespace: config.C.StatsNamespace,
|
||||
Name: "connections",
|
||||
Help: "Current number of client connections to the proxy.",
|
||||
}, []string{"type", "protocol"}),
|
||||
telegramConnections: prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
||||
Namespace: config.C.StatsNamespace,
|
||||
Name: "telegram_connections",
|
||||
Help: "Current number of telegram connections established by this proxy.",
|
||||
}, []string{"dc", "protocol"}),
|
||||
traffic: prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
||||
Namespace: config.C.StatsNamespace,
|
||||
Name: "traffic",
|
||||
Help: "Traffic passed through the proxy in bytes.",
|
||||
}, []string{"direction"}),
|
||||
crashes: prometheus.NewCounter(prometheus.CounterOpts{
|
||||
Namespace: config.C.StatsNamespace,
|
||||
Name: "crashes",
|
||||
Help: "How many crashes happened.",
|
||||
}),
|
||||
replayAttacks: prometheus.NewCounter(prometheus.CounterOpts{
|
||||
Namespace: config.C.StatsNamespace,
|
||||
Name: "replay_attacks",
|
||||
Help: "How many replay attacks were prevented.",
|
||||
}),
|
||||
authenticationFailed: prometheus.NewCounter(prometheus.CounterOpts{
|
||||
Namespace: config.C.StatsNamespace,
|
||||
Name: "authentication_failed",
|
||||
Help: "How many authentication failed events we've seen.",
|
||||
}),
|
||||
cloakedRequests: prometheus.NewCounter(prometheus.CounterOpts{
|
||||
Namespace: config.C.StatsNamespace,
|
||||
Name: "cloaked_requests",
|
||||
Help: "How many requests were proxified during cloaking.",
|
||||
}),
|
||||
}
|
||||
|
||||
registry.MustRegister(instance.connections)
|
||||
registry.MustRegister(instance.telegramConnections)
|
||||
registry.MustRegister(instance.traffic)
|
||||
registry.MustRegister(instance.crashes)
|
||||
registry.MustRegister(instance.replayAttacks)
|
||||
registry.MustRegister(instance.authenticationFailed)
|
||||
registry.MustRegister(instance.cloakedRequests)
|
||||
|
||||
handler := promhttp.HandlerFor(registry, promhttp.HandlerOpts{})
|
||||
mux.Handle("/", handler)
|
||||
|
||||
return instance
|
||||
}
|
||||
@@ -1,204 +0,0 @@
|
||||
package stats
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/9seconds/mtg/config"
|
||||
"github.com/9seconds/mtg/conntypes"
|
||||
statsd "github.com/smira/go-statsd"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
var (
|
||||
tagTrafficIngress = &statsStatsdTag{
|
||||
name: "ingress",
|
||||
tag: statsd.StringTag("type", "ingress"),
|
||||
}
|
||||
tagTrafficEgress = &statsStatsdTag{
|
||||
name: "egress",
|
||||
tag: statsd.StringTag("type", "egress"),
|
||||
}
|
||||
|
||||
tagConnectionTypeAbridged = &statsStatsdTag{
|
||||
name: "abridged",
|
||||
tag: statsd.StringTag("type", "abridged"),
|
||||
}
|
||||
tagConnectionTypeIntermediate = &statsStatsdTag{
|
||||
name: "intermediate",
|
||||
tag: statsd.StringTag("type", "intermediate"),
|
||||
}
|
||||
tagConnectionTypeSecured = &statsStatsdTag{
|
||||
name: "secured",
|
||||
tag: statsd.StringTag("type", "secured"),
|
||||
}
|
||||
|
||||
tagConnectionProtocol4 = &statsStatsdTag{
|
||||
name: "ipv4",
|
||||
tag: statsd.StringTag("protocol", "ipv4"),
|
||||
}
|
||||
tagConnectionProtocol6 = &statsStatsdTag{
|
||||
name: "ipv6",
|
||||
tag: statsd.StringTag("protocol", "ipv6"),
|
||||
}
|
||||
)
|
||||
|
||||
type statsStatsdTag struct {
|
||||
tag statsd.Tag
|
||||
name string
|
||||
}
|
||||
|
||||
type statsStatsdLogger struct {
|
||||
log *zap.SugaredLogger
|
||||
}
|
||||
|
||||
func (s statsStatsdLogger) Printf(msg string, args ...interface{}) {
|
||||
s.log.Debugw(fmt.Sprintf(msg, args...))
|
||||
}
|
||||
|
||||
type statsStatsd struct {
|
||||
seen map[string]struct{}
|
||||
seenMutex sync.RWMutex
|
||||
client *statsd.Client
|
||||
}
|
||||
|
||||
func (s *statsStatsd) IngressTraffic(traffic int) {
|
||||
s.gauge("traffic", int64(traffic), tagTrafficIngress)
|
||||
}
|
||||
|
||||
func (s *statsStatsd) EgressTraffic(traffic int) {
|
||||
s.gauge("traffic", int64(traffic), tagTrafficEgress)
|
||||
}
|
||||
|
||||
func (s *statsStatsd) ClientConnected(connectionType conntypes.ConnectionType, addr *net.TCPAddr) {
|
||||
s.changeConnections(connectionType, addr, 1)
|
||||
}
|
||||
|
||||
func (s *statsStatsd) ClientDisconnected(connectionType conntypes.ConnectionType, addr *net.TCPAddr) {
|
||||
s.changeConnections(connectionType, addr, -1)
|
||||
}
|
||||
|
||||
func (s *statsStatsd) changeConnections(connectionType conntypes.ConnectionType, addr *net.TCPAddr, increment int64) {
|
||||
tags := make([]*statsStatsdTag, 0, 2)
|
||||
|
||||
switch connectionType {
|
||||
case conntypes.ConnectionTypeAbridged:
|
||||
tags = append(tags, tagConnectionTypeAbridged)
|
||||
case conntypes.ConnectionTypeIntermediate:
|
||||
tags = append(tags, tagConnectionTypeIntermediate)
|
||||
case conntypes.ConnectionTypeSecure:
|
||||
tags = append(tags, tagConnectionTypeSecured)
|
||||
case conntypes.ConnectionTypeUnknown:
|
||||
panic("Unknown connection type")
|
||||
}
|
||||
|
||||
if addr.IP.To4() == nil {
|
||||
tags = append(tags, tagConnectionProtocol6)
|
||||
} else {
|
||||
tags = append(tags, tagConnectionProtocol4)
|
||||
}
|
||||
|
||||
s.gauge("connections", increment, tags...)
|
||||
}
|
||||
|
||||
func (s *statsStatsd) TelegramConnected(dc conntypes.DC, addr *net.TCPAddr) {
|
||||
s.changeTelegramConnections(dc, addr, 1)
|
||||
}
|
||||
|
||||
func (s *statsStatsd) TelegramDisconnected(dc conntypes.DC, addr *net.TCPAddr) {
|
||||
s.changeTelegramConnections(dc, addr, -1)
|
||||
}
|
||||
|
||||
func (s *statsStatsd) changeTelegramConnections(dc conntypes.DC, addr *net.TCPAddr, increment int64) {
|
||||
tags := []*statsStatsdTag{
|
||||
{
|
||||
name: "dc" + strconv.Itoa(int(dc)),
|
||||
tag: statsd.IntTag("dc", int(dc)),
|
||||
},
|
||||
}
|
||||
|
||||
if addr.IP.To4() == nil {
|
||||
tags = append(tags, tagConnectionProtocol6)
|
||||
} else {
|
||||
tags = append(tags, tagConnectionProtocol4)
|
||||
}
|
||||
|
||||
s.gauge("telegram_connections", increment, tags...)
|
||||
}
|
||||
|
||||
func (s *statsStatsd) Crash() {
|
||||
s.gauge("crashes", 1)
|
||||
}
|
||||
|
||||
func (s *statsStatsd) ReplayDetected() {
|
||||
s.gauge("replay_attacks", 1)
|
||||
}
|
||||
|
||||
func (s *statsStatsd) AuthenticationFailed() {
|
||||
s.gauge("authentication_failed", 1)
|
||||
}
|
||||
|
||||
func (s *statsStatsd) CloakedRequest() {
|
||||
s.gauge("cloaked_requests", 1)
|
||||
}
|
||||
|
||||
func (s *statsStatsd) gauge(metric string, value int64, tags ...*statsStatsdTag) {
|
||||
key, tagList := s.prepareVals(metric, tags)
|
||||
s.initGauge(metric, key, tagList)
|
||||
s.client.GaugeDelta(metric, value, tagList...)
|
||||
}
|
||||
|
||||
func (s *statsStatsd) prepareVals(metric string, tags []*statsStatsdTag) (string, []statsd.Tag) {
|
||||
tagList := make([]statsd.Tag, len(tags))
|
||||
builder := strings.Builder{}
|
||||
builder.WriteString(metric)
|
||||
|
||||
for i, v := range tags {
|
||||
builder.WriteRune('.')
|
||||
builder.WriteString(v.name)
|
||||
tagList[i] = v.tag
|
||||
}
|
||||
|
||||
return builder.String(), tagList
|
||||
}
|
||||
|
||||
func (s *statsStatsd) initGauge(metric, key string, tags []statsd.Tag) {
|
||||
s.seenMutex.RLock()
|
||||
if _, ok := s.seen[key]; ok {
|
||||
s.seenMutex.RUnlock()
|
||||
|
||||
return
|
||||
} else { // nolint: golint,revive
|
||||
s.seenMutex.RUnlock()
|
||||
}
|
||||
|
||||
s.seenMutex.Lock()
|
||||
defer s.seenMutex.Unlock()
|
||||
|
||||
if _, ok := s.seen[key]; !ok {
|
||||
s.seen[key] = struct{}{}
|
||||
s.client.Gauge(metric, 0, tags...)
|
||||
}
|
||||
}
|
||||
|
||||
func newStatsStatsd() Interface {
|
||||
prefix := strings.TrimSuffix(config.C.StatsNamespace, ".") + "."
|
||||
logger := statsStatsdLogger{
|
||||
log: zap.S().Named("stats").Named("statsd"),
|
||||
}
|
||||
|
||||
return &statsStatsd{
|
||||
seen: make(map[string]struct{}),
|
||||
client: statsd.NewClient(config.C.StatsdAddr.String(),
|
||||
statsd.SendLoopCount(2),
|
||||
statsd.ReconnectInterval(10*time.Second),
|
||||
statsd.Logger(logger),
|
||||
statsd.MetricPrefix(prefix),
|
||||
statsd.TagStyle(config.C.StatsdTagsFormat),
|
||||
),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user