Skip to content

Commit

Permalink
feat(inputs.nginx_plus_api): Gather slab metrics (#10448)
Browse files Browse the repository at this point in the history
  • Loading branch information
glennlod committed Jun 1, 2022
1 parent 4d92fe4 commit a34219a
Show file tree
Hide file tree
Showing 5 changed files with 285 additions and 1 deletion.
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 @@ -46,6 +46,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 @@ -66,6 +68,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 @@ -192,10 +202,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 @@ -229,6 +245,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 @@ -35,6 +35,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

0 comments on commit a34219a

Please sign in to comment.