// Copyright (c) 2021 The Jaeger Authors.
//
// 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 jaeger.api_v2.metrics;

import "openmetrics.proto";
import "otelspankind.proto";
import "gogoproto/gogo.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/duration.proto";

option go_package = "metrics";
option java_package = "io.jaegertracing.api_v2.metrics";

// Enable gogoprotobuf extensions (https://github.com/gogo/protobuf/blob/master/extensions.md).
// Enable custom Marshal method.
option (gogoproto.marshaler_all) = true;
// Enable custom Unmarshal method.
option (gogoproto.unmarshaler_all) = true;
// Enable custom Size method (Required by Marshal and Unmarshal).
option (gogoproto.sizer_all) = true;

// MetricsQueryBaseRequest is the base request parameter accompanying a MetricsQueryService RPC call.
message MetricsQueryBaseRequest {
  // service_names are the service names to fetch metrics from.
  // The results will be grouped by service_name.
  // Required. At least one service name must be provided.
  repeated string service_names = 1;

  // groupByOperation determines if the metrics returned should be grouped by operation.
  // Optional. Default = false.
  bool groupByOperation = 2;

  // end_time is the ending time of the time series query range.
  // Optional. Default = now.
  google.protobuf.Timestamp end_time = 3 [
    (gogoproto.stdtime) = true,
    (gogoproto.nullable) = true
  ];

  // lookback is the duration from the end_time to look back on for metrics data points.
  // For example, if set to 1h, the query would span from end_time-1h to end_time.
  // Optional. Default = 1h.
  google.protobuf.Duration lookback = 4 [
    (gogoproto.stdduration) = true,
    (gogoproto.nullable) = true
  ];

  // step size is the duration between data points of the query results.
  // For example, if set to 5s, the results would produce a data point every 5 seconds
  // from the start_time to end_time.
  // Optional. Default = 5s.
  google.protobuf.Duration step = 5 [
    (gogoproto.stdduration) = true,
    (gogoproto.nullable) = true
  ];

  // ratePer is the duration in which the per-second rate of change is calculated for a cumulative counter metric.
  // Optional. Default = 10m.
  google.protobuf.Duration ratePer = 6 [
    (gogoproto.stdduration) = true,
    (gogoproto.nullable) = true
  ];

  // spanKinds is the list of span kinds to include (logical OR) in the resulting metrics aggregation.
  // Optional. Default = [SPAN_KIND_SERVER].
  repeated SpanKind spanKinds = 7;
}

// GetLatenciesRequest contains parameters for the GetLatencies RPC call.
message GetLatenciesRequest {
  MetricsQueryBaseRequest baseRequest = 1;
  // quantile is the quantile to compute from latency histogram metrics.
  // Valid range: (0, 1]
  //
  // e.g. 0.99 will return the 99th percentile or P99 which is the worst latency
  // observed from 99% of all spans for the given service (and operation).
  //
  // Required.
  double quantile = 2;
}

// GetCallRatesRequest contains parameters for the GetCallRates RPC call.
message GetCallRatesRequest {
  MetricsQueryBaseRequest baseRequest = 1;
}

// GetErrorRatesRequest contains parameters for the GetErrorRates RPC call.
message GetErrorRatesRequest {
  MetricsQueryBaseRequest baseRequest = 1;
}

message GetMinStepDurationRequest{};

message GetMinStepDurationResponse {
  google.protobuf.Duration minStep = 1 [
    (gogoproto.stdduration) = true,
    (gogoproto.nullable) = false
  ];
}

message GetMetricsResponse {
  MetricFamily metrics = 1 [
    (gogoproto.nullable) = false
  ];
}

service MetricsQueryService {
  // GetMinStepDuration gets the min time resolution supported by the backing metrics store,
  // e.g. 10s means the backend can only return data points that are at least 10s apart, not closer.
  rpc GetMinStepDuration(GetMinStepDurationRequest) returns (GetMinStepDurationResponse);

  // GetLatencies gets the latency metrics for a given list of services grouped by service
  // and optionally grouped by operation.
  rpc GetLatencies(GetLatenciesRequest) returns (GetMetricsResponse);

  // GetCallRates gets the call rate metrics for a given list of services grouped by service
  // and optionally grouped by operation.
  rpc GetCallRates(GetCallRatesRequest) returns (GetMetricsResponse);

  // GetErrorRates gets the error rate metrics for a given list of services grouped by service
  // and optionally grouped by operation.
  rpc GetErrorRates(GetErrorRatesRequest) returns (GetMetricsResponse);
}
