Skip to content

Commit

Permalink
Support location zones and resolver metrics in go client
Browse files Browse the repository at this point in the history
  • Loading branch information
Vighneswar Rao Bojja authored and bvighnesha committed Sep 24, 2019
1 parent 9a5eb22 commit f2921a1
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 3 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
NGINX_PLUS_VERSION=18-1
NGINX_PLUS_VERSION=19-1
NGINX_IMAGE=nginxplus:$(NGINX_PLUS_VERSION)

test: docker-build run-nginx-plus test-run configure-no-stream-block test-run-no-stream-block clean
Expand Down
76 changes: 75 additions & 1 deletion client/nginx.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
)

// APIVersion is a version of NGINX Plus API.
const APIVersion = 4
const APIVersion = 5

const pathNotFoundCode = "PathNotFound"

Expand Down Expand Up @@ -101,6 +101,8 @@ type Stats struct {
StreamServerZones StreamServerZones
StreamUpstreams StreamUpstreams
StreamZoneSync *StreamZoneSync
LocationZones LocationZones
Resolvers Resolvers
}

// NginxInfo contains general information about NGINX Plus.
Expand Down Expand Up @@ -288,6 +290,46 @@ type HealthChecks struct {
LastPassed bool `json:"last_passed"`
}

// LocationZones represents location_zones related stats
type LocationZones map[string]LocationZone

// Resolvers represents resolvers related stats
type Resolvers map[string]Resolver

// LocationZone represents location_zones related stats
type LocationZone struct {
Requests int64
Responses Responses
Discarded int64
Received int64
Sent int64
}

// Resolver represents resolvers related stats
type Resolver struct {
Requests ResolverRequests `json:"requests"`
Responses ResolverResponses `json:"responses"`
}

// ResolverRequests represents resolver requests
type ResolverRequests struct {
Name int64
Srv int64
Addr int64
}

// ResolverResponses represents resolver responses
type ResolverResponses struct {
Noerror int64
Formerr int64
Servfail int64
Nxdomain int64
Notimp int64
Refused int64
Timedout int64
Unknown int64
}

// NewNginxClient creates an NginxClient.
func NewNginxClient(httpClient *http.Client, apiEndpoint string) (*NginxClient, error) {
versions, err := getAPIVersions(httpClient, apiEndpoint)
Expand Down Expand Up @@ -767,6 +809,16 @@ func (client *NginxClient) GetStats() (*Stats, error) {
return nil, fmt.Errorf("failed to get stats: %v", err)
}

locationZones, err := client.getLocationZones()
if err != nil {
return nil, fmt.Errorf("failed to get stats: %v", err)
}

resolvers, err := client.getResolvers()
if err != nil {
return nil, fmt.Errorf("failed to get stats: %v", err)
}

return &Stats{
NginxInfo: *info,
Connections: *cons,
Expand All @@ -777,6 +829,8 @@ func (client *NginxClient) GetStats() (*Stats, error) {
Upstreams: *upstreams,
StreamUpstreams: *streamUpstreams,
StreamZoneSync: streamZoneSync,
LocationZones: *locationZones,
Resolvers: *resolvers,
}, nil
}

Expand Down Expand Up @@ -877,6 +931,26 @@ func (client *NginxClient) getStreamZoneSync() (*StreamZoneSync, error) {
return &streamZoneSync, err
}

func (client *NginxClient) getLocationZones() (*LocationZones, error) {
var locationZones LocationZones
err := client.get("http/location_zones", &locationZones)
if err != nil {
return nil, fmt.Errorf("failed to get location zones: %v", err)
}

return &locationZones, err
}

func (client *NginxClient) getResolvers() (*Resolvers, error) {
var resolvers Resolvers
err := client.get("resolvers", &resolvers)
if err != nil {
return nil, fmt.Errorf("failed to get resolvers: %v", err)
}

return &resolvers, err
}

// KeyValPairs are the key-value pairs stored in a zone.
type KeyValPairs map[string]string

Expand Down
2 changes: 1 addition & 1 deletion docker/nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ stream {
health_check interval=10 fails=3 passes=1;
}

resolver 127.0.0.11 valid=5s;
resolver 127.0.0.11 valid=5s status_zone=resolver_test;

server {
listen 7777;
Expand Down
1 change: 1 addition & 0 deletions docker/test.conf
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ server {
}

location /api {
status_zone location_test;
api write=on;
}

Expand Down
16 changes: 16 additions & 0 deletions tests/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ const (
upstream = "test"
streamUpstream = "stream_test"
streamZoneSync = "zone_test_sync"
locationZone = "location_test"
resolverMetric = "resolver_test"
)

var defaultMaxFails = 1
Expand Down Expand Up @@ -483,6 +485,20 @@ func TestStats(t *testing.T) {
} else {
t.Errorf("Upstream 'test' not found")
}
if locZones, ok := stats.LocationZones[locationZone]; ok {
if locZones.Requests < 1 {
t.Errorf("LocationZone stats missing: %v", locZones.Requests)
}
} else {
t.Errorf("LocationZone %v not found", locationZone)
}
if resolver, ok := stats.Resolvers[resolverMetric]; ok {
if resolver.Requests.Name < 1 {
t.Errorf("Resolvers stats missing: %v", resolver.Requests)
}
} else {
t.Errorf("Resolver %v not found", resolverMetric)
}

// cleanup upstream servers
_, _, err = c.UpdateHTTPServers(upstream, []client.UpstreamServer{})
Expand Down

0 comments on commit f2921a1

Please sign in to comment.