// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package google.devtools.cloudprofiler.v2;

import "google/api/annotations.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";

option go_package = "google.golang.org/genproto/googleapis/devtools/cloudprofiler/v2;cloudprofiler";


// Service for recording the profiling data from profiling agents running as
// part of a GCP deployment being profiled or from an offline provider of
// profiling data.
//
// General guidelines:
// * Profiles for a single deployment must be created in ascending time order.
// * Profiles can be created in either online or offline mode, see below.
service ProfilerService {
  // CreateProfile creates a new profile resource.
  //
  // In the online creation mode:
  // * The server ensures that the new profiles are created at a constant rate
  //   per deployment, so the creation request may hang for some time until the
  //   next profile session is available.
  // * The request may fail with ABORTED error if the creation is not
  //   available within ~1m, the response will indicate the duration of the
  //   backoff the client should take before attempting creating a profile
  //   again. The backoff duration is returned in google.rpc.RetryInfo extension
  //   on the response status. To a gRPC client, the extension will be return as
  //   a binary-serialized proto in the trailing metadata item named
  //   "google.rpc.retryinfo-bin".
  //
  // In the offline creation mode:
  // * The client provides the profile to create along with the profile bytes,
  //   the server records it.
  rpc CreateProfile(CreateProfileRequest) returns (Profile) {
    option (google.api.http) = { post: "/v2/projects/{deployment.project_id}/profiles" body: "*" };
  }

  // UpdateProfile updates the profile bytes and labels on the profile resource
  // created in the online mode.
  rpc UpdateProfile(UpdateProfileRequest) returns (Profile) {
    option (google.api.http) = { patch: "/v2/{profile.name=projects/*/profiles/*}" body: "profile" };
  }
}

// CreateProfileRequest describes a profile resource creation request.
// Deployment field must be populated for both online and offline modes.
// For the online mode, profile field is not set and the profile_type specifies
// the list of profile types supported by the agent. The creation call will hang
// until a profile of one of these types needs to be collected. For offline
// mode, profile field must be set, profile_type must be empty, and deployment
// field must be identical to the deployment in the profile.
message CreateProfileRequest {
  // Deployment details.
  Deployment deployment = 1;

  // Online mode: One or more profile types that the agent is capable of
  // providing.
  repeated ProfileType profile_type = 2;

  // Offline mode: Contents of the profile to create.
  Profile profile = 3;
}

// UpdateProfileRequest contains the profile to update.
message UpdateProfileRequest {
  // Profile to update
  Profile profile = 1;
}

// Profile resource.
message Profile {
  // Opaque, server-assigned, unique ID for this profile.
  // Output only.
  string name = 1;

  // Type of profile.
  // Input (for the offline mode) or output (for the online mode).
  ProfileType profile_type = 2;

  // Deployment this profile corresponds to.
  Deployment deployment = 3;

  // Duration of the profiling session.
  // Input (for the offline mode) or output (for the online mode).
  // The field represents requested profiling duration. It may slightly differ
  // from the effective profiling duration, which is recorded in the profile
  // data, in case the profiling can't be stopped immediately (e.g. in case
  // stopping the profiling is handled asynchronously).
  google.protobuf.Duration duration = 4;

  // Profile bytes, as a gzip compressed serialized proto, the format is
  // https://github.com/google/pprof/blob/master/proto/profile.proto.
  bytes profile_bytes = 5;

  // Labels associated to this specific profile. These labels will get merged
  // with the deployment labels for the final data set.
  // See documentation on deployment labels for validation rules and limits.
  // Input only, will not be populated on responses.
  map<string, string> labels = 6;
}

// Deployment contains the deployment identification information.
message Deployment {
  // Project ID is the ID of a cloud project.
  // Validation regex: `^[a-z][-a-z0-9:.]{4,61}[a-z0-9]$`.
  string project_id = 1;

  // Target is the service name used to group related deployments:
  // * Service name for GAE Flex / Standard.
  // * Cluster and container name for GKE.
  // * User-specified string for direct GCE profiling (e.g. Java).
  // * Job name for Dataflow.
  // Validation regex: `^[a-z]([-a-z0-9_.]{0,253}[a-z0-9])?$`.
  string target = 2;

  // Labels identify the deployment within the user universe and same target.
  // Validation regex for label names: `^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$`.
  // Value for an individual label must be <= 512 bytes, the total
  // size of all label names and values must be <= 1024 bytes.
  //
  // Either "zone" or "region" label must be present describing the deployment
  // location. An example of a zone is "us-central1-a", an example of a region
  // is "us-central1" or "us-central".
  map<string, string> labels = 3;
}

// ProfileType is type of profiling data.
// NOTE: the enumeration member names are used (in lowercase) as unique string
// identifiers of profile types, so they must not be renamed.
enum ProfileType {
  // Unspecified profile type.
  PROFILE_TYPE_UNSPECIFIED = 0;

  // Thread CPU time sampling.
  CPU = 1;

  // Wallclock time sampling. More expensive as stops all threads.
  WALL = 2;

  // Heap allocation sampling.
  HEAP = 3;

  // Single-shot collection of all thread stacks.
  THREADS = 4;

  // Synchronization contention profile.
  CONTENTION = 5;
}
