Replace Status port using a socket
This commit is contained in:
parent
bd74dce19c
commit
34b0580225
15 changed files with 357 additions and 309 deletions
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ type collector struct {
|
|||
}
|
||||
|
||||
// NewCollector creates a new metric collector the for ingress controller
|
||||
func NewCollector(statusPort int, metricsPerHost bool, registry *prometheus.Registry) (Collector, error) {
|
||||
func NewCollector(metricsPerHost bool, registry *prometheus.Registry) (Collector, error) {
|
||||
podNamespace := os.Getenv("POD_NAMESPACE")
|
||||
if podNamespace == "" {
|
||||
podNamespace = "default"
|
||||
|
|
@ -67,7 +67,7 @@ func NewCollector(statusPort int, metricsPerHost bool, registry *prometheus.Regi
|
|||
|
||||
podName := os.Getenv("POD_NAME")
|
||||
|
||||
nc, err := collectors.NewNGINXStatus(podName, podNamespace, class.IngressClass, statusPort)
|
||||
nc, err := collectors.NewNGINXStatus(podName, podNamespace, class.IngressClass)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue