Skip to content

Commit 57ef965

Browse files
Publish v0.1.3
1 parent 8af49b9 commit 57ef965

22 files changed

Lines changed: 1009 additions & 25 deletions

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Build output
2+
phpscope
3+
4+
# OS
5+
.DS_Store

CHANGELOG.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [v0.1.3] - 2026-04-20
9+
10+
### Added
11+
- Helm chart example for deploying WordPress + MySQL + Nginx with PHPScope as a sidecar container and Pyroscope as a subchart dependency (`examples/helm-chart/wordpress-example`)
12+
13+
### Changed
14+
- Go version bumped from `1.23.3` to `1.26.2`
15+
- Builder Docker image updated: `golang:1.23.3-alpine``golang:1.26.2-alpine3.23`
16+
- phpspy build stage base image updated: `alpine:3.21``alpine:3.23`
17+
- Pyroscope image in Docker Compose updated: `1.12.0``1.21.0`
18+
- `github.com/google/pprof` dependency updated to `v0.0.0-20260402051712-545e8a4df936`
19+
20+
### Fixed
21+
- Typos in README (`trought``through`, `Incuded``Included`)
22+
- README Go version prerequisite corrected to `1.26.2`
23+
24+
## [v0.1.2] - 2025-04-11
25+
26+
### Added
27+
- `--pgrep` flag to configure the pgrep pattern used by phpspy for PHP process discovery (default: `-x "(php-fpm.*|^php$)"`)
28+
- `pgrepPattern` displayed in the startup banner
29+
30+
### Changed
31+
- phpspy process filter is no longer hardcoded — it is now driven by the `--pgrep` argument
32+
33+
## [v0.1.1] - 2025-03-03
34+
35+
### Added
36+
- `--phpspyRequestInfo` flag to control which request info fields phpspy includes in traces (default: `qcup`)
37+
38+
### Fixed
39+
- `PhpspyRequestInfo` argument was not being passed correctly to phpspy
40+
41+
## [v0.1.0] - 2025-02-20
42+
43+
### Added
44+
- Initial pre-release of PHPScope
45+
- Continuous PHP profiling via [phpspy](https://github.com/adsr/phpspy) with Pyroscope integration
46+
- Support for PHP-FPM and PHP CLI process profiling
47+
- Configurable sampling rate (`--rateHz`), batch size (`--batch`), and send interval (`--interval`)
48+
- Function exclusion via regex pattern (`--exclude`)
49+
- Custom tag support (`--tags key=value`)
50+
- Docker image with phpspy and binutils bundled
51+
- Docker Compose setup with Pyroscope for local usage

Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM golang:1.23.3-alpine AS builder
1+
FROM golang:1.26.2-alpine3.23 AS builder
22

33
RUN apk add --no-cache git
44

@@ -14,7 +14,7 @@ COPY . .
1414

1515
RUN CGO_ENABLED=0 GOOS=linux go build -o phpscope .
1616

17-
FROM alpine:3.21 AS phpspy
17+
FROM alpine:3.23 AS phpspy
1818

1919
# Install phpspy
2020
RUN apk add --no-cache git make gcc g++ libc-dev && \

README.md

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
[![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner2-direct.svg)](https://vshymanskyy.github.io/StandWithUkraine/)
44

5-
PHPScope is a PHP profiling tool based on [phpspy](https://github.com/adsr/phpspy) that integrates with Pyroscope to provide continuous profiling for PHP applications. It captures trought [phpspy](https://github.com/adsr/phpspy) PHP-FPM and PHP CLI processes performance data and sends it to a Pyroscope server for visualization and analysis.
5+
PHPScope is a PHP profiling tool based on [phpspy](https://github.com/adsr/phpspy) that integrates with Pyroscope to provide continuous profiling for PHP applications. It captures through [phpspy](https://github.com/adsr/phpspy) PHP-FPM and PHP CLI processes performance data and sends it to a Pyroscope server for visualization and analysis.
66

77
## Features
88

@@ -27,10 +27,10 @@ The diagram above shows the main components of PHPScope:
2727

2828
## Prerequisites
2929

30-
- Go 1.23.3 or higher
30+
- Go 1.26.2 or higher
3131
- PHP-FPM or PHP CLI processes running ( Tested on PHP 8.3 )
3232
- Access to a Pyroscope server
33-
- phpspy installed on the system ( Incuded in docker container )
33+
- phpspy installed on the system ( Included in docker container )
3434

3535
## Installation
3636

@@ -39,15 +39,47 @@ You can either run PHPScope using Docker Compose or build it from source.
3939
### Using Docker Compose
4040

4141
```shell
42-
curl -sSL https://raw.githubusercontent.com/everythings-gonna-be-alright/phpScope/refs/heads/main/docker-compose.yaml | docker compose -f - up -d
42+
curl -sSL https://raw.githubusercontent.com/everythings-gonna-be-alright/phpScope/refs/heads/main/examples/docker-compose/docker-compose.yaml | docker compose -f - up -d
4343
```
4444

45+
Once running, PHPScope will automatically discover and profile all PHP processes (PHP-FPM and PHP CLI) running on the host — including those inside Docker containers — and continuously stream profiling data to the bundled Pyroscope instance.
46+
4547
After installation, you can access the Pyroscope UI at:
4648

4749
```shell
4850
http://127.0.0.1:4040
4951
```
5052

53+
### Deploying on Kubernetes (Helm)
54+
55+
For Kubernetes environments, the recommended approach is to run PHPScope as a **sidecar container** alongside your PHP application pod. This gives PHPScope direct access to the PHP processes within the same pod namespace without requiring host-level privileges beyond the pod boundary.
56+
57+
A Helm chart example is available in [`examples/helm-chart/wordpress-example`](examples/helm-chart/wordpress-example). It includes a full deployment with PHPScope as a sidecar, Pyroscope as a subchart dependency, NetworkPolicy, and all required RBAC resources.
58+
59+
```shell
60+
git clone https://github.com/everythings-gonna-be-alright/phpScope
61+
cd phpScope/
62+
63+
# Install into your cluster
64+
helm upgrade --install wordpress-example examples/helm-chart/wordpress-example/ \
65+
--namespace wordpress-example \
66+
--create-namespace
67+
```
68+
69+
Once installed, use port-forwarding to access the services locally:
70+
71+
```shell
72+
# Pyroscope UI
73+
kubectl port-forward -n wordpress-example svc/wordpress-example-pyroscope 4040:4040
74+
75+
# WordPress
76+
kubectl port-forward -n wordpress-example svc/wordpress-example 8080:8080
77+
```
78+
79+
Then open:
80+
- Pyroscope UI: `http://localhost:4040`
81+
- WordPress: `http://localhost:8080`
82+
5183
### Building from Source
5284

5385
```shell
@@ -66,21 +98,23 @@ Basic usage example:
6698

6799
### Command Line Options
68100

69-
| Option | Default | Description |
70-
|--------|---------|-------------|
71-
| --pyroscopeUrl | required | URL of the Pyroscope server |
72-
| --auth | "" | Pyroscope authentication token |
73-
| --appName | required | Application name for profiling |
74-
| --rateHz | 400 | Sample rate in Hz |
75-
| --interval | 0.1 | Maximum time between requests to Pyroscope server |
76-
| --batch | 50000 | Maximum number of traces in request |
77-
| --concurrent | 1 | Concurrent request limit |
78-
| --exclude | "" | Regex pattern to exclude functions |
79-
| --tags | [] | Tags in format key=value |
80-
| --phpspyBufferSize | 131072 | phpspy buffer size |
81-
| --phpspyMaxDepth | 50000 | phpspy max stack depth |
82-
| --phpspyThreads | 64 | phpspy threads count |
83-
| --debug | false | Enable debug logging |
101+
| Option | Default | Description |
102+
|---------------------|---------------------------|---------------------------------------------------|
103+
| --pyroscopeUrl | required | URL of the Pyroscope server |
104+
| --auth | "" | Pyroscope authentication token |
105+
| --appName | required | Application name for profiling |
106+
| --rateHz | 400 | Sample rate in Hz |
107+
| --interval | 0.1 | Maximum time between requests to Pyroscope server |
108+
| --batch | 50000 | Maximum number of traces in request |
109+
| --concurrent | 1 | Concurrent request limit |
110+
| --exclude | "" | Regex pattern to exclude functions |
111+
| --tags | [] | Tags in format key=value |
112+
| --phpspyBufferSize | 131072 | phpspy buffer size |
113+
| --phpspyMaxDepth | -1 | phpspy max stack depth (-1 = unlimited) |
114+
| --phpspyThreads | 64 | phpspy threads count |
115+
| --phpspyRequestInfo | qcup | Request info fields included in traces |
116+
| --pgrep | `-x "(php-fpm.*\|^php$)"` | pgrep pattern for finding PHP processes |
117+
| --debug | false | Enable debug logging |
84118

85119
## Example
86120

docker-compose.yaml renamed to examples/docker-compose/docker-compose.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
services:
22
pyroscope:
3-
image: grafana/pyroscope:1.12.0
3+
image: grafana/pyroscope:1.21.0
44
ports:
55
- 4040:4040
66
command:
@@ -22,4 +22,4 @@ services:
2222
cap_add:
2323
- SYS_PTRACE
2424
security_opt:
25-
- apparmor=unconfined
25+
- apparmor=unconfined
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
dependencies:
2+
- name: pyroscope
3+
repository: https://grafana.github.io/helm-charts
4+
version: 1.21.0
5+
digest: sha256:875a8cabe90f2a20da1c70e1461273b87dbe959d30e808607889fb23721cb353
6+
generated: "2026-04-19T23:02:27.340978+03:00"
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
apiVersion: v2
2+
name: wordpress-example
3+
description: WordPress + MySQL + phpScope profiling sidecar + Grafana Pyroscope
4+
type: application
5+
version: 0.1.0
6+
appVersion: "php8.3-apache"
7+
keywords:
8+
- wordpress
9+
- mysql
10+
- php
11+
- phpscope
12+
- pyroscope
13+
maintainers:
14+
- name: everything-gonna-be-alright
15+
dependencies:
16+
- name: pyroscope
17+
version: "1.21.0"
18+
repository: "https://grafana.github.io/helm-charts"
19+
condition: pyroscope.enabled
Binary file not shown.
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{{- define "wordpress-example.name" -}}
2+
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
3+
{{- end }}
4+
5+
{{- define "wordpress-example.fullname" -}}
6+
{{- if .Values.fullnameOverride }}
7+
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
8+
{{- else }}
9+
{{- $name := default .Chart.Name .Values.nameOverride }}
10+
{{- if contains $name .Release.Name }}
11+
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
12+
{{- else }}
13+
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
14+
{{- end }}
15+
{{- end }}
16+
{{- end }}
17+
18+
{{- define "wordpress-example.chart" -}}
19+
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
20+
{{- end }}
21+
22+
{{- define "wordpress-example.labels" -}}
23+
helm.sh/chart: {{ include "wordpress-example.chart" . }}
24+
{{ include "wordpress-example.selectorLabels" . }}
25+
{{- if .Chart.AppVersion }}
26+
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
27+
{{- end }}
28+
app.kubernetes.io/managed-by: {{ .Release.Service }}
29+
{{- end }}
30+
31+
{{- define "wordpress-example.selectorLabels" -}}
32+
app.kubernetes.io/name: {{ include "wordpress-example.name" . }}
33+
app.kubernetes.io/instance: {{ .Release.Name }}
34+
{{- end }}
35+
36+
{{- define "wordpress-example.serviceAccountName" -}}
37+
{{- if .Values.serviceAccount.create }}
38+
{{- default (include "wordpress-example.fullname" .) .Values.serviceAccount.name }}
39+
{{- else }}
40+
{{- default "default" .Values.serviceAccount.name }}
41+
{{- end }}
42+
{{- end }}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
{{- $pyroscopeUrl := .Values.phpscope.config.pyroscopeUrl -}}
2+
{{- if .Values.pyroscope.enabled -}}
3+
{{- $pyroscopeUrl = printf "http://%s-pyroscope:%d" .Release.Name (.Values.pyroscope.pyroscope.service.port | int) -}}
4+
{{- end -}}
5+
apiVersion: v1
6+
kind: ConfigMap
7+
metadata:
8+
name: {{ include "wordpress-example.fullname" . }}-phpscope
9+
namespace: {{ .Release.Namespace }}
10+
labels:
11+
{{- include "wordpress-example.labels" . | nindent 4 }}
12+
data:
13+
pyroscopeUrl: {{ $pyroscopeUrl | quote }}
14+
appName: {{ .Values.phpscope.config.appName | quote }}
15+
---
16+
apiVersion: v1
17+
kind: ConfigMap
18+
metadata:
19+
name: {{ include "wordpress-example.fullname" . }}-nginx
20+
namespace: {{ .Release.Namespace }}
21+
labels:
22+
{{- include "wordpress-example.labels" . | nindent 4 }}
23+
data:
24+
default.conf: |
25+
server {
26+
listen {{ .Values.service.port }};
27+
server_name _;
28+
root /var/www/html;
29+
index index.php;
30+
31+
client_max_body_size 64m;
32+
33+
location / {
34+
try_files $uri $uri/ /index.php?$args;
35+
}
36+
37+
location ~ \.php$ {
38+
fastcgi_split_path_info ^(.+\.php)(/.+)$;
39+
fastcgi_pass 127.0.0.1:9000;
40+
fastcgi_index index.php;
41+
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
42+
fastcgi_read_timeout 300;
43+
include fastcgi_params;
44+
}
45+
46+
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
47+
expires max;
48+
log_not_found off;
49+
}
50+
51+
location ~ /\.ht {
52+
deny all;
53+
}
54+
}

0 commit comments

Comments
 (0)