|
| 1 | +# Unless explicitly stated otherwise all files in this repository are licensed |
| 2 | +# under the Apache License Version 2.0. |
| 3 | +# This product includes software developed at Datadog (https://www.datadoghq.com/). |
| 4 | +# Copyright 2019 Datadog, Inc. |
| 5 | + |
| 6 | +import logging |
| 7 | +import os |
| 8 | + |
| 9 | +logger = logging.getLogger(__name__) |
| 10 | + |
| 11 | + |
| 12 | +def _get_env(key, default=None, cast=None, depends_on_tracing=False): |
| 13 | + @property |
| 14 | + def _getter(self): |
| 15 | + if not hasattr(self, prop_key): |
| 16 | + val = self._resolve_env(key, default, cast, depends_on_tracing) |
| 17 | + setattr(self, prop_key, val) |
| 18 | + return getattr(self, prop_key) |
| 19 | + |
| 20 | + prop_key = f"_config_{key}" |
| 21 | + return _getter |
| 22 | + |
| 23 | + |
| 24 | +def as_bool(val): |
| 25 | + return val.lower() == "true" or val == "1" |
| 26 | + |
| 27 | + |
| 28 | +def as_list(val): |
| 29 | + return [val.strip() for val in val.split(",") if val.strip()] |
| 30 | + |
| 31 | + |
| 32 | +class Config: |
| 33 | + def _resolve_env(self, key, default=None, cast=None, depends_on_tracing=False): |
| 34 | + if depends_on_tracing and not self.trace_enabled: |
| 35 | + return False |
| 36 | + val = os.environ.get(key, default) |
| 37 | + if cast is not None: |
| 38 | + try: |
| 39 | + val = cast(val) |
| 40 | + except (ValueError, TypeError): |
| 41 | + msg = ( |
| 42 | + "Failed to cast environment variable '%s' with " |
| 43 | + "value '%s' to type %s. Using default value '%s'." |
| 44 | + ) |
| 45 | + logger.warning(msg, key, val, cast.__name__, default) |
| 46 | + val = default |
| 47 | + return val |
| 48 | + |
| 49 | + service = _get_env("DD_SERVICE") |
| 50 | + env = _get_env("DD_ENV") |
| 51 | + |
| 52 | + cold_start_tracing = _get_env( |
| 53 | + "DD_COLD_START_TRACING", "true", as_bool, depends_on_tracing=True |
| 54 | + ) |
| 55 | + min_cold_start_trace_duration = _get_env("DD_MIN_COLD_START_DURATION", 3, int) |
| 56 | + cold_start_trace_skip_lib = _get_env( |
| 57 | + "DD_COLD_START_TRACE_SKIP_LIB", |
| 58 | + "ddtrace.internal.compat,ddtrace.filters", |
| 59 | + as_list, |
| 60 | + ) |
| 61 | + |
| 62 | + capture_payload_max_depth = _get_env("DD_CAPTURE_LAMBDA_PAYLOAD_MAX_DEPTH", 10, int) |
| 63 | + capture_payload_enabled = _get_env("DD_CAPTURE_LAMBDA_PAYLOAD", "false", as_bool) |
| 64 | + |
| 65 | + trace_enabled = _get_env("DD_TRACE_ENABLED", "true", as_bool) |
| 66 | + make_inferred_span = _get_env( |
| 67 | + "DD_TRACE_MANAGED_SERVICES", "true", as_bool, depends_on_tracing=True |
| 68 | + ) |
| 69 | + encode_authorizer_context = _get_env( |
| 70 | + "DD_ENCODE_AUTHORIZER_CONTEXT", "true", as_bool, depends_on_tracing=True |
| 71 | + ) |
| 72 | + decode_authorizer_context = _get_env( |
| 73 | + "DD_DECODE_AUTHORIZER_CONTEXT", "true", as_bool, depends_on_tracing=True |
| 74 | + ) |
| 75 | + add_span_pointers = _get_env("DD_BOTOCORE_ADD_SPAN_POINTERS", "true", as_bool) |
| 76 | + trace_extractor = _get_env("DD_TRACE_EXTRACTOR") |
| 77 | + |
| 78 | + enhanced_metrics_enabled = _get_env("DD_ENHANCED_METRICS", "true", as_bool) |
| 79 | + |
| 80 | + flush_in_thread = _get_env("DD_FLUSH_IN_THREAD", "false", as_bool) |
| 81 | + flush_to_log = _get_env("DD_FLUSH_TO_LOG", "false", as_bool) |
| 82 | + logs_injection = _get_env("DD_LOGS_INJECTION", "true", as_bool) |
| 83 | + merge_xray_traces = _get_env("DD_MERGE_XRAY_TRACES", "false", as_bool) |
| 84 | + |
| 85 | + telemetry_enabled = _get_env( |
| 86 | + "DD_INSTRUMENTATION_TELEMETRY_ENABLED", |
| 87 | + "false", |
| 88 | + as_bool, |
| 89 | + depends_on_tracing=True, |
| 90 | + ) |
| 91 | + otel_enabled = _get_env("DD_TRACE_OTEL_ENABLED", "false", as_bool) |
| 92 | + profiling_enabled = _get_env("DD_PROFILING_ENABLED", "false", as_bool) |
| 93 | + llmobs_enabled = _get_env("DD_LLMOBS_ENABLED", "false", as_bool) |
| 94 | + exception_replay_enabled = _get_env("DD_EXCEPTION_REPLAY_ENABLED", "false", as_bool) |
| 95 | + data_streams_enabled = _get_env( |
| 96 | + "DD_DATA_STREAMS_ENABLED", "false", as_bool, depends_on_tracing=True |
| 97 | + ) |
| 98 | + |
| 99 | + is_gov_region = _get_env("AWS_REGION", "", lambda x: x.startswith("us-gov-")) |
| 100 | + |
| 101 | + local_test = _get_env("DD_LOCAL_TEST", "false", as_bool) |
| 102 | + integration_test = _get_env("DD_INTEGRATION_TEST", "false", as_bool) |
| 103 | + |
| 104 | + aws_lambda_function_name = _get_env("AWS_LAMBDA_FUNCTION_NAME") |
| 105 | + |
| 106 | + @property |
| 107 | + def function_name(self): |
| 108 | + if not hasattr(self, "_config_function_name"): |
| 109 | + if self.aws_lambda_function_name is None: |
| 110 | + self._config_function_name = "function" |
| 111 | + else: |
| 112 | + self._config_function_name = self.aws_lambda_function_name |
| 113 | + return self._config_function_name |
| 114 | + |
| 115 | + @property |
| 116 | + def is_lambda_context(self): |
| 117 | + if not hasattr(self, "_config_is_lambda_context"): |
| 118 | + self._config_is_lambda_context = bool(self.aws_lambda_function_name) |
| 119 | + return self._config_is_lambda_context |
| 120 | + |
| 121 | + @property |
| 122 | + def fips_mode_enabled(self): |
| 123 | + if not hasattr(self, "_config_fips_mode_enabled"): |
| 124 | + self._config_fips_mode_enabled = ( |
| 125 | + os.environ.get( |
| 126 | + "DD_LAMBDA_FIPS_MODE", |
| 127 | + "true" if self.is_gov_region else "false", |
| 128 | + ).lower() |
| 129 | + == "true" |
| 130 | + ) |
| 131 | + return self._config_fips_mode_enabled |
| 132 | + |
| 133 | + def _reset(self): |
| 134 | + for attr in dir(self): |
| 135 | + if attr.startswith("_config_"): |
| 136 | + delattr(self, attr) |
| 137 | + |
| 138 | + |
| 139 | +config = Config() |
| 140 | + |
| 141 | +if config.is_gov_region or config.fips_mode_enabled: |
| 142 | + logger.debug( |
| 143 | + "Python Lambda Layer FIPS mode is %s.", |
| 144 | + "enabled" if config.fips_mode_enabled else "not enabled", |
| 145 | + ) |
0 commit comments