Skip to content

Commit 12baadc

Browse files
authored
Merge pull request #218 from anywherelan/continuous-profiling
monitoring: add continuous profiling Pyroscope to docker compose
2 parents 9e956cd + 9222a8a commit 12baadc

File tree

7 files changed

+103
-14
lines changed

7 files changed

+103
-14
lines changed

README.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,9 +202,19 @@ It is not recommended to amend config file while application is still running.
202202

203203
## Monitoring
204204

205-
AWL includes built-in Prometheus metrics support. You can access the metrics endpoint at `http://localhost:8639/metrics`.
205+
AWL includes built-in Prometheus metrics and pprof profiling support:
206206

207-
A pre-packaged monitoring stack with Prometheus and Grafana dashboards is available in the [monitoring/](monitoring/) directory. See [monitoring/README.md](monitoring/README.md) for setup instructions.
207+
- **Metrics**: `http://localhost:8639/metrics` (Prometheus format)
208+
- **Profiling**: `http://localhost:8639/api/v0/debug/pprof/`
209+
210+
A pre-packaged monitoring stack is available in the [monitoring/](monitoring/) directory with:
211+
212+
- **Prometheus** — scrapes AWL metrics
213+
- **Grafana** — dashboards for libp2p subsystems and AWL-specific metrics, plus profile exploration via Pyroscope datasource
214+
- **Pyroscope** — continuous profiling storage
215+
- **Grafana Alloy** — scrapes pprof endpoints and pushes CPU, heap, goroutine, mutex, and block profiles to Pyroscope
216+
217+
See [monitoring/README.md](monitoring/README.md) for setup instructions.
208218

209219
## Terminal based client
210220

