Skip to content
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

feat(inputs.nginx_plus_api): Gather slab metrics #10448

Merged
merged 5 commits into from
Jun 1, 2022
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
24 changes: 23 additions & 1 deletion plugins/inputs/nginx_plus_api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ Nginx Plus is a commercial version of the open source web server Nginx. The use
| nginx_plus_api_processes | >= 3 |
| nginx_plus_api_connections | >= 3 |
| nginx_plus_api_ssl | >= 3 |
| nginx_plus_api_slabs_pages | >= 3 |
| nginx_plus_api_slabs_slots | >= 3 |
| nginx_plus_api_http_requests | >= 3 |
| nginx_plus_api_http_server_zones | >= 3 |
| nginx_plus_api_http_upstreams | >= 3 |
Expand All @@ -56,6 +58,14 @@ Nginx Plus is a commercial version of the open source web server Nginx. The use
- dropped
- active
- idle
- nginx_plus_api_slabs_pages
- used
- free
- nginx_plus_api_slabs_slots
- used
- free
- reqs
- fails
- nginx_plus_api_ssl
- handshakes
- handshakes_failed
Expand Down Expand Up @@ -182,10 +192,16 @@ Nginx Plus is a commercial version of the open source web server Nginx. The use
- source
- port

- nginx_plus_api_http_server_zones, nginx_plus_api_upstream_server_zones, nginx_plus_api_http_location_zones, nginx_plus_api_resolver_zones
- nginx_plus_api_http_server_zones, nginx_plus_api_upstream_server_zones, nginx_plus_api_http_location_zones, nginx_plus_api_resolver_zones, nginx_plus_api_slabs_pages
- source
- port
- zone

- nginx_plus_api_slabs_slots
- source
- port
- zone
- slot

- nginx_plus_api_upstream_peers, nginx_plus_api_stream_upstream_peers
- id
Expand Down Expand Up @@ -219,6 +235,12 @@ It produces:
```text
> nginx_plus_api_processes,port=80,source=demo.nginx.com respawned=0i 1570696321000000000
> nginx_plus_api_connections,port=80,source=demo.nginx.com accepted=68998606i,active=7i,dropped=0i,idle=57i 1570696322000000000
> nginx_plus_api_slabs_pages,port=80,source=demo.nginx.com,zone=hg.nginx.org used=1i,free=503i 1570696322000000000
> nginx_plus_api_slabs_pages,port=80,source=demo.nginx.com,zone=trac.nginx.org used=3i,free=500i 1570696322000000000
> nginx_plus_api_slabs_slots,port=80,source=demo.nginx.com,zone=hg.nginx.org,slot=8 used=1i,free=503i,reqs=10i,fails=0i 1570696322000000000
> nginx_plus_api_slabs_slots,port=80,source=demo.nginx.com,zone=hg.nginx.org,slot=16 used=3i,free=500i,reqs=1024i,fails=0i 1570696322000000000
> nginx_plus_api_slabs_slots,port=80,source=demo.nginx.com,zone=trac.nginx.org,slot=8 used=1i,free=503i,reqs=10i,fails=0i 1570696322000000000
> nginx_plus_api_slabs_slots,port=80,source=demo.nginx.com,zone=trac.nginx.org,slot=16 used=0i,free=1520i,reqs=0i,fails=1i 1570696322000000000
> nginx_plus_api_ssl,port=80,source=demo.nginx.com handshakes=9398978i,handshakes_failed=289353i,session_reuses=1004389i 1570696322000000000
> nginx_plus_api_http_requests,port=80,source=demo.nginx.com current=51i,total=264649353i 1570696322000000000
> nginx_plus_api_http_server_zones,port=80,source=demo.nginx.com,zone=hg.nginx.org discarded=5i,processing=0i,received=24123604i,requests=60138i,responses_1xx=0i,responses_2xx=59353i,responses_3xx=531i,responses_4xx=249i,responses_5xx=0i,responses_total=60133i,sent=830165221i 1570696322000000000
Expand Down
1 change: 1 addition & 0 deletions plugins/inputs/nginx_plus_api/nginx_plus_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const (
// Paths
processesPath = "processes"
connectionsPath = "connections"
slabsPath = "slabs"
sslPath = "ssl"

httpRequestsPath = "http/requests"
Expand Down
54 changes: 54 additions & 0 deletions plugins/inputs/nginx_plus_api/nginx_plus_api_metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ var (
func (n *NginxPlusAPI) gatherMetrics(addr *url.URL, acc telegraf.Accumulator) {
addError(acc, n.gatherProcessesMetrics(addr, acc))
addError(acc, n.gatherConnectionsMetrics(addr, acc))
addError(acc, n.gatherSlabsMetrics(addr, acc))
addError(acc, n.gatherSslMetrics(addr, acc))
addError(acc, n.gatherHTTPRequestsMetrics(addr, acc))
addError(acc, n.gatherHTTPServerZonesMetrics(addr, acc))
Expand Down Expand Up @@ -130,6 +131,59 @@ func (n *NginxPlusAPI) gatherConnectionsMetrics(addr *url.URL, acc telegraf.Accu
return nil
}

func (n *NginxPlusAPI) gatherSlabsMetrics(addr *url.URL, acc telegraf.Accumulator) error {
body, err := n.gatherURL(addr, slabsPath)
if err != nil {
return err
}

var slabs Slabs

if err := json.Unmarshal(body, &slabs); err != nil {
return err
}

tags := getTags(addr)

for zoneName, slab := range slabs {
slabTags := map[string]string{}
for k, v := range tags {
slabTags[k] = v
}
slabTags["zone"] = zoneName

acc.AddFields(
"nginx_plus_api_slabs_pages",
map[string]interface{}{
"used": slab.Pages.Used,
"free": slab.Pages.Free,
},
slabTags,
)

for slotID, slot := range slab.Slots {
slotTags := map[string]string{}
for k, v := range slabTags {
slotTags[k] = v
}
slotTags["slot"] = slotID

acc.AddFields(
"nginx_plus_api_slabs_slots",
map[string]interface{}{
"used": slot.Used,
"free": slot.Free,
"reqs": slot.Reqs,
"fails": slot.Fails,
},
slotTags,
)
}
}

return nil
}

func (n *NginxPlusAPI) gatherSslMetrics(addr *url.URL, acc telegraf.Accumulator) error {
body, err := n.gatherURL(addr, sslPath)
if err != nil {
Expand Down
194 changes: 194 additions & 0 deletions plugins/inputs/nginx_plus_api/nginx_plus_api_metrics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,135 @@ const connectionsPayload = `
}
`

const slabsPayload = `
{
"zone1":{
"pages":{
"used":7,
"free":56
},
"slots":{
"8":{
"used":1,
"free":503,
"reqs":1,
"fails":0
},
"16":{
"used":1,
"free":253,
"reqs":1,
"fails":0
},
"32":{
"used":3,
"free":124,
"reqs":3,
"fails":0
},
"64":{
"used":3,
"free":61,
"reqs":3,
"fails":0
},
"128":{
"used":6,
"free":26,
"reqs":6,
"fails":0
},
"256":{
"used":0,
"free":0,
"reqs":0,
"fails":0
},
"512":{
"used":2,
"free":6,
"reqs":2,
"fails":0
},
"1024":{
"used":2,
"free":2,
"reqs":2,
"fails":0
},
"2048":{
"used":0,
"free":0,
"reqs":0,
"fails":0
}
}
},
"zone2":{
"pages":{
"used":2218,
"free":252290
},
"slots":{
"8":{
"used":1,
"free":503,
"reqs":4,
"fails":0
},
"16":{
"used":0,
"free":0,
"reqs":0,
"fails":0
},
"32":{
"used":8,
"free":119,
"reqs":98,
"fails":0
},
"64":{
"used":10899,
"free":45,
"reqs":124255,
"fails":0
},
"128":{
"used":1,
"free":31,
"reqs":1,
"fails":0
},
"256":{
"used":10901,
"free":11,
"reqs":124270,
"fails":0
},
"512":{
"used":10893,
"free":3,
"reqs":124245,
"fails":0
},
"1024":{
"used":0,
"free":0,
"reqs":0,
"fails":0
},
"2048":{
"used":0,
"free":0,
"reqs":10,
"fails":0
}
}
}
}
`

const sslPayload = `
{
"handshakes": 79572,
Expand Down Expand Up @@ -564,6 +693,71 @@ func TestGatherConnectionsMetrics(t *testing.T) {
})
}

