Skip to content

Commit 48b76a9

Browse files
author
anahan
committed
Refactored prom metrics
1 parent f7d11ff commit 48b76a9

5 files changed

Lines changed: 206 additions & 241 deletions

File tree

cmd/docker-fpm-wrapper/config.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,8 @@ type Config struct {
2323
LineBufferSize int `mapstructure:"line-buffer-size"`
2424

2525
//
26-
Listen string `mapstructure:"listen"`
27-
MetricsPath string `mapstructure:"metrics-path"`
28-
ScrapeInterval time.Duration `mapstructure:"scrape-interval"`
26+
Listen string `mapstructure:"listen"`
27+
MetricsPath string `mapstructure:"metrics-path"`
2928

3029
ShutdownDelay time.Duration `mapstructure:"shutdown-delay"`
3130
}
@@ -45,7 +44,6 @@ func parseCommandLineFlags() {
4544
// Prom section
4645
pflag.String("listen", ":8080", "prometheus statistic addr")
4746
pflag.String("metrics-path", "/metrics", "prometheus statistic path")
48-
pflag.Duration("scrape-interval", time.Second, "fpm metrics scrape interval")
4947

5048
pflag.Duration("shutdown-delay", 500*time.Millisecond, "Delay before process shutdown")
5149

cmd/docker-fpm-wrapper/main.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"os/signal"
99
"syscall"
1010

11+
"github.com/prometheus/client_golang/prometheus"
1112
"github.com/prometheus/client_golang/prometheus/promhttp"
1213
"go.uber.org/zap"
1314
"go.uber.org/zap/zapcore"
@@ -86,12 +87,9 @@ func main() {
8687
os.Exit(1)
8788
}
8889

89-
if cfg.ScrapeInterval > 0 {
90-
if err = phpfpm.RegisterPrometheus(fpmConfig, cfg.ScrapeInterval); err != nil {
91-
log.Fatal("can't init prometheus collector", zap.Error(err))
92-
os.Exit(1)
93-
}
94-
}
90+
prometheus.MustRegister(
91+
phpfpm.NewPromCollector(log.Named("prom-collector"), phpfpm.NewPromMetrics(), fpmConfig.Pools),
92+
)
9593

9694
signalCh := make(chan os.Signal, 1)
9795
signal.Notify(signalCh, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGUSR1, syscall.SIGUSR2)

pkg/phpfpm/prom_collector.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package phpfpm
2+
3+
import (
4+
"sync"
5+
6+
"github.com/prometheus/client_golang/prometheus"
7+
"go.uber.org/zap"
8+
)
9+
10+
type PromCollector struct {
11+
log *zap.Logger
12+
metrics *PromMetrics
13+
pools []Pool
14+
}
15+
16+
func NewPromCollector(log *zap.Logger, metrics *PromMetrics, pools []Pool) *PromCollector {
17+
return &PromCollector{
18+
log: log,
19+
metrics: metrics,
20+
pools: pools,
21+
}
22+
}
23+
24+
func (c *PromCollector) Describe(descs chan<- *prometheus.Desc) {
25+
c.metrics.ListenQueue.Describe(descs)
26+
c.metrics.ListenQueueLen.Describe(descs)
27+
c.metrics.IdleProcesses.Describe(descs)
28+
c.metrics.ActiveProcesses.Describe(descs)
29+
c.metrics.TotalProcesses.Describe(descs)
30+
c.metrics.AcceptedConn.Describe(descs)
31+
32+
c.metrics.StartSince.Describe(descs)
33+
c.metrics.MaxListenQueue.Describe(descs)
34+
c.metrics.MaxActiveProcesses.Describe(descs)
35+
c.metrics.MaxChildrenReached.Describe(descs)
36+
c.metrics.SlowRequests.Describe(descs)
37+
}
38+
39+
func (c *PromCollector) setAndCollect(gaugeVec *prometheus.GaugeVec, poolName string, val int, ch chan<- prometheus.Metric) {
40+
gauge := gaugeVec.WithLabelValues(poolName)
41+
gauge.Set(float64(val))
42+
gauge.Collect(ch)
43+
}
44+
45+
func (c *PromCollector) collectForPool(pool Pool, ch chan<- prometheus.Metric) {
46+
status, err := GetStats(pool.Listen, pool.StatusPath)
47+
if err != nil {
48+
c.log.Error("can't collect metrics", zap.String("pool", pool.Name), zap.Error(err))
49+
return
50+
}
51+
52+
c.setAndCollect(c.metrics.ListenQueue, status.Name, status.ListenQueue, ch)
53+
c.setAndCollect(c.metrics.ListenQueueLen, status.Name, status.ListenQueueLen, ch)
54+
c.setAndCollect(c.metrics.IdleProcesses, status.Name, status.IdleProcesses, ch)
55+
c.setAndCollect(c.metrics.ActiveProcesses, status.Name, status.ActiveProcesses, ch)
56+
c.setAndCollect(c.metrics.TotalProcesses, status.Name, status.TotalProcesses, ch)
57+
c.setAndCollect(c.metrics.AcceptedConn, status.Name, status.AcceptedConn, ch)
58+
c.setAndCollect(c.metrics.StartSince, status.Name, status.StartSince, ch)
59+
c.setAndCollect(c.metrics.MaxListenQueue, status.Name, status.MaxListenQueue, ch)
60+
c.setAndCollect(c.metrics.MaxActiveProcesses, status.Name, status.MaxActiveProcesses, ch)
61+
c.setAndCollect(c.metrics.MaxChildrenReached, status.Name, status.MaxChildrenReached, ch)
62+
c.setAndCollect(c.metrics.SlowRequests, status.Name, status.SlowRequests, ch)
63+
}
64+
65+
func (c *PromCollector) Collect(metrics chan<- prometheus.Metric) {
66+
var wg sync.WaitGroup
67+
for pIdx := range c.pools {
68+
pool := c.pools[pIdx]
69+
70+
if pool.StatusPath == "" {
71+
continue
72+
}
73+
74+
wg.Add(1)
75+
go func() {
76+
defer wg.Done()
77+
78+
c.collectForPool(pool, metrics)
79+
}()
80+
}
81+
82+
wg.Wait()
83+
}

pkg/phpfpm/prom_metrics.go

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
package phpfpm
2+
3+
import (
4+
"github.com/prometheus/client_golang/prometheus"
5+
)
6+
7+
const namespace = "phpfpm"
8+
9+
type PromMetrics struct {
10+
ListenQueue *prometheus.GaugeVec
11+
ListenQueueLen *prometheus.GaugeVec
12+
IdleProcesses *prometheus.GaugeVec
13+
ActiveProcesses *prometheus.GaugeVec
14+
TotalProcesses *prometheus.GaugeVec
15+
AcceptedConn *prometheus.GaugeVec
16+
17+
StartSince *prometheus.GaugeVec
18+
MaxListenQueue *prometheus.GaugeVec
19+
MaxActiveProcesses *prometheus.GaugeVec
20+
MaxChildrenReached *prometheus.GaugeVec
21+
SlowRequests *prometheus.GaugeVec
22+
}
23+
24+
func NewPromMetrics() *PromMetrics {
25+
poolLabelNames := []string{"pool_name"}
26+
27+
return &PromMetrics{
28+
StartSince: prometheus.NewGaugeVec(
29+
prometheus.GaugeOpts{
30+
Namespace: namespace,
31+
Name: "start_since",
32+
Help: "Number of seconds since FPM has started",
33+
},
34+
poolLabelNames,
35+
),
36+
AcceptedConn: prometheus.NewGaugeVec(
37+
prometheus.GaugeOpts{
38+
Namespace: namespace,
39+
Name: "accepted_conn",
40+
Help: "The number of requests accepted by the pool",
41+
},
42+
poolLabelNames,
43+
),
44+
ListenQueue: prometheus.NewGaugeVec(
45+
prometheus.GaugeOpts{
46+
Namespace: namespace,
47+
Name: "listen_queue",
48+
Help: "The number of requests in the queue of pending connections",
49+
},
50+
poolLabelNames,
51+
),
52+
MaxListenQueue: prometheus.NewGaugeVec(
53+
prometheus.GaugeOpts{
54+
Namespace: namespace,
55+
Name: "max_listen_queue",
56+
Help: "The maximum number of requests in the queue of pending connections since FPM has started",
57+
},
58+
poolLabelNames,
59+
),
60+
ListenQueueLen: prometheus.NewGaugeVec(
61+
prometheus.GaugeOpts{
62+
Namespace: namespace,
63+
Name: "listen_queue_len",
64+
Help: "The size of the socket queue of pending connections",
65+
},
66+
poolLabelNames,
67+
),
68+
IdleProcesses: prometheus.NewGaugeVec(
69+
prometheus.GaugeOpts{
70+
Namespace: namespace,
71+
Name: "idle_processes",
72+
Help: "The number of idle processes",
73+
},
74+
poolLabelNames,
75+
),
76+
ActiveProcesses: prometheus.NewGaugeVec(
77+
prometheus.GaugeOpts{
78+
Namespace: namespace,
79+
Name: "active_processes",
80+
Help: "The number of active processes",
81+
},
82+
poolLabelNames,
83+
),
84+
TotalProcesses: prometheus.NewGaugeVec(
85+
prometheus.GaugeOpts{
86+
Namespace: namespace,
87+
Name: "total_processes",
88+
Help: "The number of idle + active processes",
89+
},
90+
poolLabelNames,
91+
),
92+
MaxActiveProcesses: prometheus.NewGaugeVec(
93+
prometheus.GaugeOpts{
94+
Namespace: namespace,
95+
Name: "max_active_processes",
96+
Help: "The maximum number of active processes since FPM has started",
97+
},
98+
poolLabelNames,
99+
),
100+
MaxChildrenReached: prometheus.NewGaugeVec(
101+
prometheus.GaugeOpts{
102+
Namespace: namespace,
103+
Name: "max_children_reached",
104+
Help: "The number of times, the process limit has been reached, when pm tries to start more children (works only for pm 'dynamic' and 'ondemand')",
105+
},
106+
poolLabelNames,
107+
),
108+
SlowRequests: prometheus.NewGaugeVec(
109+
prometheus.GaugeOpts{
110+
Namespace: namespace,
111+
Name: "slow_requests",
112+
Help: "The number of requests that exceeded your request_slowlog_timeout value",
113+
},
114+
poolLabelNames,
115+
),
116+
}
117+
}

0 commit comments

Comments
 (0)