Mit Sammlungen den Überblick behalten
Sie können Inhalte basierend auf Ihren Einstellungen speichern und kategorisieren.
Profildaten herunterladen
In diesem Dokument wird beschrieben, wie Sie Ihre Profildaten in Ihr
und wie Profildaten programmatisch abgerufen werden können,
mit einer Go-Anwendung.
Profile mit der Google Cloud Console herunterladen
Wenn Sie das im Flame-Diagramm angezeigte Profil herunterladen möchten, klicken Sie auf Herunterladenget_app.
Profiler verwendet für die heruntergeladene Datei die folgende Namenskonvention:
Verwenden Sie zum Abrufen von Profildaten die API-Methode ListProfiles. Die folgenden
Das Go-Beispielprogramm demonstriert die Verwendung dieser API.
Das Beispielprogramm erstellt in dem Verzeichnis, in dem es ausgeführt wird, einen Ordner und
generiert eine Reihe nummerierter pprof-Dateien. Jede Datei hat einen Namen,
ähnlich wie bei profile000042.pb.gz. Jedes Verzeichnis enthält Profildaten.
und die Metadatendatei metadata.csv, die Informationen zur
heruntergeladene Dateien.
// 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")
}
Das Beispielprogramm akzeptiert die folgenden Befehlszeilenargumente:
project: Das Projekt, aus dem die Profile abgerufen werden. Erforderlich.
page_size: Die maximale Anzahl von Profilen, die pro API-Aufruf abgerufen werden. Die
der Maximalwert von page_size 1.000 ist. Wenn keine Angabe erfolgt, wird dieses Feld festgelegt.
auf 100.
page_token: Ein Stringtoken, das durch eine vorherige Ausführung des
zum Fortsetzen von Downloads. Optional.
max_profiles: Die maximale Anzahl der Profile, die abgerufen werden sollen. Wenn ein negativer
Ganzzahl angegeben wird, versucht das Programm, alle Profile abzurufen.
Optional.
Wechseln Sie in das Verzeichnis, das das Beispielprogramm enthält:
cd golang-samples/profiler/export
Führen Sie das Programm aus, nachdem Sie YOUR_GCP_PROJECT durch die ID Ihres
Google Cloud-Projekt:
go run main.go -project YOUR_GCP_PROJECT -page_size 1000 -max_profiles 10000
Das Programm kann einige Zeit in Anspruch nehmen. Das Programm gibt eine
Token für die nächste Seite nach dem Abrufen der aktuellen Seite. Sie können die
Token, um den Prozess fortzusetzen, wenn das Programm unterbrochen wird.