syntax = "proto3";

package envoy.extensions.stat_sinks.open_telemetry.v3;

import "envoy/config/core/v3/extension.proto";
import "envoy/config/core/v3/grpc_service.proto";
import "envoy/config/core/v3/http_service.proto";

import "google/protobuf/wrappers.proto";

import "opentelemetry/proto/common/v1/common.proto";
import "xds/type/matcher/v3/matcher.proto";

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

option java_package = "io.envoyproxy.envoy.extensions.stat_sinks.open_telemetry.v3";
option java_outer_classname = "OpenTelemetryProto";
option java_multiple_files = true;
option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/stat_sinks/open_telemetry/v3;open_telemetryv3";
option (udpa.annotations.file_status).package_version_status = ACTIVE;

// [#protodoc-title: Open Telemetry Stats Sink]
// Stats configuration proto schema for ``envoy.stat_sinks.open_telemetry`` sink.
// [#extension: envoy.stat_sinks.open_telemetry]

// [#next-free-field: 11]
message SinkConfig {
  // ConversionAction is used to convert a stat to a metric. If a stat matches,
  // the metric_name and static_metric_labels will be
  // used to create the metric. This can be used to rename a
  // stat, add static labels, and aggregate multiple stats into a single metric.
  message ConversionAction {
    // The metric name to use for the stat.
    string metric_name = 2;

    // Static metric labels to use for the metric.
    repeated opentelemetry.proto.common.v1.KeyValue static_metric_labels = 3;
  }

  // DropAction is an action that, when matched, will prevent the stat from being converted to an OTLP metric and flushed.
  message DropAction {
  }

  oneof protocol_specifier {
    option (validate.required) = true;

    // The upstream gRPC cluster that implements the OTLP/gRPC collector.
    config.core.v3.GrpcService grpc_service = 1 [(validate.rules).message = {required: true}];

    // The upstream HTTP cluster that implements the OTLP/HTTP collector.
    // See `OTLP/HTTP <https://opentelemetry.io/docs/specs/otlp/#otlphttp>`_.
    //
    // .. note::
    //
    //   The ``request_headers_to_add`` property in the OTLP HTTP exporter service
    //   does not support the :ref:`format specifier <config_access_log_format>`.
    //   The values configured are added as HTTP headers on the OTLP export request
    //   without any formatting applied.
    config.core.v3.HttpService http_service = 9;
  }

  // Attributes to be associated with the resource in the OTLP message.
  // [#extension-category: envoy.tracers.opentelemetry.resource_detectors]
  repeated config.core.v3.TypedExtensionConfig resource_detectors = 7;

  // If set to true, counters will be emitted as deltas, and the OTLP message will have
  // ``AGGREGATION_TEMPORALITY_DELTA`` set as AggregationTemporality.
  bool report_counters_as_deltas = 2;

  // If set to true, histograms will be emitted as deltas, and the OTLP message will have
  // ``AGGREGATION_TEMPORALITY_DELTA`` set as AggregationTemporality.
  bool report_histograms_as_deltas = 3;

  // If set to true, metrics will have their tags emitted as OTLP attributes, which may
  // contain values used by the tag extractor or additional tags added during stats creation.
  // Otherwise, no attributes will be associated with the export message. Default value is true.
  google.protobuf.BoolValue emit_tags_as_attributes = 4;

  // If set to true, metric names will be represented as the tag extracted name instead
  // of the full metric name. Default value is true.
  google.protobuf.BoolValue use_tag_extracted_name = 5;

  // If set, emitted stats names will be prepended with a prefix, so full stat name will be
  // <prefix>.<stats_name>. For example, if the stat name is "foo.bar" and prefix is
  // "pre", the full stat name will be "pre.foo.bar". If this field is not set, there is no
  // prefix added. According to the example, the full stat name will remain "foo.bar".
  string prefix = 6;

  // The custom conversion from a stat to a metric. Currently, the only supported input is
  // ``envoy.extensions.matching.common_inputs.stats.v3.StatFullNameMatchInput``.
  // The supported actions are
  // - ``envoy.extensions.stat_sinks.open_telemetry.v3.SinkConfig.DropAction``.
  // - ``envoy.extensions.stat_sinks.open_telemetry.v3.SinkConfig.ConversionAction``.
  // If stats are not matched, they will be directly converted to OTLP metrics as usual.
  xds.type.matcher.v3.Matcher custom_metric_conversions = 8;

  // Maximum number of data points per request. If explicitly set to 0, there is no limit. If unset, it currently defaults to no limit.
  // When the maximum number of data points is reached, the remaining data points will be sent in subsequent requests.
  uint32 max_data_points_per_request = 10;
}
