syntax = "proto3";

package envoy.extensions.filters.http.grpc_stats.v3;

import "envoy/config/core/v3/grpc_method_list.proto";

import "google/protobuf/wrappers.proto";

import "udpa/annotations/status.proto";
import "udpa/annotations/versioning.proto";

option java_package = "io.envoyproxy.envoy.extensions.filters.http.grpc_stats.v3";
option java_outer_classname = "ConfigProto";
option java_multiple_files = true;
option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/grpc_stats/v3;grpc_statsv3";
option (udpa.annotations.file_status).package_version_status = ACTIVE;

// [#protodoc-title: gRPC statistics] gRPC statistics filter
// :ref:`configuration overview <config_http_filters_grpc_stats>`.
// [#extension: envoy.filters.http.grpc_stats]

// gRPC statistics filter configuration
// [#next-free-field: 6]
message FilterConfig {
  option (udpa.annotations.versioning).previous_message_type =
      "envoy.config.filter.http.grpc_stats.v2alpha.FilterConfig";

  // If true, the filter maintains a filter state object with the request and response message
  // counts.
  bool emit_filter_state = 1;

  oneof per_method_stat_specifier {
    // If set, specifies an allowlist of service/methods that will have individual stats
    // emitted for them. Any call that does not match the allowlist will be counted
    // in a stat with no method specifier: ``cluster.<name>.grpc.*``.
    config.core.v3.GrpcMethodList individual_method_stats_allowlist = 2;

    // If set to true, emit stats for all service/method names.
    //
    // If set to false, emit stats for all service/message types to the same stats without including
    // the service/method in the name, with prefix ``cluster.<name>.grpc``. This can be useful if
    // service/method granularity is not needed, or if each cluster only receives a single method.
    //
    // .. attention::
    //   This option is only safe if all clients are trusted. If this option is enabled
    //   with untrusted clients, the clients could cause unbounded growth in the number of stats in
    //   Envoy, using unbounded memory and potentially slowing down stats pipelines.
    //
    // .. attention::
    //   If neither ``individual_method_stats_allowlist`` nor ``stats_for_all_methods`` is set, the
    //   behavior will default to ``stats_for_all_methods=false``.
    google.protobuf.BoolValue stats_for_all_methods = 3;
  }

  // If true, the filter will gather a histogram for the request time of the upstream.
  // It works with :ref:`stats_for_all_methods
  // <envoy_v3_api_field_extensions.filters.http.grpc_stats.v3.FilterConfig.stats_for_all_methods>`
  // and :ref:`individual_method_stats_allowlist
  // <envoy_v3_api_field_extensions.filters.http.grpc_stats.v3.FilterConfig.individual_method_stats_allowlist>` the same way
  // request_message_count and response_message_count works.
  bool enable_upstream_stats = 4;

  // If true, the filter will replace dots in the grpc_service_name with underscores before emitting
  // the metrics. Only works when :ref:`stats_for_all_methods
  // <envoy_v3_api_field_extensions.filters.http.grpc_stats.v3.FilterConfig.stats_for_all_methods>`
  // is set to true. It could cause metrics to be merged if the edited service name conflicts with
  // an existing service. For example there are both service "foo.bar" & "foo_bar" running.
  // This config can fix incorrect gRPC metrics with dots because the existing stats tag extractor
  // assumes no dots in the gRPC service name. By default this is set as false.
  bool replace_dots_in_grpc_service_name = 5;
}

// gRPC statistics filter state object in protobuf form.
message FilterObject {
  option (udpa.annotations.versioning).previous_message_type =
      "envoy.config.filter.http.grpc_stats.v2alpha.FilterObject";

  // Count of request messages in the request stream.
  uint64 request_message_count = 1;

  // Count of response messages in the response stream.
  uint64 response_message_count = 2;
}
