Grafana Pyroscope es una plataforma de perfilado continuo que te ayuda a encontrar cuellos de botella de rendimiento en tus aplicaciones. Soporta múltiples lenguajes, se integra nativamente con Grafana y ofrece modos push y pull para la recopilación de perfiles.
Instalación
Linux/Ubuntu
# Download Pyroscope binary
curl -fL https://github.com/grafana/pyroscope/releases/latest/download/pyroscope_Linux_x86_64.tar.gz | tar xz
sudo mv pyroscope /usr/local/bin/
# Verify
pyroscope --version
# Docker
docker run -d --name pyroscope \
-p 4040:4040 \
grafana/pyroscope:latest
Helm (Kubernetes)
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
helm install pyroscope grafana/pyroscope -n pyroscope --create-namespace
Configuración del servidor
# pyroscope-config.yaml
# Iniciar con: pyroscope -config.file=pyroscope-config.yaml
storage:
backend: filesystem
filesystem:
dir: /var/lib/pyroscope/data
server:
http_listen_port: 4040
limits:
max_query_lookback: 720h
max_query_length: 6h
scrape_configs:
- job_name: "my-go-service"
scrape_interval: "15s"
static_configs:
- targets: ["my-service:6060"]
profiling_config:
pprof_config:
process_cpu:
enabled: true
memory:
enabled: true
# Iniciar servidor Pyroscope
pyroscope -config.file=pyroscope-config.yaml
# Iniciar con configuración predeterminada
pyroscope
# Acceder a la interfaz web
# http://localhost:4040
Modo Push — SDK de Go
// Install: go get github.com/grafana/pyroscope-go
// Add to your Go application main():
// import "github.com/grafana/pyroscope-go"
//
// pyroscope.Start(pyroscope.Config{
// ApplicationName: "my-go-service",
// ServerAddress: "http://pyroscope:4040",
// ProfileTypes: []pyroscope.ProfileType{
// pyroscope.ProfileCPU,
// pyroscope.ProfileAllocObjects,
// pyroscope.ProfileAllocSpace,
// pyroscope.ProfileInuseObjects,
// pyroscope.ProfileInuseSpace,
// pyroscope.ProfileGoroutines,
// pyroscope.ProfileMutexCount,
// pyroscope.ProfileMutexDuration,
// pyroscope.ProfileBlockCount,
// pyroscope.ProfileBlockDuration,
// },
// })
Modo Push — SDK de Python
# Instalar el SDK de Python
pip install pyroscope-io
# Agregar a tu aplicación Python
import pyroscope
pyroscope.configure(
application_name="my-python-service",
server_address="http://pyroscope:4040",
tags={
"region": "us-east-1",
"env": "production",
},
)
# Usar etiquetas para etiquetado dinámico
with pyroscope.tag_wrapper({"endpoint": "/api/users"}):
handle_users_request()
Modo Push — SDK de Java
# Agregar a los argumentos de JVM
# Descargar el JAR del agente Java desde las releases de GitHub
java -javaagent:pyroscope.jar \
-Dpyroscope.application.name=my-java-service \
-Dpyroscope.server.address=http://pyroscope:4040 \
-Dpyroscope.format=jfr \
-jar my-app.jar
Modo Push — SDK de Ruby
# Instalar la gema Ruby
gem install pyroscope
# Agregar a tu aplicación Ruby
require 'pyroscope'
Pyroscope.configure do |config|
config.application_name = "my-ruby-service"
config.server_address = "http://pyroscope:4040"
config.tags = {
"region" => "us-east-1",
"env" => "production",
}
end
Modo Push — SDK de Node.js
# Instalar el paquete Node.js
npm install @pyroscope/nodejs
// Agregar a tu aplicación Node.js
const Pyroscope = require('@pyroscope/nodejs');
Pyroscope.init({
serverAddress: 'http://pyroscope:4040',
appName: 'my-node-service',
tags: {
region: 'us-east-1',
env: 'production',
},
});
Pyroscope.start();
Modo Push — SDK de .NET
# Instalar el paquete NuGet
dotnet add package Pyroscope
// Agregar a tu aplicación .NET Program.cs
// Pyroscope.Profiler.Instance.SetTag("region", "us-east-1");
// Usar las variables de entorno PYROSCOPE_APPLICATION_NAME y PYROSCOPE_SERVER_ADDRESS
// para configurar
Modo Pull — Recopilación de endpoints pprof
# Configurar Pyroscope para recopilar endpoints pprof (en pyroscope-config.yaml)
scrape_configs:
- job_name: "go-services"
scrape_interval: "15s"
static_configs:
- targets: ["app1:6060", "app2:6060"]
profiling_config:
pprof_config:
process_cpu:
enabled: true
path: "/debug/pprof/profile"
delta: true
memory:
enabled: true
path: "/debug/pprof/heap"
delta: true
goroutine:
enabled: true
path: "/debug/pprof/goroutine"
block:
enabled: true
path: "/debug/pprof/block"
delta: true
mutex:
enabled: true
path: "/debug/pprof/mutex"
delta: true
- job_name: "kubernetes-pods"
scrape_interval: "15s"
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_annotation_pyroscope_io_scrape]
action: keep
regex: true
- source_labels: [__meta_kubernetes_pod_annotation_pyroscope_io_port]
action: replace
target_label: __address__
regex: (.+)
replacement: ${1}
Integración con Grafana
# Agregar Pyroscope como fuente de datos en Grafana
# 1. Navegar a Configuration > Data Sources > Add data source
# 2. Buscar "Pyroscope" (o "Grafana Pyroscope")
# 3. Establecer URL en http://pyroscope:4040
# 4. Hacer clic en "Save & Test"
# Grafana Explore:
# 1. Seleccionar la fuente de datos Pyroscope
# 2. Elegir tipo de perfil (cpu, memoria, goroutine, etc.)
# 3. Filtrar por etiquetas (service_name, env, region)
# 4. Ver flame graph, tabla, o ambos
Consulta de perfiles
# Consultar perfiles vía API HTTP
# Listar nombres de etiquetas disponibles
curl -s http://localhost:4040/pyroscope/api/v1/labels | python3 -m json.tool
# Listar valores de etiquetas
curl -s "http://localhost:4040/pyroscope/api/v1/label-values?label=service_name" | python3 -m json.tool
# Renderizar un perfil (retorna formato pprof)
curl -s "http://localhost:4040/pyroscope/api/v1/profiles/render?query=process_cpu:cpu:nanoseconds:cpu:nanoseconds{service_name=\"my-service\"}&from=now-1h&until=now" -o profile.pb.gz
# Analizar con go tool pprof
go tool pprof -http=:8080 profile.pb.gz
Vista diferencial (Comparación de perfiles)
# En la interfaz web de Pyroscope:
# 1. Seleccionar modo "Comparison" en la barra superior
# 2. Establecer rango temporal de referencia a la izquierda
# 3. Establecer rango temporal de comparación a la derecha
# 4. Ver flame graph diferencial
# Rojo = tiempo incrementado, Verde = tiempo disminuido
# Vía API — comparar dos rangos temporales
curl -s "http://localhost:4040/pyroscope/api/v1/profiles/render-diff?leftQuery=process_cpu:cpu:nanoseconds{service_name=\"my-service\"}&leftFrom=now-2h&leftUntil=now-1h&rightQuery=process_cpu:cpu:nanoseconds{service_name=\"my-service\"}&rightFrom=now-1h&rightUntil=now"
Tipos de perfil
| Tipo de perfil | Descripción |
|---|
process_cpu | Tiempo de CPU consumido por el proceso |
memory | Asignaciones de memoria del heap |
goroutine | Conteo de goroutines activas (Go) |
mutex | Contención de mutex (Go) |
block | Operaciones de bloqueo (Go) |
wall | Tiempo de reloj de pared |
alloc_objects | Número de asignaciones |
alloc_space | Bytes asignados |
inuse_objects | Objetos activos en memoria |
inuse_space | Bytes activos en memoria |
Referencia rápida
| Componente | Puerto predeterminado | Propósito |
|---|
| Pyroscope Server | 4040 | Almacenamiento, consultas, interfaz web |
| Grafana | 3000 | Visualización y dashboards |
| pprof endpoints | 6060 | Perfilado de aplicaciones Go |
| Característica | Descripción |
|---|
| Modo push | Los SDKs envían perfiles a Pyroscope |
| Modo pull | Pyroscope recopila endpoints pprof |
| Flame graphs | Visualización interactiva de CPU/memoria |
| Vista diferencial | Comparar perfiles entre períodos de tiempo |
| Filtrado por etiquetas | Filtrar por servicio, entorno, región, etc. |
| Nativo en Grafana | Fuente de datos Pyroscope incorporada |