Skip to content

Commit d78829a

Browse files
committed
Add metrics
1 parent 600bf05 commit d78829a

File tree

3 files changed

+41
-21
lines changed

3 files changed

+41
-21
lines changed

metrics/metrics.go

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import (
2121
"time"
2222

2323
onet "github.com/Jigsaw-Code/outline-ss-server/net"
24-
"github.com/oschwald/geoip2-golang"
24+
geoip2 "github.com/oschwald/geoip2-golang"
2525
"github.com/prometheus/client_golang/prometheus"
2626
)
2727

@@ -30,21 +30,25 @@ type ShadowsocksMetrics interface {
3030
GetLocation(net.Addr) (string, error)
3131

3232
SetNumAccessKeys(numKeys int, numPorts int)
33-
AddUDPPacketFromClient(clientLocation, accessKey, status string, clientProxyBytes, proxyTargetBytes int)
34-
AddUDPPacketFromTarget(clientLocation, accessKey, status string, targetProxyBytes, proxyClientBytes int)
33+
34+
// TCP metrics
3535
AddOpenTCPConnection(clientLocation string)
36-
AddClosedTCPConnection(clientLocation, accessKey, status string, data ProxyMetrics, duration time.Duration)
36+
AddClosedTCPConnection(clientLocation, accessKey, status string, data ProxyMetrics, timeToCipher, duration time.Duration)
3737

38-
AddUdpNatEntry()
39-
RemoveUdpNatEntry()
38+
// UDP metrics
39+
AddUDPPacketFromClient(clientLocation, accessKey, status string, clientProxyBytes, proxyTargetBytes int, timeToCipher time.Duration)
40+
AddUDPPacketFromTarget(clientLocation, accessKey, status string, targetProxyBytes, proxyClientBytes int)
41+
AddUDPNatEntry()
42+
RemoveUDPNatEntry()
4043
}
4144

4245
type shadowsocksMetrics struct {
4346
ipCountryDB *geoip2.Reader
4447

45-
accessKeys prometheus.Gauge
46-
ports prometheus.Gauge
47-
dataBytes *prometheus.CounterVec
48+
accessKeys prometheus.Gauge
49+
ports prometheus.Gauge
50+
dataBytes *prometheus.CounterVec
51+
timeToCipherMs *prometheus.SummaryVec
4852
// TODO: Add time to first byte.
4953

5054
tcpOpenConnections *prometheus.CounterVec
@@ -87,14 +91,21 @@ func NewShadowsocksMetrics(ipCountryDB *geoip2.Reader) ShadowsocksMetrics {
8791
Subsystem: "tcp",
8892
Name: "connection_duration_ms",
8993
Help: "TCP connection duration distributions.",
90-
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
94+
Objectives: map[float64]float64{0.5: 0.02, 0.9: 0.01, 0.99: 0.005},
9195
}, []string{"location", "status", "access_key"}),
9296
dataBytes: prometheus.NewCounterVec(
9397
prometheus.CounterOpts{
9498
Namespace: "shadowsocks",
9599
Name: "data_bytes",
96100
Help: "Bytes transferred by the proxy",
97101
}, []string{"dir", "proto", "location", "status", "access_key"}),
102+
timeToCipherMs: prometheus.NewSummaryVec(
103+
prometheus.SummaryOpts{
104+
Namespace: "shadowsocks",
105+
Name: "time_to_cipher_ms",
106+
Help: "Time needed to find the cipher",
107+
Objectives: map[float64]float64{0.5: 0.02, 0.9: 0.01, 0.99: 0.005},
108+
}, []string{"proto", "location", "status", "access_key"}),
98109
udpAddedNatEntries: prometheus.NewCounter(
99110
prometheus.CounterOpts{
100111
Namespace: "shadowsocks",
@@ -112,7 +123,7 @@ func NewShadowsocksMetrics(ipCountryDB *geoip2.Reader) ShadowsocksMetrics {
112123
}
113124
// TODO: Is it possible to pass where to register the collectors?
114125
prometheus.MustRegister(m.accessKeys, m.ports, m.tcpOpenConnections, m.tcpClosedConnections, m.tcpConnectionDurationMs,
115-
m.dataBytes, m.udpAddedNatEntries, m.udpRemovedNatEntries)
126+
m.dataBytes, m.timeToCipherMs, m.udpAddedNatEntries, m.udpRemovedNatEntries)
116127
return m
117128
}
118129

@@ -163,16 +174,18 @@ func (m *shadowsocksMetrics) AddOpenTCPConnection(clientLocation string) {
163174
m.tcpOpenConnections.WithLabelValues(clientLocation).Inc()
164175
}
165176

