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 auf Ihr lokales System herunterladen und wie Sie Profildaten programmatisch mithilfe einer Go-Anwendung abrufen können.
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. Im folgenden Go-Beispielprogramm wird die Verwendung dieser API veranschaulicht.
Das Beispielprogramm erstellt einen Ordner in dem Verzeichnis, in dem es ausgeführt wird, und generiert eine Reihe nummerierter Dateien vom Typ pprof. Jede Datei hat eine ähnliche Namenskonvention wie profile000042.pb.gz. Jedes Verzeichnis enthält Profildaten und die Metadatendatei metadata.csv mit Informationen zu den heruntergeladenen 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: %v", 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: %v", 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. Der Höchstwert von page_size beträgt 1.000. Wenn keine Angabe erfolgt, wird dieses Feld auf 100 gesetzt.
page_token: Ein Stringtoken, das bei einer vorherigen Ausführung des Programms generiert wurde, um Downloads fortzusetzen. Optional.
max_profiles: Die maximale Anzahl von Profilen, die abgerufen werden sollen. Wenn eine nicht positive 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-Projekts ersetzt haben:
go run main.go -project YOUR_GCP_PROJECT -page_size 1000 -max_profiles 10000
Die Teilnahme am Programm kann einige Zeit in Anspruch nehmen. Nach dem Abrufen der aktuellen Seite gibt das Programm ein Token für die nächste Seite aus. Sie können das Token verwenden, um den Prozess fortzusetzen, wenn das Programm unterbrochen wird.