api/api.go

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -133,17 +133,15 @@ func (h *Handler) setupRouter(address string) (*echo.Echo, error) {
133133
e.GET(GetP2pDebugInfoPath, h.GetP2pDebugInfo)
134134
e.GET(GetDebugLogPath, h.GetLog)
135135

136-
if h.conf.DevMode() {
137-
e.Any(V0Prefix+"debug/pprof/", echo.WrapHandler(http.HandlerFunc(http_pprof.Index)))
138-
e.Any(V0Prefix+"debug/pprof/profile", echo.WrapHandler(http.HandlerFunc(http_pprof.Profile)))
139-
e.Any(V0Prefix+"debug/pprof/trace", echo.WrapHandler(http.HandlerFunc(http_pprof.Trace)))
140-
e.Any(V0Prefix+"debug/pprof/cmdline", echo.WrapHandler(http.HandlerFunc(http_pprof.Cmdline)))
141-
e.Any(V0Prefix+"debug/pprof/symbol", echo.WrapHandler(http.HandlerFunc(http_pprof.Symbol)))
142-
143-
for _, p := range pprof.Profiles() {
144-
name := p.Name()
145-
e.Any(V0Prefix+"debug/pprof/"+name, echo.WrapHandler(http_pprof.Handler(name)))
146-
}
136+
e.Any(V0Prefix+"debug/pprof/", echo.WrapHandler(http.HandlerFunc(http_pprof.Index)))
137+
e.Any(V0Prefix+"debug/pprof/profile", echo.WrapHandler(http.HandlerFunc(http_pprof.Profile)))
138+
e.Any(V0Prefix+"debug/pprof/trace", echo.WrapHandler(http.HandlerFunc(http_pprof.Trace)))
139+
e.Any(V0Prefix+"debug/pprof/cmdline", echo.WrapHandler(http.HandlerFunc(http_pprof.Cmdline)))
140+
e.Any(V0Prefix+"debug/pprof/symbol", echo.WrapHandler(http.HandlerFunc(http_pprof.Symbol)))
141+
142+
for _, p := range pprof.Profiles() {
143+
name := p.Name()
144+
e.Any(V0Prefix+"debug/pprof/"+name, echo.WrapHandler(http_pprof.Handler(name)))
147145
}
148146

149147
// Start

monitoring/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@ docker compose -f docker-compose.yml -f docker-compose-linux.yml up
2121
Then open:
2222
- **Grafana**: http://localhost:3000 (no login required)
2323
- **Prometheus**: http://localhost:9090
24+
- **Pyroscope**: http://localhost:4040
25+
26+
## Continuous Profiling
27+
28+
AWL exposes pprof endpoints at `http://localhost:8639/api/v0/debug/pprof/`. **Grafana Alloy** scrapes these every 15 seconds (CPU, heap, goroutine, mutex, block profiles) and pushes them to **Pyroscope** for storage and querying.
29+
30+
To view profiles in Grafana: **Explore → select Pyroscope datasource** → pick `process_cpu{app="anywherelan"}` (or `memory`, `goroutine`, etc.).
31+
32+
You can also browse profiles directly in the Pyroscope UI at http://localhost:4040.
2433

2534
## Metrics Reference
2635

monitoring/alloy/config.alloy

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
pyroscope.scrape "anywherelan" {
2+
targets = [{
3+
__address__ = "host.docker.internal:8639",
4+
"service_name" = "anywherelan",
5+
}]
6+
forward_to = [pyroscope.write.local.receiver]
7+
8+
profiling_config {
9+
profile.process_cpu {
10+
enabled = true
11+
path = "/api/v0/debug/pprof/profile"
12+
delta = true
13+
}
14+
profile.memory {
15+
enabled = true
16+
path = "/api/v0/debug/pprof/heap"
17+
delta = false
18+
}
19+
profile.goroutine {
20+
enabled = true
21+
path = "/api/v0/debug/pprof/goroutine"
22+
delta = false
23+
}
24+
profile.mutex {
25+
enabled = true
26+
path = "/api/v0/debug/pprof/mutex"
27+
delta = true
28+
}
29+
profile.block {
30+
enabled = true
31+
path = "/api/v0/debug/pprof/block"
32+
delta = true
33+
}
34+
}
35+
}
36+
37+
pyroscope.write "local" {
38+
endpoint {
39+
url = "http://pyroscope:4040"
40+
}
41+
}

monitoring/docker-compose-linux.yml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,18 @@ services:
44
extra_hosts:
55
# define a host.docker.internal alias, so we can use the same prometheus.yml on Linux and macOS
66
- "host.docker.internal:127.0.0.1"
7+
pyroscope:
8+
network_mode: "host"
9+
alloy:
10+
network_mode: "host"
11+
extra_hosts:
12+
# define a host.docker.internal alias, so we can use the same config.alloy on Linux and macOS
13+
- "host.docker.internal:127.0.0.1"
14+
# define a pyroscope alias so Alloy can reach Pyroscope via the same URL on Linux and macOS
15+
- "pyroscope:127.0.0.1"
716
grafana:
817
network_mode: "host"
918
extra_hosts:
10-
# define a prometheus alias, so we can use the same datasources.yml on Linux and macOS
19+
# define aliases so we can use the same datasources.yml on Linux and macOS
1120
- "prometheus:127.0.0.1"
21+
- "pyroscope:127.0.0.1"

monitoring/docker-compose.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,29 @@ services:
55
- "9090:9090"
66
volumes:
77
- ./prometheus.yml:/etc/prometheus/prometheus.yml
8+
pyroscope:
9+
image: grafana/pyroscope:latest
10+
ports:
11+
- "4040:4040"
12+
alloy:
13+
image: grafana/alloy:latest
14+
depends_on:
15+
- pyroscope
16+
volumes:
17+
- ./alloy/config.alloy:/etc/alloy/config.alloy
18+
command: run /etc/alloy/config.alloy
819
grafana:
920
image: grafana/grafana:latest
1021
depends_on:
1122
- prometheus
23+
- pyroscope
1224
ports:
1325
- "3000:3000"
1426
environment:
1527
- GF_AUTH_DISABLE_LOGIN_FORM=true
1628
- GF_AUTH_ANONYMOUS_ENABLED=true
1729
- GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
30+
- GF_INSTALL_PLUGINS=grafana-pyroscope-app
1831
volumes:
1932
- ./grafana/dashboard.yml:/etc/grafana/provisioning/dashboards/main.yml
2033
- ./grafana/datasources.yml:/etc/grafana/provisioning/datasources/prom.yml

monitoring/grafana/datasources.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ apiVersion: 1
33
deleteDatasources:
44
- name: Prometheus
55
orgId: 1
6+
- name: Pyroscope
7+
orgId: 1
68

79
datasources:
810
- name: Prometheus
@@ -11,3 +13,9 @@ datasources:
1113
access: proxy
1214
url: http://prometheus:9090
1315
editable: false
16+
- name: Pyroscope
17+
orgId: 1
18+
type: grafana-pyroscope-datasource
19+
access: proxy
20+
url: http://pyroscope:4040
21+
editable: false

0 commit comments

Comments
 (0)