apollo-opentelemetry 0.8.0

OpenTelemetry configuration types for Apollo platform
Documentation
//! Log record processor configuration.
//!
//! See the [OpenTelemetry Logs SDK specification](https://opentelemetry.io/docs/specs/otel/logs/sdk/)
//! for details on processor behavior and defaults.

use apollo_configuration::configuration;

use crate::config::processor::validate_rate_limited_processor;
use crate::config::{BatchProcessorConfig, LogExporter, RateLimitedProcessorConfig};

/// Log record processor configuration.
#[configuration]
pub(crate) enum LogRecordProcessor {
    /// Batch processor that collects log records and exports them in batches.
    Batch(BatchLogRecordProcessorConfig),
    /// Simple processor that exports each log record immediately.
    Simple(SimpleLogRecordProcessorConfig),
    /// Rate-limited processor that applies rate limiting before batch processing.
    RateLimited(RateLimitedLogRecordProcessorConfig),
}

/// Batch log record processor configuration.
///
/// Batches log records and exports them periodically or when the batch reaches
/// a size threshold. See the [SDK specification](https://opentelemetry.io/docs/specs/otel/trace/sdk/#batching-processor)
/// for details (logs follow the same model as traces).
#[configuration]
pub(crate) struct BatchLogRecordProcessorConfig {
    #[config(required)]
    pub(crate) exporter: LogExporter,

    /// Maximum time to wait before exporting a batch (in milliseconds).
    ///
    /// Default: 5000ms per [SDK specification](https://opentelemetry.io/docs/specs/otel/trace/sdk/#batching-processor).
    #[config(default = 5000)]
    pub(crate) schedule_delay: u64,

    /// Maximum time to wait for export to complete (in milliseconds).
    ///
    /// Default: 30000ms per [SDK specification](https://opentelemetry.io/docs/specs/otel/trace/sdk/#batching-processor).
    #[config(default = 30000)]
    pub(crate) export_timeout: u64,

    /// Maximum number of log records per batch.
    ///
    /// Default: 512 per [SDK specification](https://opentelemetry.io/docs/specs/otel/trace/sdk/#batching-processor).
    #[config(default = 512)]
    pub(crate) max_export_batch_size: u32,

    /// Maximum queue size for pending log records.
    ///
    /// Default: 2048 per [SDK specification](https://opentelemetry.io/docs/specs/otel/trace/sdk/#batching-processor).
    #[config(default = 2048)]
    pub(crate) max_queue_size: u32,
}

/// Simple log record processor configuration.
///
/// Exports each log record immediately as it is emitted.
#[configuration]
pub(crate) struct SimpleLogRecordProcessorConfig {
    #[config(required)]
    pub(crate) exporter: LogExporter,
}

/// Rate-limited log record processor configuration.
///
/// Protects against unexpected telemetry costs by enforcing a maximum logs-per-second
/// limit. Logs exceeding the limit are dropped before entering the batch queue,
/// preventing runaway telemetry from infinite loops, retry storms, or load spikes.
///
/// # Observability
///
/// **UNSTABLE:** Metrics follow the [OTel SDK semantic conventions] which are currently
/// in development status. Metric names and attributes may change in future releases.
///
/// **Processor metric:** `otel.sdk.processor.log.processed`
///
/// | Attribute            | Description                                           |
/// |----------------------|-------------------------------------------------------|
/// | `otel.component.type`| `rate_limited_log_processor`                          |
/// | `otel.component.name`| `rate_limited_log_processor/{instance_id}`            |
/// | `error.type`         | `rate_limited` (only present when logs are dropped)   |
///
/// **Exporter metric:** `otel.sdk.exporter.log.exported`
///
/// | Attribute            | Description                                           |
/// |----------------------|-------------------------------------------------------|
/// | `otel.component.type`| `{exporter}_exporter` (e.g., `otlp_http_exporter`)    |
/// | `otel.component.name`| `{exporter}_exporter/{instance_id}`                   |
/// | `server.address`     | Destination host (e.g., `localhost`)                  |
/// | `server.port`        | Destination port (e.g., `4318`)                       |
/// | `error.type`         | `export_failed` (only present on failure)             |
///
/// The processor and exporter share the same `{instance_id}` so you can correlate
/// rate-limited drops with export failures for the same pipeline.
///
/// Use these metrics to:
/// - Alert when processor drops exceed a threshold (rate limit too low)
/// - Monitor exporter failures and retries
/// - Calculate drop rates by comparing records with/without `error.type`
///
/// [OTel SDK semantic conventions]: https://github.com/open-telemetry/semantic-conventions/blob/main/docs/otel/sdk-metrics.md
///
/// # Configuration
///
/// Batch parameters use SDK defaults. If `max_rate` exceeds the batch processor's
/// throughput (`max_export_batch_size / schedule_delay`), validation will fail with
/// suggestions for how to adjust the configuration.
#[configuration(validate = validate_rate_limited_processor)]
pub(crate) struct RateLimitedLogRecordProcessorConfig {
    #[config(required)]
    pub(crate) exporter: LogExporter,

