Skip to content

Support location zones and resolver metrics in go client #31

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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