Organiza tus páginas con colecciones
Guarda y categoriza el contenido según tus preferencias.
Descarga los datos del perfil
En este documento, se describe cómo puedes descargar tus datos de perfil en tu
sistema local y cómo recuperar datos de perfil de manera programática
con una aplicación de Go.
Descarga perfiles con la consola de Google Cloud
Para descargar el perfil que se muestra en el gráfico tipo llama, haz clic en Descargarget_app.
Profiler usa la siguiente convención a fin de asignar nombres para el archivo descargado:
Para recuperar los datos del perfil, usa el método de la API ListProfiles. Lo siguiente
el programa de muestra de Go demuestra el uso de esta API.
El programa de muestra crea una carpeta en el directorio desde el que se ejecuta.
Genera un conjunto de archivos pprof numerados. Cada archivo tiene un nombre
similar a profile000042.pb.gz. Cada directorio contiene datos de perfil
y un archivo de metadatos, metadata.csv, que contiene información sobre el
archivos descargados.
// Sample export shows how ListProfiles API can be used to download
// existing pprof profiles for a given project from GCP.
package main
import (
"bytes"
"context"
"encoding/csv"
"encoding/json"
"flag"
"fmt"
"io"
"log"
"os"
"time"
cloudprofiler "cloud.google.com/go/cloudprofiler/apiv2"
pb "cloud.google.com/go/cloudprofiler/apiv2/cloudprofilerpb"
"google.golang.org/api/iterator"
)
var project = flag.String("project", "", "GCP project ID from which profiles should be fetched")
var pageSize = flag.Int("page_size", 100, "Number of profiles fetched per page. Maximum 1000.")
var pageToken = flag.String("page_token", "", "PageToken from a previous ListProfiles call. If empty, the listing will start from the begnning. Invalid page tokens result in error.")
var maxProfiles = flag.Int("max_profiles", 1000, "Maximum number of profiles to fetch across all pages. If this is <= 0, will fetch all available profiles")
const ProfilesDownloadedSuccessfully = "Read max allowed profiles"
// This function reads profiles for a given project and stores them into locally created files.
// The profile metadata gets stored into a 'metdata.csv' file, while the individual pprof files
// are created per profile.
func downloadProfiles(ctx context.Context, w io.Writer, project, pageToken string, pageSize, maxProfiles int) error {
client, err := cloudprofiler.NewExportClient(ctx)
if err != nil {
return err
}
defer client.Close()
log.Printf("Attempting to fetch %v profiles with a pageSize of %v for %v\n", maxProfiles, pageSize, project)
// Initial request for the ListProfiles API
request := &pb.ListProfilesRequest{
Parent: fmt.Sprintf("projects/%s", project),
PageSize: int32(pageSize),
PageToken: pageToken,
}
// create a folder for storing profiles & metadata
profilesDirName := fmt.Sprintf("profiles_%v", time.Now().Unix())
if err := os.Mkdir(profilesDirName, 0750); err != nil {
log.Fatal(err)
}
// create a file for storing profile metadata
metadata, err := os.Create(fmt.Sprintf("%s/metadata.csv", profilesDirName))
if err != nil {
return err
}
defer metadata.Close()
writer := csv.NewWriter(metadata)
defer writer.Flush()
writer.Write([]string{"File", "Name", "ProfileType", "Target", "Duration", "Labels"})
profileCount := 0
// Keep calling ListProfiles API till all profile pages are fetched or max pages reached
profilesIterator := client.ListProfiles(ctx, request)
for {
// Read individual profile - the client will automatically make API calls to fetch next pages
profile, err := profilesIterator.Next()
if err == iterator.Done {
log.Println("Read all available profiles")
break
}
if err != nil {
return fmt.Errorf("error reading profile from response: %w", err)
}
profileCount++
filename := fmt.Sprintf("%s/profile%06d.pb.gz", profilesDirName, profileCount)
err = os.WriteFile(filename, profile.ProfileBytes, 0640)
if err != nil {
return fmt.Errorf("unable to write file %s: %w", filename, err)
}
fmt.Fprintf(w, "deployment target: %v\n", profile.Deployment.Labels)
labelBytes, err := json.Marshal(profile.Labels)
if err != nil {
return err
}
err = writer.Write([]string{filename, profile.Name, profile.Deployment.Target, profile.Duration.String(), string(labelBytes)})
if err != nil {
return err
}
if maxProfiles > 0 && profileCount >= maxProfiles {
fmt.Fprintf(w, "result: %v", ProfilesDownloadedSuccessfully)
break
}
if profilesIterator.PageInfo().Remaining() == 0 {
// This signifies that the client will make a new API call internally
log.Printf("next page token: %v\n", profilesIterator.PageInfo().Token)
}
}
return nil
}
func main() {
flag.Parse()
// validate project ID
if *project == "" {
log.Fatalf("No project ID provided, please provide the GCP project ID via '-project' flag")
}
var writer bytes.Buffer
if err := downloadProfiles(context.Background(), &writer, *project, *pageToken, *pageSize, *maxProfiles); err != nil {
log.Fatal(err)
}
log.Println("Finished reading all profiles")
}
El programa de muestra acepta los siguientes argumentos de línea de comandos:
project: El proyecto del que se recuperan los perfiles. Obligatorio.
page_size: La cantidad máxima de perfiles recuperados por llamada a la API. El
el valor máximo de page_size es 1,000. Si no se especifica, este campo se establece
en 100 puntos.
page_token: un token de cadena generado por una ejecución anterior del
programa para reanudar las descargas. Opcional.
max_profiles: Es la cantidad máxima de perfiles que se recuperarán. Si el resultado no es positivo,
se proporciona un número entero, el programa intenta recuperar todos los perfiles.
Opcional.
Ejecuta la aplicación de ejemplo
Para ejecutar la aplicación de ejemplo, haz lo siguiente:
Cambia al directorio que contiene el programa de muestra:
cd golang-samples/profiler/export
Ejecuta el programa después de reemplazar YOUR_GCP_PROJECT con el ID de tu
Proyecto de Google Cloud:
go run main.go -project YOUR_GCP_PROJECT -page_size 1000 -max_profiles 10000
El programa puede tardar bastante tiempo en completarse. El programa genera un
token para la página siguiente después de recuperar la página actual. Puedes usar la
para reanudar el proceso si se interrumpe el programa.