Skip to content

Commit

Permalink
Add TLS upstream and TLS server_zone metrics (#470)
Browse files Browse the repository at this point in the history
  • Loading branch information
Dean-Coakley authored Sep 12, 2023
1 parent 9a61fc7 commit a9728fe
Show file tree
Hide file tree
Showing 5 changed files with 198 additions and 86 deletions.
6 changes: 6 additions & 0 deletions src/core/metrics/metrics_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,9 @@ func GetCalculationMap() map[string]string {
"plus.http.status.3xx": "sum",
"plus.http.status.4xx": "sum",
"plus.http.status.5xx": "sum",
"plus.http.ssl.handshakes": "sum",
"plus.http.ssl.handshakes.failed": "sum",
"plus.http.ssl.session.reuses": "sum",
"plus.http.status.discarded": "sum",
"plus.http.status.processing": "avg",
"plus.stream.bytes_rcvd": "sum",
Expand Down Expand Up @@ -312,6 +315,9 @@ func GetCalculationMap() map[string]string {
"plus.http.upstream.peers.response.time.pctl95": "avg",
"plus.http.upstream.peers.request.count": "sum",
"plus.http.upstream.peers.response.count": "sum",
"plus.http.upstream.peers.ssl.handshakes": "sum",
"plus.http.upstream.peers.ssl.handshakes.failed": "sum",
"plus.http.upstream.peers.ssl.session.reuses": "sum",
"plus.http.upstream.peers.status.1xx": "sum",
"plus.http.upstream.peers.status.2xx": "sum",
"plus.http.upstream.peers.status.3xx": "sum",
Expand Down
49 changes: 38 additions & 11 deletions src/core/metrics/sources/nginx_plus.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,19 +257,34 @@ func (c *NginxPlus) serverZoneMetrics(stats, prevStats *plusclient.Stats) []*met
if sz.Responses.Responses5xx < prevStats.ServerZones[name].Responses.Responses5xx {
status5xx = sz.Responses.Responses5xx
}
handshakes := sz.SSL.Handshakes - prevStats.ServerZones[name].SSL.Handshakes
if sz.SSL.Handshakes < prevStats.ServerZones[name].SSL.Handshakes {
handshakes = sz.SSL.Handshakes
}
handshakesFailed := sz.SSL.HandshakesFailed - prevStats.ServerZones[name].SSL.HandshakesFailed
if sz.SSL.HandshakesFailed < prevStats.ServerZones[name].SSL.HandshakesFailed {
handshakesFailed = sz.SSL.Handshakes
}
sessionReuses := sz.SSL.SessionReuses - prevStats.ServerZones[name].SSL.SessionReuses
if sz.SSL.SessionReuses < prevStats.ServerZones[name].SSL.SessionReuses {
sessionReuses = sz.SSL.SessionReuses
}

simpleMetrics := l.convertSamplesToSimpleMetrics(map[string]float64{
"request.count": float64(requestCount),
"response.count": float64(responseCount),
"status.discarded": float64(statusDiscarded),
"status.processing": float64(sz.Processing),
"request.bytes_rcvd": float64(requestBytesRcvd),
"request.bytes_sent": float64(requestBytesSent),
"status.1xx": float64(status1xx),
"status.2xx": float64(status2xx),
"status.3xx": float64(status3xx),
"status.4xx": float64(status4xx),
"status.5xx": float64(status5xx),
"request.count": float64(requestCount),
"response.count": float64(responseCount),
"status.discarded": float64(statusDiscarded),
"status.processing": float64(sz.Processing),
"request.bytes_rcvd": float64(requestBytesRcvd),
"request.bytes_sent": float64(requestBytesSent),
"status.1xx": float64(status1xx),
"status.2xx": float64(status2xx),
"status.3xx": float64(status3xx),
"status.4xx": float64(status4xx),
"status.5xx": float64(status5xx),
"ssl.handshakes": float64(handshakes),
"ssl.handshakes.failed": float64(handshakesFailed),
"ssl.session.reuses": float64(sessionReuses),
})

dims := c.baseDimensions.ToDimensions()
Expand Down Expand Up @@ -425,6 +440,15 @@ func (c *NginxPlus) httpUpstreamMetrics(stats, prevStats *plusclient.Stats) []*m
if peer.Responses.Total >= prevPeer.Responses.Total {
tempPeer.Responses.Total = peer.Responses.Total - prevPeer.Responses.Total
}
if peer.SSL.Handshakes >= prevPeer.SSL.Handshakes {
tempPeer.SSL.Handshakes = peer.SSL.Handshakes - prevPeer.SSL.Handshakes
}
if peer.SSL.HandshakesFailed >= prevPeer.SSL.HandshakesFailed {
tempPeer.SSL.HandshakesFailed = peer.SSL.HandshakesFailed - prevPeer.SSL.HandshakesFailed
}
if peer.SSL.SessionReuses >= prevPeer.SSL.SessionReuses {
tempPeer.SSL.SessionReuses = peer.SSL.SessionReuses - prevPeer.SSL.SessionReuses
}
if peer.Responses.Responses1xx >= prevPeer.Responses.Responses1xx {
tempPeer.Responses.Responses1xx = peer.Responses.Responses1xx - prevPeer.Responses.Responses1xx
}
Expand Down Expand Up @@ -472,6 +496,9 @@ func (c *NginxPlus) httpUpstreamMetrics(stats, prevStats *plusclient.Stats) []*m
"upstream.peers.response.time": float64(tempPeer.ResponseTime),
"upstream.peers.request.count": float64(tempPeer.Requests),
"upstream.peers.response.count": float64(tempPeer.Responses.Total),
"upstream.peers.ssl.handshakes": float64(tempPeer.SSL.Handshakes),
"upstream.peers.ssl.handshakes.failed": float64(tempPeer.SSL.HandshakesFailed),
"upstream.peers.ssl.session.reuses": float64(tempPeer.SSL.SessionReuses),
"upstream.peers.status.1xx": float64(tempPeer.Responses.Responses1xx),
"upstream.peers.status.2xx": float64(tempPeer.Responses.Responses2xx),
"upstream.peers.status.3xx": float64(tempPeer.Responses.Responses3xx),
Expand Down
174 changes: 110 additions & 64 deletions src/core/metrics/sources/nginx_plus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ const (
cacheMiss = 1
cacheHitBytes = 5024
cacheMissBytes = 1256
currentSSLHandshakes = 5
currentSSLHandshakesFailed = 5
currentSSLSessionReuses = 5
previousSSLHandshakes = 5
previousSSLHandshakesFailed = 5
previousSSLSessionReuses = 5
upstreamQueueMaxSize = 20
currentPeer1UpstreamHeaderTime = 100
currentPeer2UpstreamHeaderTime = 80
Expand Down Expand Up @@ -101,6 +107,11 @@ func (f *FakeNginxPlus) Collect(ctx context.Context, wg *sync.WaitGroup, m chan<
Discarded: 0,
Received: currentZoneReceived,
Sent: currentZoneSent,
SSL: plusclient.SSL{
Handshakes: currentSSLHandshakes,
HandshakesFailed: currentSSLHandshakesFailed,
SessionReuses: currentSSLSessionReuses,
},
},
},
StreamServerZones: plusclient.StreamServerZones{
Expand Down Expand Up @@ -181,12 +192,17 @@ func (f *FakeNginxPlus) Collect(ctx context.Context, wg *sync.WaitGroup, m chan<
upstreamName: plusclient.Upstream{
Peers: []plusclient.Peer{
{
ID: 0,
Server: upstreamPeer1ServerAddress,
Name: upstreamPeer1Name,
Backup: false,
Weight: 1,
State: "up",
ID: 0,
Server: upstreamPeer1ServerAddress,
Name: upstreamPeer1Name,
Backup: false,
Weight: 1,
State: "up",
SSL: plusclient.SSL{
Handshakes: currentSSLHandshakes,
HandshakesFailed: currentSSLHandshakesFailed,
SessionReuses: currentSSLSessionReuses,
},
Requests: currentZoneRequests,
Responses: plusclient.Responses{
Responses1xx: 0,
Expand All @@ -210,12 +226,17 @@ func (f *FakeNginxPlus) Collect(ctx context.Context, wg *sync.WaitGroup, m chan<
ResponseTime: currentPeer1UpstreamResponseTime,
},
{
ID: 1,
Server: upstreamPeer2ServerAddress,
Name: upstreamPeer2Name,
Backup: false,
Weight: 1,
State: "up",
ID: 1,
Server: upstreamPeer2ServerAddress,
Name: upstreamPeer2Name,
Backup: false,
Weight: 1,
State: "up",
SSL: plusclient.SSL{
Handshakes: currentSSLHandshakes,
HandshakesFailed: currentSSLHandshakesFailed,
SessionReuses: currentSSLSessionReuses,
},
Requests: currentZoneRequests,
Responses: plusclient.Responses{
Responses1xx: 0,
Expand Down Expand Up @@ -353,6 +374,11 @@ func (f *FakeNginxPlus) Collect(ctx context.Context, wg *sync.WaitGroup, m chan<
Discarded: 0,
Received: previousZoneReceived,
Sent: previousZoneSent,
SSL: plusclient.SSL{
Handshakes: previousSSLHandshakes,
HandshakesFailed: previousSSLHandshakesFailed,
SessionReuses: previousSSLSessionReuses,
},
},
},
LocationZones: plusclient.LocationZones{
Expand All @@ -375,12 +401,51 @@ func (f *FakeNginxPlus) Collect(ctx context.Context, wg *sync.WaitGroup, m chan<
upstreamName: plusclient.Upstream{
Peers: []plusclient.Peer{
{
ID: 0,
Server: upstreamPeer2ServerAddress,
Name: upstreamPeer2Name,
Backup: false,
Weight: 1,
State: "up",
ID: 0,
Server: upstreamPeer1ServerAddress,
Name: upstreamPeer1Name,
Backup: false,
Weight: 1,
State: "up",
SSL: plusclient.SSL{
Handshakes: previousSSLHandshakes,
HandshakesFailed: previousSSLHandshakesFailed,
SessionReuses: previousSSLSessionReuses,
},
Requests: previousZoneRequests,
Responses: plusclient.Responses{
Responses1xx: 0,
Responses2xx: previousZoneResponses,
Responses3xx: 0,
Responses4xx: 0,
Responses5xx: 0,
Total: previousZoneResponses,
},
Sent: previousZoneSent,
Received: previousZoneReceived,
Fails: 0,
Unavail: 0,
HealthChecks: plusclient.HealthChecks{
Checks: 0,
Fails: 0,
Unhealthy: 0,
LastPassed: false,
},
HeaderTime: previousUpstreamHeaderTime,
ResponseTime: previousUpstreamResponseTime,
},
{
ID: 1,
Server: upstreamPeer2ServerAddress,
Name: upstreamPeer2Name,
Backup: false,
Weight: 1,
State: "up",
SSL: plusclient.SSL{
Handshakes: previousSSLHandshakes,
HandshakesFailed: previousSSLHandshakesFailed,
SessionReuses: previousSSLSessionReuses,
},
Requests: previousZoneRequests,
Responses: plusclient.Responses{
Responses1xx: 0,
Expand Down Expand Up @@ -482,17 +547,20 @@ func TestNginxPlus_Collect(t *testing.T) {
}

expectedServerZoneMetrics := map[string]float64{
"plus.http.request.count": currentZoneRequests - previousZoneRequests,
"plus.http.response.count": currentZoneResponses - previousZoneResponses,
"plus.http.status.discarded": 0,
"plus.http.status.processing": 0,
"plus.http.request.bytes_rcvd": currentZoneReceived - previousZoneReceived,
"plus.http.request.bytes_sent": currentZoneSent - previousZoneSent,
"plus.http.status.1xx": 0,
"plus.http.status.2xx": currentZoneResponses - previousZoneResponses,
"plus.http.status.3xx": 0,
"plus.http.status.4xx": 0,
"plus.http.status.5xx": 0,
"plus.http.request.count": currentZoneRequests - previousZoneRequests,
"plus.http.response.count": currentZoneResponses - previousZoneResponses,
"plus.http.status.discarded": 0,
"plus.http.status.processing": 0,
"plus.http.request.bytes_rcvd": currentZoneReceived - previousZoneReceived,
"plus.http.request.bytes_sent": currentZoneSent - previousZoneSent,
"plus.http.status.1xx": 0,
"plus.http.status.2xx": currentZoneResponses - previousZoneResponses,
"plus.http.status.3xx": 0,
"plus.http.status.4xx": 0,
"plus.http.status.5xx": 0,
"plus.http.ssl.handshakes": currentSSLHandshakes - previousSSLHandshakes,
"plus.http.ssl.handshakes.failed": currentSSLHandshakesFailed - previousSSLHandshakesFailed,
"plus.http.ssl.session.reuses": currentSSLSessionReuses - previousSSLSessionReuses,
}

expectedStreamServerZoneMetrics := map[string]float64{
Expand Down Expand Up @@ -565,15 +633,15 @@ func TestNginxPlus_Collect(t *testing.T) {
"plus.http.upstream.peers.conn.active": 0,
"plus.http.upstream.peers.header_time": currentPeer1UpstreamHeaderTime,
"plus.http.upstream.peers.response.time": currentPeer1UpstreamResponseTime,
"plus.http.upstream.peers.request.count": currentZoneRequests,
"plus.http.upstream.peers.response.count": currentZoneResponses,
"plus.http.upstream.peers.request.count": currentZoneRequests - previousZoneRequests,
"plus.http.upstream.peers.response.count": currentZoneResponses - previousZoneResponses,
"plus.http.upstream.peers.status.1xx": 0,
"plus.http.upstream.peers.status.2xx": currentZoneResponses,
"plus.http.upstream.peers.status.2xx": currentZoneResponses - previousZoneResponses,
"plus.http.upstream.peers.status.3xx": 0,
"plus.http.upstream.peers.status.4xx": 0,
"plus.http.upstream.peers.status.5xx": 0,
"plus.http.upstream.peers.bytes_sent": currentZoneSent,
"plus.http.upstream.peers.bytes_rcvd": currentZoneReceived,
"plus.http.upstream.peers.bytes_sent": currentZoneSent - previousZoneSent,
"plus.http.upstream.peers.bytes_rcvd": currentZoneReceived - previousZoneReceived,
"plus.http.upstream.peers.fails": 0,
"plus.http.upstream.peers.unavail": 0,
"plus.http.upstream.peers.health_checks.fails": 0,
Expand All @@ -585,6 +653,9 @@ func TestNginxPlus_Collect(t *testing.T) {
"plus.http.upstream.peers.state.unavail": 0,
"plus.http.upstream.peers.state.checking": 0,
"plus.http.upstream.peers.state.unhealthy": 0,
"plus.http.upstream.peers.ssl.handshakes": currentSSLHandshakes - previousSSLHandshakes,
"plus.http.upstream.peers.ssl.handshakes.failed": currentSSLHandshakesFailed - previousSSLHandshakesFailed,
"plus.http.upstream.peers.ssl.session.reuses": currentSSLSessionReuses - previousSSLSessionReuses,
}

expectedHttpPeer2UpstreamMetrics := map[string]float64{
Expand All @@ -611,6 +682,9 @@ func TestNginxPlus_Collect(t *testing.T) {
"plus.http.upstream.peers.state.unavail": 0,
"plus.http.upstream.peers.state.checking": 0,
"plus.http.upstream.peers.state.unhealthy": 0,
"plus.http.upstream.peers.ssl.handshakes": currentSSLHandshakes - previousSSLHandshakes,
"plus.http.upstream.peers.ssl.handshakes.failed": currentSSLHandshakesFailed - previousSSLHandshakesFailed,
"plus.http.upstream.peers.ssl.session.reuses": currentSSLSessionReuses - previousSSLSessionReuses,
}

expectedStreamUpstreamMetrics := map[string]float64{
Expand Down Expand Up @@ -763,18 +837,7 @@ func TestNginxPlus_Collect(t *testing.T) {
}
for _, metric := range serverZoneMetrics.Data.Simplemetrics {
assert.Contains(t, expectedServerZoneMetrics, metric.Name)
switch metric.Name {
case "plus.http.request.count":
assert.Equal(t, expectedServerZoneMetrics["plus.http.request.count"], metric.Value)
case "plus.http.response.count":
assert.Equal(t, expectedServerZoneMetrics["plus.http.response.count"], metric.Value)
case "plus.http.status.2xx":
assert.Equal(t, expectedServerZoneMetrics["plus.http.status.2xx"], metric.Value)
case "plus.http.request.bytes_rcvd":
assert.Equal(t, expectedServerZoneMetrics["plus.http.request.bytes_rcvd"], metric.Value)
case "plus.http.request.bytes_sent":
assert.Equal(t, expectedServerZoneMetrics["plus.http.request.bytes_sent"], metric.Value)
}
assert.Equal(t, expectedServerZoneMetrics[metric.Name], metric.Value)
}

streamServerZoneMetrics := <-test.m
Expand Down Expand Up @@ -940,24 +1003,7 @@ func TestNginxPlus_Collect(t *testing.T) {
}
for _, metric := range httpPeer1upstreamMetrics.Data.Simplemetrics {
assert.Contains(t, expectedHttpPeer1UpstreamMetrics, metric.Name)
switch metric.Name {
case "plus.http.upstream.peers.header_time":
assert.Equal(t, expectedHttpPeer1UpstreamMetrics["plus.http.upstream.peers.header_time"], metric.Value)
case "plus.http.upstream.peers.response.time":
assert.Equal(t, expectedHttpPeer1UpstreamMetrics["plus.http.upstream.peers.response.time"], metric.Value)
case "plus.http.upstream.peers.request.count":
assert.Equal(t, expectedHttpPeer1UpstreamMetrics["plus.http.upstream.peers.request.count"], metric.Value)
case "plus.http.upstream.peers.response.count":
assert.Equal(t, expectedHttpPeer1UpstreamMetrics["plus.http.upstream.peers.response.count"], metric.Value)
case "plus.http.upstream.peers.status.2xx":
assert.Equal(t, expectedHttpPeer1UpstreamMetrics["plus.http.upstream.peers.status.2xx"], metric.Value)
case "plus.http.upstream.peers.bytes_sent":
assert.Equal(t, expectedHttpPeer1UpstreamMetrics["plus.http.upstream.peers.bytes_sent"], metric.Value)
case "plus.http.upstream.peers.bytes_rcvd":
assert.Equal(t, expectedHttpPeer1UpstreamMetrics["plus.http.upstream.peers.bytes_rcvd"], metric.Value)
case "plus.http.upstream.peers.state.up":
assert.Equal(t, expectedHttpPeer1UpstreamMetrics["plus.http.upstream.peers.state.up"], metric.Value)
}
assert.Equal(t, expectedHttpPeer1UpstreamMetrics[metric.Name], metric.Value)
}

httpPeer2upstreamMetrics := <-test.m
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit a9728fe

Please sign in to comment.