|
2 | 2 |
|
3 | 3 | # pylint: disable=too-many-lines |
4 | 4 |
|
| 5 | +import os |
5 | 6 | import re |
6 | 7 | from enum import Enum |
7 | 8 | from functools import cached_property |
@@ -2830,6 +2831,83 @@ def compiled_patterns(self) -> CompiledPatterns: |
2830 | 2831 | return list(self._compiled_patterns) |
2831 | 2832 |
|
2832 | 2833 |
|
| 2834 | +class ObservabilityConfiguration(ConfigurationBase): |
| 2835 | + """OpenTelemetry observability configuration. |
| 2836 | +
|
| 2837 | + This configuration is automatically populated from OTEL_* environment variables |
| 2838 | + to provide visibility into the active tracing setup. |
| 2839 | +
|
| 2840 | + Attributes: |
| 2841 | + otel: Dictionary of OTEL_* environment variables with secrets redacted. |
| 2842 | + """ |
| 2843 | + |
| 2844 | + otel: dict[str, str] = Field( |
| 2845 | + default_factory=dict, |
| 2846 | + title="OpenTelemetry configuration", |
| 2847 | + description="Active OpenTelemetry configuration from OTEL_* environment variables", |
| 2848 | + ) |
| 2849 | + |
| 2850 | + @field_validator("otel", mode="before") |
| 2851 | + @classmethod |
| 2852 | + def redact_secrets(cls, value: dict[str, str]) -> dict[str, str]: |
| 2853 | + """Redact sensitive OTEL environment variables. |
| 2854 | +
|
| 2855 | + Redacts headers, certificates, and client keys for generic and signal-specific |
| 2856 | + (traces, metrics, logs) OTLP exporters. |
| 2857 | +
|
| 2858 | + Parameters: |
| 2859 | + ---------- |
| 2860 | + value: Dictionary of OTEL environment variables |
| 2861 | +
|
| 2862 | + Returns: |
| 2863 | + New dictionary with sensitive values redacted as "[REDACTED]" |
| 2864 | + """ |
| 2865 | + if not value: |
| 2866 | + return value |
| 2867 | + |
| 2868 | + # Create a new dict to avoid mutating caller's data |
| 2869 | + redacted = {} |
| 2870 | + |
| 2871 | + for key, val in value.items(): |
| 2872 | + # Redact generic and signal-specific OTLP headers |
| 2873 | + # Matches: OTEL_EXPORTER_OTLP_HEADERS, |
| 2874 | + # OTEL_EXPORTER_OTLP_TRACES_HEADERS, |
| 2875 | + # OTEL_EXPORTER_OTLP_METRICS_HEADERS, |
| 2876 | + # OTEL_EXPORTER_OTLP_LOGS_HEADERS |
| 2877 | + if "HEADERS" in key and "OTLP" in key: |
| 2878 | + redacted[key] = "[REDACTED]" |
| 2879 | + # Redact generic and signal-specific certificates |
| 2880 | + # Matches: OTEL_EXPORTER_OTLP_CERTIFICATE, |
| 2881 | + # OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE, etc. |
| 2882 | + elif "CERTIFICATE" in key and "OTLP" in key: |
| 2883 | + redacted[key] = "[REDACTED]" |
| 2884 | + # Redact generic and signal-specific client keys |
| 2885 | + # Matches: OTEL_EXPORTER_OTLP_CLIENT_KEY, |
| 2886 | + # OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY, etc. |
| 2887 | + elif "CLIENT_KEY" in key and "OTLP" in key: |
| 2888 | + redacted[key] = "[REDACTED]" |
| 2889 | + else: |
| 2890 | + redacted[key] = val |
| 2891 | + |
| 2892 | + return redacted |
| 2893 | + |
| 2894 | + @classmethod |
| 2895 | + def from_environment(cls) -> "ObservabilityConfiguration": |
| 2896 | + """Collect all OTEL_* environment variables from the environment. |
| 2897 | +
|
| 2898 | + Sensitive variables (headers, certificates, keys) are automatically redacted |
| 2899 | + by the field validator. |
| 2900 | +
|
| 2901 | + Returns: |
| 2902 | + ObservabilityConfiguration with otel dict populated from environment. |
| 2903 | + """ |
| 2904 | + otel_vars = {} |
| 2905 | + for key, value in os.environ.items(): |
| 2906 | + if key.startswith("OTEL_"): |
| 2907 | + otel_vars[key] = value |
| 2908 | + return cls(otel=otel_vars) |
| 2909 | + |
| 2910 | + |
2833 | 2911 | class Configuration(ConfigurationBase): |
2834 | 2912 | """Global service configuration.""" |
2835 | 2913 |
|
@@ -2991,6 +3069,13 @@ class Configuration(ConfigurationBase): |
2991 | 3069 | description="Splunk HEC configuration for sending telemetry events.", |
2992 | 3070 | ) |
2993 | 3071 |
|
| 3072 | + observability: ObservabilityConfiguration = Field( |
| 3073 | + default_factory=ObservabilityConfiguration.from_environment, |
| 3074 | + title="Observability configuration", |
| 3075 | + description="OpenTelemetry and observability configuration collected " |
| 3076 | + "from OTEL_* environment variables.", |
| 3077 | + ) |
| 3078 | + |
2994 | 3079 | deployment_environment: str = Field( |
2995 | 3080 | "development", |
2996 | 3081 | title="Deployment environment", |
|
0 commit comments