// 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.logging.v2;

import "google/api/annotations.proto";
import "google/api/distribution.proto";
import "google/api/metric.proto";
import "google/protobuf/empty.proto";

option csharp_namespace = "Google.Cloud.Logging.V2";
option go_package = "google.golang.org/genproto/googleapis/logging/v2;logging";
option java_multiple_files = true;
option java_outer_classname = "LoggingMetricsProto";
option java_package = "com.google.logging.v2";


// Service for configuring logs-based metrics.
service MetricsServiceV2 {
  // Lists logs-based metrics.
  rpc ListLogMetrics(ListLogMetricsRequest) returns (ListLogMetricsResponse) {
    option (google.api.http) = { get: "/v2/{parent=projects/*}/metrics" };
  }

  // Gets a logs-based metric.
  rpc GetLogMetric(GetLogMetricRequest) returns (LogMetric) {
    option (google.api.http) = { get: "/v2/{metric_name=projects/*/metrics/*}" };
  }

  // Creates a logs-based metric.
  rpc CreateLogMetric(CreateLogMetricRequest) returns (LogMetric) {
    option (google.api.http) = { post: "/v2/{parent=projects/*}/metrics" body: "metric" };
  }

  // Creates or updates a logs-based metric.
  rpc UpdateLogMetric(UpdateLogMetricRequest) returns (LogMetric) {
    option (google.api.http) = { put: "/v2/{metric_name=projects/*/metrics/*}" body: "metric" };
  }

  // Deletes a logs-based metric.
  rpc DeleteLogMetric(DeleteLogMetricRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = { delete: "/v2/{metric_name=projects/*/metrics/*}" };
  }
}

// Describes a logs-based metric.  The value of the metric is the
// number of log entries that match a logs filter in a given time interval.
message LogMetric {
  // Stackdriver Logging API version.
  enum ApiVersion {
    // Stackdriver Logging API v2.
    V2 = 0;

    // Stackdriver Logging API v1.
    V1 = 1;
  }

  // Required. The client-assigned metric identifier.
  // Examples: `"error_count"`, `"nginx/requests"`.
  //
  // Metric identifiers are limited to 100 characters and can include
  // only the following characters: `A-Z`, `a-z`, `0-9`, and the
  // special characters `_-.,+!*',()%/`.  The forward-slash character
  // (`/`) denotes a hierarchy of name pieces, and it cannot be the
  // first character of the name.
  //
  // The metric identifier in this field must not be
  // [URL-encoded](https://en.wikipedia.org/wiki/Percent-encoding).
  // However, when the metric identifier appears as the `[METRIC_ID]`
  // part of a `metric_name` API parameter, then the metric identifier
  // must be URL-encoded. Example:
  // `"projects/my-project/metrics/nginx%2Frequests"`.
  string name = 1;

  // Optional. A description of this metric, which is used in documentation.
  string description = 2;

  // Required. An [advanced logs filter](/logging/docs/view/advanced_filters)
  // which is used to match log entries.
  // Example:
  //
  //     "resource.type=gae_app AND severity>=ERROR"
  //
  // The maximum length of the filter is 20000 characters.
  string filter = 3;

  // Output only. The API version that created or updated this metric.
  // The version also dictates the syntax of the filter expression. When a value
  // for this field is missing, the default value of V2 should be assumed.
  ApiVersion version = 4;
}

// The parameters to ListLogMetrics.
message ListLogMetricsRequest {
  // Required. The name of the project containing the metrics:
  //
  //     "projects/[PROJECT_ID]"
  string parent = 1;

  // Optional. If present, then retrieve the next batch of results from the
  // preceding call to this method.  `pageToken` must be the value of
  // `nextPageToken` from the previous response.  The values of other method
  // parameters should be identical to those in the previous call.
  string page_token = 2;

  // Optional. The maximum number of results to return from this request.
  // Non-positive values are ignored.  The presence of `nextPageToken` in the
  // response indicates that more results might be available.
  int32 page_size = 3;
}

// Result returned from ListLogMetrics.
message ListLogMetricsResponse {
  // A list of logs-based metrics.
  repeated LogMetric metrics = 1;

  // If there might be more results than appear in this response, then
  // `nextPageToken` is included.  To get the next set of results, call this
  // method again using the value of `nextPageToken` as `pageToken`.
  string next_page_token = 2;
}

// The parameters to GetLogMetric.
message GetLogMetricRequest {
  // The resource name of the desired metric:
  //
  //     "projects/[PROJECT_ID]/metrics/[METRIC_ID]"
  string metric_name = 1;
}

// The parameters to CreateLogMetric.
message CreateLogMetricRequest {
  // The resource name of the project in which to create the metric:
  //
  //     "projects/[PROJECT_ID]"
  //
  // The new metric must be provided in the request.
  string parent = 1;

  // The new logs-based metric, which must not have an identifier that
  // already exists.
  LogMetric metric = 2;
}

// The parameters to UpdateLogMetric.
message UpdateLogMetricRequest {
  // The resource name of the metric to update:
  //
  //     "projects/[PROJECT_ID]/metrics/[METRIC_ID]"
  //
  // The updated metric must be provided in the request and it's
  // `name` field must be the same as `[METRIC_ID]` If the metric
  // does not exist in `[PROJECT_ID]`, then a new metric is created.
  string metric_name = 1;

  // The updated metric.
  LogMetric metric = 2;
}

// The parameters to DeleteLogMetric.
message DeleteLogMetricRequest {
  // The resource name of the metric to delete:
  //
  //     "projects/[PROJECT_ID]/metrics/[METRIC_ID]"
  string metric_name = 1;
}
