Untuk mengambil data profil, gunakan metode API ListProfiles. Contoh program Go berikut menunjukkan penggunaan API ini.
Program contoh membuat folder di direktori tempat program dijalankan, dan
membuat serangkaian file pprof bernomor. Setiap file memiliki konvensi penamaan yang mirip dengan profile000042.pb.gz. Setiap direktori berisi data profil
dan file metadata - metadata.csv, yang berisi informasi tentang
file yang didownload.
// Sample export shows how ListProfiles API can be used to download// existing pprof profiles for a given project from GCP.packagemainimport("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")varproject=flag.String("project","","GCP project ID from which profiles should be fetched")varpageSize=flag.Int("page_size",100,"Number of profiles fetched per page. Maximum 1000.")varpageToken=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.")varmaxProfiles=flag.Int("max_profiles",1000,"Maximum number of profiles to fetch across all pages. If this is <= 0, will fetch all available profiles")constProfilesDownloadedSuccessfully="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.funcdownloadProfiles(ctxcontext.Context,wio.Writer,project,pageTokenstring,pageSize,maxProfilesint)error{client,err:=cloudprofiler.NewExportClient(ctx)iferr!=nil{returnerr}deferclient.Close()log.Printf("Attempting to fetch %v profiles with a pageSize of %v for %v\n",maxProfiles,pageSize,project)// Initial request for the ListProfiles APIrequest:=&pb.ListProfilesRequest{Parent:fmt.Sprintf("projects/%s",project),PageSize:int32(pageSize),PageToken:pageToken,}// create a folder for storing profiles & metadataprofilesDirName:=fmt.Sprintf("profiles_%v",time.Now().Unix())iferr:=os.Mkdir(profilesDirName,0750);err!=nil{log.Fatal(err)}// create a file for storing profile metadatametadata,err:=os.Create(fmt.Sprintf("%s/metadata.csv",profilesDirName))iferr!=nil{returnerr}defermetadata.Close()writer:=csv.NewWriter(metadata)deferwriter.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 reachedprofilesIterator:=client.ListProfiles(ctx,request)for{// Read individual profile - the client will automatically make API calls to fetch next pagesprofile,err:=profilesIterator.Next()iferr==iterator.Done{log.Println("Read all available profiles")break}iferr!=nil{returnfmt.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)iferr!=nil{returnfmt.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)iferr!=nil{returnerr}err=writer.Write([]string{filename,profile.Name,profile.Deployment.Target,profile.Duration.String(),string(labelBytes)})iferr!=nil{returnerr}ifmaxProfiles > 0 && profileCount>=maxProfiles{fmt.Fprintf(w,"result: %v",ProfilesDownloadedSuccessfully)break}ifprofilesIterator.PageInfo().Remaining()==0{// This signifies that the client will make a new API call internallylog.Printf("next page token: %v\n",profilesIterator.PageInfo().Token)}}returnnil}funcmain(){flag.Parse()// validate project IDif*project==""{log.Fatalf("No project ID provided, please provide the GCP project ID via '-project' flag")}varwriterbytes.Bufferiferr:=downloadProfiles(context.Background(),&writer,*project,*pageToken,*pageSize,*maxProfiles);err!=nil{log.Fatal(err)}log.Println("Finished reading all profiles")}
Program contoh menerima argumen command line berikut:
project: Project tempat profil diambil. Wajib.
page_size: Jumlah maksimum profil yang diambil per panggilan API. Nilai
maksimum page_size adalah 1000. Jika tidak ditentukan, kolom ini akan ditetapkan ke 100.
page_token: Token string yang dibuat oleh eksekusi
program sebelumnya untuk melanjutkan download. Opsional.
max_profiles: Jumlah maksimum profil yang akan diambil. Jika bilangan bulat non-positif diberikan, program akan mencoba mengambil semua profil.
Opsional.
Menjalankan aplikasi contoh
Untuk menjalankan aplikasi contoh, lakukan langkah-langkah berikut:
Program ini mungkin memerlukan waktu yang cukup lama untuk diselesaikan. Program menampilkan token
untuk halaman berikutnya setelah mengambil halaman saat ini. Anda dapat menggunakan token untuk melanjutkan proses jika program terganggu.
Melihat profil yang didownload
Untuk membaca file yang didownload, yang ditulis dalam format
protocol buffer berserial, gunakan alat
pprof open source.
[[["Mudah dipahami","easyToUnderstand","thumb-up"],["Memecahkan masalah saya","solvedMyProblem","thumb-up"],["Lainnya","otherUp","thumb-up"]],[["Sulit dipahami","hardToUnderstand","thumb-down"],["Informasi atau kode contoh salah","incorrectInformationOrSampleCode","thumb-down"],["Informasi/contoh yang saya butuhkan tidak ada","missingTheInformationSamplesINeed","thumb-down"],["Masalah terjemahan","translationIssue","thumb-down"],["Lainnya","otherDown","thumb-down"]],["Terakhir diperbarui pada 2025-08-18 UTC."],[],[],null,["# Download profile data\n=====================\n\nThis document describes how you can download your profile data to your\nlocal system, and how you can programmatically retrieve profile data by\nusing a Go application.\n\nDownload profiles by using the Google Cloud console\n---------------------------------------------------\n\nTo download the profile displayed in the flame graph,\nclick **Download** *get_app*.\n\nProfiler uses the following naming convention for the\ndownloaded file: \n\n```\nprofiler_[SERVICE_NAME]_[PROFILE_TYPE]_[FROM_DATE]_[TO_DATE]_[ZONE]_[VERSION].pb.gz\n```\n\nIn this expression:\n\n- `SERVICE_NAME` contains your **Service** selection\n- `PROFILE_TYPE` contains your **Profile type** selection\n- `FROM_DATE` and `TO_DATE` contains your time-range specifications\n- `ZONE` contains your **Zone** selection\n- `VERSION` contains your **Version** selection\n\nExample: `profiler_docdemo-service_HEAP_2018-04-22T20_25_31Z_2018-05-22T20_25_31Z_us-east1-c.pb.gz`\n\nDownload profiles programmatically\n----------------------------------\n\n|\n| **Preview**\n|\n|\n| This product or feature is subject to the \"Pre-GA Offerings Terms\" in the General Service Terms section\n| of the [Service Specific Terms](/terms/service-terms#1).\n|\n| Pre-GA products and features are available \"as is\" and might have limited support.\n|\n| For more information, see the\n| [launch stage descriptions](/products#product-launch-stages).\n\nTo retrieve profile data, use the `ListProfiles` API method. The following\nsample Go program demonstrates the use of this API.\n\nThe sample program creates a folder in the directory from where it is run, and\ngenerates a set of numbered [`pprof`](https://github.com/google/pprof) files. Each file has a naming\nconvention similar to `profile000042.pb.gz`. Each directory contains profile data\nand a metadata file - `metadata.csv`, which contains information about the\ndownloaded files. \n\n\n // Sample export shows how ListProfiles API can be used to download\n // existing pprof profiles for a given project from GCP.\n package main\n\n import (\n \t\"bytes\"\n \t\"context\"\n \t\"encoding/csv\"\n \t\"encoding/json\"\n \t\"flag\"\n \t\"fmt\"\n \t\"io\"\n \t\"log\"\n \t\"os\"\n \t\"time\"\n\n \tcloudprofiler \"cloud.google.com/go/cloudprofiler/apiv2\"\n \tpb \"cloud.google.com/go/cloudprofiler/apiv2/cloudprofilerpb\"\n \t\"google.golang.org/api/iterator\"\n )\n\n var project = flag.String(\"project\", \"\", \"GCP project ID from which profiles should be fetched\")\n var pageSize = flag.Int(\"page_size\", 100, \"Number of profiles fetched per page. Maximum 1000.\")\n 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.\")\n var maxProfiles = flag.Int(\"max_profiles\", 1000, \"Maximum number of profiles to fetch across all pages. If this is \u003c= 0, will fetch all available profiles\")\n\n const ProfilesDownloadedSuccessfully = \"Read max allowed profiles\"\n\n // This function reads profiles for a given project and stores them into locally created files.\n // The profile metadata gets stored into a 'metdata.csv' file, while the individual pprof files\n // are created per profile.\n func downloadProfiles(ctx context.Context, w io.Writer, project, pageToken string, pageSize, maxProfiles int) error {\n \tclient, err := cloudprofiler.https://cloud.google.com/go/docs/reference/cloud.google.com/go/cloudprofiler/latest/apiv2.html#cloud_google_com_go_cloudprofiler_apiv2_ExportClient_NewExportClient(ctx)\n \tif err != nil {\n \t\treturn err\n \t}\n \tdefer client.Close()\n \tlog.Printf(\"Attempting to fetch %v profiles with a pageSize of %v for %v\\n\", maxProfiles, pageSize, project)\n\n \t// Initial request for the ListProfiles API\n \trequest := &pb.ListProfilesRequest{\n \t\tParent: fmt.Sprintf(\"projects/%s\", project),\n \t\tPageSize: int32(pageSize),\n \t\tPageToken: pageToken,\n \t}\n\n \t// create a folder for storing profiles & metadata\n \tprofilesDirName := fmt.Sprintf(\"profiles_%v\", time.Now().Unix())\n \tif err := os.Mkdir(profilesDirName, 0750); err != nil {\n \t\tlog.Fatal(err)\n \t}\n \t// create a file for storing profile metadata\n \tmetadata, err := os.Create(fmt.Sprintf(\"%s/metadata.csv\", profilesDirName))\n \tif err != nil {\n \t\treturn err\n \t}\n \tdefer metadata.Close()\n\n \twriter := csv.NewWriter(metadata)\n \tdefer writer.Flush()\n\n \twriter.Write([]string{\"File\", \"Name\", \"ProfileType\", \"Target\", \"Duration\", \"Labels\"})\n\n \tprofileCount := 0\n \t// Keep calling ListProfiles API till all profile pages are fetched or max pages reached\n \tprofilesIterator := client.ListProfiles(ctx, request)\n \tfor {\n \t\t// Read individual profile - the client will automatically make API calls to fetch next pages\n \t\tprofile, err := profilesIterator.https://cloud.google.com/go/docs/reference/cloud.google.com/go/cloudprofiler/latest/apiv2.html#cloud_google_com_go_cloudprofiler_apiv2_ProfileIterator_Next()\n\n \t\tif err == iterator.Done {\n \t\t\tlog.Println(\"Read all available profiles\")\n \t\t\tbreak\n \t\t}\n \t\tif err != nil {\n \t\t\treturn fmt.Errorf(\"error reading profile from response: %w\", err)\n \t\t}\n \t\tprofileCount++\n\n \t\tfilename := fmt.Sprintf(\"%s/profile%06d.pb.gz\", profilesDirName, profileCount)\n \t\terr = os.WriteFile(filename, profile.ProfileBytes, 0640)\n\n \t\tif err != nil {\n \t\t\treturn fmt.Errorf(\"unable to write file %s: %w\", filename, err)\n \t\t}\n \t\tfmt.Fprintf(w, \"deployment target: %v\\n\", profile.Deployment.Labels)\n\n \t\tlabelBytes, err := json.Marshal(profile.Labels)\n \t\tif err != nil {\n \t\t\treturn err\n \t\t}\n\n \t\terr = writer.Write([]string{filename, profile.Name, profile.Deployment.Target, profile.Duration.String(), string(labelBytes)})\n \t\tif err != nil {\n \t\t\treturn err\n \t\t}\n\n \t\tif maxProfiles \u003e 0 && profileCount \u003e= maxProfiles {\n \t\t\tfmt.Fprintf(w, \"result: %v\", ProfilesDownloadedSuccessfully)\n \t\t\tbreak\n \t\t}\n\n \t\tif profilesIterator.PageInfo().Remaining() == 0 {\n \t\t\t// This signifies that the client will make a new API call internally\n \t\t\tlog.Printf(\"next page token: %v\\n\", profilesIterator.https://cloud.google.com/go/docs/reference/cloud.google.com/go/cloudprofiler/latest/apiv2.html#cloud_google_com_go_cloudprofiler_apiv2_ProfileIterator_PageInfo().Token)\n \t\t}\n \t}\n \treturn nil\n }\n\n func main() {\n \tflag.Parse()\n \t// validate project ID\n \tif *project == \"\" {\n \t\tlog.Fatalf(\"No project ID provided, please provide the GCP project ID via '-project' flag\")\n \t}\n \tvar writer bytes.Buffer\n \tif err := downloadProfiles(context.Background(), &writer, *project, *pageToken, *pageSize, *maxProfiles); err != nil {\n \t\tlog.Fatal(err)\n \t}\n \tlog.Println(\"Finished reading all profiles\")\n }\n\nThe sample program accepts the following command line arguments:\n\n- `project`: The project from which the profiles are retrieved. Required.\n- `page_size`: The maximum number of profiles retrieved per API call. The maximum value of `page_size` is 1000. When not specified, this field is set to 100.\n- `page_token`: A string token generated by a previous run of the program to resume downloads. Optional.\n- `max_profiles`: The maximum number of profiles to retrieve. If a non-positive integer is provided, then the program attempts to retrieve all profiles. \n Optional.\n\n### Run the sample application\n\n| **Note:** To successfully run the program, it must be authenticated to Profiler. Authentication can be set up using Application Default Credentials (ADC). For more information, see [Set up ADC for a local development environment](/docs/authentication/set-up-adc-local-dev-environment).\n\nTo run the sample application, do the following:\n\n1. Clone the repository:\n\n git clone https://github.com/GoogleCloudPlatform/golang-samples.git\n\n2. Change to the directory that contains the sample program:\n\n cd golang-samples/profiler/export\n\n3. Run the program after you replace \u003cvar translate=\"no\"\u003eYOUR_GCP_PROJECT\u003c/var\u003e with the ID of your\n Google Cloud project:\n\n go run main.go -project \u003cvar translate=\"no\"\u003eYOUR_GCP_PROJECT\u003c/var\u003e -page_size 1000 -max_profiles 10000\n\nThe program might take considerable time to complete. The program outputs a\ntoken for the next page after retrieving the current page. You can use the\ntoken to resume the process if the program is interrupted.\n\nView the downloaded profiles\n----------------------------\n\nTo read a downloaded file, which is written in the\n[serialized protocol buffer](https://github.com/google/pprof/tree/master/proto) format, use the open source\n[`pprof`](https://github.com/google/pprof) tool."]]