Skip to content

Commit e9469f0

Browse files
committed
Consolidate env reading to single config object.
1 parent 1d6d28f commit e9469f0

File tree

9 files changed

+102
-70
lines changed

9 files changed

+102
-70
lines changed

datadog_lambda/api.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import logging
22
import os
33

4-
from datadog_lambda.fips import fips_mode_enabled
4+
from datadog_lambda.config import config
55

66
logger = logging.getLogger(__name__)
77
KMS_ENCRYPTION_CONTEXT_KEY = "LambdaFunctionName"
@@ -29,7 +29,6 @@ def decrypt_kms_api_key(kms_client, ciphertext):
2929
is added. We need to try decrypting the API key both with and without the encryption context.
3030
"""
3131
# Try without encryption context, in case API key was encrypted using the AWS CLI
32-
function_name = os.environ.get("AWS_LAMBDA_FUNCTION_NAME")
3332
try:
3433
plaintext = kms_client.decrypt(CiphertextBlob=decoded_bytes)[
3534
"Plaintext"
@@ -43,7 +42,7 @@ def decrypt_kms_api_key(kms_client, ciphertext):
4342
plaintext = kms_client.decrypt(
4443
CiphertextBlob=decoded_bytes,
4544
EncryptionContext={
46-
KMS_ENCRYPTION_CONTEXT_KEY: function_name,
45+
KMS_ENCRYPTION_CONTEXT_KEY: config.function_name,
4746
},
4847
)["Plaintext"].decode("utf-8")
4948

@@ -66,7 +65,7 @@ def get_api_key() -> str:
6665
DD_API_KEY = os.environ.get("DD_API_KEY", os.environ.get("DATADOG_API_KEY", ""))
6766

6867
LAMBDA_REGION = os.environ.get("AWS_REGION", "")
69-
if fips_mode_enabled:
68+
if config.fips_mode_enabled:
7069
logger.debug(
7170
"FIPS mode is enabled, using FIPS endpoints for secrets management."
7271
)
@@ -82,7 +81,7 @@ def get_api_key() -> str:
8281
return ""
8382
endpoint_url = (
8483
f"https://secretsmanager-fips.{secrets_region}.amazonaws.com"
85-
if fips_mode_enabled
84+
if config.fips_mode_enabled
8685
else None
8786
)
8887
secrets_manager_client = _boto3_client(
@@ -95,7 +94,7 @@ def get_api_key() -> str:
9594
# SSM endpoints: https://docs.aws.amazon.com/general/latest/gr/ssm.html
9695
fips_endpoint = (
9796
f"https://ssm-fips.{LAMBDA_REGION}.amazonaws.com"
98-
if fips_mode_enabled
97+
if config.fips_mode_enabled
9998
else None
10099
)
101100
ssm_client = _boto3_client("ssm", endpoint_url=fips_endpoint)
@@ -106,7 +105,7 @@ def get_api_key() -> str:
106105
# KMS endpoints: https://docs.aws.amazon.com/general/latest/gr/kms.html
107106
fips_endpoint = (
108107
f"https://kms-fips.{LAMBDA_REGION}.amazonaws.com"
109-
if fips_mode_enabled
108+
if config.fips_mode_enabled
110109
else None
111110
)
112111
kms_client = _boto3_client("kms", endpoint_url=fips_endpoint)
@@ -118,7 +117,7 @@ def get_api_key() -> str:
118117

119118

120119
def init_api():
121-
if not os.environ.get("DD_FLUSH_TO_LOG", "").lower() == "true":
120+
if not config.flush_to_log:
122121
# Make sure that this package would always be lazy-loaded/outside from the critical path
123122
# since underlying packages are quite heavy to load
124123
# and useless with the extension unless sending metrics with timestamps

datadog_lambda/cold_start.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
from typing import List, Hashable
44
import logging
55

6+
from datadog_lambda.config import config
7+
68
logger = logging.getLogger(__name__)
79

810
_cold_start = True
@@ -147,11 +149,7 @@ def wrapped_find_spec(*args, **kwargs):
147149

148150

149151
def initialize_cold_start_tracing():
150-
if (
151-
is_new_sandbox()
152-
and os.environ.get("DD_TRACE_ENABLED", "true").lower() == "true"
153-
and os.environ.get("DD_COLD_START_TRACING", "true").lower() == "true"
154-
):
152+
if is_new_sandbox() and config.trace_enabled and config.cold_start_tracing:
155153
from sys import meta_path
156154

157155
for importer in meta_path:

datadog_lambda/config.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
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+
10+
def _get_env(key, default=None, cast=None):
11+
"""Get an environment variable with a default value."""
12+
val = os.environ.get(key, default)
13+
if cast is not None:
14+
try:
15+
val = cast(val)
16+
except ValueError:
17+
raise ValueError(f"Invalid value for {key}: {val}")
18+
return cast(default)
19+
return val
20+
21+
22+
def as_bool(val):
23+
"""Convert a string to a boolean."""
24+
if isinstance(val, bool):
25+
return val
26+
if isinstance(val, str):
27+
val = val.lower()
28+
if val in ("true", "1", "yes"):
29+
return True
30+
return False
31+
32+
33+
class config:
34+
35+
function_name = os.environ.get("AWS_LAMBDA_FUNCTION_NAME")
36+
flush_to_log = os.environ.get("DD_FLUSH_TO_LOG", "").lower() == "true"
37+
trace_enabled = os.environ.get("DD_TRACE_ENABLED", "true").lower() == "true"
38+
cold_start_tracing = os.environ.get("DD_COLD_START_TRACING", "true").lower() == "true"
39+
is_gov_region = os.environ.get("AWS_REGION", "").startswith("us-gov-")
40+
fips_mode_enabled = (
41+
os.environ.get(
42+
"DD_LAMBDA_FIPS_MODE",
43+
"true" if is_gov_region else "false",
44+
).lower()
45+
== "true"
46+
)
47+
log_level = (os.environ.get("DD_LOG_LEVEL") or "INFO").upper()
48+
flush_in_thread = os.environ.get("DD_FLUSH_IN_THREAD", "").lower() == "true"
49+
enhanced_metrics_enabled = (
50+
os.environ.get("DD_ENHANCED_METRICS", "true").lower() == "true"
51+
)
52+
is_in_tests = os.environ.get("DD_INTEGRATION_TEST", "false").lower() == "true"
53+
add_span_pointers = os.environ.get(
54+
"DD_BOTOCORE_ADD_SPAN_POINTERS", "true"
55+
).lower() in ("true", "1")
56+
otel_enabled = (
57+
os.environ.get("DD_TRACE_OTEL_ENABLED", "false").lower() == "true"
58+
)
59+
is_lambda_context = bool(function_name)
60+
telemetry_enabled = os.environ.get(
61+
"DD_INSTRUMENTATION_TELEMETRY_ENABLED", "false").lower()
62+
== "true"
63+
)
64+
65+
66+
if config.is_gov_region or config.fips_mode_enabled:
67+
logger = logging.getLogger(__name__)
68+
logger.debug(
69+
"Python Lambda Layer FIPS mode is %s.",
70+
"enabled" if fips_mode_enabled else "not enabled",
71+
)

datadog_lambda/fips.py

Lines changed: 0 additions & 19 deletions
This file was deleted.

datadog_lambda/logger.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import logging
22
import os
33

4+
from datadog_lambda.config import config
5+
46
try:
57
_level_mappping = logging.getLevelNamesMapping()
68
except AttributeError:
@@ -18,10 +20,9 @@
1820

1921
def initialize_logging(name):
2022
logger = logging.getLogger(name)
21-
str_level = (os.environ.get("DD_LOG_LEVEL") or "INFO").upper()
22-
level = _level_mappping.get(str_level)
23+
level = _level_mappping.get(config.log_level)
2324
if level is None:
2425
logger.setLevel(logging.INFO)
25-
logger.warning("Invalid log level: %s Defaulting to INFO", str_level)
26+
logger.warning("Invalid log level: %s Defaulting to INFO", config.log_level)
2627
else:
2728
logger.setLevel(level)

datadog_lambda/metric.py

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111

1212
import ujson as json
1313

14+
from datadog_lambda.config import config
1415
from datadog_lambda.extension import should_use_extension
15-
from datadog_lambda.fips import fips_mode_enabled
1616
from datadog_lambda.tags import dd_lambda_layer_tag, get_enhanced_metrics_tags
1717

1818
logger = logging.getLogger(__name__)
@@ -28,10 +28,10 @@ class MetricsHandler(enum.Enum):
2828
def _select_metrics_handler():
2929
if should_use_extension:
3030
return MetricsHandler.EXTENSION
31-
if os.environ.get("DD_FLUSH_TO_LOG", "").lower() == "true":
31+
if config.flush_to_log:
3232
return MetricsHandler.FORWARDER
3333

34-
if fips_mode_enabled:
34+
if config.fips_mode_enabled:
3535
logger.debug(
3636
"With FIPS mode enabled, the Datadog API metrics handler is unavailable."
3737
)
@@ -58,14 +58,8 @@ def _select_metrics_handler():
5858
from datadog_lambda.api import init_api
5959
from datadog_lambda.thread_stats_writer import ThreadStatsWriter
6060

61-
flush_in_thread = os.environ.get("DD_FLUSH_IN_THREAD", "").lower() == "true"
6261
init_api()
63-
lambda_stats = ThreadStatsWriter(flush_in_thread)
64-
65-
66-
enhanced_metrics_enabled = (
67-
os.environ.get("DD_ENHANCED_METRICS", "true").lower() == "true"
68-
)
62+
lambda_stats = ThreadStatsWriter(config.flush_in_thread)
6963

7064

7165
def lambda_metric(metric_name, value, timestamp=None, tags=None, force_async=False):
@@ -191,7 +185,7 @@ def submit_enhanced_metric(metric_name, lambda_context):
191185
metric_name (str): metric name w/o enhanced prefix i.e. "invocations" or "errors"
192186
lambda_context (object): Lambda context dict passed to the function by AWS
193187
"""
194-
if not enhanced_metrics_enabled:
188+
if not config.enhanced_metrics_enabled:
195189
logger.debug(
196190
"Not submitting enhanced metric %s because enhanced metrics are disabled",
197191
metric_name,

datadog_lambda/patch.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from wrapt.importer import when_imported
1414
from ddtrace import patch_all as patch_all_dd
1515

16+
from datadog_lambda import config
1617
from datadog_lambda.tracing import (
1718
get_dd_trace_context,
1819
dd_tracing_enabled,
@@ -44,8 +45,7 @@ def _patch_for_integration_tests():
4445
Patch `requests` to log the outgoing requests for integration tests.
4546
"""
4647
global _integration_tests_patched
47-
is_in_tests = os.environ.get("DD_INTEGRATION_TEST", "false").lower() == "true"
48-
if not _integration_tests_patched and is_in_tests:
48+
if not _integration_tests_patched and config.is_in_tests:
4949
wrap("requests", "Session.send", _log_request)
5050
_integration_tests_patched = True
5151

datadog_lambda/span_pointers.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,18 @@
77
from ddtrace._trace._span_pointer import _SpanPointerDirection
88
from ddtrace._trace._span_pointer import _SpanPointerDescription
99

10+
from datadog_lambda import config
1011
from datadog_lambda.metric import submit_dynamodb_stream_type_metric
1112
from datadog_lambda.trigger import EventTypes
1213

1314

1415
logger = logging.getLogger(__name__)
1516

1617

17-
dd_botocore_add_span_pointers = os.environ.get(
18-
"DD_BOTOCORE_ADD_SPAN_POINTERS", "true"
19-
).lower() in ("true", "1")
20-
21-
2218
def calculate_span_pointers(
2319
event_source,
2420
event,
25-
botocore_add_span_pointers=dd_botocore_add_span_pointers,
21+
botocore_add_span_pointers=config.add_span_pointers,
2622
) -> List[_SpanPointerDescription]:
2723
try:
2824
if botocore_add_span_pointers:

datadog_lambda/tracing.py

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
from ddtrace import __version__ as ddtrace_version
3333
from ddtrace.propagation.http import HTTPPropagator
3434
from ddtrace.trace import Context, Span, tracer
35+
36+
from datadog_lambda import config
3537
from datadog_lambda import __version__ as datadog_lambda_version
3638
from datadog_lambda.trigger import (
3739
_EventSource,
@@ -42,10 +44,7 @@
4244
EventSubtypes,
4345
)
4446

45-
dd_trace_otel_enabled = (
46-
os.environ.get("DD_TRACE_OTEL_ENABLED", "false").lower() == "true"
47-
)
48-
if dd_trace_otel_enabled:
47+
if config.otel_enabled:
4948
from opentelemetry.trace import set_tracer_provider
5049
from ddtrace.opentelemetry import TracerProvider
5150

@@ -55,18 +54,11 @@
5554
logger = logging.getLogger(__name__)
5655

5756
dd_trace_context = None
58-
dd_tracing_enabled = os.environ.get("DD_TRACE_ENABLED", "false").lower() == "true"
59-
if dd_tracing_enabled:
57+
if config.trace_enabled and config.telemetry_enabled:
6058
# Enable the telemetry client if the user has opted in
61-
if (
62-
os.environ.get("DD_INSTRUMENTATION_TELEMETRY_ENABLED", "false").lower()
63-
== "true"
64-
):
65-
from ddtrace.internal.telemetry import telemetry_writer
66-
67-
telemetry_writer.enable()
59+
from ddtrace.internal.telemetry import telemetry_writer
6860

69-
is_lambda_context = os.environ.get(XrayDaemon.FUNCTION_NAME_HEADER_NAME) != ""
61+
telemetry_writer.enable()
7062

7163
propagator = HTTPPropagator()
7264

@@ -97,7 +89,7 @@ def _convert_xray_sampling(xray_sampled):
9789

9890

9991
def _get_xray_trace_context():
100-
if not is_lambda_context:
92+
if not config.is_lambda_context:
10193
return None
10294

10395
xray_trace_entity = parse_xray_header(
@@ -690,7 +682,7 @@ def set_correlation_ids():
690682
691683
TODO: Remove me when Datadog tracer is natively supported in Lambda.
692684
"""
693-
if not is_lambda_context:
685+
if not config.is_lambda_context:
694686
logger.debug("set_correlation_ids is only supported in LambdaContext")
695687
return
696688
if dd_tracing_enabled:

0 commit comments

Comments
 (0)