feat(inputs.nginx_plus_api): Gather limit_reqs metrics (#10874)

This commit is contained in:
glennlod 2022-07-07 18:43:29 +02:00 committed by GitHub
parent 8f789c5cd8
commit c91eacda42
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 129 additions and 5 deletions

View File

@ -62,8 +62,9 @@ between Nginx (F/OSS) and Nginx Plus, see the Nginx [documentation][diff-doc].
| nginx_plus_api_stream_server_zones | >= 3 |
| nginx_plus_api_http_location_zones | >= 5 |
| nginx_plus_api_resolver_zones | >= 5 |
| nginx_plus_api_http_limit_reqs | >= 6 |
## Measurements & Fields
## Metrics
- nginx_plus_api_processes
- respawned
@ -194,8 +195,14 @@ between Nginx (F/OSS) and Nginx Plus, see the Nginx [documentation][diff-doc].
- refused
- timedout
- unknown
- nginx_plus_api_http_limit_reqs
- passed
- delayed
- rejected
- delayed_dry_run
- rejected_dry_run
## Tags
### Tags
- nginx_plus_api_processes, nginx_plus_api_connections, nginx_plus_api_ssl, nginx_plus_api_http_requests
- source
@ -228,6 +235,11 @@ between Nginx (F/OSS) and Nginx Plus, see the Nginx [documentation][diff-doc].
- source
- port
- nginx_plus_api_http_limit_reqs
- source
- port
- limit
## Example Output
Using this configuration:
@ -287,8 +299,11 @@ It produces:
> nginx_plus_api_http_location_zones,port=80,source=demo.nginx.com,zone=swagger discarded=0i,received=1622i,requests=8i,responses_1xx=0i,responses_2xx=7i,responses_3xx=0i,responses_4xx=1i,responses_5xx=0i,responses_total=8i,sent=638333i 1570696323000000000
> nginx_plus_api_http_location_zones,port=80,source=demo.nginx.com,zone=api-calls discarded=64i,received=337530181i,requests=1726513i,responses_1xx=0i,responses_2xx=1726428i,responses_3xx=0i,responses_4xx=21i,responses_5xx=0i,responses_total=1726449i,sent=1902577668i 1570696323000000000
> nginx_plus_api_resolver_zones,port=80,source=demo.nginx.com,zone=resolver1 addr=0i,formerr=0i,name=0i,noerror=0i,notimp=0i,nxdomain=0i,refused=0i,servfail=0i,srv=0i,timedout=0i,unknown=0i 1570696324000000000
> nginx_plus_api_http_limit_reqs,port=80,source=demo.nginx.com,limit=limit_1 delayed=0i,delayed_dry_run=0i,passed=6i,rejected=9i,rejected_dry_run=0i 1570696322000000000
> nginx_plus_api_http_limit_reqs,port=80,source=demo.nginx.com,limit=limit_2 delayed=13i,delayed_dry_run=3i,passed=6i,rejected=1i,rejected_dry_run=31i 1570696322000000000
```
### Reference material
[api documentation](http://demo.nginx.com/swagger-ui/#/)
- [api documentation](http://demo.nginx.com/swagger-ui/#/)
- [nginx_api_module documentation](http://nginx.org/en/docs/http/ngx_http_api_module.html)

View File

@ -43,8 +43,8 @@ const (
httpLocationZonesPath = "http/location_zones"
httpUpstreamsPath = "http/upstreams"
httpCachesPath = "http/caches"
resolverZonesPath = "resolvers"
httpLimitReqsPath = "http/limit_reqs"
resolverZonesPath = "resolvers"
streamServerZonesPath = "stream/server_zones"
streamUpstreamsPath = "stream/upstreams"

View File

@ -35,6 +35,9 @@ func (n *NginxPlusAPI) gatherMetrics(addr *url.URL, acc telegraf.Accumulator) {
addError(acc, n.gatherHTTPLocationZonesMetrics(addr, acc))
addError(acc, n.gatherResolverZonesMetrics(addr, acc))
}
if n.APIVersion >= 6 {
addError(acc, n.gatherHTTPLimitReqsMetrics(addr, acc))
}
}
func addError(acc telegraf.Accumulator, err error) {
@ -613,6 +616,43 @@ func (n *NginxPlusAPI) gatherStreamUpstreamsMetrics(addr *url.URL, acc telegraf.
return nil
}
// Added in 6 API version
func (n *NginxPlusAPI) gatherHTTPLimitReqsMetrics(addr *url.URL, acc telegraf.Accumulator) error {
body, err := n.gatherURL(addr, httpLimitReqsPath)
if err != nil {
return err
}
var httpLimitReqs HTTPLimitReqs
if err := json.Unmarshal(body, &httpLimitReqs); err != nil {
return err
}
tags := getTags(addr)
for limitReqName, limit := range httpLimitReqs {
limitReqsTags := map[string]string{}
for k, v := range tags {
limitReqsTags[k] = v
}
limitReqsTags["limit"] = limitReqName
acc.AddFields(
"nginx_plus_api_http_limit_reqs",
map[string]interface{}{
"passed": limit.Passed,
"delayed": limit.Delayed,
"rejected": limit.Rejected,
"delayed_dry_run": limit.DelayedDryRun,
"rejected_dry_run": limit.RejectedDryRun,
},
limitReqsTags,
)
}
return nil
}
func getTags(addr *url.URL) map[string]string {
h := addr.Host
host, port, err := net.SplitHostPort(h)

View File

@ -245,6 +245,25 @@ const httpServerZonesPayload = `
}
`
const httpLimitReqsPayload = `
{
"limit_1": {
"passed": 2,
"delayed": 9,
"rejected": 4,
"delayed_dry_run": 100,
"rejected_dry_run": 330
},
"limit_2": {
"passed": 451,
"delayed": 10,
"rejected": 0,
"delayed_dry_run": 10,
"rejected_dry_run": 32
}
}
`
const httpLocationZonesPayload = `
{
"site1": {
@ -857,6 +876,48 @@ func TestGatherHttpServerZonesMetrics(t *testing.T) {
})
}
func TestGatherHttpLimitReqsMetrics(t *testing.T) {
ts, n := prepareEndpoint(t, httpLimitReqsPath, httpLimitReqsPayload)
defer ts.Close()
var acc testutil.Accumulator
addr, host, port := prepareAddr(t, ts)
require.NoError(t, n.gatherHTTPLimitReqsMetrics(addr, &acc))
acc.AssertContainsTaggedFields(
t,
"nginx_plus_api_http_limit_reqs",
map[string]interface{}{
"passed": int64(2),
"delayed": int64(9),
"rejected": int64(4),
"delayed_dry_run": int64(100),
"rejected_dry_run": int64(330),
},
map[string]string{
"source": host,
"port": port,
"limit": "limit_1",
})
acc.AssertContainsTaggedFields(
t,
"nginx_plus_api_http_limit_reqs",
map[string]interface{}{
"passed": int64(451),
"delayed": int64(10),
"rejected": int64(0),
"delayed_dry_run": int64(10),
"rejected_dry_run": int64(32),
},
map[string]string{
"source": host,
"port": port,
"limit": "limit_2",
})
}
func TestGatherHttpLocationZonesMetrics(t *testing.T) {
ts, n := prepareEndpoint(t, httpLocationZonesPath, httpLocationZonesPayload)
defer ts.Close()

View File

@ -170,3 +170,11 @@ type HTTPCaches map[string]struct { // added in version 2
Expired ExtendedHitStats `json:"expired"`
Bypass ExtendedHitStats `json:"bypass"`
}
type HTTPLimitReqs map[string]struct {
Passed int64 `json:"passed"`
Delayed int64 `json:"delayed"`
Rejected int64 `json:"rejected"`
DelayedDryRun int64 `json:"delayed_dry_run"`
RejectedDryRun int64 `json:"rejected_dry_run"`
}