Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,9 +202,19 @@ It is not recommended to amend config file while application is still running.

## Monitoring

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

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.
- **Metrics**: `http://localhost:8639/metrics` (Prometheus format)
- **Profiling**: `http://localhost:8639/api/v0/debug/pprof/`

A pre-packaged monitoring stack is available in the [monitoring/](monitoring/) directory with:

- **Prometheus** — scrapes AWL metrics
- **Grafana** — dashboards for libp2p subsystems and AWL-specific metrics, plus profile exploration via Pyroscope datasource
- **Pyroscope** — continuous profiling storage
- **Grafana Alloy** — scrapes pprof endpoints and pushes CPU, heap, goroutine, mutex, and block profiles to Pyroscope

See [monitoring/README.md](monitoring/README.md) for setup instructions.

## Terminal based client

Expand Down
20 changes: 9 additions & 11 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,17 +133,15 @@ func (h *Handler) setupRouter(address string) (*echo.Echo, error) {
e.GET(GetP2pDebugInfoPath, h.GetP2pDebugInfo)
e.GET(GetDebugLogPath, h.GetLog)

if h.conf.DevMode() {
e.Any(V0Prefix+"debug/pprof/", echo.WrapHandler(http.HandlerFunc(http_pprof.Index)))
e.Any(V0Prefix+"debug/pprof/profile", echo.WrapHandler(http.HandlerFunc(http_pprof.Profile)))
e.Any(V0Prefix+"debug/pprof/trace", echo.WrapHandler(http.HandlerFunc(http_pprof.Trace)))
e.Any(V0Prefix+"debug/pprof/cmdline", echo.WrapHandler(http.HandlerFunc(http_pprof.Cmdline)))
e.Any(V0Prefix+"debug/pprof/symbol", echo.WrapHandler(http.HandlerFunc(http_pprof.Symbol)))

for _, p := range pprof.Profiles() {
name := p.Name()
e.Any(V0Prefix+"debug/pprof/"+name, echo.WrapHandler(http_pprof.Handler(name)))
}
e.Any(V0Prefix+"debug/pprof/", echo.WrapHandler(http.HandlerFunc(http_pprof.Index)))
e.Any(V0Prefix+"debug/pprof/profile", echo.WrapHandler(http.HandlerFunc(http_pprof.Profile)))
e.Any(V0Prefix+"debug/pprof/trace", echo.WrapHandler(http.HandlerFunc(http_pprof.Trace)))
e.Any(V0Prefix+"debug/pprof/cmdline", echo.WrapHandler(http.HandlerFunc(http_pprof.Cmdline)))
e.Any(V0Prefix+"debug/pprof/symbol", echo.WrapHandler(http.HandlerFunc(http_pprof.Symbol)))

for _, p := range pprof.Profiles() {
name := p.Name()
e.Any(V0Prefix+"debug/pprof/"+name, echo.WrapHandler(http_pprof.Handler(name)))
}

// Start
Expand Down
9 changes: 9 additions & 0 deletions monitoring/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ docker compose -f docker-compose.yml -f docker-compose-linux.yml up
Then open:
- **Grafana**: http://localhost:3000 (no login required)
- **Prometheus**: http://localhost:9090
- **Pyroscope**: http://localhost:4040

## Continuous Profiling

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.

To view profiles in Grafana: **Explore → select Pyroscope datasource** → pick `process_cpu{app="anywherelan"}` (or `memory`, `goroutine`, etc.).

You can also browse profiles directly in the Pyroscope UI at http://localhost:4040.

## Metrics Reference

Expand Down
41 changes: 41 additions & 0 deletions monitoring/alloy/config.alloy
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
pyroscope.scrape "anywherelan" {
targets = [{
__address__ = "host.docker.internal:8639",
"service_name" = "anywherelan",
}]
forward_to = [pyroscope.write.local.receiver]

profiling_config {
profile.process_cpu {
enabled = true
path = "/api/v0/debug/pprof/profile"
delta = true
}
profile.memory {
enabled = true
path = "/api/v0/debug/pprof/heap"
delta = false
}
profile.goroutine {
enabled = true
path = "/api/v0/debug/pprof/goroutine"
delta = false
}
profile.mutex {
enabled = true
path = "/api/v0/debug/pprof/mutex"
delta = true
}
profile.block {
enabled = true
path = "/api/v0/debug/pprof/block"
delta = true
}
}
}

pyroscope.write "local" {
endpoint {
url = "http://pyroscope:4040"
}
}
12 changes: 11 additions & 1 deletion monitoring/docker-compose-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,18 @@ services:
extra_hosts:
# define a host.docker.internal alias, so we can use the same prometheus.yml on Linux and macOS
- "host.docker.internal:127.0.0.1"
pyroscope:
network_mode: "host"
alloy:
network_mode: "host"
extra_hosts:
# define a host.docker.internal alias, so we can use the same config.alloy on Linux and macOS
- "host.docker.internal:127.0.0.1"
# define a pyroscope alias so Alloy can reach Pyroscope via the same URL on Linux and macOS
- "pyroscope:127.0.0.1"
grafana:
network_mode: "host"
extra_hosts:
# define a prometheus alias, so we can use the same datasources.yml on Linux and macOS
# define aliases so we can use the same datasources.yml on Linux and macOS
- "prometheus:127.0.0.1"
- "pyroscope:127.0.0.1"
13 changes: 13 additions & 0 deletions monitoring/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,29 @@ services:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
pyroscope:
image: grafana/pyroscope:latest
ports:
- "4040:4040"
alloy:
image: grafana/alloy:latest
depends_on:
- pyroscope
volumes:
- ./alloy/config.alloy:/etc/alloy/config.alloy
command: run /etc/alloy/config.alloy
grafana:
image: grafana/grafana:latest
depends_on:
- prometheus
- pyroscope
ports:
- "3000:3000"
environment:
- GF_AUTH_DISABLE_LOGIN_FORM=true
- GF_AUTH_ANONYMOUS_ENABLED=true
- GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
- GF_INSTALL_PLUGINS=grafana-pyroscope-app
volumes:
- ./grafana/dashboard.yml:/etc/grafana/provisioning/dashboards/main.yml
- ./grafana/datasources.yml:/etc/grafana/provisioning/datasources/prom.yml
Expand Down
8 changes: 8 additions & 0 deletions monitoring/grafana/datasources.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ apiVersion: 1
deleteDatasources:
- name: Prometheus
orgId: 1
- name: Pyroscope
orgId: 1

datasources:
- name: Prometheus
Expand All @@ -11,3 +13,9 @@ datasources:
access: proxy
url: http://prometheus:9090
editable: false
- name: Pyroscope
orgId: 1
type: grafana-pyroscope-datasource
access: proxy
url: http://pyroscope:4040
editable: false
Loading