Replace Status port using a socket

This commit is contained in:
Manuel Alejandro de Brito Fontes 2019-01-21 11:29:36 -03:00
parent bd74dce19c
commit 34b0580225
No known key found for this signature in database
GPG key ID: 786136016A8BA02A
15 changed files with 357 additions and 309 deletions

View file

@ -17,13 +17,12 @@ limitations under the License.
package collectors
import (
"fmt"
"io/ioutil"
"net/http"
"log"
"regexp"
"strconv"
"github.com/prometheus/client_golang/prometheus"
"k8s.io/ingress-nginx/internal/nginx"
"k8s.io/klog"
)
@ -39,9 +38,6 @@ type (
nginxStatusCollector struct {
scrapeChan chan scrapeRequest
ngxHealthPort int
ngxStatusPath string
data *nginxStatusData
}
@ -78,12 +74,10 @@ type NGINXStatusCollector interface {
}
// NewNGINXStatus returns a new prometheus collector the default nginx status module
func NewNGINXStatus(podName, namespace, ingressClass string, ngxHealthPort int) (NGINXStatusCollector, error) {
func NewNGINXStatus(podName, namespace, ingressClass string) (NGINXStatusCollector, error) {
p := nginxStatusCollector{
scrapeChan: make(chan scrapeRequest),
ngxHealthPort: ngxHealthPort,
ngxStatusPath: "/nginx_status",
scrapeChan: make(chan scrapeRequest),
}
constLabels := prometheus.Labels{
@ -138,24 +132,6 @@ func (p nginxStatusCollector) Stop() {
close(p.scrapeChan)
}
func httpBody(url string) ([]byte, error) {
resp, err := http.DefaultClient.Get(url)
if err != nil {
return nil, fmt.Errorf("unexpected error scraping nginx : %v", err)
}
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("unexpected error scraping nginx (%v)", err)
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 400 {
return nil, fmt.Errorf("unexpected error scraping nginx (status %v)", resp.StatusCode)
}
return data, nil
}
func toInt(data []string, pos int) int {
if len(data) == 0 {
return 0
@ -187,27 +163,23 @@ func parse(data string) *basicStatus {
}
}
func getNginxStatus(port int, path string) (*basicStatus, error) {
url := fmt.Sprintf("http://0.0.0.0:%v%v", port, path)
klog.V(3).Infof("start scraping url: %v", url)
data, err := httpBody(url)
if err != nil {
return nil, fmt.Errorf("unexpected error scraping nginx status page: %v", err)
}
return parse(string(data)), nil
}
// nginxStatusCollector scrape the nginx status
func (p nginxStatusCollector) scrape(ch chan<- prometheus.Metric) {
s, err := getNginxStatus(p.ngxHealthPort, p.ngxStatusPath)
klog.V(3).Infof("start scraping socket: %v", nginx.StatusPath)
status, data, err := nginx.NewGetStatusRequest(nginx.StatusPath)
if err != nil {
log.Printf("%v", err)
klog.Warningf("unexpected error obtaining nginx status info: %v", err)
return
}
if status < 200 || status >= 400 {
klog.Warningf("unexpected error obtaining nginx status info (status %v)", status)
return
}
s := parse(string(data))
ch <- prometheus.MustNewConstMetric(p.data.connectionsTotal,
prometheus.CounterValue, float64(s.Active), "active")
ch <- prometheus.MustNewConstMetric(p.data.connectionsTotal,

View file

@ -21,9 +21,12 @@ import (
"net"
"net/http"
"net/http/httptest"
"os"
"testing"
"time"
"github.com/prometheus/client_golang/prometheus"
"k8s.io/ingress-nginx/internal/nginx"
)
func TestStatusCollector(t *testing.T) {
@ -96,24 +99,39 @@ func TestStatusCollector(t *testing.T) {
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, c.mock)
}))
p := server.Listener.Addr().(*net.TCPAddr).Port
listener, err := net.Listen("unix", nginx.StatusSocket)
if err != nil {
t.Fatalf("crating unix listener: %s", err)
}
cm, err := NewNGINXStatus("pod", "default", "nginx", p)
server := &httptest.Server{
Listener: listener,
Config: &http.Server{Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
if r.URL.Path == "/nginx_status" {
_, err := fmt.Fprintf(w, c.mock)
if err != nil {
t.Fatal(err)
}
return
}
fmt.Fprintf(w, "OK")
})},
}
server.Start()
time.Sleep(1 * time.Second)
cm, err := NewNGINXStatus("pod", "default", "nginx")
if err != nil {
t.Errorf("unexpected error creating nginx status collector: %v", err)
}
go cm.Start()
defer func() {
server.Close()
cm.Stop()
}()
reg := prometheus.NewPedanticRegistry()
if err := reg.Register(cm); err != nil {
t.Errorf("registering collector failed: %s", err)
@ -124,6 +142,12 @@ func TestStatusCollector(t *testing.T) {
}
reg.Unregister(cm)
server.Close()
cm.Stop()
listener.Close()
os.Remove(nginx.StatusSocket)
})
}
}