func TestGatherSlabsMetrics(t *testing.T) {
ts, n := prepareEndpoint(t, slabsPath, slabsPayload)
defer ts.Close()

var acc testutil.Accumulator
addr, host, port := prepareAddr(t, ts)

require.NoError(t, n.gatherSlabsMetrics(addr, &acc))

acc.AssertContainsTaggedFields(
t,
"nginx_plus_api_slabs_pages",
map[string]interface{}{
"used": int64(7),
"free": int64(56),
},
map[string]string{
"source": host,
"port": port,
"zone": "zone1",
})
acc.AssertContainsTaggedFields(
t,
"nginx_plus_api_slabs_pages",
map[string]interface{}{
"used": int64(2218),
"free": int64(252290),
},
map[string]string{
"source": host,
"port": port,
"zone": "zone2",
})
acc.AssertContainsTaggedFields(
t,
"nginx_plus_api_slabs_slots",
map[string]interface{}{
"used": int64(1),
"free": int64(503),
"reqs": int64(1),
"fails": int64(0),
},
map[string]string{
"source": host,
"port": port,
"zone": "zone1",
"slot": "8",
})
acc.AssertContainsTaggedFields(
t,
"nginx_plus_api_slabs_slots",
map[string]interface{}{
"used": int64(10893),
"free": int64(3),
"reqs": int64(124245),
"fails": int64(0),
},
map[string]string{
"source": host,
"port": port,
"zone": "zone2",
"slot": "512",
})
}

func TestGatherSslMetrics(t *testing.T) {
ts, n := prepareEndpoint(t, sslPath, sslPayload)
defer ts.Close()
Expand Down
13 changes: 13 additions & 0 deletions plugins/inputs/nginx_plus_api/nginx_plus_api_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,19 @@ type Connections struct {
Idle int64 `json:"idle"`
}

type Slabs map[string]struct {
Pages struct {
Used int64 `json:"used"`
Free int64 `json:"free"`
} `json:"pages"`
Slots map[string]struct {
Used int64 `json:"used"`
Free int64 `json:"free"`
Reqs int64 `json:"reqs"`
Fails int64 `json:"fails"`
} `json:"slots"`
}

type Ssl struct { // added in version 6
Handshakes int64 `json:"handshakes"`
HandshakesFailed int64 `json:"handshakes_failed"`
Expand Down