166-
func (m *shadowsocksMetrics) AddClosedTCPConnection(clientLocation, accessKey, status string, data ProxyMetrics, duration time.Duration) {
177+
func (m *shadowsocksMetrics) AddClosedTCPConnection(clientLocation, accessKey, status string, data ProxyMetrics, timeToCipher, duration time.Duration) {
167178
m.tcpClosedConnections.WithLabelValues(clientLocation, status, accessKey).Inc()
168179
m.tcpConnectionDurationMs.WithLabelValues(clientLocation, status, accessKey).Observe(duration.Seconds() * 1000)
180+
m.timeToCipherMs.WithLabelValues("tcp", clientLocation, status, accessKey).Observe(timeToCipher.Seconds() * 1000)
169181
m.dataBytes.WithLabelValues("c>p", "tcp", clientLocation, status, accessKey).Add(float64(data.ClientProxy))
170182
m.dataBytes.WithLabelValues("p>t", "tcp", clientLocation, status, accessKey).Add(float64(data.ProxyTarget))
171183
m.dataBytes.WithLabelValues("p<t", "tcp", clientLocation, status, accessKey).Add(float64(data.TargetProxy))
172184
m.dataBytes.WithLabelValues("c<p", "tcp", clientLocation, status, accessKey).Add(float64(data.ProxyClient))
173185
}
174186

175-
func (m *shadowsocksMetrics) AddUDPPacketFromClient(clientLocation, accessKey, status string, clientProxyBytes, proxyTargetBytes int) {
187+
func (m *shadowsocksMetrics) AddUDPPacketFromClient(clientLocation, accessKey, status string, clientProxyBytes, proxyTargetBytes int, timeToCipher time.Duration) {
188+
m.timeToCipherMs.WithLabelValues("udp", clientLocation, status, accessKey).Observe(timeToCipher.Seconds() * 1000)
176189
m.dataBytes.WithLabelValues("c>p", "udp", clientLocation, status, accessKey).Add(float64(clientProxyBytes))
177190
m.dataBytes.WithLabelValues("p>t", "udp", clientLocation, status, accessKey).Add(float64(proxyTargetBytes))
178191
}
@@ -182,11 +195,11 @@ func (m *shadowsocksMetrics) AddUDPPacketFromTarget(clientLocation, accessKey, s
182195
m.dataBytes.WithLabelValues("c<p", "udp", clientLocation, status, accessKey).Add(float64(proxyClientBytes))
183196
}
184197

185-
func (m *shadowsocksMetrics) AddUdpNatEntry() {
198+
func (m *shadowsocksMetrics) AddUDPNatEntry() {
186199
m.udpAddedNatEntries.Inc()
187200
}
188201

189-
func (m *shadowsocksMetrics) RemoveUdpNatEntry() {
202+
func (m *shadowsocksMetrics) RemoveUDPNatEntry() {
190203
m.udpRemovedNatEntries.Inc()
191204
}
192205

shadowsocks/tcp.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,21 +173,24 @@ func (s *tcpService) Start() {
173173
clientConn.(*net.TCPConn).SetKeepAlive(true)
174174
keyID := ""
175175
var proxyMetrics metrics.ProxyMetrics
176+
var timeToCipher time.Duration
176177
clientConn = metrics.MeasureConn(clientConn, &proxyMetrics.ProxyClient, &proxyMetrics.ClientProxy)
177178
defer func() {
178-
connEnd := time.Now()
179-
connDuration := connEnd.Sub(connStart)
179+
connDuration := time.Now().Sub(connStart)
180180
clientConn.Close()
181181
status := "OK"
182182
if connError != nil {
183183
logger.Debugf("TCP Error: %v: %v", connError.Message, connError.Cause)
184184
status = connError.Status
185185
}
186186
logger.Debugf("Done with status %v, duration %v", status, connDuration)
187-
s.m.AddClosedTCPConnection(clientLocation, keyID, status, proxyMetrics, connDuration)
187+
s.m.AddClosedTCPConnection(clientLocation, keyID, status, proxyMetrics, timeToCipher, connDuration)
188188
}()
189189

190+
findStartTime := time.Now()
190191
keyID, clientConn, err := findAccessKey(clientConn, *s.ciphers)
192+
timeToCipher = time.Now().Sub(findStartTime)
193+
191194
if err != nil {
192195
return onet.NewConnectionError("ERR_CIPHER", "Failed to find a valid cipher", err)
193196
}

shadowsocks/udp.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,14 @@ func (s *udpService) Start() {
9797
clientLocation := ""
9898
keyID := ""
9999
var clientProxyBytes, proxyTargetBytes int
100+
var timeToCipher time.Duration
100101
defer func() {
101102
status := "OK"
102103
if connError != nil {
103104
logger.Debugf("UDP Error: %v: %v", connError.Message, connError.Cause)
104105
status = connError.Status
105106
}
106-
s.m.AddUDPPacketFromClient(clientLocation, keyID, status, clientProxyBytes, proxyTargetBytes)
107+
s.m.AddUDPPacketFromClient(clientLocation, keyID, status, clientProxyBytes, proxyTargetBytes, timeToCipher)
107108
}()
108109
clientProxyBytes, clientAddr, err := s.clientConn.ReadFrom(cipherBuf)
109110
if err != nil {
@@ -119,7 +120,10 @@ func (s *udpService) Start() {
119120
logger.Debugf("Got location \"%v\" for IP %v", clientLocation, clientAddr.String())
120121
defer logger.Debugf("UDP done with %v", clientAddr.String())
121122
logger.Debugf("UDP Request from %v with %v bytes", clientAddr, clientProxyBytes)
123+
unpackStart := time.Now()
122124
buf, keyID, cipher, err := unpack(textBuf, cipherBuf[:clientProxyBytes], *s.ciphers)
125+
timeToCipher = time.Now().Sub(unpackStart)
126+
123127
if err != nil {
124128
return onet.NewConnectionError("ERR_CIPHER", "Failed to upack data from client", err)
125129
}
@@ -206,10 +210,10 @@ func (m *natmap) del(key string) net.PacketConn {
206210
func (m *natmap) Add(clientAddr net.Addr, clientConn net.PacketConn, cipher shadowaead.Cipher, targetConn net.PacketConn, clientLocation, keyID string) {
207211
m.set(clientAddr.String(), targetConn)
208212

209-
m.metrics.AddUdpNatEntry()
213+
m.metrics.AddUDPNatEntry()
210214
go func() {
211215
timedCopy(clientAddr, clientConn, cipher, targetConn, m.timeout, clientLocation, keyID, m.metrics)
212-
m.metrics.RemoveUdpNatEntry()
216+
m.metrics.RemoveUDPNatEntry()
213217
if pc := m.del(clientAddr.String()); pc != nil {
214218
pc.Close()
215219
}

0 commit comments

Comments
 (0)