diff --git a/Dockerfile b/Dockerfile index 24312888d..4ff208bfb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -112,7 +112,7 @@ ENV CGO_LDFLAGS="-L/usr/local/lib -lssl -lcrypto -lreadline -largon2 -lcurl -lon RUN echo $CGO_LDFLAGS WORKDIR /go/src/app/caddy/frankenphp -RUN GOBIN=/usr/local/bin go install -tags 'nobadger,nomysql,nopgx' -ldflags "-w -s -X 'github.com/caddyserver/caddy/v2.CustomVersion=FrankenPHP $FRANKENPHP_VERSION PHP $PHP_VERSION Caddy'" && \ +RUN GOBIN=/usr/local/bin go install -tags 'nobadger,nomysql,nopgx' -ldflags "-w -s -X 'github.com/dunglas/frankenphp.VersionString=$FRANKENPHP_VERSION' -X 'github.com/caddyserver/caddy/v2.CustomVersion=FrankenPHP $FRANKENPHP_VERSION PHP $PHP_VERSION Caddy'" && \ setcap cap_net_bind_service=+ep /usr/local/bin/frankenphp && \ cp Caddyfile /etc/caddy/Caddyfile && \ frankenphp version diff --git a/alpine.Dockerfile b/alpine.Dockerfile index 0270825d1..63da85211 100644 --- a/alpine.Dockerfile +++ b/alpine.Dockerfile @@ -131,7 +131,7 @@ ENV CGO_CPPFLAGS=$PHP_CPPFLAGS ENV CGO_LDFLAGS="-lssl -lcrypto -lreadline -largon2 -lcurl -lonig -lz $PHP_LDFLAGS" WORKDIR /go/src/app/caddy/frankenphp -RUN GOBIN=/usr/local/bin go install -tags 'nobadger,nomysql,nopgx' -ldflags "-w -s -extldflags '-Wl,-z,stack-size=0x80000' -X 'github.com/caddyserver/caddy/v2.CustomVersion=FrankenPHP $FRANKENPHP_VERSION PHP $PHP_VERSION Caddy'" && \ +RUN GOBIN=/usr/local/bin go install -tags 'nobadger,nomysql,nopgx' -ldflags "-w -s -extldflags '-Wl,-z,stack-size=0x80000' -X 'github.com/dunglas/frankenphp.VersionString=$FRANKENPHP_VERSION' -X 'github.com/caddyserver/caddy/v2.CustomVersion=FrankenPHP $FRANKENPHP_VERSION PHP $PHP_VERSION Caddy'" && \ setcap cap_net_bind_service=+ep /usr/local/bin/frankenphp && \ ([ -z "${NO_COMPRESS}" ] && upx --best /usr/local/bin/frankenphp || true) && \ frankenphp version diff --git a/build-static.sh b/build-static.sh index c72594094..c3674cce1 100755 --- a/build-static.sh +++ b/build-static.sh @@ -271,7 +271,7 @@ fi cd caddy/frankenphp/ go env -go build -buildmode=pie -tags "cgo,netgo,osusergo,static_build,nobadger,nomysql,nopgx" -ldflags "-linkmode=external -extldflags '-static-pie ${extraExtldflags}' ${extraLdflags} -X 'github.com/caddyserver/caddy/v2.CustomVersion=FrankenPHP ${FRANKENPHP_VERSION} PHP ${LIBPHP_VERSION} Caddy'" -o "../../dist/${bin}" +go build -buildmode=pie -tags "cgo,netgo,osusergo,static_build,nobadger,nomysql,nopgx" -ldflags "-linkmode=external -extldflags '-static-pie ${extraExtldflags}' ${extraLdflags} -X 'github.com/dunglas/frankenphp.VersionString=${FRANKENPHP_VERSION}' -X 'github.com/caddyserver/caddy/v2.CustomVersion=FrankenPHP ${FRANKENPHP_VERSION} PHP ${LIBPHP_VERSION} Caddy'" -o "../../dist/${bin}" cd ../.. if [ -d "${EMBED}" ]; then diff --git a/caddy/caddy_test.go b/caddy/caddy_test.go index 51a0ca8e0..e63b3974d 100644 --- a/caddy/caddy_test.go +++ b/caddy/caddy_test.go @@ -460,6 +460,10 @@ func TestWorkerMetrics(t *testing.T) { # HELP frankenphp_testdata_index_php_worker_restarts Number of PHP worker restarts for this worker # TYPE frankenphp_testdata_index_php_worker_restarts counter frankenphp_testdata_index_php_worker_restarts 0 + + # HELP frankenphp_version Current version of FrankenPHP + # TYPE frankenphp_version gauge + frankenphp_version{php_version="` + frankenphp.Version().Version + `",version="dev"} 1 ` require.NoError(t, @@ -474,6 +478,7 @@ func TestWorkerMetrics(t *testing.T) { "frankenphp_testdata_index_php_worker_crashes", "frankenphp_testdata_index_php_worker_restarts", "frankenphp_testdata_index_php_ready_workers", + "frankenphp_version", )) } diff --git a/docs/metrics.md b/docs/metrics.md index d15020543..8c835b275 100644 --- a/docs/metrics.md +++ b/docs/metrics.md @@ -11,5 +11,6 @@ When [Caddy metrics](https://caddyserver.com/docs/metrics) are enabled, FrankenP * `frankenphp_[worker]_worker_restarts`: The number of times a worker has been deliberately restarted. * `frankenphp_total_threads`: The total number of PHP threads. * `frankenphp_busy_threads`: The number of PHP threads currently processing a request (running workers always consume a thread). +* `frankenphp_version`: The current version of FrankenPHP and PHP as a label. For worker metrics, the `[worker]` placeholder is replaced by the worker script path in the Caddyfile. diff --git a/frankenphp.go b/frankenphp.go index 4f3544e4c..c833d4234 100644 --- a/frankenphp.go +++ b/frankenphp.go @@ -349,7 +349,7 @@ func Init(options ...Option) error { } if c := logger.Check(zapcore.InfoLevel, "FrankenPHP started 🐘"); c != nil { - c.Write(zap.String("php_version", Version().Version), zap.Int("num_threads", opt.numThreads)) + c.Write(zap.String("php_version", Version().Version), zap.Int("num_threads", opt.numThreads), zap.String("frankenphp_version", VersionString)) } if EmbeddedAppPath != "" { if c := logger.Check(zapcore.InfoLevel, "embedded PHP app 📦"); c != nil { diff --git a/metrics.go b/metrics.go index 467e1a5dc..f27da4022 100644 --- a/metrics.go +++ b/metrics.go @@ -11,6 +11,7 @@ import ( var metricsNameRegex = regexp.MustCompile(`\W+`) var metricsNameFixRegex = regexp.MustCompile(`^_+|_+$`) +var VersionString = "dev" const ( StopReasonCrash = iota @@ -85,6 +86,7 @@ type PrometheusMetrics struct { workerRestarts map[string]prometheus.Counter workerRequestTime map[string]prometheus.Counter workerRequestCount map[string]prometheus.Counter + version *prometheus.GaugeVec mu sync.Mutex } @@ -292,6 +294,8 @@ func (m *PrometheusMetrics) Shutdown() { m.workerCrashes = map[string]prometheus.Counter{} m.readyWorkers = map[string]prometheus.Gauge{} + // version does not change while running/restarting/stopping + m.registry.MustRegister(m.totalThreads) m.registry.MustRegister(m.busyThreads) } @@ -325,8 +329,15 @@ func NewPrometheusMetrics(registry prometheus.Registerer) *PrometheusMetrics { workerRestarts: map[string]prometheus.Counter{}, workerCrashes: map[string]prometheus.Counter{}, readyWorkers: map[string]prometheus.Gauge{}, + version: prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Name: "frankenphp_version", + Help: "Current version of FrankenPHP", + }, []string{"version", "php_version"}), } + m.registry.MustRegister(m.version) + m.version.WithLabelValues(VersionString, Version().Version).Set(1) + m.registry.MustRegister(m.totalThreads) m.registry.MustRegister(m.busyThreads)