package nginx_vts import ( "fmt" "net" "net/http" "net/http/httptest" "net/url" "testing" "github.com/influxdata/telegraf/testutil" "github.com/stretchr/testify/require" ) const sampleStatusResponse = ` { "hostName": "test.example.com", "nginxVersion": "1.12.2", "loadMsec": 1518180328331, "nowMsec": 1518256058416, "connections": { "active": 111, "reading": 222, "writing": 333, "waiting": 444, "accepted": 555, "handled": 666, "requests": 777 }, "serverZones": { "example.com": { "requestCounter": 1415887, "inBytes": 1296356607, "outBytes": 4404939605, "responses": { "1xx": 100, "2xx": 200, "3xx": 300, "4xx": 400, "5xx": 500, "miss": 14, "bypass": 15, "expired": 16, "stale": 17, "updating": 18, "revalidated": 19, "hit": 20, "scarce": 21 }, "requestMsec": 13 }, "other.example.com": { "requestCounter": 505, "inBytes": 171388, "outBytes": 1273382, "responses": { "1xx": 101, "2xx": 201, "3xx": 301, "4xx": 401, "5xx": 501, "miss": 22, "bypass": 23, "expired": 24, "stale": 25, "updating": 26, "revalidated": 27, "hit": 28, "scarce": 29 }, "requestMsec": 12 } }, "filterZones": { "country": { "FI": { "requestCounter": 60, "inBytes": 2570, "outBytes": 53597, "responses": { "1xx": 106, "2xx": 206, "3xx": 306, "4xx": 406, "5xx": 506, "miss": 61, "bypass": 62, "expired": 63, "stale": 64, "updating": 65, "revalidated": 66, "hit": 67, "scarce": 68 }, "requestMsec": 69 } } }, "upstreamZones": { "backend_cluster": [ { "server": "127.0.0.1:6000", "requestCounter": 2103849, "inBytes": 1774680141, "outBytes": 11727669190, "responses": { "1xx": 103, "2xx": 203, "3xx": 303, "4xx": 403, "5xx": 503 }, "requestMsec": 30, "responseMsec": 31, "weight": 32, "maxFails": 33, "failTimeout": 34, "backup": false, "down": false } ], "::nogroups": [ { "server": "127.0.0.1:4433", "requestCounter": 8, "inBytes": 5013, "outBytes": 487585, "responses": { "1xx": 104, "2xx": 204, "3xx": 304, "4xx": 404, "5xx": 504 }, "requestMsec": 34, "responseMsec": 35, "weight": 36, "maxFails": 37, "failTimeout": 38, "backup": true, "down": false }, { "server": "127.0.0.1:8080", "requestCounter": 7, "inBytes": 2926, "outBytes": 3846638, "responses": { "1xx": 105, "2xx": 205, "3xx": 305, "4xx": 405, "5xx": 505 }, "requestMsec": 39, "responseMsec": 40, "weight": 41, "maxFails": 42, "failTimeout": 43, "backup": true, "down": true } ] }, "cacheZones": { "example": { "maxSize": 9223372036854776000, "usedSize": 68639232, "inBytes": 697138673, "outBytes": 11305044106, "responses": { "miss": 44, "bypass": 45, "expired": 46, "stale": 47, "updating": 48, "revalidated": 49, "hit": 50, "scarce": 51 } }, "static": { "maxSize": 9223372036854776000, "usedSize": 569856, "inBytes": 551652333, "outBytes": 1114889271, "responses": { "miss": 52, "bypass": 53, "expired": 54, "stale": 55, "updating": 56, "revalidated": 57, "hit": 58, "scarce": 59 } } } } ` func TestNginxPlusGeneratesMetrics(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var rsp string if r.URL.Path == "/status" { rsp = sampleStatusResponse w.Header()["Content-Type"] = []string{"application/json"} } else { panic("Cannot handle request") } fmt.Fprintln(w, rsp) })) defer ts.Close() n := &NginxVTS{ Urls: []string{fmt.Sprintf("%s/status", ts.URL)}, } var acc testutil.Accumulator err := n.Gather(&acc) require.NoError(t, err) addr, err := url.Parse(ts.URL) if err != nil { panic(err) } host, port, err := net.SplitHostPort(addr.Host) if err != nil { host = addr.Host if addr.Scheme == "http" { port = "80" } else if addr.Scheme == "https" { port = "443" } else { port = "" } } acc.AssertContainsTaggedFields( t, "nginx_vts_connections", map[string]interface{}{ "accepted": uint64(555), "active": uint64(111), "handled": uint64(666), "reading": uint64(222), "requests": uint64(777), "waiting": uint64(444), "writing": uint64(333), }, map[string]string{ "source": host, "port": port, }) acc.AssertContainsTaggedFields( t, "nginx_vts_server", map[string]interface{}{ "requests": uint64(1415887), "request_time": uint64(13), "in_bytes": uint64(1296356607), "out_bytes": uint64(4404939605), "response_1xx_count": uint64(100), "response_2xx_count": uint64(200), "response_3xx_count": uint64(300), "response_4xx_count": uint64(400), "response_5xx_count": uint64(500), "cache_miss": uint64(14), "cache_bypass": uint64(15), "cache_expired": uint64(16), "cache_stale": uint64(17), "cache_updating": uint64(18), "cache_revalidated": uint64(19), "cache_hit": uint64(20), "cache_scarce": uint64(21), }, map[string]string{ "source": host, "port": port, "zone": "example.com", }) acc.AssertContainsTaggedFields( t, "nginx_vts_filter", map[string]interface{}{ "requests": uint64(60), "request_time": uint64(69), "in_bytes": uint64(2570), "out_bytes": uint64(53597), "response_1xx_count": uint64(106), "response_2xx_count": uint64(206), "response_3xx_count": uint64(306), "response_4xx_count": uint64(406), "response_5xx_count": uint64(506), "cache_miss": uint64(61), "cache_bypass": uint64(62), "cache_expired": uint64(63), "cache_stale": uint64(64), "cache_updating": uint64(65), "cache_revalidated": uint64(66), "cache_hit": uint64(67), "cache_scarce": uint64(68), }, map[string]string{ "source": host, "port": port, "filter_key": "FI", "filter_name": "country", }) acc.AssertContainsTaggedFields( t, "nginx_vts_server", map[string]interface{}{ "requests": uint64(505), "request_time": uint64(12), "in_bytes": uint64(171388), "out_bytes": uint64(1273382), "response_1xx_count": uint64(101), "response_2xx_count": uint64(201), "response_3xx_count": uint64(301), "response_4xx_count": uint64(401), "response_5xx_count": uint64(501), "cache_miss": uint64(22), "cache_bypass": uint64(23), "cache_expired": uint64(24), "cache_stale": uint64(25), "cache_updating": uint64(26), "cache_revalidated": uint64(27), "cache_hit": uint64(28), "cache_scarce": uint64(29), }, map[string]string{ "source": host, "port": port, "zone": "other.example.com", }) acc.AssertContainsTaggedFields( t, "nginx_vts_upstream", map[string]interface{}{ "requests": uint64(2103849), "request_time": uint64(30), "response_time": uint64(31), "in_bytes": uint64(1774680141), "out_bytes": uint64(11727669190), "response_1xx_count": uint64(103), "response_2xx_count": uint64(203), "response_3xx_count": uint64(303), "response_4xx_count": uint64(403), "response_5xx_count": uint64(503), "weight": uint64(32), "max_fails": uint64(33), "fail_timeout": uint64(34), "backup": bool(false), "down": bool(false), }, map[string]string{ "source": host, "port": port, "upstream": "backend_cluster", "upstream_address": "127.0.0.1:6000", }) acc.AssertContainsTaggedFields( t, "nginx_vts_upstream", map[string]interface{}{ "requests": uint64(8), "request_time": uint64(34), "response_time": uint64(35), "in_bytes": uint64(5013), "out_bytes": uint64(487585), "response_1xx_count": uint64(104), "response_2xx_count": uint64(204), "response_3xx_count": uint64(304), "response_4xx_count": uint64(404), "response_5xx_count": uint64(504), "weight": uint64(36), "max_fails": uint64(37), "fail_timeout": uint64(38), "backup": bool(true), "down": bool(false), }, map[string]string{ "source": host, "port": port, "upstream": "::nogroups", "upstream_address": "127.0.0.1:4433", }) acc.AssertContainsTaggedFields( t, "nginx_vts_upstream", map[string]interface{}{ "requests": uint64(7), "request_time": uint64(39), "response_time": uint64(40), "in_bytes": uint64(2926), "out_bytes": uint64(3846638), "response_1xx_count": uint64(105), "response_2xx_count": uint64(205), "response_3xx_count": uint64(305), "response_4xx_count": uint64(405), "response_5xx_count": uint64(505), "weight": uint64(41), "max_fails": uint64(42), "fail_timeout": uint64(43), "backup": bool(true), "down": bool(true), }, map[string]string{ "source": host, "port": port, "upstream": "::nogroups", "upstream_address": "127.0.0.1:8080", }) acc.AssertContainsTaggedFields( t, "nginx_vts_cache", map[string]interface{}{ "max_bytes": uint64(9223372036854776000), "used_bytes": uint64(68639232), "in_bytes": uint64(697138673), "out_bytes": uint64(11305044106), "miss": uint64(44), "bypass": uint64(45), "expired": uint64(46), "stale": uint64(47), "updating": uint64(48), "revalidated": uint64(49), "hit": uint64(50), "scarce": uint64(51), }, map[string]string{ "source": host, "port": port, "zone": "example", }) acc.AssertContainsTaggedFields( t, "nginx_vts_cache", map[string]interface{}{ "max_bytes": uint64(9223372036854776000), "used_bytes": uint64(569856), "in_bytes": uint64(551652333), "out_bytes": uint64(1114889271), "miss": uint64(52), "bypass": uint64(53), "expired": uint64(54), "stale": uint64(55), "updating": uint64(56), "revalidated": uint64(57), "hit": uint64(58), "scarce": uint64(59), }, map[string]string{ "source": host, "port": port, "zone": "static", }) }