    /// Maximum log records per second.
    ///
    /// Default: 100 per second.
    #[config(default = 100)]
    pub(crate) max_rate: u32,

    /// Maximum time to wait before exporting a batch (in milliseconds).
    ///
    /// Default: 5000ms per [SDK specification](https://opentelemetry.io/docs/specs/otel/trace/sdk/#batching-processor).
    #[config(default = 5000)]
    pub(crate) schedule_delay: u64,

    /// Maximum time to wait for export to complete (in milliseconds).
    ///
    /// Default: 30000ms per [SDK specification](https://opentelemetry.io/docs/specs/otel/trace/sdk/#batching-processor).
    #[config(default = 30000)]
    pub(crate) export_timeout: u64,

    /// Maximum number of log records per batch.
    ///
    /// Default: 512 per [SDK specification](https://opentelemetry.io/docs/specs/otel/trace/sdk/#batching-processor).
    #[config(default = 512)]
    pub(crate) max_export_batch_size: u32,

    /// Maximum queue size for pending log records.
    ///
    /// Default: 2048 per [SDK specification](https://opentelemetry.io/docs/specs/otel/trace/sdk/#batching-processor).
    #[config(default = 2048)]
    pub(crate) max_queue_size: u32,
}

impl BatchProcessorConfig for BatchLogRecordProcessorConfig {
    fn schedule_delay(&self) -> u64 {
        self.schedule_delay
    }

    fn export_timeout(&self) -> u64 {
        self.export_timeout
    }

    fn max_export_batch_size(&self) -> u32 {
        self.max_export_batch_size
    }

    fn max_queue_size(&self) -> u32 {
        self.max_queue_size
    }
}

impl BatchProcessorConfig for RateLimitedLogRecordProcessorConfig {
    fn schedule_delay(&self) -> u64 {
        self.schedule_delay
    }

    fn export_timeout(&self) -> u64 {
        self.export_timeout
    }

    fn max_export_batch_size(&self) -> u32 {
        self.max_export_batch_size
    }

    fn max_queue_size(&self) -> u32 {
        self.max_queue_size
    }
}

impl RateLimitedProcessorConfig for RateLimitedLogRecordProcessorConfig {
    fn max_rate(&self) -> u32 {
        self.max_rate
    }
}

/// Log record limits configuration.
///
/// See the [attribute limits specification](https://opentelemetry.io/docs/specs/otel/common/#attribute-limits)
/// for details on limit behavior.
#[configuration]
pub(crate) struct LogRecordLimitsConfig {
    /// Maximum number of attributes per log record.
    ///
    /// Default: 128 per [attribute limits specification](https://opentelemetry.io/docs/specs/otel/common/#attribute-limits).
    #[config(default = 128)]
    pub(crate) attribute_count_limit: u32,

    /// Maximum length of string attribute values. No limit by default.
    ///
    /// Per the [attribute limits specification](https://opentelemetry.io/docs/specs/otel/common/#attribute-limits),
    /// there is no default length limit.
    pub(crate) attribute_value_length_limit: Option<u32>,
}